extract helpers from integration tests

This commit is contained in:
Ivan Socolsky 2015-11-03 13:24:23 -03:00
parent e55983b151
commit c1a456d32a
2 changed files with 384 additions and 353 deletions

380
test/integration/helpers.js Normal file
View File

@ -0,0 +1,380 @@
'use strict';
var _ = require('lodash');
var async = require('async');
var chai = require('chai');
var sinon = require('sinon');
var should = chai.should();
var log = require('npmlog');
log.debug = log.verbose;
var Bitcore = require('bitcore-lib');
var Common = require('../../lib/common');
var Utils = Common.Utils;
var Constants = Common.Constants;
var Defaults = Common.Defaults;
var Model = require('../../lib/model');
var WalletService = require('../../lib/server');
var TestData = require('../testdata');
var blockchainExplorer;
var helpers = {};
helpers.setBlockchainExplorer = function(bce) {
blockchainExplorer = bce;
};
helpers.signMessage = function(text, privKey) {
var priv = new Bitcore.PrivateKey(privKey);
var hash = Utils.hashMessage(text);
return Bitcore.crypto.ECDSA.sign(hash, priv, 'little').toString();
};
helpers.signRequestPubKey = function(requestPubKey, xPrivKey) {
var priv = new Bitcore.HDPrivateKey(xPrivKey).derive(Constants.PATHS.REQUEST_KEY_AUTH).privateKey;
return helpers.signMessage(requestPubKey, priv);
};
helpers.getAuthServer = function(copayerId, cb) {
var verifyStub = sinon.stub(WalletService.prototype, '_verifySignature');
verifyStub.returns(true);
WalletService.getInstanceWithAuth({
copayerId: copayerId,
message: 'dummy',
signature: 'dummy',
clientVersion: 'bwc-0.1.0',
}, function(err, server) {
verifyStub.restore();
if (err || !server) throw new Error('Could not login as copayerId ' + copayerId);
return cb(server);
});
};
helpers._generateCopayersTestData = function(n) {
console.log('var copayers = [');
_.each(_.range(n), function(c) {
var xpriv = new Bitcore.HDPrivateKey();
var xpub = Bitcore.HDPublicKey(xpriv);
var xpriv_45H = xpriv.derive(45, true);
var xpub_45H = Bitcore.HDPublicKey(xpriv_45H);
var id45 = Copayer._xPubToCopayerId(xpub_45H.toString());
var xpriv_44H_0H_0H = xpriv.derive(44, true).derive(0, true).derive(0, true);
var xpub_44H_0H_0H = Bitcore.HDPublicKey(xpriv_44H_0H_0H);
var id44 = Copayer._xPubToCopayerId(xpub_44H_0H_0H.toString());
var xpriv_1H = xpriv.derive(1, true);
var xpub_1H = Bitcore.HDPublicKey(xpriv_1H);
var priv = xpriv_1H.derive(0).privateKey;
var pub = xpub_1H.derive(0).publicKey;
console.log('{id44: ', "'" + id44 + "',");
console.log('id45: ', "'" + id45 + "',");
console.log('xPrivKey: ', "'" + xpriv.toString() + "',");
console.log('xPubKey: ', "'" + xpub.toString() + "',");
console.log('xPrivKey_45H: ', "'" + xpriv_45H.toString() + "',");
console.log('xPubKey_45H: ', "'" + xpub_45H.toString() + "',");
console.log('xPrivKey_44H_0H_0H: ', "'" + xpriv_44H_0H_0H.toString() + "',");
console.log('xPubKey_44H_0H_0H: ', "'" + xpub_44H_0H_0H.toString() + "',");
console.log('xPrivKey_1H: ', "'" + xpriv_1H.toString() + "',");
console.log('xPubKey_1H: ', "'" + xpub_1H.toString() + "',");
console.log('privKey_1H_0: ', "'" + priv.toString() + "',");
console.log('pubKey_1H_0: ', "'" + pub.toString() + "'},");
});
console.log('];');
};
helpers.getSignedCopayerOpts = function(opts) {
var hash = WalletService._getCopayerHash(opts.name, opts.xPubKey, opts.requestPubKey);
opts.copayerSignature = helpers.signMessage(hash, TestData.keyPair.priv);
return opts;
};
helpers.createAndJoinWallet = function(m, n, opts, cb) {
if (_.isFunction(opts)) {
cb = opts;
opts = {};
}
opts = opts || {};
var server = new WalletService();
var copayerIds = [];
var offset = opts.offset || 0;
var walletOpts = {
name: 'a wallet',
m: m,
n: n,
pubKey: TestData.keyPair.pub,
};
if (_.isBoolean(opts.supportBIP44AndP2PKH))
walletOpts.supportBIP44AndP2PKH = opts.supportBIP44AndP2PKH;
server.createWallet(walletOpts, function(err, walletId) {
if (err) return cb(err);
async.each(_.range(n), function(i, cb) {
var copayerData = TestData.copayers[i + offset];
var copayerOpts = helpers.getSignedCopayerOpts({
walletId: walletId,
name: 'copayer ' + (i + 1),
xPubKey: (_.isBoolean(opts.supportBIP44AndP2PKH) && !opts.supportBIP44AndP2PKH) ? copayerData.xPubKey_45H : copayerData.xPubKey_44H_0H_0H,
requestPubKey: copayerData.pubKey_1H_0,
customData: 'custom data ' + (i + 1),
});
if (_.isBoolean(opts.supportBIP44AndP2PKH))
copayerOpts.supportBIP44AndP2PKH = opts.supportBIP44AndP2PKH;
server.joinWallet(copayerOpts, function(err, result) {
should.not.exist(err);
copayerIds.push(result.copayerId);
return cb(err);
});
}, function(err) {
if (err) return new Error('Could not generate wallet');
helpers.getAuthServer(copayerIds[0], function(s) {
s.getWallet({}, function(err, w) {
cb(s, w);
});
});
});
});
};
helpers.randomTXID = function() {
return Bitcore.crypto.Hash.sha256(new Buffer(Math.random() * 100000)).toString('hex');;
};
helpers.toSatoshi = function(btc) {
if (_.isArray(btc)) {
return _.map(btc, helpers.toSatoshi);
} else {
return Utils.strip(btc * 1e8);
}
};
helpers.stubUtxos = function(server, wallet, amounts, cb) {
async.mapSeries(_.range(0, amounts.length > 2 ? 2 : 1), function(i, next) {
server.createAddress({}, next);
}, function(err, addresses) {
should.not.exist(err);
addresses.should.not.be.empty;
var utxos = _.map([].concat(amounts), function(amount, i) {
var address = addresses[i % addresses.length];
var confirmations;
if (_.isString(amount) && _.startsWith(amount, 'u')) {
amount = parseFloat(amount.substring(1));
confirmations = 0;
} else {
confirmations = Math.floor(Math.random() * 100 + 1);
}
var scriptPubKey;
switch (wallet.addressType) {
case Constants.SCRIPT_TYPES.P2SH:
scriptPubKey = Bitcore.Script.buildMultisigOut(address.publicKeys, wallet.m).toScriptHashOut();
break;
case Constants.SCRIPT_TYPES.P2PKH:
scriptPubKey = Bitcore.Script.buildPublicKeyHashOut(address.address);
break;
}
should.exist(scriptPubKey);
return {
txid: helpers.randomTXID(),
vout: Math.floor(Math.random() * 10 + 1),
satoshis: helpers.toSatoshi(amount).toString(),
scriptPubKey: scriptPubKey.toBuffer().toString('hex'),
address: address.address,
confirmations: confirmations,
};
});
blockchainExplorer.getUnspentUtxos = function(addresses, cb) {
var selected = _.filter(utxos, function(utxo) {
return _.contains(addresses, utxo.address);
});
return cb(null, selected);
};
return cb(utxos);
});
};
helpers.stubBroadcast = function(thirdPartyBroadcast) {
blockchainExplorer.broadcast = sinon.stub().callsArgWith(1, null, '112233');
blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, null);
};
helpers.stubHistory = function(txs) {
blockchainExplorer.getTransactions = function(addresses, from, to, cb) {
var MAX_BATCH_SIZE = 100;
var nbTxs = txs.length;
if (_.isUndefined(from) && _.isUndefined(to)) {
from = 0;
to = MAX_BATCH_SIZE;
}
if (!_.isUndefined(from) && _.isUndefined(to))
to = from + MAX_BATCH_SIZE;
if (!_.isUndefined(from) && !_.isUndefined(to) && to - from > MAX_BATCH_SIZE)
to = from + MAX_BATCH_SIZE;
if (from < 0) from = 0;
if (to < 0) to = 0;
if (from > nbTxs) from = nbTxs;
if (to > nbTxs) to = nbTxs;
var page = txs.slice(from, to);
return cb(null, page);
};
};
helpers.stubFeeLevels = function(levels) {
blockchainExplorer.estimateFee = function(nbBlocks, cb) {
var result = _.zipObject(_.map(_.pick(levels, nbBlocks), function(fee, n) {
return [+n, fee > 0 ? fee / 1e8 : fee];
}));
return cb(null, result);
};
};
helpers.stubAddressActivity = function(activeAddresses) {
blockchainExplorer.getAddressActivity = function(address, cb) {
return cb(null, _.contains(activeAddresses, address));
};
};
helpers.clientSign = function(txp, xPrivKey) {
var self = this;
function getBaseAddressDerivationPath(derivationStrategy, network, account) {
if (derivationStrategy == Constants.DERIVATION_STRATEGIES.BIP45) return "m/45'";
return "m/44'/" + (network == 'livenet' ? "0'" : "1'") + "/" + account + "'";
};
function deriveXPrivFromMaster(masterXPriv, derivationStrategy, network, account) {
var path = getBaseAddressDerivationPath(derivationStrategy, network, account || 0);
return new Bitcore.HDPrivateKey(masterXPriv, network).derive(path);
};
//Derive proper key to sign, for each input
var privs = [];
var derived = {};
var network = new Bitcore.Address(txp.changeAddress.address).network.name;
var xpriv = deriveXPrivFromMaster(xPrivKey, txp.derivationStrategy, network);
_.each(txp.inputs, function(i) {
if (!derived[i.path]) {
derived[i.path] = xpriv.derive(i.path).privateKey;
privs.push(derived[i.path]);
}
});
var t = txp.getBitcoreTx();
var signatures = _.map(privs, function(priv, i) {
return t.getSignatures(priv);
});
signatures = _.map(_.sortBy(_.flatten(signatures), 'inputIndex'), function(s) {
return s.signature.toDER().toString('hex');
});
return signatures;
};
helpers.createProposalOptsLegacy = function(toAddress, amount, message, signingKey, feePerKb) {
var opts = {
toAddress: toAddress,
amount: helpers.toSatoshi(amount),
message: message,
proposalSignature: null,
};
if (feePerKb) opts.feePerKb = feePerKb;
var hash = WalletService._getProposalHash(toAddress, opts.amount, message);
try {
opts.proposalSignature = helpers.signMessage(hash, signingKey);
} catch (ex) {}
return opts;
};
helpers.createSimpleProposalOpts = function(toAddress, amount, signingKey, opts) {
var outputs = [{
toAddress: toAddress,
amount: amount,
}];
return helpers.createProposalOpts(Model.TxProposal.Types.SIMPLE, outputs, signingKey, opts);
};
helpers.createProposalOpts = function(type, outputs, signingKey, moreOpts) {
_.each(outputs, function(output) {
output.amount = helpers.toSatoshi(output.amount);
});
var opts = {
type: type,
proposalSignature: null
};
if (moreOpts) {
moreOpts = _.chain(moreOpts)
.pick(['feePerKb', 'customData', 'message'])
.value();
opts = _.assign(opts, moreOpts);
}
opts = _.defaults(opts, {
message: null
});
var hash;
if (type == Model.TxProposal.Types.SIMPLE) {
opts.toAddress = outputs[0].toAddress;
opts.amount = outputs[0].amount;
hash = WalletService._getProposalHash(opts.toAddress, opts.amount,
opts.message, opts.payProUrl);
} else if (type == Model.TxProposal.Types.MULTIPLEOUTPUTS) {
opts.outputs = outputs;
var header = {
outputs: outputs,
message: opts.message,
payProUrl: opts.payProUrl
};
hash = WalletService._getProposalHash(header);
}
try {
opts.proposalSignature = helpers.signMessage(hash, signingKey);
} catch (ex) {}
return opts;
};
helpers.createAddresses = function(server, wallet, main, change, cb) {
var clock = sinon.useFakeTimers(Date.now(), 'Date');
async.map(_.range(main + change), function(i, next) {
clock.tick(1000);
var address = wallet.createAddress(i >= main);
server.storage.storeAddressAndWallet(wallet, address, function(err) {
next(err, address);
});
}, function(err, addresses) {
if (err) throw new Error('Could not generate addresses');
clock.restore();
return cb(_.take(addresses, main), _.takeRight(addresses, change));
});
};
module.exports = helpers;

View File

@ -23,366 +23,17 @@ var Constants = Common.Constants;
var Defaults = Common.Defaults;
var Storage = require('../../lib/storage');
var Model = require('../../lib/model');
var WalletService = require('../../lib/server');
var EmailService = require('../../lib/emailservice');
var TestData = require('../testdata');
var helpers = require('./helpers');
var CLIENT_VERSION = 'bwc-0.1.1';
var helpers = {};
helpers.signMessage = function(text, privKey) {
var priv = new Bitcore.PrivateKey(privKey);
var hash = Utils.hashMessage(text);
return Bitcore.crypto.ECDSA.sign(hash, priv, 'little').toString();
};
helpers.signRequestPubKey = function(requestPubKey, xPrivKey) {
var priv = new Bitcore.HDPrivateKey(xPrivKey).derive(Constants.PATHS.REQUEST_KEY_AUTH).privateKey;
return helpers.signMessage(requestPubKey, priv);
};
helpers.getAuthServer = function(copayerId, cb) {
var verifyStub = sinon.stub(WalletService.prototype, '_verifySignature');
verifyStub.returns(true);
WalletService.getInstanceWithAuth({
copayerId: copayerId,
message: 'dummy',
signature: 'dummy',
clientVersion: 'bwc-0.1.0',
}, function(err, server) {
verifyStub.restore();
if (err || !server) throw new Error('Could not login as copayerId ' + copayerId);
return cb(server);
});
};
helpers._generateCopayersTestData = function(n) {
console.log('var copayers = [');
_.each(_.range(n), function(c) {
var xpriv = new Bitcore.HDPrivateKey();
var xpub = Bitcore.HDPublicKey(xpriv);
var xpriv_45H = xpriv.derive(45, true);
var xpub_45H = Bitcore.HDPublicKey(xpriv_45H);
var id45 = Copayer._xPubToCopayerId(xpub_45H.toString());
var xpriv_44H_0H_0H = xpriv.derive(44, true).derive(0, true).derive(0, true);
var xpub_44H_0H_0H = Bitcore.HDPublicKey(xpriv_44H_0H_0H);
var id44 = Copayer._xPubToCopayerId(xpub_44H_0H_0H.toString());
var xpriv_1H = xpriv.derive(1, true);
var xpub_1H = Bitcore.HDPublicKey(xpriv_1H);
var priv = xpriv_1H.derive(0).privateKey;
var pub = xpub_1H.derive(0).publicKey;
console.log('{id44: ', "'" + id44 + "',");
console.log('id45: ', "'" + id45 + "',");
console.log('xPrivKey: ', "'" + xpriv.toString() + "',");
console.log('xPubKey: ', "'" + xpub.toString() + "',");
console.log('xPrivKey_45H: ', "'" + xpriv_45H.toString() + "',");
console.log('xPubKey_45H: ', "'" + xpub_45H.toString() + "',");
console.log('xPrivKey_44H_0H_0H: ', "'" + xpriv_44H_0H_0H.toString() + "',");
console.log('xPubKey_44H_0H_0H: ', "'" + xpub_44H_0H_0H.toString() + "',");
console.log('xPrivKey_1H: ', "'" + xpriv_1H.toString() + "',");
console.log('xPubKey_1H: ', "'" + xpub_1H.toString() + "',");
console.log('privKey_1H_0: ', "'" + priv.toString() + "',");
console.log('pubKey_1H_0: ', "'" + pub.toString() + "'},");
});
console.log('];');
};
helpers.getSignedCopayerOpts = function(opts) {
var hash = WalletService._getCopayerHash(opts.name, opts.xPubKey, opts.requestPubKey);
opts.copayerSignature = helpers.signMessage(hash, TestData.keyPair.priv);
return opts;
};
helpers.createAndJoinWallet = function(m, n, opts, cb) {
if (_.isFunction(opts)) {
cb = opts;
opts = {};
}
opts = opts || {};
var server = new WalletService();
var copayerIds = [];
var offset = opts.offset || 0;
var walletOpts = {
name: 'a wallet',
m: m,
n: n,
pubKey: TestData.keyPair.pub,
};
if (_.isBoolean(opts.supportBIP44AndP2PKH))
walletOpts.supportBIP44AndP2PKH = opts.supportBIP44AndP2PKH;
server.createWallet(walletOpts, function(err, walletId) {
if (err) return cb(err);
async.each(_.range(n), function(i, cb) {
var copayerData = TestData.copayers[i + offset];
var copayerOpts = helpers.getSignedCopayerOpts({
walletId: walletId,
name: 'copayer ' + (i + 1),
xPubKey: (_.isBoolean(opts.supportBIP44AndP2PKH) && !opts.supportBIP44AndP2PKH) ? copayerData.xPubKey_45H : copayerData.xPubKey_44H_0H_0H,
requestPubKey: copayerData.pubKey_1H_0,
customData: 'custom data ' + (i + 1),
});
if (_.isBoolean(opts.supportBIP44AndP2PKH))
copayerOpts.supportBIP44AndP2PKH = opts.supportBIP44AndP2PKH;
server.joinWallet(copayerOpts, function(err, result) {
should.not.exist(err);
copayerIds.push(result.copayerId);
return cb(err);
});
}, function(err) {
if (err) return new Error('Could not generate wallet');
helpers.getAuthServer(copayerIds[0], function(s) {
s.getWallet({}, function(err, w) {
cb(s, w);
});
});
});
});
};
helpers.randomTXID = function() {
return Bitcore.crypto.Hash.sha256(new Buffer(Math.random() * 100000)).toString('hex');;
};
helpers.toSatoshi = function(btc) {
if (_.isArray(btc)) {
return _.map(btc, helpers.toSatoshi);
} else {
return Utils.strip(btc * 1e8);
}
};
helpers.stubUtxos = function(server, wallet, amounts, cb) {
async.mapSeries(_.range(0, amounts.length > 2 ? 2 : 1), function(i, next) {
server.createAddress({}, next);
}, function(err, addresses) {
should.not.exist(err);
addresses.should.not.be.empty;
var utxos = _.map([].concat(amounts), function(amount, i) {
var address = addresses[i % addresses.length];
var confirmations;
if (_.isString(amount) && _.startsWith(amount, 'u')) {
amount = parseFloat(amount.substring(1));
confirmations = 0;
} else {
confirmations = Math.floor(Math.random() * 100 + 1);
}
var scriptPubKey;
switch (wallet.addressType) {
case Constants.SCRIPT_TYPES.P2SH:
scriptPubKey = Bitcore.Script.buildMultisigOut(address.publicKeys, wallet.m).toScriptHashOut();
break;
case Constants.SCRIPT_TYPES.P2PKH:
scriptPubKey = Bitcore.Script.buildPublicKeyHashOut(address.address);
break;
}
should.exist(scriptPubKey);
return {
txid: helpers.randomTXID(),
vout: Math.floor(Math.random() * 10 + 1),
satoshis: helpers.toSatoshi(amount).toString(),
scriptPubKey: scriptPubKey.toBuffer().toString('hex'),
address: address.address,
confirmations: confirmations,
};
});
blockchainExplorer.getUnspentUtxos = function(addresses, cb) {
var selected = _.filter(utxos, function(utxo) {
return _.contains(addresses, utxo.address);
});
return cb(null, selected);
};
return cb(utxos);
});
};
helpers.stubBroadcast = function(thirdPartyBroadcast) {
blockchainExplorer.broadcast = sinon.stub().callsArgWith(1, null, '112233');
blockchainExplorer.getTransaction = sinon.stub().callsArgWith(1, null, null);
};
helpers.stubHistory = function(txs) {
blockchainExplorer.getTransactions = function(addresses, from, to, cb) {
var MAX_BATCH_SIZE = 100;
var nbTxs = txs.length;
if (_.isUndefined(from) && _.isUndefined(to)) {
from = 0;
to = MAX_BATCH_SIZE;
}
if (!_.isUndefined(from) && _.isUndefined(to))
to = from + MAX_BATCH_SIZE;
if (!_.isUndefined(from) && !_.isUndefined(to) && to - from > MAX_BATCH_SIZE)
to = from + MAX_BATCH_SIZE;
if (from < 0) from = 0;
if (to < 0) to = 0;
if (from > nbTxs) from = nbTxs;
if (to > nbTxs) to = nbTxs;
var page = txs.slice(from, to);
return cb(null, page);
};
};
helpers.stubFeeLevels = function(levels) {
blockchainExplorer.estimateFee = function(nbBlocks, cb) {
var result = _.zipObject(_.map(_.pick(levels, nbBlocks), function(fee, n) {
return [+n, fee > 0 ? fee / 1e8 : fee];
}));
return cb(null, result);
};
};
helpers.stubAddressActivity = function(activeAddresses) {
blockchainExplorer.getAddressActivity = function(address, cb) {
return cb(null, _.contains(activeAddresses, address));
};
};
helpers.clientSign = function(txp, xPrivKey) {
var self = this;
function getBaseAddressDerivationPath(derivationStrategy, network, account) {
if (derivationStrategy == Constants.DERIVATION_STRATEGIES.BIP45) return "m/45'";
return "m/44'/" + (network == 'livenet' ? "0'" : "1'") + "/" + account + "'";
};
function deriveXPrivFromMaster(masterXPriv, derivationStrategy, network, account) {
var path = getBaseAddressDerivationPath(derivationStrategy, network, account || 0);
return new Bitcore.HDPrivateKey(masterXPriv, network).derive(path);
};
//Derive proper key to sign, for each input
var privs = [];
var derived = {};
var network = new Bitcore.Address(txp.changeAddress.address).network.name;
var xpriv = deriveXPrivFromMaster(xPrivKey, txp.derivationStrategy, network);
_.each(txp.inputs, function(i) {
if (!derived[i.path]) {
derived[i.path] = xpriv.derive(i.path).privateKey;
privs.push(derived[i.path]);
}
});
var t = txp.getBitcoreTx();
var signatures = _.map(privs, function(priv, i) {
return t.getSignatures(priv);
});
signatures = _.map(_.sortBy(_.flatten(signatures), 'inputIndex'), function(s) {
return s.signature.toDER().toString('hex');
});
return signatures;
};
helpers.createProposalOptsLegacy = function(toAddress, amount, message, signingKey, feePerKb) {
var opts = {
toAddress: toAddress,
amount: helpers.toSatoshi(amount),
message: message,
proposalSignature: null,
};
if (feePerKb) opts.feePerKb = feePerKb;
var hash = WalletService._getProposalHash(toAddress, opts.amount, message);
try {
opts.proposalSignature = helpers.signMessage(hash, signingKey);
} catch (ex) {}
return opts;
};
helpers.createSimpleProposalOpts = function(toAddress, amount, signingKey, opts) {
var outputs = [{
toAddress: toAddress,
amount: amount,
}];
return helpers.createProposalOpts(Model.TxProposal.Types.SIMPLE, outputs, signingKey, opts);
};
helpers.createProposalOpts = function(type, outputs, signingKey, moreOpts) {
_.each(outputs, function(output) {
output.amount = helpers.toSatoshi(output.amount);
});
var opts = {
type: type,
proposalSignature: null
};
if (moreOpts) {
moreOpts = _.chain(moreOpts)
.pick(['feePerKb', 'customData', 'message'])
.value();
opts = _.assign(opts, moreOpts);
}
opts = _.defaults(opts, {
message: null
});
var hash;
if (type == Model.TxProposal.Types.SIMPLE) {
opts.toAddress = outputs[0].toAddress;
opts.amount = outputs[0].amount;
hash = WalletService._getProposalHash(opts.toAddress, opts.amount,
opts.message, opts.payProUrl);
} else if (type == Model.TxProposal.Types.MULTIPLEOUTPUTS) {
opts.outputs = outputs;
var header = {
outputs: outputs,
message: opts.message,
payProUrl: opts.payProUrl
};
hash = WalletService._getProposalHash(header);
}
try {
opts.proposalSignature = helpers.signMessage(hash, signingKey);
} catch (ex) {}
return opts;
};
helpers.createAddresses = function(server, wallet, main, change, cb) {
var clock = sinon.useFakeTimers(Date.now(), 'Date');
async.map(_.range(main + change), function(i, next) {
clock.tick(1000);
var address = wallet.createAddress(i >= main);
server.storage.storeAddressAndWallet(wallet, address, function(err) {
next(err, address);
});
}, function(err, addresses) {
if (err) throw new Error('Could not generate addresses');
clock.restore();
return cb(_.take(addresses, main), _.takeRight(addresses, change));
});
};
var storage, blockchainExplorer;
var useMongoDb = !!process.env.USE_MONGO_DB;
@ -423,6 +74,7 @@ describe('Wallet service', function() {
beforeEach(function(done) {
resetStorage(function() {
blockchainExplorer = sinon.stub();
helpers.setBlockchainExplorer(blockchainExplorer);
WalletService.initialize({
storage: storage,
blockchainExplorer: blockchainExplorer,
@ -866,7 +518,6 @@ describe('Wallet service', function() {
});
});
});
});
describe('#getServiceVersion', function() {