commit
12dee6fd59
|
@ -7,6 +7,13 @@ var encoding = bitcore.encoding;
|
|||
var secp256k1 = require('secp256k1');
|
||||
|
||||
var Utils = {};
|
||||
var Bitcore = require('bitcore-lib');
|
||||
var Bitcore_ = {
|
||||
btc: Bitcore,
|
||||
bch: require('bitcore-lib-cash')
|
||||
};
|
||||
|
||||
|
||||
|
||||
Utils.getMissingFields = function(obj, args) {
|
||||
args = [].concat(args);
|
||||
|
@ -186,4 +193,30 @@ Utils.checkValueInCollection = function(value, collection) {
|
|||
return _.contains(_.values(collection), value);
|
||||
};
|
||||
|
||||
|
||||
Utils.getAddressCoin = function(address) {
|
||||
try {
|
||||
new Bitcore_['btc'].Address(address);
|
||||
return 'btc';
|
||||
} catch (e) {
|
||||
try {
|
||||
new Bitcore_['bch'].Address(address);
|
||||
return 'bch';
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Utils.translateAddress = function(address, coin) {
|
||||
var origCoin = Utils.getAddressCoin(address);
|
||||
var origAddress = new Bitcore_[origCoin].Address(address);
|
||||
var origObj = origAddress.toObject();
|
||||
|
||||
var result = Bitcore_[coin].Address.fromObject(origObj)
|
||||
return result.toString();
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = Utils;
|
||||
|
|
|
@ -1077,7 +1077,8 @@ WalletService.prototype._getUtxos = function(coin, addresses, cb) {
|
|||
var self = this;
|
||||
|
||||
if (addresses.length == 0) return cb(null, []);
|
||||
var networkName = Bitcore.Address(addresses[0]).toObject().network;
|
||||
|
||||
var networkName = Bitcore_[coin].Address(addresses[0]).toObject().network;
|
||||
|
||||
var bc = self._getBlockchainExplorer(coin, networkName);
|
||||
if (!bc) return cb(new Error('Could not get blockchain explorer instance'));
|
||||
|
@ -1106,20 +1107,16 @@ WalletService.prototype._getUtxosForCurrentWallet = function(opts, cb) {
|
|||
return utxo.txid + '|' + utxo.vout
|
||||
};
|
||||
|
||||
var coin, allAddresses, allUtxos, utxoIndex;
|
||||
var coin, allAddresses, allUtxos, utxoIndex, addressStrs;
|
||||
|
||||
async.series([
|
||||
|
||||
function(next) {
|
||||
if (opts.coin) {
|
||||
coin = opts.coin;
|
||||
next();
|
||||
} else {
|
||||
self.getWallet({}, function(err, wallet) {
|
||||
if (err) return next(err);
|
||||
|
||||
coin = wallet.coin;
|
||||
return next();
|
||||
});
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
if (_.isArray(opts.addresses)) {
|
||||
|
@ -1128,13 +1125,23 @@ WalletService.prototype._getUtxosForCurrentWallet = function(opts, cb) {
|
|||
}
|
||||
self.storage.fetchAddresses(self.walletId, function(err, addresses) {
|
||||
allAddresses = addresses;
|
||||
if (allAddresses.length == 0) return cb(null, []);
|
||||
|
||||
return next();
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
if (allAddresses.length == 0) return cb(null, []);
|
||||
addressStrs = _.pluck(allAddresses, 'address');
|
||||
if (!opts.coin) return next();
|
||||
|
||||
coin = opts.coin;
|
||||
addressStrs = _.map(addressStrs, function(a) {
|
||||
return Utils.translateAddress(a, coin);
|
||||
});
|
||||
next();
|
||||
},
|
||||
function(next) {
|
||||
|
||||
var addressStrs = _.pluck(allAddresses, 'address');
|
||||
self._getUtxos(coin, addressStrs, function(err, utxos) {
|
||||
if (err) return next(err);
|
||||
|
||||
|
@ -1206,16 +1213,17 @@ WalletService.prototype.getUtxos = function(opts, cb) {
|
|||
|
||||
opts = opts || {};
|
||||
|
||||
opts.coin = opts.coin || Defaults.COIN;
|
||||
if (opts.coin) {
|
||||
if (!Utils.checkValueInCollection(opts.coin, Constants.COINS))
|
||||
return cb(new ClientError('Invalid coin'));
|
||||
}
|
||||
|
||||
if (_.isUndefined(opts.addresses)) {
|
||||
self._getUtxosForCurrentWallet({
|
||||
coin: opts.coin
|
||||
}, cb);
|
||||
} else {
|
||||
self._getUtxos(opts.coin, opts.addresses, cb);
|
||||
self._getUtxos(Utils.getAddressCoin(opts.addresses[0]), opts.addresses, cb);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1922,6 +1930,7 @@ WalletService.prototype._canCreateTx = function(cb) {
|
|||
};
|
||||
|
||||
WalletService.prototype._validateOutputs = function(opts, wallet, cb) {
|
||||
var A = Bitcore_[wallet.coin].Address;
|
||||
var dustThreshold = Math.max(Defaults.MIN_OUTPUT_AMOUNT, Bitcore_[wallet.coin].Transaction.DUST_AMOUNT);
|
||||
|
||||
if (_.isEmpty(opts.outputs)) return new ClientError('No outputs were specified');
|
||||
|
@ -1936,7 +1945,7 @@ WalletService.prototype._validateOutputs = function(opts, wallet, cb) {
|
|||
|
||||
var toAddress = {};
|
||||
try {
|
||||
toAddress = new Bitcore.Address(output.toAddress);
|
||||
toAddress = new A(output.toAddress);
|
||||
} catch (ex) {
|
||||
return Errors.INVALID_ADDRESS;
|
||||
}
|
||||
|
|
14
package.json
14
package.json
|
@ -2,7 +2,7 @@
|
|||
"name": "bitcore-wallet-service",
|
||||
"description": "A service for Mutisig HD Bitcoin Wallets",
|
||||
"author": "BitPay Inc",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.0",
|
||||
"licence": "MIT",
|
||||
"keywords": [
|
||||
"bitcoin",
|
||||
|
@ -71,14 +71,18 @@
|
|||
"coveralls": "./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
|
||||
},
|
||||
"bitcoreNode": "./bitcorenode",
|
||||
"contributors": [{
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Braydon Fuller",
|
||||
"email": "braydon@bitpay.com"
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"name": "Ivan Socolsky",
|
||||
"email": "ivan@bitpay.com"
|
||||
}, {
|
||||
},
|
||||
{
|
||||
"name": "Matias Alejo Garcia",
|
||||
"email": "ematiu@gmail.com"
|
||||
}]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -277,6 +277,8 @@ helpers.stubUtxos = function(server, wallet, amounts, opts, cb) {
|
|||
|
||||
if (!helpers._utxos) helpers._utxos = {};
|
||||
|
||||
var S = Bitcore_[wallet.coin].Script;
|
||||
|
||||
async.waterfall([
|
||||
|
||||
function(next) {
|
||||
|
@ -298,10 +300,10 @@ helpers.stubUtxos = function(server, wallet, amounts, opts, cb) {
|
|||
var scriptPubKey;
|
||||
switch (wallet.addressType) {
|
||||
case Constants.SCRIPT_TYPES.P2SH:
|
||||
scriptPubKey = Bitcore.Script.buildMultisigOut(address.publicKeys, wallet.m).toScriptHashOut();
|
||||
scriptPubKey = S.buildMultisigOut(address.publicKeys, wallet.m).toScriptHashOut();
|
||||
break;
|
||||
case Constants.SCRIPT_TYPES.P2PKH:
|
||||
scriptPubKey = Bitcore.Script.buildPublicKeyHashOut(address.address);
|
||||
scriptPubKey = S.buildPublicKeyHashOut(address.address);
|
||||
break;
|
||||
}
|
||||
should.exist(scriptPubKey);
|
||||
|
|
|
@ -11,6 +11,12 @@ log.debug = log.verbose;
|
|||
log.level = 'info';
|
||||
|
||||
var Bitcore = require('bitcore-lib');
|
||||
var Bitcore_ = {
|
||||
btc: Bitcore,
|
||||
bch: require('bitcore-lib-cash')
|
||||
};
|
||||
|
||||
|
||||
|
||||
var Common = require('../../lib/common');
|
||||
var Utils = Common.Utils;
|
||||
|
@ -1222,6 +1228,7 @@ describe('Wallet service', function() {
|
|||
address.network.should.equal('livenet');
|
||||
address.address.should.equal('36q2G5FMGvJbPgAVEaiyAsFGmpkhPKwk2r');
|
||||
address.isChange.should.be.false;
|
||||
address.coin.should.equal('btc');
|
||||
address.path.should.equal('m/0/0');
|
||||
address.type.should.equal('P2SH');
|
||||
server.getNotifications({}, function(err, notifications) {
|
||||
|
@ -1271,6 +1278,76 @@ describe('Wallet service', function() {
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe('shared wallets (BIP44/BCH)', function() {
|
||||
beforeEach(function(done) {
|
||||
helpers.createAndJoinWallet(2, 2, {
|
||||
coin: 'bch'
|
||||
}, function(s, w) {
|
||||
server = s;
|
||||
wallet = w;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should create address', function(done) {
|
||||
server.createAddress({}, function(err, address) {
|
||||
should.not.exist(err);
|
||||
should.exist(address);
|
||||
address.walletId.should.equal(wallet.id);
|
||||
address.network.should.equal('livenet');
|
||||
address.address.should.equal('HBf8isgS8EXG1r3X6GP89FmooUmiJ42wHS');
|
||||
address.isChange.should.be.false;
|
||||
address.path.should.equal('m/0/0');
|
||||
address.type.should.equal('P2SH');
|
||||
address.coin.should.equal('bch');
|
||||
server.getNotifications({}, function(err, notifications) {
|
||||
should.not.exist(err);
|
||||
var notif = _.find(notifications, {
|
||||
type: 'NewAddress'
|
||||
});
|
||||
should.exist(notif);
|
||||
notif.data.address.should.equal(address.address);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should create many addresses on simultaneous requests', function(done) {
|
||||
var N = 5;
|
||||
async.mapSeries(_.range(N), function(i, cb) {
|
||||
server.createAddress({}, cb);
|
||||
}, function(err, addresses) {
|
||||
addresses.length.should.equal(N);
|
||||
_.each(_.range(N), function(i) {
|
||||
addresses[i].path.should.equal('m/0/' + i);
|
||||
});
|
||||
// No two identical addresses
|
||||
_.uniq(_.pluck(addresses, 'address')).length.should.equal(N);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not create address if unable to store it', function(done) {
|
||||
sinon.stub(server.storage, 'storeAddressAndWallet').yields('dummy error');
|
||||
server.createAddress({}, function(err, address) {
|
||||
should.exist(err);
|
||||
should.not.exist(address);
|
||||
|
||||
server.getMainAddresses({}, function(err, addresses) {
|
||||
addresses.length.should.equal(0);
|
||||
|
||||
server.storage.storeAddressAndWallet.restore();
|
||||
server.createAddress({}, function(err, address) {
|
||||
should.not.exist(err);
|
||||
should.exist(address);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('1-of-1 (BIP44 & P2PKH)', function() {
|
||||
beforeEach(function(done) {
|
||||
helpers.createAndJoinWallet(1, 1, function(s, w) {
|
||||
|
@ -2447,22 +2524,45 @@ describe('Wallet service', function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe('#createTx', function() {
|
||||
describe('Tx proposal creation & publishing', function() {
|
||||
var addrMap = {
|
||||
btc: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
bch: 'CPrtPWbp8cCftTQu5fzuLG5zPJNDHMMf8X',
|
||||
}
|
||||
|
||||
var idKeyMap = {
|
||||
btc: 'id44btc',
|
||||
bch: 'id44bch',
|
||||
};
|
||||
|
||||
_.each(['bch', 'btc'], function(coin) {
|
||||
|
||||
describe('#createTx ' + coin, function() {
|
||||
var addressStr, idKey;
|
||||
before(function() {
|
||||
addressStr = addrMap[coin];
|
||||
idKey = idKeyMap[coin];
|
||||
});
|
||||
|
||||
|
||||
|
||||
describe('Tx proposal creation & publishing ' + coin, function() {
|
||||
var server, wallet;
|
||||
beforeEach(function(done) {
|
||||
helpers.createAndJoinWallet(1, 1, function(s, w) {
|
||||
helpers.createAndJoinWallet(1, 1, {
|
||||
coin: coin,
|
||||
}, function(s, w) {
|
||||
server = s;
|
||||
wallet = w;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should create a tx', function(done) {
|
||||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8 * 1e8,
|
||||
}],
|
||||
message: 'some message',
|
||||
|
@ -2545,7 +2645,7 @@ describe('Wallet service', function() {
|
|||
it('should fail to create tx for invalid amount', function(done) {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2561,7 +2661,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, 2, function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1e8,
|
||||
}],
|
||||
feeLevel: 'normal',
|
||||
|
@ -2582,7 +2682,7 @@ describe('Wallet service', function() {
|
|||
var inputs = [utxos[0], utxos[2]];
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 2.5e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2604,7 +2704,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function(utxos) {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2623,7 +2723,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function(utxos) {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8e8,
|
||||
}],
|
||||
inputs: utxos,
|
||||
|
@ -2650,7 +2750,7 @@ describe('Wallet service', function() {
|
|||
var txOpts = {
|
||||
txProposalId: '123',
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2668,7 +2768,7 @@ describe('Wallet service', function() {
|
|||
var txOpts = {
|
||||
txProposalId: '123',
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2696,7 +2796,7 @@ describe('Wallet service', function() {
|
|||
var txOpts = {
|
||||
txProposalId: '123',
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2731,7 +2831,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8 * 1e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2758,7 +2858,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8 * 1e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2784,7 +2884,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8 * 1e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2834,7 +2934,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8 * 1e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2858,7 +2958,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8 * 1e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -2885,7 +2985,7 @@ describe('Wallet service', function() {
|
|||
var txp1, txp2;
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8 * 1e8,
|
||||
}],
|
||||
message: 'some message',
|
||||
|
@ -2953,7 +3053,7 @@ describe('Wallet service', function() {
|
|||
var txp1, txp2;
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8 * 1e8,
|
||||
}],
|
||||
message: 'some message',
|
||||
|
@ -3018,6 +3118,9 @@ describe('Wallet service', function() {
|
|||
|
||||
describe('Fee levels', function() {
|
||||
it('should create a tx specifying feeLevel', function(done) {
|
||||
//ToDo
|
||||
var level = wallet.coin == 'btc' ? 'economy' : 'normal';
|
||||
var expected = wallet.coin == 'btc' ? 180e2 : 200e2;
|
||||
helpers.stubFeeLevels({
|
||||
1: 400e2,
|
||||
2: 200e2,
|
||||
|
@ -3027,16 +3130,17 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, 2, function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1e8,
|
||||
}],
|
||||
feeLevel: 'economy',
|
||||
// ToDo
|
||||
feeLevel: level,
|
||||
};
|
||||
server.createTx(txOpts, function(err, txp) {
|
||||
should.not.exist(err);
|
||||
should.exist(txp);
|
||||
txp.feePerKb.should.equal(180e2);
|
||||
txp.feeLevel.should.equal('economy');
|
||||
txp.feePerKb.should.equal(expected);
|
||||
txp.feeLevel.should.equal(level);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -3045,7 +3149,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, 2, function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1e8,
|
||||
}],
|
||||
feeLevel: 'madeUpLevel',
|
||||
|
@ -3068,7 +3172,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, 2, function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1e8,
|
||||
}],
|
||||
};
|
||||
|
@ -3086,7 +3190,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3108,7 +3212,7 @@ describe('Wallet service', function() {
|
|||
var max = 3e8 - 7000; // Fees for this tx at 100bits/kB = 7000 sat
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: max,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3129,7 +3233,7 @@ describe('Wallet service', function() {
|
|||
should.not.exist(err);
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1e8
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3143,14 +3247,14 @@ describe('Wallet service', function() {
|
|||
});
|
||||
it('should fail gracefully when bitcore throws exception on raw tx creation', function(done) {
|
||||
helpers.stubUtxos(server, wallet, 1, function() {
|
||||
var bitcoreStub = sinon.stub(Bitcore, 'Transaction');
|
||||
var bitcoreStub = sinon.stub(Bitcore_[coin], 'Transaction');
|
||||
bitcoreStub.throws({
|
||||
name: 'dummy',
|
||||
message: 'dummy exception'
|
||||
});
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.5e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3169,7 +3273,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, _.range(1, 10, 0), function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 8e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3186,7 +3290,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 1], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1.1e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3211,7 +3315,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, 1, function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 20e2,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3231,7 +3335,7 @@ describe('Wallet service', function() {
|
|||
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: amount,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3250,7 +3354,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1.1, 1.2, 1.3], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1.5e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3278,7 +3382,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1.1, 1.2, 1.3], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 1.5e8,
|
||||
}],
|
||||
feePerKb: 100e2,
|
||||
|
@ -3313,7 +3417,7 @@ describe('Wallet service', function() {
|
|||
var xPrivKey = TestData.copayers[0].xPrivKey_44H_0H_0H;
|
||||
|
||||
var accessOpts = {
|
||||
copayerId: TestData.copayers[0].id44btc,
|
||||
copayerId: TestData.copayers[0][idKey],
|
||||
requestPubKey: reqPubKey,
|
||||
signature: helpers.signRequestPubKey(reqPubKey, xPrivKey),
|
||||
};
|
||||
|
@ -3324,7 +3428,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: 0.8 * 1e8,
|
||||
}],
|
||||
message: 'some message',
|
||||
|
@ -3359,7 +3463,7 @@ describe('Wallet service', function() {
|
|||
helpers.stubUtxos(server, wallet, [1, 2], function() {
|
||||
var txOpts = {
|
||||
outputs: [{
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: null,
|
||||
}],
|
||||
feePerKb: 10000,
|
||||
|
@ -3385,7 +3489,7 @@ describe('Wallet service', function() {
|
|||
var txOpts = {
|
||||
outputs: _.times(30, function(i) {
|
||||
return {
|
||||
toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7',
|
||||
toAddress: addressStr,
|
||||
amount: (i + 1) * 100e2,
|
||||
};
|
||||
}),
|
||||
|
@ -3415,6 +3519,7 @@ describe('Wallet service', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Backoff time', function(done) {
|
||||
var server, wallet, txid, clock;
|
||||
|
@ -7672,7 +7777,7 @@ describe('Wallet service', function() {
|
|||
address.walletId.should.equal(wallet.bch.id);
|
||||
address.coin.should.equal('bch');
|
||||
address.network.should.equal('livenet');
|
||||
address.address.should.equal('1L3z9LPd861FWQhf3vDn89Fnc9dkdBo2CG');
|
||||
address.address.should.equal('CbWsiNjh18ynQYc5jfYhhespEGrAaW8YUq');
|
||||
server.btc.getMainAddresses({}, function(err, addresses) {
|
||||
should.not.exist(err);
|
||||
addresses.length.should.equal(1);
|
||||
|
@ -7684,7 +7789,7 @@ describe('Wallet service', function() {
|
|||
addresses.length.should.equal(1);
|
||||
addresses[0].coin.should.equal('bch');
|
||||
addresses[0].walletId.should.equal(wallet.bch.id);
|
||||
addresses[0].address.should.equal('1L3z9LPd861FWQhf3vDn89Fnc9dkdBo2CG');
|
||||
addresses[0].address.should.equal('CbWsiNjh18ynQYc5jfYhhespEGrAaW8YUq');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -131,4 +131,42 @@ describe('Utils', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getAddressCoin', function() {
|
||||
it('should identify btc as coin for 1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA', function() {
|
||||
Utils.getAddressCoin('1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA').should.equal('btc');
|
||||
});
|
||||
it('should identify bch as coin for CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz', function() {
|
||||
Utils.getAddressCoin('CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz').should.equal('bch');
|
||||
});
|
||||
it('should return null for 1L', function() {
|
||||
should.not.exist(Utils.getAddressCoin('1L'));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#translateAddress', function() {
|
||||
it('should translate address from btc to bch', function() {
|
||||
var res = Utils.translateAddress('1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA', 'bch');
|
||||
res.should.equal('CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz');
|
||||
});
|
||||
it('should translate address from bch to btc', function() {
|
||||
var res = Utils.translateAddress('HBf8isgS8EXG1r3X6GP89FmooUmiJ42wHS', 'btc');
|
||||
res.should.equal('36q2G5FMGvJbPgAVEaiyAsFGmpkhPKwk2r');
|
||||
});
|
||||
|
||||
it('should keep the address if there is nothing to do (bch)', function() {
|
||||
var res = Utils.translateAddress('CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz', 'bch');
|
||||
res.should.equal('CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz');
|
||||
});
|
||||
it('should keep the address if there is nothing to do (btc)', function() {
|
||||
var res = Utils.translateAddress('1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA', 'btc');
|
||||
should.exist(res);
|
||||
res.should.equal('1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA');
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue