commit
1dc420b215
9 changed files with 351 additions and 8 deletions
|
|
@ -2,13 +2,27 @@
|
|||
var bitcore = require('bitcore');
|
||||
|
||||
angular.module('copayApp.controllers').controller('SendController',
|
||||
function($scope, $rootScope, $window, $location, $timeout) {
|
||||
function($scope, $rootScope, $window, $location, $timeout, $anchorScroll, $modal) {
|
||||
$scope.title = 'Send';
|
||||
$scope.loading = false;
|
||||
var satToUnit = 1 / config.unitToSatoshi;
|
||||
$scope.defaultFee = bitcore.TransactionBuilder.FEE_PER_1000B_SAT * satToUnit;
|
||||
$scope.unitToBtc = config.unitToSatoshi / bitcore.util.COIN;
|
||||
|
||||
$scope.showAddressBook = function() {
|
||||
var w = $rootScope.wallet;
|
||||
var flag;
|
||||
if (w) {
|
||||
for (var k in w.addressBook) {
|
||||
if (w.addressBook[k].copayerId != -1) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
};
|
||||
|
||||
// TODO this shouldnt be on a particular controller.
|
||||
// Detect mobile devices
|
||||
var isMobile = {
|
||||
|
|
@ -187,4 +201,80 @@ angular.module('copayApp.controllers').controller('SendController',
|
|||
}
|
||||
}, 500);
|
||||
};
|
||||
|
||||
$scope.deleteAddressBook = function(addressBook) {
|
||||
var w = $rootScope.wallet;
|
||||
$timeout(function() {
|
||||
var errorMsg;
|
||||
try {
|
||||
w.deleteAddressBook(addressBook);
|
||||
} catch (e) {
|
||||
errorMsg = e.message;
|
||||
}
|
||||
|
||||
$rootScope.$flashMessage = {
|
||||
message: errorMsg ? errorMsg : 'Entry removed successful',
|
||||
type: errorMsg ? 'error' : 'success'
|
||||
};
|
||||
$rootScope.$digest();
|
||||
}, 500);
|
||||
};
|
||||
|
||||
$scope.copyAddress = function(address) {
|
||||
$scope.address = address;
|
||||
$anchorScroll();
|
||||
};
|
||||
|
||||
$scope.openAddressBookModal = function() {
|
||||
var modalInstance = $modal.open({
|
||||
templateUrl: 'addressBookModal.html',
|
||||
windowClass: 'tiny',
|
||||
controller: function($scope, $modalInstance) {
|
||||
|
||||
$scope.submitAddressBook = function(form) {
|
||||
if (form.$invalid) {
|
||||
$rootScope.$flashMessage = {
|
||||
message: 'Complete required fields, please',
|
||||
type: 'error'
|
||||
};
|
||||
return;
|
||||
}
|
||||
var entry = {
|
||||
"address": form.newaddress.$modelValue,
|
||||
"label": form.newlabel.$modelValue
|
||||
};
|
||||
form.newaddress.$pristine = form.newlabel.$pristine = true;
|
||||
$modalInstance.close(entry);
|
||||
};
|
||||
|
||||
$scope.cancel = function() {
|
||||
$modalInstance.dismiss('cancel');
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
modalInstance.result.then(function(entry) {
|
||||
var w = $rootScope.wallet;
|
||||
|
||||
$timeout(function() {
|
||||
$scope.loading = false;
|
||||
var errorMsg;
|
||||
try {
|
||||
w.setAddressBook(entry.address, entry.label);
|
||||
} catch (e) {
|
||||
errorMsg = e.message;
|
||||
}
|
||||
|
||||
$rootScope.$flashMessage = {
|
||||
message: errorMsg ? errorMsg : 'New entry has been created',
|
||||
type: errorMsg ? 'error' : 'success'
|
||||
};
|
||||
$rootScope.$digest();
|
||||
}, 500);
|
||||
$anchorScroll();
|
||||
// reset fields
|
||||
$scope.newaddress = $scope.newlabel = null;
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -45,12 +45,13 @@ function Wallet(opts) {
|
|||
this.token = opts.token;
|
||||
this.tokenTime = opts.tokenTime;
|
||||
}
|
||||
|
||||
|
||||
this.verbose = opts.verbose;
|
||||
this.publicKeyRing.walletId = this.id;
|
||||
this.txProposals.walletId = this.id;
|
||||
this.network.maxPeers = this.totalCopayers;
|
||||
this.registeredPeerIds = [];
|
||||
this.addressBook = opts.addressBook || {};
|
||||
}
|
||||
|
||||
Wallet.parent = EventEmitter;
|
||||
|
|
@ -133,6 +134,28 @@ Wallet.prototype._handleTxProposal = function(senderId, data) {
|
|||
}
|
||||
};
|
||||
|
||||
Wallet.prototype._handleAddressBook = function(senderId, data, isInbound) {
|
||||
this.log('RECV ADDRESSBOOK:', data);
|
||||
var rcv = data.addressBook;
|
||||
var hasChange;
|
||||
for(var key in rcv) {
|
||||
if (!this.addressBook[key]) {
|
||||
this.addressBook[key] = rcv[key];
|
||||
hasChange = true;
|
||||
}
|
||||
else {
|
||||
if (rcv[key].createdTs > this.addressBook[key].createdTs) {
|
||||
this.addressBook[key] = rcv[key];
|
||||
hasChange = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasChange) {
|
||||
this.emit('addressBookUpdated');
|
||||
this.store();
|
||||
}
|
||||
};
|
||||
|
||||
Wallet.prototype._handleData = function(senderId, data, isInbound) {
|
||||
|
||||
// TODO check message signature
|
||||
|
|
@ -149,6 +172,7 @@ Wallet.prototype._handleData = function(senderId, data, isInbound) {
|
|||
break;
|
||||
case 'walletReady':
|
||||
this.sendPublicKeyRing(senderId);
|
||||
this.sendAddressBook(senderId);
|
||||
this.sendAllTxProposals(senderId); // send old txps
|
||||
break;
|
||||
case 'publicKeyRing':
|
||||
|
|
@ -160,6 +184,9 @@ Wallet.prototype._handleData = function(senderId, data, isInbound) {
|
|||
case 'indexes':
|
||||
this._handleIndexes(senderId, data, isInbound);
|
||||
break;
|
||||
case 'addressbook':
|
||||
this._handleAddressBook(senderId, data, isInbound);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -325,7 +352,8 @@ Wallet.prototype.toObj = function() {
|
|||
opts: optsObj,
|
||||
publicKeyRing: this.publicKeyRing.toObj(),
|
||||
txProposals: this.txProposals.toObj(),
|
||||
privateKey: this.privateKey ? this.privateKey.toObj() : undefined
|
||||
privateKey: this.privateKey ? this.privateKey.toObj() : undefined,
|
||||
addressBook: this.addressBook
|
||||
};
|
||||
|
||||
return walletObj;
|
||||
|
|
@ -333,6 +361,7 @@ Wallet.prototype.toObj = function() {
|
|||
|
||||
Wallet.fromObj = function(o, storage, network, blockchain) {
|
||||
var opts = JSON.parse(JSON.stringify(o.opts));
|
||||
opts.addressBook = o.addressBook;
|
||||
opts.publicKeyRing = PublicKeyRing.fromObj(o.publicKeyRing);
|
||||
opts.txProposals = TxProposals.fromObj(o.txProposals);
|
||||
opts.privateKey = PrivateKey.fromObj(o.privateKey);
|
||||
|
|
@ -412,6 +441,15 @@ Wallet.prototype.sendIndexes = function(recipients) {
|
|||
});
|
||||
};
|
||||
|
||||
Wallet.prototype.sendAddressBook = function(recipients) {
|
||||
this.log('### SENDING addressBook TO:', recipients || 'All', this.addressBook);
|
||||
this.network.send(recipients, {
|
||||
type: 'addressbook',
|
||||
addressBook: this.addressBook,
|
||||
walletId: this.id,
|
||||
});
|
||||
};
|
||||
|
||||
Wallet.prototype.getName = function() {
|
||||
return this.name || this.id;
|
||||
};
|
||||
|
|
@ -779,4 +817,31 @@ Wallet.prototype.getNetwork = function() {
|
|||
return this.network;
|
||||
};
|
||||
|
||||
Wallet.prototype._checkAddressBook = function(key) {
|
||||
if (this.addressBook[key] && this.addressBook[key].copayerId != -1) {
|
||||
throw new Error('This address already exists in your Address Book: ' + address);
|
||||
}
|
||||
};
|
||||
|
||||
Wallet.prototype.setAddressBook = function(key, label) {
|
||||
this._checkAddressBook(key);
|
||||
var addressbook = {
|
||||
createdTs: Date.now(),
|
||||
copayerId: this.getMyCopayerId(),
|
||||
label: label
|
||||
};
|
||||
this.addressBook[key] = addressbook;
|
||||
this.sendAddressBook();
|
||||
this.store();
|
||||
};
|
||||
|
||||
Wallet.prototype.deleteAddressBook = function(key) {
|
||||
if (key) {
|
||||
this.addressBook[key].copayerId = -1;
|
||||
this.addressBook[key].createdTs = Date.now();
|
||||
this.sendAddressBook();
|
||||
this.store();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = require('soop')(Wallet);
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ WalletFactory.prototype.read = function(walletId) {
|
|||
obj.publicKeyRing = s.get(walletId, 'publicKeyRing');
|
||||
obj.txProposals = s.get(walletId, 'txProposals');
|
||||
obj.privateKey = s.get(walletId, 'privateKey');
|
||||
obj.addressBook = s.get(walletId, 'addressBook');
|
||||
|
||||
var w = this.fromObj(obj);
|
||||
return w;
|
||||
|
|
|
|||
|
|
@ -134,6 +134,11 @@ angular.module('copayApp.services')
|
|||
break;
|
||||
}
|
||||
});
|
||||
w.on('addressBookUpdated', function(dontDigest) {
|
||||
if (!dontDigest) {
|
||||
$rootScope.$digest();
|
||||
}
|
||||
});
|
||||
w.on('connectionError', function(msg) {
|
||||
root.onErrorDigest(null, msg);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue