mirror of https://github.com/BTCPrivate/copay.git
mv wallet test from walletfactory to wallet
This commit is contained in:
parent
1ff109b5e5
commit
abf74695b6
|
@ -142,6 +142,13 @@ Identity.isAvailable = function(email, opts, cb) {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* store
|
||||
*
|
||||
* @param opts
|
||||
* @param cb
|
||||
* @return {undefined}
|
||||
*/
|
||||
Identity.prototype.store = function(opts, cb) {
|
||||
var self = this;
|
||||
self.profile.store(opts, function(err) {
|
||||
|
@ -319,7 +326,7 @@ Identity.prototype.read_Old = function(walletId, skipFields, cb) {
|
|||
*/
|
||||
|
||||
|
||||
Identity.prototype._getWallet = function(opts) {
|
||||
Identity.prototype._newWallet = function(opts) {
|
||||
return new Wallet(opts);
|
||||
};
|
||||
|
||||
|
@ -396,12 +403,12 @@ Identity.prototype.createWallet = function(opts, cb) {
|
|||
|
||||
|
||||
var self = this;
|
||||
var w = this._getWallet(opts);
|
||||
var w = this._newWallet(opts);
|
||||
this.profile.addWallet(w.id, function(err) {
|
||||
if (err) return cb(err);
|
||||
w.store(function(err) {
|
||||
if (err) return cb(err);
|
||||
self.storage.setLastOpened(w.id, function(err) {
|
||||
self.profile.setLastOpenedTs(w.id, function(err) {
|
||||
return cb(err, w);
|
||||
});
|
||||
});
|
||||
|
@ -445,7 +452,7 @@ Identity.prototype.openWallet = function(walletId, passphrase, cb) {
|
|||
if (err) return cb(err);
|
||||
|
||||
w.store(function(err) {
|
||||
self.storage.setLastOpened(walletId, function() {
|
||||
self.profile.setLastOpenedTs(walletId, function() {
|
||||
return cb(err, w);
|
||||
});
|
||||
});
|
||||
|
@ -454,42 +461,25 @@ Identity.prototype.openWallet = function(walletId, passphrase, cb) {
|
|||
};
|
||||
|
||||
|
||||
TODO
|
||||
from profile
|
||||
implement lastOpen
|
||||
Identity.prototype.listWallets = function(cb) {
|
||||
var self = this;
|
||||
this.storage.getWallets(function(wallets) {
|
||||
wallets.forEach(function(i) {
|
||||
i.show = i.name ? ((i.name + ' <' + i.id + '>')) : i.id;
|
||||
});
|
||||
self.storage.getLastOpened(function(lastId) {
|
||||
var last = _.findWhere(wallets, {
|
||||
id: lastId
|
||||
});
|
||||
if (last)
|
||||
last.lastOpened = true;
|
||||
return cb(null, wallets);
|
||||
})
|
||||
});
|
||||
Identity.prototype.listWallets = function() {
|
||||
return this.profile.listWallets();
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc Deletes this wallet. This involves removing it from the storage instance
|
||||
* @TODO: delete is a reserved javascript keyword. NEVER USE IT.
|
||||
* @param {string} walletId
|
||||
* @TODO: Why is there a callback?
|
||||
* @callback cb
|
||||
* @return {?} the result of the callback
|
||||
* @return {err}
|
||||
*/
|
||||
Identity.prototype.deleteWallet = function(walletId, cb) {
|
||||
var self = this;
|
||||
self.storage.deleteWallet(walletId, function(err) {
|
||||
|
||||
Wallet.delete(walletId, this.storage, function(err) {
|
||||
if (err) return cb(err);
|
||||
self.storage.setLastOpened(null, function(err) {
|
||||
self.profile.deleteWallet(walletId, function(err) {
|
||||
return cb(err);
|
||||
});
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,13 +84,23 @@ Profile.prototype.addWallet = function(walletId, info, cb) {
|
|||
if (this.walletInfos[walletId])
|
||||
return cb(new Error('WEXIST: Wallet already on profile'));
|
||||
|
||||
this.walletInfos[walletId] = _.extend(info, {createdTs: Date.now(), id: walletId} );
|
||||
this.walletInfos[walletId] = _.extend(info, {
|
||||
createdTs: Date.now(),
|
||||
id: walletId
|
||||
});
|
||||
|
||||
this.store({
|
||||
overwrite: true
|
||||
}, cb);
|
||||
};
|
||||
|
||||
|
||||
Profile.prototype.setLasOpenedTs = function(walletId, cb) {
|
||||
return this.addToWallet(walletId, {
|
||||
lastOpenedTs: Date.now()
|
||||
}, cb);
|
||||
};
|
||||
|
||||
Profile.prototype.store = function(opts, cb) {
|
||||
var self = this;
|
||||
var val = self.toObj();
|
||||
|
|
|
@ -57,6 +57,9 @@ var copayConfig = require('../../config');
|
|||
*/
|
||||
function Wallet(opts) {
|
||||
var self = this;
|
||||
preconditions.checkArgument(opts);
|
||||
|
||||
opts.reconnectDelay = opts.reconnectDelay || 500;
|
||||
|
||||
//required params
|
||||
['storage', 'network', 'blockchain',
|
||||
|
@ -177,6 +180,25 @@ Wallet.getMaxRequiredCopayers = function(totalCopayers) {
|
|||
return Wallet.COPAYER_PAIR_LIMITS[totalCopayers];
|
||||
};
|
||||
|
||||
/**
|
||||
* delete
|
||||
*
|
||||
* @param walletId
|
||||
* @param storage
|
||||
* @param cb
|
||||
* @return {undefined}
|
||||
*/
|
||||
Wallet.delete = function(walletId, storage, cb) {
|
||||
preconditions.checkArgument(cb);
|
||||
|
||||
storage.deletePrefix('wallet::' + walletId, function(err) {
|
||||
if (err) return cb(err);
|
||||
storage.deletePrefix(walletId + '::', function(err) {
|
||||
return cb(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @desc Set the copayer id for the owner of this wallet
|
||||
|
@ -919,8 +941,22 @@ Wallet.prototype.toObj = function() {
|
|||
* @param {Storage} storage - a Storage instance to store the data of the wallet
|
||||
* @param {Network} network - a Network instance to communicate with peers
|
||||
* @param {Blockchain} blockchain - a Blockchain instance to retrieve state from the blockchain
|
||||
* @param skipFields
|
||||
*/
|
||||
Wallet.fromObj = function(o, storage, network, blockchain) {
|
||||
Wallet.fromObj = function(o, storage, network, blockchain, skipFields) {
|
||||
|
||||
|
||||
if (skipFields) {
|
||||
_.each(skipFields, function(k) {
|
||||
if (o[k]) {
|
||||
delete o[k];
|
||||
} else {
|
||||
throw new Error('unknown field:' + k);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO Why moving everything to opts. This needs refactoring.
|
||||
|
||||
// clone opts
|
||||
var opts = JSON.parse(JSON.stringify(o.opts));
|
||||
|
|
|
@ -10,6 +10,16 @@ var TransactionBuilder = bitcore.TransactionBuilder;
|
|||
var Transaction = bitcore.Transaction;
|
||||
var Address = bitcore.Address;
|
||||
|
||||
|
||||
function assertObjectEqual(a, b) {
|
||||
Wallet.PERSISTED_PROPERTIES.forEach(function(k) {
|
||||
if (a[k] && b[k]) {
|
||||
_.omit(a[k], 'name').should.be.deep.equal(b[k], k + ' differs');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
var walletConfig = {
|
||||
requiredCopayers: 3,
|
||||
totalCopayers: 5,
|
||||
|
@ -1806,4 +1816,52 @@ describe('Wallet model', function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe('#fromObj / #toObj', function() {
|
||||
var storage = new Storage(walletConfig.storage);
|
||||
var network = new Network(walletConfig.network);
|
||||
var blockchain = new Blockchain(walletConfig.blockchain);
|
||||
|
||||
it('Import backup using old copayerIndex', function() {
|
||||
var w = Wallet.fromObj(JSON.parse(o), storage, network, blockchain);
|
||||
|
||||
should.exist(w);
|
||||
w.id.should.equal("dbfe10c3fae71cea");
|
||||
should.exist(w.publicKeyRing.getCopayerId);
|
||||
should.exist(w.txProposals.toObj());
|
||||
should.exist(w.privateKey.toObj());
|
||||
assertObjectEqual(w.toObj(), JSON.parse(o));
|
||||
});
|
||||
|
||||
it('#fromObj, skipping fields', function() {
|
||||
var w = Wallet.fromObj(JSON.parse(o), storage, network, blockchain, ['publicKeyRing']);
|
||||
|
||||
should.exist(w);
|
||||
w.id.should.equal("dbfe10c3fae71cea");
|
||||
should.exist(w.publicKeyRing.getCopayerId);
|
||||
should.exist(w.txProposals.toObj());
|
||||
should.exist(w.privateKey.toObj());
|
||||
(function() {
|
||||
assertObjectEqual(w.toObj(), JSON.parse(o))
|
||||
}).should.throw();
|
||||
});
|
||||
|
||||
it('support old index schema: #fromObj #toObj round trip', function() {
|
||||
var o = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":{"changeIndex":0,"receiveIndex":0},"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}';
|
||||
var o2 = '{"opts":{"id":"dbfe10c3fae71cea","spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2147483647,"changeIndex":0,"receiveIndex":0},{"copayerIndex":0,"changeIndex":0,"receiveIndex":0},{"copayerIndex":1,"changeIndex":0,"receiveIndex":0},{"copayerIndex":2,"changeIndex":0,"receiveIndex":0},{"copayerIndex":3,"changeIndex":0,"receiveIndex":0},{"copayerIndex":4,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{}}';
|
||||
|
||||
var w = Wallet.fromObj(JSON.parse(o), storage, network, blockchain);
|
||||
|
||||
should.exist(w);
|
||||
w.id.should.equal("dbfe10c3fae71cea");
|
||||
should.exist(w.publicKeyRing.getCopayerId);
|
||||
should.exist(w.txProposals.toObj);
|
||||
should.exist(w.privateKey.toObj);
|
||||
|
||||
assertObjectEqual(w.toObj(), JSON.parse(o2));
|
||||
});
|
||||
});
|
||||
|
||||
// DATA
|
||||
var o = '{"opts":{"id":"dbfe10c3fae71cea", "spendUnconfirmed":1,"requiredCopayers":3,"totalCopayers":5,"version":"0.0.5","networkName":"testnet"},"networkNonce":"0000000000000001","networkNonces":[],"publicKeyRing":{"walletId":"dbfe10c3fae71cea","networkName":"testnet","requiredCopayers":3,"totalCopayers":5,"indexes":[{"copayerIndex":2,"changeIndex":0,"receiveIndex":0}],"copayersBackup":[],"copayersExtPubKeys":["tpubD6NzVbkrYhZ4YGK8ZhZ8WVeBXNAAoTYjjpw9twCPiNGrGQYFktP3iVQkKmZNiFnUcAFMJRxJVJF6Nq9MDv2kiRceExJaHFbxUCGUiRhmy97","tpubD6NzVbkrYhZ4YKGDJkzWdQsQV3AcFemaQKiwNhV4RL8FHnBFvinidGdQtP8RKj3h34E65RkdtxjrggZYqsEwJ8RhhN2zz9VrjLnrnwbXYNc","tpubD6NzVbkrYhZ4YkDiewjb32Pp3Sz9WK2jpp37KnL7RCrHAyPpnLfgdfRnTdpn6DTWmPS7niywfgWiT42aJb1J6CjWVNmkgsMCxuw7j9DaGKB","tpubD6NzVbkrYhZ4XEtUAz4UUTWbprewbLTaMhR8NUvSJUEAh4Sidxr6rRPFdqqVRR73btKf13wUjds2i8vVCNo8sbKrAnyoTr3o5Y6QSbboQjk","tpubD6NzVbkrYhZ4Yj9AAt6xUVuGPVd8jXCrEE6V2wp7U3PFh8jYYvVad31b4VUXEYXzSnkco4fktu8r4icBsB2t3pCR3WnhVLedY2hxGcPFLKD"],"nicknameFor":{}},"txProposals":{"txps":[],"walletId":"dbfe10c3fae71cea","networkName":"testnet"},"privateKey":{"extendedPrivateKeyString":"tprv8ZgxMBicQKsPeoHLg3tY75z4xLeEe8MqAXLNcRA6J6UTRvHV8VZTXznt9eoTmSk1fwSrwZtMhY3XkNsceJ14h6sCXHSWinRqMSSbY8tfhHi","networkName":"testnet"},"addressBook":{},"settings":{"unitName":"BTC","unitToSatoshi":100000000,"unitDecimals":8,"alternativeName":"Argentine Peso","alternativeIsoCode":"ARS"}}';
|
||||
|
||||
});
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue