Merge pull request #849 from yemel/feature/backup-wallet

Wallet Backups
This commit is contained in:
Gustavo Maximiliano Cortez 2014-07-08 19:17:43 -03:00
commit 5d5bf3dfc5
12 changed files with 166 additions and 45 deletions

View file

@ -30,6 +30,7 @@ function PublicKeyRing(opts) {
this.publicKeysCache = opts.publicKeysCache || {};
this.nicknameFor = opts.nicknameFor || {};
this.copayerIds = [];
this.copayersBackup = opts.copayersBackup || [];
this.addressToPath = {};
}
@ -59,6 +60,7 @@ PublicKeyRing.prototype.toObj = function() {
requiredCopayers: this.requiredCopayers,
totalCopayers: this.totalCopayers,
indexes: AddressIndex.serialize(this.indexes),
copayersBackup: this.copayersBackup,
copayersExtPubKeys: this.copayersHK.map(function(b) {
return b.extendedPublicKeyString();
@ -78,7 +80,11 @@ PublicKeyRing.prototype.registeredCopayers = function() {
};
PublicKeyRing.prototype.isComplete = function() {
return this.registeredCopayers() === this.totalCopayers;
return this.remainingCopayers() == 0;
};
PublicKeyRing.prototype.remainingCopayers = function() {
return this.totalCopayers - this.registeredCopayers();
};
PublicKeyRing.prototype.getAllCopayerIds = function() {
@ -350,12 +356,34 @@ PublicKeyRing.prototype._mergePubkeys = function(inPKR) {
return hasChanged;
};
PublicKeyRing.prototype.setBackupReady = function(copayerId) {
if (this.isBackupReady()) return false;
var cid = this.myCopayerId();
this.copayersBackup.push(cid);
return true;
}
PublicKeyRing.prototype.isBackupReady = function(copayerId) {
var cid = copayerId || this.myCopayerId();
return this.copayersBackup.indexOf(cid) != -1;
}
PublicKeyRing.prototype.isFullyBackup = function(copayerId) {
return this.remainingBackups() == 0;
}
PublicKeyRing.prototype.remainingBackups = function() {
return this.totalCopayers - this.copayersBackup.length;
};
PublicKeyRing.prototype.merge = function(inPKR, ignoreId) {
this._checkInPKR(inPKR, ignoreId);
var hasChanged = false;
hasChanged |= this.mergeIndexes(inPKR.indexes);
hasChanged |= this._mergePubkeys(inPKR);
hasChanged |= this.mergeBackups(inPKR.copayersBackup);
return !!hasChanged;
};
@ -372,4 +400,18 @@ PublicKeyRing.prototype.mergeIndexes = function(indexes) {
return !!hasChanged
}
PublicKeyRing.prototype.mergeBackups = function(backups) {
var self = this;
var hasChanged = false;
backups.forEach(function(cid) {
var isNew = self.copayersBackup.indexOf(cid) == -1;
if (isNew) self.copayersBackup.push(cid);
hasChanged |= isNew;
});
return !!hasChanged
}
module.exports = require('soop')(PublicKeyRing);

View file

@ -49,7 +49,6 @@ function Wallet(opts) {
this.network.maxPeers = this.totalCopayers;
this.registeredPeerIds = [];
this.addressBook = opts.addressBook || {};
this.backupOffered = opts.backupOffered || false;
this.publicKey = this.privateKey.publicHex;
}
@ -327,6 +326,7 @@ Wallet.prototype.getRegisteredPeerIds = function() {
var pid = this.network.peerFromCopayer(cid);
this.registeredPeerIds.push({
peerId: pid,
copayerId: cid,
nick: this.publicKeyRing.nicknameForCopayer(cid),
index: i,
});
@ -349,7 +349,6 @@ Wallet.prototype.toObj = function() {
txProposals: this.txProposals.toObj(),
privateKey: this.privateKey ? this.privateKey.toObj() : undefined,
addressBook: this.addressBook,
backupOffered: this.backupOffered,
};
return walletObj;
@ -358,7 +357,6 @@ Wallet.prototype.toObj = function() {
Wallet.fromObj = function(o, storage, network, blockchain) {
var opts = JSON.parse(JSON.stringify(o.opts));
opts.addressBook = o.addressBook;
opts.backupOffered = o.backupOffered;
opts.publicKeyRing = PublicKeyRing.fromObj(o.publicKeyRing);
opts.txProposals = TxProposals.fromObj(o.txProposals);
@ -879,12 +877,13 @@ Wallet.prototype.toggleAddressBookEntry = function(key) {
};
Wallet.prototype.isReady = function() {
var ret = this.publicKeyRing.isComplete() && this.backupOffered;
var ret = this.publicKeyRing.isComplete() && this.publicKeyRing.isFullyBackup();
return ret;
};
Wallet.prototype.offerBackup = function() {
this.backupOffered = true;
Wallet.prototype.setBackupReady = function() {
this.publicKeyRing.setBackupReady();
this.sendPublicKeyRing();
this.store();
};