Merge pull request #181 from matiu/walletNames
add wallets nicknames, handle error messages
This commit is contained in:
commit
9acff3db3f
8 changed files with 98 additions and 48 deletions
25
index.html
25
index.html
|
|
@ -17,7 +17,13 @@
|
||||||
<a href="#"><img src="./img/logo-negative.svg" alt="Copay" width="130" /></a>
|
<a href="#"><img src="./img/logo-negative.svg" alt="Copay" width="130" /></a>
|
||||||
</figure>
|
</figure>
|
||||||
<div class="text-right" ng-show="$root.wallet">
|
<div class="text-right" ng-show="$root.wallet">
|
||||||
<h5 ng-show="$root.wallet.id">Wallet ID: {{$root.wallet.id}}</h5>
|
<div ng-if="$root.wallet.name">
|
||||||
|
<h5>Wallet: {{$root.wallet.name}} <{{$root.wallet.id}}></h5>
|
||||||
|
<p>
|
||||||
|
</div>
|
||||||
|
<div ng-if="!$root.wallet.name && $root.wallet.id">
|
||||||
|
<h5 >Wallet ID: {{$root.wallet.id}}</h5>
|
||||||
|
</div>
|
||||||
<p>
|
<p>
|
||||||
Balance: {{totalBalance || 0}} <i class="fi-bitcoin"></i><br>
|
Balance: {{totalBalance || 0}} <i class="fi-bitcoin"></i><br>
|
||||||
Available to Spend: {{availableBalance || 0}} <i class="fi-bitcoin"></i>
|
Available to Spend: {{availableBalance || 0}} <i class="fi-bitcoin"></i>
|
||||||
|
|
@ -98,7 +104,7 @@
|
||||||
Connecting to wallet...
|
Connecting to wallet...
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="!loading">
|
<div ng-show="!loading">
|
||||||
<div ng-show="!walletIds.length">
|
<div ng-show="!wallets.length">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="large-6 columns">
|
<div class="large-6 columns">
|
||||||
<h3>Create a New Wallet</h3>
|
<h3>Create a New Wallet</h3>
|
||||||
|
|
@ -109,12 +115,12 @@
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="walletIds.length">
|
<div ng-show="wallets.length">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="large-6 columns">
|
<div class="large-6 columns">
|
||||||
<h3>Open Wallet</h3>
|
<h3>Open Wallet</h3>
|
||||||
<select class="form-control" ng-model="selectedWalletId"
|
<select class="form-control" ng-model="selectedWalletId"
|
||||||
ng-options="walletId for walletId in walletIds">
|
ng-options="w.id as w.show for w in wallets">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="large-3 columns">
|
<div class="large-3 columns">
|
||||||
|
|
@ -141,7 +147,7 @@
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="large-12 columns">
|
<div class="large-12 columns">
|
||||||
<div ng-show="walletIds.length">
|
<div ng-show="wallets.length">
|
||||||
<a ng-click="create()">Create a new wallet</a>
|
<a ng-click="create()">Create a new wallet</a>
|
||||||
</div>
|
</div>
|
||||||
<a class="right" ng-click="import()">Import from file</a>
|
<a class="right" ng-click="import()">Import from file</a>
|
||||||
|
|
@ -176,10 +182,15 @@
|
||||||
ng-options="requiredCopayers as requiredCopayers for requiredCopayers in RCValues">
|
ng-options="requiredCopayers as requiredCopayers for requiredCopayers in RCValues">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="large-6 large-centered columns">
|
<div class="large-6 large-centered columns m30v">
|
||||||
|
<h6>Wallet name (optional)</h6>
|
||||||
|
<input ng-model="walletName" placeholder="wallet name" class="size-24" style="width:100%">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="large-6 large-centered columns m30v">
|
||||||
<hr>
|
<hr>
|
||||||
<button class="button primary round right" type="button"
|
<button class="button primary round right" type="button"
|
||||||
ng-click="create(totalCopayers, requiredCopayers)">
|
ng-click="create(totalCopayers, requiredCopayers, walletName)">
|
||||||
Create {{requiredCopayers}}-of-{{totalCopayers}} wallet
|
Create {{requiredCopayers}}-of-{{totalCopayers}} wallet
|
||||||
</button>
|
</button>
|
||||||
<div class="left">
|
<div class="left">
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,12 @@ angular.module('copay.setup').controller('SetupController',
|
||||||
updateRCSelect(tc);
|
updateRCSelect(tc);
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.create = function(totalCopayers, requiredCopayers) {
|
$scope.create = function(totalCopayers, requiredCopayers, walletName) {
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
var opts = {
|
var opts = {
|
||||||
requiredCopayers: requiredCopayers,
|
requiredCopayers: requiredCopayers,
|
||||||
totalCopayers: totalCopayers
|
totalCopayers: totalCopayers,
|
||||||
|
name: walletName,
|
||||||
};
|
};
|
||||||
var w = walletFactory.create(opts);
|
var w = walletFactory.create(opts);
|
||||||
controllerUtils.setupUxHandlers(w);
|
controllerUtils.setupUxHandlers(w);
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
angular.module('copay.signin').controller('SigninController',
|
angular.module('copay.signin').controller('SigninController',
|
||||||
function($scope, $rootScope, $location, walletFactory, controllerUtils) {
|
function($scope, $rootScope, $location, walletFactory, controllerUtils) {
|
||||||
$scope.loading = false;
|
$scope.loading = false;
|
||||||
$scope.walletIds = walletFactory.getWalletIds();
|
$scope.wallets = walletFactory.getWallets();
|
||||||
$scope.selectedWalletId = $scope.walletIds.length ? $scope.walletIds[0]:null;
|
$scope.selectedWalletId = $scope.wallets.length ? $scope.wallets[0].id : null;
|
||||||
|
|
||||||
$scope.create = function() {
|
$scope.create = function() {
|
||||||
$location.path('setup');
|
$location.path('setup');
|
||||||
|
|
@ -12,14 +12,13 @@ angular.module('copay.signin').controller('SigninController',
|
||||||
|
|
||||||
$scope.open = function(walletId, opts) {
|
$scope.open = function(walletId, opts) {
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
|
|
||||||
console.log('[signin.js.23:walletId:]',walletId); //TODO
|
|
||||||
var w = walletFactory.open(walletId, opts);
|
var w = walletFactory.open(walletId, opts);
|
||||||
controllerUtils.setupUxHandlers(w);
|
controllerUtils.setupUxHandlers(w);
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.join = function(secret) {
|
$scope.join = function(secret) {
|
||||||
if (!secret || !secret.length) {
|
if (!secret || secret.length !==66 || !secret.match(/^[0-9a-f]*$/) ) {
|
||||||
|
$rootScope.flashMessage = { message: 'Bad secret secret string', type: 'error'};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$scope.loading = true;
|
$scope.loading = true;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ function Wallet(opts) {
|
||||||
this.log('creating '+opts.requiredCopayers+' of '+opts.totalCopayers+' wallet');
|
this.log('creating '+opts.requiredCopayers+' of '+opts.totalCopayers+' wallet');
|
||||||
|
|
||||||
this.id = opts.id || Wallet.getRandomId();
|
this.id = opts.id || Wallet.getRandomId();
|
||||||
|
this.name = opts.name;
|
||||||
this.verbose = opts.verbose;
|
this.verbose = opts.verbose;
|
||||||
this.publicKeyRing.walletId = this.id;
|
this.publicKeyRing.walletId = this.id;
|
||||||
this.txProposals.walletId = this.id;
|
this.txProposals.walletId = this.id;
|
||||||
|
|
@ -137,6 +138,7 @@ Wallet.prototype._optsToObj = function () {
|
||||||
spendUnconfirmed: this.spendUnconfirmed,
|
spendUnconfirmed: this.spendUnconfirmed,
|
||||||
requiredCopayers: this.requiredCopayers,
|
requiredCopayers: this.requiredCopayers,
|
||||||
totalCopayers: this.totalCopayers,
|
totalCopayers: this.totalCopayers,
|
||||||
|
name: this.name,
|
||||||
};
|
};
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
|
@ -172,6 +174,7 @@ Wallet.prototype.netStart = function() {
|
||||||
copayerId: myId,
|
copayerId: myId,
|
||||||
signingKeyHex: self.privateKey.getSigningKey(),
|
signingKeyHex: self.privateKey.getSigningKey(),
|
||||||
};
|
};
|
||||||
|
|
||||||
net.start(startOpts, function() {
|
net.start(startOpts, function() {
|
||||||
self.emit('created');
|
self.emit('created');
|
||||||
for (var i=0; i<self.publicKeyRing.registeredCopayers(); i++) {
|
for (var i=0; i<self.publicKeyRing.registeredCopayers(); i++) {
|
||||||
|
|
@ -518,6 +521,8 @@ Wallet.prototype.connectTo = function(peerId) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.disconnect = function() {
|
Wallet.prototype.disconnect = function() {
|
||||||
|
|
||||||
|
console.log('[Wallet.js.524] DISC'); //TODO
|
||||||
this.network.disconnect();
|
this.network.disconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ WalletFactory.prototype.read = function(walletId) {
|
||||||
w.privateKey.getExtendedPublicKeyString()
|
w.privateKey.getExtendedPublicKeyString()
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.log('NOT NECCESARY AN ERROR:', e); //TODO
|
// No really an error, just to be sure.
|
||||||
}
|
}
|
||||||
this.log('### WALLET OPENED:', w.id);
|
this.log('### WALLET OPENED:', w.id);
|
||||||
return w;
|
return w;
|
||||||
|
|
@ -129,9 +129,13 @@ WalletFactory.prototype.open = function(walletId, opts) {
|
||||||
return w;
|
return w;
|
||||||
};
|
};
|
||||||
|
|
||||||
WalletFactory.prototype.getWalletIds = function() {
|
WalletFactory.prototype.getWallets = function() {
|
||||||
return this.storage.getWalletIds();
|
var ret = this.storage.getWallets();
|
||||||
}
|
ret.forEach(function(i) {
|
||||||
|
i.show = i.name ? ( (i.name + ' <'+i.id+'>') ) : i.id;
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
WalletFactory.prototype.remove = function(walletId) {
|
WalletFactory.prototype.remove = function(walletId) {
|
||||||
// TODO remove wallet contents
|
// TODO remove wallet contents
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,7 @@ Network.prototype._onData = function(data, isInbound, peerId) {
|
||||||
Network.prototype._checkAnyPeer = function() {
|
Network.prototype._checkAnyPeer = function() {
|
||||||
if (!this.connectedPeers.length) {
|
if (!this.connectedPeers.length) {
|
||||||
console.log('EMIT openError: no more peers, not even you!');
|
console.log('EMIT openError: no more peers, not even you!');
|
||||||
|
this._cleanUp();
|
||||||
this.emit('openError');
|
this.emit('openError');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -251,8 +252,9 @@ Network.prototype._setupPeerHandlers = function(openCallback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
p.on('error', function(err) {
|
p.on('error', function(err) {
|
||||||
console.log('### PEER ERROR:', err);
|
if (!err.message.match(/Could\snot\sconnect\sto peer/)) {
|
||||||
//self.disconnect(null, true); // force disconnect
|
console.log('### PEER ERROR:', err);
|
||||||
|
}
|
||||||
self._checkAnyPeer();
|
self._checkAnyPeer();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -311,11 +313,12 @@ Network.prototype.start = function(opts, openCallback) {
|
||||||
if (this.started) return openCallback();
|
if (this.started) return openCallback();
|
||||||
opts.connectedPeers = opts.connectedPeers || [];
|
opts.connectedPeers = opts.connectedPeers || [];
|
||||||
|
|
||||||
if (!this.copayerId)
|
if (!this.copayerId)
|
||||||
this.setCopayerId(opts.copayerId);
|
this.setCopayerId(opts.copayerId);
|
||||||
if (!this.signingKey)
|
if (!this.signingKey)
|
||||||
this.setSigningKey(opts.signingKeyHex);
|
this.setSigningKey(opts.signingKeyHex);
|
||||||
|
|
||||||
|
console.log('CREATING PEER INSTANCE:', this.peerId); //TODO
|
||||||
this.peer = new Peer(this.peerId, this.opts);
|
this.peer = new Peer(this.peerId, this.opts);
|
||||||
this._setupPeerHandlers(openCallback);
|
this._setupPeerHandlers(openCallback);
|
||||||
for (var i = 0; i<opts.connectedPeers.length; i++) {
|
for (var i = 0; i<opts.connectedPeers.length; i++) {
|
||||||
|
|
@ -399,27 +402,28 @@ Network.prototype.connectTo = function(copayerId) {
|
||||||
self._setupConnectionHandlers(dataConn, false);
|
self._setupConnectionHandlers(dataConn, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Network.prototype._cleanUp = function() {
|
||||||
|
self.connectedPeers = [];
|
||||||
|
self.started = false;
|
||||||
|
self.peerId = null;
|
||||||
|
self.copayerId = null;
|
||||||
|
self.signingKey = null;
|
||||||
|
if (self.peer) {
|
||||||
|
console.log('## DESTROYING PEER INSTANCE'); //TODO
|
||||||
|
self.peer.disconnect();
|
||||||
|
self.peer.destroy();
|
||||||
|
self.peer = null;
|
||||||
|
}
|
||||||
|
self.closing = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Network.prototype.disconnect = function(cb, forced) {
|
Network.prototype.disconnect = function(cb, forced) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.closing = 1;
|
self.closing = 1;
|
||||||
var cleanUp = function() {
|
this.send(null, { type: 'disconnect' });
|
||||||
self.connectedPeers = [];
|
this._cleanUp();
|
||||||
self.started = false;
|
if (typeof cb === 'function') cb();
|
||||||
self.peerId = null;
|
|
||||||
if (self.peer) {
|
|
||||||
self.peer.disconnect();
|
|
||||||
self.peer.destroy();
|
|
||||||
self.peer = null;
|
|
||||||
}
|
|
||||||
self.closing = 0;
|
|
||||||
if (typeof cb === 'function') cb();
|
|
||||||
};
|
|
||||||
if (!forced) {
|
|
||||||
this.send(null, { type: 'disconnect' }, cleanUp);
|
|
||||||
} else {
|
|
||||||
cleanUp();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = require('soop')(Network);
|
module.exports = require('soop')(Network);
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ Storage.prototype._getWalletKeys = function(walletId) {
|
||||||
for (var i = 0; i < localStorage.length; i++) {
|
for (var i = 0; i < localStorage.length; i++) {
|
||||||
var key = localStorage.key(i);
|
var key = localStorage.key(i);
|
||||||
var split = key.split('::');
|
var split = key.split('::');
|
||||||
if (split.length == 2) {
|
if (split.length == 3) {
|
||||||
if (walletId = split[0])
|
if (walletId = split[0])
|
||||||
keys.push(split[1]);
|
keys.push(split[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,30 +69,54 @@ Storage.prototype.remove = function(walletId, k) {
|
||||||
this.removeGlobal(this._key(walletId,k));
|
this.removeGlobal(this._key(walletId,k));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Storage.prototype.setName = function(walletId, name) {
|
||||||
|
this.setGlobal('nameFor::'+walletId, name);
|
||||||
|
};
|
||||||
|
|
||||||
|
Storage.prototype.getName = function(walletId) {
|
||||||
|
return this.getGlobal('nameFor::'+walletId);
|
||||||
|
};
|
||||||
|
|
||||||
Storage.prototype.getWalletIds = function() {
|
Storage.prototype.getWalletIds = function() {
|
||||||
var walletIds = [];
|
var walletIds = [];
|
||||||
var uniq = {};
|
var uniq = {};
|
||||||
|
|
||||||
for (var i = 0; i < localStorage.length; i++) {
|
for (var i = 0; i < localStorage.length; i++) {
|
||||||
var key = localStorage.key(i);
|
var key = localStorage.key(i);
|
||||||
var split = key.split('::');
|
var split = key.split('::');
|
||||||
if (split.length == 2) {
|
if (split.length == 2) {
|
||||||
var walletId = split[0];
|
var walletId = split[0];
|
||||||
|
|
||||||
|
if (walletId === 'nameFor') continue;
|
||||||
|
|
||||||
if (typeof uniq[walletId] === 'undefined' ) {
|
if (typeof uniq[walletId] === 'undefined' ) {
|
||||||
walletIds.push(walletId);
|
walletIds.push(walletId);
|
||||||
uniq[walletId] = 1;
|
uniq[walletId] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return walletIds;
|
return walletIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Storage.prototype.getWallets = function() {
|
||||||
|
var wallets = [];
|
||||||
|
var uniq = {};
|
||||||
|
var ids = this.getWalletIds();
|
||||||
|
|
||||||
|
for (var i in ids){
|
||||||
|
wallets.push({
|
||||||
|
id:ids[i],
|
||||||
|
name: this.getName(ids[i]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return wallets;
|
||||||
|
};
|
||||||
|
|
||||||
//obj contains keys to be set
|
//obj contains keys to be set
|
||||||
Storage.prototype.setFromObj = function(walletId, obj) {
|
Storage.prototype.setFromObj = function(walletId, obj) {
|
||||||
for (var k in obj) {
|
for (var k in obj) {
|
||||||
this.set(walletId, k, obj[k]);
|
this.set(walletId, k, obj[k]);
|
||||||
}
|
}
|
||||||
|
this.setName(walletId, obj.opts.name);
|
||||||
};
|
};
|
||||||
|
|
||||||
// remove all values
|
// remove all values
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@ angular.module('copay.controllerUtils').factory('controllerUtils', function ($ro
|
||||||
|
|
||||||
root.updateBalance = function() {
|
root.updateBalance = function() {
|
||||||
var w = $rootScope.wallet;
|
var w = $rootScope.wallet;
|
||||||
|
if (!w) return;
|
||||||
|
|
||||||
w.getBalance(false,function(balance, balanceByAddr) {
|
w.getBalance(false,function(balance, balanceByAddr) {
|
||||||
$rootScope.totalBalance = balance;
|
$rootScope.totalBalance = balance;
|
||||||
$rootScope.balanceByAddr = balanceByAddr;
|
$rootScope.balanceByAddr = balanceByAddr;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue