Merge pull request #697 from cmgustavo/feature/addressbook

Addressbook
This commit is contained in:
Matias Alejo Garcia 2014-06-19 17:03:18 -03:00
commit 1dc420b215
9 changed files with 351 additions and 8 deletions

View file

@ -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;
});
};
});

View file

@ -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);

View file

@ -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;

View file

@ -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);
});