From da3dfb73d27ff5bba8ee40de0759d9f7c6dc84a1 Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Thu, 12 Oct 2017 16:51:42 -0400 Subject: [PATCH 01/25] test(Shift): test shapeshift trade --- tests/shift/trade.spec.js | 237 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 tests/shift/trade.spec.js diff --git a/tests/shift/trade.spec.js b/tests/shift/trade.spec.js new file mode 100644 index 000000000..3c514cabc --- /dev/null +++ b/tests/shift/trade.spec.js @@ -0,0 +1,237 @@ +/* eslint-disable semi */ +const Trade = require('../../src/shift/trade') +const Quote = require('../../src/shift/quote') + +describe('ShapeShift.Trade', () => { + const quoteData = { + 'orderId': '18408bc9-a592-4d15-9409-fe0b8f56c408', + 'pair': 'btc_eth', + 'withdrawal': '0x632a4f72b7dd73f60194e09a073ca494ccba5a9c', + 'withdrawalAmount': '1.13500523', + 'deposit': '1L2mnCoD8hzTukbGBvkwyoGBeAfgzqhcx3', + 'depositAmount': '0.1', + 'expiration': 1502292508112, + 'quotedRate': '11.40005229', + 'maxLimit': 1.51084099, + 'returnAddress': '1EhvfATiZukipzSxhHw5cJ5F5N56HawExu', + 'apiPubKey': 'shapeshift', + 'minerFee': '0.005' + } + + const tradeData = { + 'status': 'complete', + 'hashIn': '2eeda12829d025d4672a4653e6ca9c93321727bf54d01f8ebfb18c6abd2c7925', + 'hashOut': '0xc1341e8ec046dff48f524cd87fe812c6fd86a41c868ff5843f04619906882123', + 'time': 'Mon Oct 09 2017 10:57:50 GMT+0100 (BST)', + 'quote': { + 'orderId': '2b92f15c-1bc9-50d3-73d1-8cd9f332ba94', + 'quotedRate': '5.15', + 'deposit': '1FcBaMUHXMZRsbwUUwAYWdsaxoyvYFxRbW', + 'minerFee': '0.001' + } + } + + describe('static', () => { + describe('trade states', () => { + it('should have NO_DEPOSITS', () => { + expect(Trade.NO_DEPOSITS).toEqual('no_deposits') + }) + + it('should have RECEIVED', () => { + expect(Trade.RECEIVED).toEqual('received') + }) + + it('should have COMPLETE', () => { + expect(Trade.COMPLETE).toEqual('complete') + }) + + it('should have FAILED', () => { + expect(Trade.FAILED).toEqual('failed') + }) + + it('should have RESOLVED', () => { + expect(Trade.RESOLVED).toEqual('resolved') + }) + }) + + describe('.fromMetadata', () => { + it('should create a trade from the metadata service format', () => { + let trade = Trade.fromMetadata(tradeData) + expect(trade.constructor).toEqual(Trade) + }) + }) + + describe('.fromQuote', () => { + it('should create a trade from api response json', () => { + let quote = Quote.fromApiResponse(quoteData) + let trade = Trade.fromQuote(quote) + expect(trade.constructor).toEqual(Trade) + }) + }) + }) + + describe('instance', () => { + let trade + let now = new Date() + + beforeEach(() => { + spyOn(Date, 'now').and.returnValue(now.getTime()) + let quote = Quote.fromApiResponse(quoteData) + trade = Trade.fromQuote(quote) + }) + + describe('getters', () => { + it('should get: quote', () => { + expect(trade.quote.constructor).toEqual(Quote) + }) + + it('should get: pair', () => { + expect(trade.pair).toEqual(quoteData.pair) + }) + + it('should get: rate', () => { + expect(trade.rate).toEqual(quoteData.quotedRate) + }) + + it('should get: fromCurrency', () => { + expect(trade.fromCurrency).toEqual('btc') + }) + + it('should get: toCurrency', () => { + expect(trade.toCurrency).toEqual('eth') + }) + + it('should get: depositAddress', () => { + expect(trade.depositAddress).toEqual(quoteData.deposit) + }) + + it('should get: depositAmount', () => { + expect(trade.depositAmount).toEqual(quoteData.depositAmount) + }) + + it('should get: withdrawalAddress', () => { + expect(trade.withdrawalAddress).toEqual(quoteData.withdrawal) + }) + + it('should get: withdrawalAmount', () => { + expect(trade.withdrawalAmount).toEqual(quoteData.withdrawalAmount) + }) + + it('should get: error', () => { + trade._error = 'some error' + expect(trade.error).toEqual('some error') + }) + + it('should get: status', () => { + trade._status = 'some status' + expect(trade.status).toEqual('some status') + }) + + it('should get: isPending', () => { + trade._status = null + expect(trade.isPending).toEqual(false) + trade._status = Trade.NO_DEPOSITS + expect(trade.isPending).toEqual(true) + trade._status = Trade.RECEIVED + expect(trade.isPending).toEqual(true) + }) + + it('should get: isWaitingForDeposit', () => { + trade._status = null + expect(trade.isWaitingForDeposit).toEqual(false) + trade._status = Trade.NO_DEPOSITS + expect(trade.isWaitingForDeposit).toEqual(true) + }) + + it('should get: isProcessing', () => { + trade._status = null + expect(trade.isProcessing).toEqual(false) + trade._status = Trade.RECEIVED + expect(trade.isProcessing).toEqual(true) + }) + + it('should get: isComplete', () => { + trade._status = null + expect(trade.isComplete).toEqual(false) + trade._status = Trade.COMPLETE + expect(trade.isComplete).toEqual(true) + }) + + it('should get: isFailed', () => { + trade._status = null + expect(trade.isFailed).toEqual(false) + trade._status = Trade.FAILED + expect(trade.isFailed).toEqual(true) + }) + + it('should get: isResolved', () => { + trade._status = null + expect(trade.isResolved).toEqual(false) + trade._status = Trade.RESOLVED + expect(trade.isResolved).toEqual(true) + }) + + it('should get: failedReason', () => { + trade._error = 'reason' + expect(trade.failedReason).toEqual('reason') + }) + + it('should get: depositHash', () => { + trade._hashIn = 'hash_in' + expect(trade.depositHash).toEqual('hash_in') + }) + + it('should get: withdrawalHash', () => { + trade._hashOut = 'hash_out' + expect(trade.withdrawalHash).toEqual('hash_out') + }) + + it('should get: time', () => { + expect(trade.time.constructor).toEqual(Date) + }) + }) + + describe('.setStatus', () => { + it('should set from a completed status', () => { + let statusObj = { status: 'complete', transaction: 'tx_hash_out' } + trade.setStatus(statusObj) + expect(trade.isComplete).toEqual(true) + expect(trade.withdrawalHash).toEqual('tx_hash_out') + }) + + it('should should not override existing fields', () => { + let statusObj = { status: 'failed', error: 'some_error' } + trade.setStatus(statusObj) + expect(trade.isFailed).toEqual(true) + expect(trade.failedReason).toEqual('some_error') + }) + }) + + describe('.setDepositHash', () => { + it('should set the proper fields', () => { + trade.setDepositHash('deposit_hash') + expect(trade.depositHash).toEqual('deposit_hash') + }) + }) + + describe('.toJSON', () => { + it('should return the full json', () => { + let json = JSON.stringify({ + 'status': 'no_deposits', + 'time': now.toString(), + 'quote': { + 'orderId': '18408bc9-a592-4d15-9409-fe0b8f56c408', + 'quotedRate': '11.40005229', + 'deposit': '1L2mnCoD8hzTukbGBvkwyoGBeAfgzqhcx3', + 'minerFee': '0.005', + 'pair': 'btc_eth', + 'depositAmount': '0.1', + 'withdrawal': '0x632a4f72b7dd73f60194e09a073ca494ccba5a9c', + 'withdrawalAmount': '1.13500523' + } + }) + expect(JSON.stringify(trade)).toEqual(json) + }) + }) + }) +}) From 1c058200a842bb07e38d2c8b1ff27c48e21ca913 Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Thu, 12 Oct 2017 17:00:36 -0400 Subject: [PATCH 02/25] fix(Shift): save trade in metadata with unix timestamp --- src/shift/trade.js | 11 +++++++++-- tests/shift/trade.spec.js | 9 ++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/shift/trade.js b/src/shift/trade.js index 3f493db7c..e3d84953f 100644 --- a/src/shift/trade.js +++ b/src/shift/trade.js @@ -8,8 +8,14 @@ class Trade { this._error = obj.error this._hashIn = obj.hashIn this._hashOut = obj.hashOut - this._time = obj.time ? new Date(obj.time) : void 0 this._quote = obj.quote + + /* prefer `timestamp` if exists */ + if (obj.timestamp) { + this._time = new Date(obj.timestamp) + } else if (obj.time) { + this._time = new Date(obj.time) + } } get quote () { @@ -120,7 +126,8 @@ class Trade { status: this._status, hashIn: this._hashIn, hashOut: this._hashOut, - time: this._time && this._time.toString(), + // save `timestamp` as UNIX timestamp integer + timestamp: this._time && this._time.getTime(), quote: this.isComplete ? this._quote.toPartialJSON() : this._quote.toJSON() } } diff --git a/tests/shift/trade.spec.js b/tests/shift/trade.spec.js index 3c514cabc..211658e13 100644 --- a/tests/shift/trade.spec.js +++ b/tests/shift/trade.spec.js @@ -189,6 +189,13 @@ describe('ShapeShift.Trade', () => { it('should get: time', () => { expect(trade.time.constructor).toEqual(Date) }) + + it('should use .timestamp over .time', () => { + let time = new Date('Thu Oct 12 2017 16:56:12 GMT-0400 (EDT)') + let timestamp = new Date(1507841784426) + trade = new Trade({ time, timestamp }) + expect(trade.time.getTime()).toEqual(timestamp.getTime()) + }) }) describe('.setStatus', () => { @@ -218,7 +225,7 @@ describe('ShapeShift.Trade', () => { it('should return the full json', () => { let json = JSON.stringify({ 'status': 'no_deposits', - 'time': now.toString(), + 'timestamp': now.getTime(), 'quote': { 'orderId': '18408bc9-a592-4d15-9409-fe0b8f56c408', 'quotedRate': '11.40005229', From 5c3fec808665e15968d9e06f23b8fb9ab7438b5f Mon Sep 17 00:00:00 2001 From: plondon Date: Sun, 15 Oct 2017 10:37:33 -0400 Subject: [PATCH 03/25] chore(Release): upgrade bitcoin-coinify-client --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index e9501ce78..3118a2472 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "bigi": "1.4.*", "bignumber.js": "^4.0.2", "bip39": "2.1.*", - "bitcoin-coinify-client": "^0.6.9", + "bitcoin-coinify-client": "^0.7.0", "bitcoin-exchange-client": "^0.4.6", "bitcoin-sfox-client": "^0.1.11", "bitcoin-unocoin-client": "^0.3.4", diff --git a/yarn.lock b/yarn.lock index 62c1fc2fa..327d5941b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1021,9 +1021,9 @@ bip66@^1.1.0, bip66@^1.1.3: dependencies: safe-buffer "^5.0.1" -bitcoin-coinify-client@^0.6.9: - version "0.6.9" - resolved "https://registry.npmjs.org/bitcoin-coinify-client/-/bitcoin-coinify-client-0.6.9.tgz#933458ce5161262112cea4e29cdc94cb2f66c8de" +bitcoin-coinify-client@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/bitcoin-coinify-client/-/bitcoin-coinify-client-0.7.0.tgz#303433818bf4b9853bbd12e8914375137d548763" dependencies: babel-polyfill "6.16.*" babel-preset-es2015 "6.16.*" From 4242c2316704209f8d0a7f49e69083e33a82d868 Mon Sep 17 00:00:00 2001 From: plondon Date: Sun, 15 Oct 2017 10:38:47 -0400 Subject: [PATCH 04/25] chore(Release): v3.39.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3118a2472..52e28641d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-client", - "version": "3.38.5", + "version": "3.39.0", "description": "Blockchain.info JavaScript Wallet", "homepage": "https://github.com/blockchain/my-wallet-v3", "bugs": { From 6ecb9d6e7b9a7ce6c3f147b2ff0a09760d0b5c69 Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Mon, 16 Oct 2017 13:15:23 -0400 Subject: [PATCH 05/25] fix(Shift): preserve time property --- src/shift/trade.js | 1 + tests/shift/trade.spec.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/shift/trade.js b/src/shift/trade.js index e3d84953f..8e3a6f71c 100644 --- a/src/shift/trade.js +++ b/src/shift/trade.js @@ -126,6 +126,7 @@ class Trade { status: this._status, hashIn: this._hashIn, hashOut: this._hashOut, + time: this._time && this._time.toString(), // save `timestamp` as UNIX timestamp integer timestamp: this._time && this._time.getTime(), quote: this.isComplete ? this._quote.toPartialJSON() : this._quote.toJSON() diff --git a/tests/shift/trade.spec.js b/tests/shift/trade.spec.js index 211658e13..da675bed8 100644 --- a/tests/shift/trade.spec.js +++ b/tests/shift/trade.spec.js @@ -225,6 +225,7 @@ describe('ShapeShift.Trade', () => { it('should return the full json', () => { let json = JSON.stringify({ 'status': 'no_deposits', + 'time': now.toString(), 'timestamp': now.getTime(), 'quote': { 'orderId': '18408bc9-a592-4d15-9409-fe0b8f56c408', From 1feebfb72b68dd61b65cdc6ca1643acd439b0712 Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 16 Oct 2017 14:17:43 -0400 Subject: [PATCH 06/25] chore(Release): v3.39.1 --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 52e28641d..a69203885 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-client", - "version": "3.39.0", + "version": "3.39.1", "description": "Blockchain.info JavaScript Wallet", "homepage": "https://github.com/blockchain/my-wallet-v3", "bugs": { @@ -48,7 +48,6 @@ "bignumber.js": "^4.0.2", "bip39": "2.1.*", "bitcoin-coinify-client": "^0.7.0", - "bitcoin-exchange-client": "^0.4.6", "bitcoin-sfox-client": "^0.1.11", "bitcoin-unocoin-client": "^0.3.4", "bitcoincashjs-lib": "https://github.com/bitcoinjs/bitcoinjs-lib#9ac221c80dbc3462d7a2392cec2045ae2b590461", From 85d99fef75065d0b54e80f1c474c362ef99b6dac Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 16 Oct 2017 15:09:28 -0400 Subject: [PATCH 07/25] chore(Release): bump coinify client version --- package.json | 2 +- yarn.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index a69203885..9789f27ce 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "bigi": "1.4.*", "bignumber.js": "^4.0.2", "bip39": "2.1.*", - "bitcoin-coinify-client": "^0.7.0", + "bitcoin-coinify-client": "^0.7.1", "bitcoin-sfox-client": "^0.1.11", "bitcoin-unocoin-client": "^0.3.4", "bitcoincashjs-lib": "https://github.com/bitcoinjs/bitcoinjs-lib#9ac221c80dbc3462d7a2392cec2045ae2b590461", diff --git a/yarn.lock b/yarn.lock index 327d5941b..4d7fd11f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1021,14 +1021,14 @@ bip66@^1.1.0, bip66@^1.1.3: dependencies: safe-buffer "^5.0.1" -bitcoin-coinify-client@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/bitcoin-coinify-client/-/bitcoin-coinify-client-0.7.0.tgz#303433818bf4b9853bbd12e8914375137d548763" +bitcoin-coinify-client@^0.7.1: + version "0.7.1" + resolved "https://registry.npmjs.org/bitcoin-coinify-client/-/bitcoin-coinify-client-0.7.1.tgz#44bc7c1910eaf1020fac0ab1b3fe3aca9337aaf3" dependencies: babel-polyfill "6.16.*" babel-preset-es2015 "6.16.*" babelify "7.3.*" - bitcoin-exchange-client "^0.4.6" + bitcoin-exchange-client "^0.5.0" bitcoin-exchange-client@0.2.*: version "0.2.2" @@ -1036,9 +1036,9 @@ bitcoin-exchange-client@0.2.*: dependencies: isomorphic-fetch "^2.2.0" -bitcoin-exchange-client@^0.4.6: - version "0.4.6" - resolved "https://registry.npmjs.org/bitcoin-exchange-client/-/bitcoin-exchange-client-0.4.6.tgz#46ae8eff5275fe49df4b6c6ee01252e8b6e0e224" +bitcoin-exchange-client@^0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/bitcoin-exchange-client/-/bitcoin-exchange-client-0.5.0.tgz#e9d70ca7cd17909fbae86d79c43c4367fcda02f9" dependencies: isomorphic-fetch "^2.2.0" From cf37be890ac3dc13ce3d37fdd19a27fb7610259e Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 16 Oct 2017 15:10:34 -0400 Subject: [PATCH 08/25] chore(Release): v3.39.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9789f27ce..9618df3f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-client", - "version": "3.39.1", + "version": "3.39.2", "description": "Blockchain.info JavaScript Wallet", "homepage": "https://github.com/blockchain/my-wallet-v3", "bugs": { From 2d8a636fdd4f969e28ae4d2f0fb4ee1a2de115b8 Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Thu, 19 Oct 2017 14:17:32 -0400 Subject: [PATCH 09/25] test(Cash): test bch signing function --- src/bch/bch-api.js | 8 +++- tests/__data__/signing-data.json | 70 ++++++++++++++++++++++++++++++++ tests/bch/signer.spec.js | 19 +++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 tests/__data__/signing-data.json create mode 100644 tests/bch/signer.spec.js diff --git a/src/bch/bch-api.js b/src/bch/bch-api.js index ff7b720ba..1e8846458 100644 --- a/src/bch/bch-api.js +++ b/src/bch/bch-api.js @@ -50,6 +50,11 @@ const multiaddr = (addresses, n = 1) => { }).then(r => r.status === 200 ? r.json() : r.json().then(e => Promise.reject(e))); }; +const addIndexToOutput = curry((hdwallet, output) => { + let addIndex = (xpub) => assoc('index', hdwallet.account(xpub.m).index, xpub) + return over(lensProp('xpub'), addIndex, output) +}) + // source can be a list of legacy addresses or a single integer for account index const getUnspents = curry((wallet, source) => { switch (true) { @@ -57,7 +62,7 @@ const getUnspents = curry((wallet, source) => { const accIdx = wallet.hdwallet.accounts[source].extendedPublicKey return apiGetUnspents([accIdx]) .then(prop('unspent_outputs')) - .then(over(compose(mapped, lensProp('xpub')), assoc('index', source))) + .then(map(addIndexToOutput(wallet.hdwallet))) .then(map(Coin.fromJS)); case is(Array, source): return apiGetUnspents(source) @@ -70,6 +75,7 @@ const getUnspents = curry((wallet, source) => { }) module.exports = { + addIndexToOutput, getUnspents, pushTx, multiaddr diff --git a/tests/__data__/signing-data.json b/tests/__data__/signing-data.json new file mode 100644 index 000000000..7d849d475 --- /dev/null +++ b/tests/__data__/signing-data.json @@ -0,0 +1,70 @@ +{ + "wallet": { + "guid": "35184925-09c3-4153-946b-e604d597b672", + "sharedKey": "6a794227-1278-448c-9c91-47a743164ec1", + "double_encryption": false, + "metadataHDNode": "xprv9vUdSmQHAzqKd9ZArrJXqEzDhkmfQ7zp6TJ1C27cETXcgdfP3W54i1Umdv6hhGTGRVtAGKTAp98CQr893VaksWu77diviTMn4r6JKE9CvK7", + "options": { + "pbkdf2_iterations": 5000, + "fee_per_kb": 10000, + "html5_notifications": false, + "logout_time": 600000 + }, + "address_book": [], + "tx_notes": {}, + "tx_names": [], + "keys": [], + "hd_wallets": [ + { + "seed_hex": "59e33544d97a041b6c74ada06469c163", + "passphrase": "", + "mnemonic_verified": false, + "default_account_idx": 0, + "accounts": [ + { + "label": "My Bitcoin Wallet", + "archived": false, + "xpriv": "xprv9xrdr5KSDuFjMRZsFtYo7kzBLqX5wabxLkrVZab6iLEN2fmwRFuTyBYXrz93QaxXAivmseXpaxLWX1nnTwCao93MARAGMA8kvNwRaWvmEcn", + "xpub": "xpub6BqzFarL4Gp2ZueLMv5oUtvutsMaM3Kohyn6MxziGfmLuU75xoDiWys1iGnrQwqQT3PJRAkE2ZPyoPSLq8GVVStSi8DnCAxDKXUttnfH2Wu", + "address_labels": [], + "cache": { + "receiveAccount": "xpub6EvRwUVEmxMkYReJ2d1korWa9R2AriQhXeyJB55ns4G6mmF7JoBPABuSS9FLti5B3Ddk6XJ4HU2sXW5AGDYZLPVMEXLaM4pNLhZ8DFVgEnN", + "changeAccount": "xpub6EvRwUVEmxMka4otnrSt8ssFxNWcNb5pDc479E9H1zKxwMTFz9BRxkHdiFYG4EmLafU4bzj6w713haUibQ5qF4atDYYEnLXa44CCWE6KAg3" + } + } + ] + } + ] + }, + "tx_hex": "01000000026c1b0fee717838e4d7c0b0fe88aa4929cc775f8b2d25f42e6783198aea1447db000000006a473044022046623d6d62db125fe4281c7888a995c572377223b50acd11eb06a095f3d5e3c80220221359d419f2241c0c7bef5530e0a2c3438364fd9fe825e914ad44f0bc6498154121031c77d382badb52767699c14366d3ef47d9538b0bd12bf75ced6b1aa37a9d1a29ffffffffa3a9c77436956511fa7da5c458e23dc1e9af53f1f48a59411e3f168c1e41e568010000006b483045022100dd869488f239422164bc1049ec2c434049b4706cc74f38daf4402f41aebf42df022066376640c814cd7a7d1ab02e35bd4246c6ee4640aa999a1ebf604d737f270c844121026a622460994a92deae67834775fe54ee652f77fe65c9f279443e277348698d14ffffffff01ca140100000000001976a914b4d4b04597645ccb38465c2983b9e83804d8381488ac00000000", + "unspent_outputs": [ + { + "tx_hash": "6c1b0fee717838e4d7c0b0fe88aa4929cc775f8b2d25f42e6783198aea1447db", + "tx_hash_big_endian": "db4714ea8a1983672ef4252d8b5f77cc2949aa88feb0c0d7e4387871ee0f1b6c", + "tx_index": 293191941, + "tx_output_n": 0, + "script": "76a9142066179ca1e77a26d09447e1543508436cab5e0088ac", + "xpub": { + "m": "xpub6BqzFarL4Gp2ZueLMv5oUtvutsMaM3Kohyn6MxziGfmLuU75xoDiWys1iGnrQwqQT3PJRAkE2ZPyoPSLq8GVVStSi8DnCAxDKXUttnfH2Wu", + "path": "M/0/1" + }, + "value": 39448, + "value_hex": "009a18", + "confirmations": 0 + }, + { + "tx_hash": "a3a9c77436956511fa7da5c458e23dc1e9af53f1f48a59411e3f168c1e41e568", + "tx_hash_big_endian": "68e5411e8c163f1e41598af4f153afe9c13de258c4a57dfa1165953674c7a9a3", + "tx_index": 293191876, + "tx_output_n": 1, + "script": "76a914d91dae4825e52351f12b81d7e500a11cd719187088ac", + "xpub": { + "m": "xpub6BqzFarL4Gp2ZueLMv5oUtvutsMaM3Kohyn6MxziGfmLuU75xoDiWys1iGnrQwqQT3PJRAkE2ZPyoPSLq8GVVStSi8DnCAxDKXUttnfH2Wu", + "path": "M/0/0" + }, + "value": 50000, + "value_hex": "00c350", + "confirmations": 0 + } + ] +} diff --git a/tests/bch/signer.spec.js b/tests/bch/signer.spec.js new file mode 100644 index 000000000..1b12d2250 --- /dev/null +++ b/tests/bch/signer.spec.js @@ -0,0 +1,19 @@ +/* eslint-disable semi */ +let { compose, map } = require('ramda') +let Wallet = require('../../src/blockchain-wallet') +let { addIndexToOutput } = require('../../src/bch/bch-api') +let signer = require('../../src/bch/signer') +let Coin = require('../../src/bch/coin') +let cs = require('../../src/bch/coin-selection') +let signingData = require('../__data__/signing-data.json') + +describe('Signer', () => { + let wallet = new Wallet(signingData.wallet) + let inputToCoin = compose(Coin.fromJS, addIndexToOutput(wallet.hdwallet)) + let selection = cs.selectAll(55, map(inputToCoin, signingData.unspent_outputs), '1HV9RPcPAwcCEDmNET5BEWvVVgCY3Pbg7i') + + it('should sign a bch transaction', () => { + let tx = signer.sign(void 0, wallet, selection) + expect(tx.toHex()).toEqual(signingData.tx_hex) + }) +}) From a3eac777dac5f5d111b6a30b3bccc50bb9d25b66 Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Thu, 19 Oct 2017 14:36:25 -0400 Subject: [PATCH 10/25] feat(Signer): sign for btc as well --- src/bch/bch-payment.js | 4 +-- src/bch/signer.js | 55 +++++++++++++++++++++----------- tests/__data__/signing-data.json | 3 +- tests/bch/signer.spec.js | 9 ++++-- 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/bch/bch-payment.js b/src/bch/bch-payment.js index d43995fb1..0a31bc043 100644 --- a/src/bch/bch-payment.js +++ b/src/bch/bch-payment.js @@ -4,7 +4,7 @@ const Coin = require('./coin') const BchApi = require('./bch-api') const { isBitcoinAddress, isPositiveInteger } = require('../helpers') const { selectAll, descentDraw } = require('./coin-selection') -const { sign } = require('./signer') +const signer = require('./signer') const isValidFrom = (from) => ( is(Number, from) || @@ -123,7 +123,7 @@ class BchPayment { if (payment.selection == null) { throw new PaymentError('cannot sign an unbuilt transaction', payment) } - let tx = sign(secPass, this._wallet, payment.selection) + let tx = signer.signBitcoinCash(secPass, this._wallet, payment.selection) let setData = compose(assoc('hash', tx.getId()), assoc('rawTx', tx.toHex())) return setData(payment) }) diff --git a/src/bch/signer.js b/src/bch/signer.js index d1dbce998..f70a936d1 100644 --- a/src/bch/signer.js +++ b/src/bch/signer.js @@ -1,17 +1,18 @@ const { curry, forEach, addIndex, lensProp, compose, over } = require('ramda'); const { mapped } = require('ramda-lens'); -const Bitcoin = require('bitcoincashjs-lib'); +const Bitcoin = require('bitcoinjs-lib'); +const BitcoinCash = require('bitcoincashjs-lib'); const constants = require('../constants'); const WalletCrypto = require('../wallet-crypto'); const Helpers = require('../helpers'); const KeyRing = require('../keyring'); -const getKey = (priv, addr) => { +const getKey = (BitcoinLib, priv, addr) => { let format = Helpers.detectPrivateKeyFormat(priv); - let key = Helpers.privateKeyStringToKey(priv, format, Bitcoin); - let network = constants.getNetwork(Bitcoin); - let ckey = new Bitcoin.ECPair(key.d, null, { compressed: true, network: network }); - let ukey = new Bitcoin.ECPair(key.d, null, { compressed: false, network: network }); + let key = Helpers.privateKeyStringToKey(priv, format, BitcoinLib); + let network = constants.getNetwork(BitcoinLib); + let ckey = new BitcoinLib.ECPair(key.d, null, { compressed: true, network: network }); + let ukey = new BitcoinLib.ECPair(key.d, null, { compressed: false, network: network }); if (ckey.getAddress() === addr) { return ckey; } else if (ukey.getAddress() === addr) { @@ -20,11 +21,11 @@ const getKey = (priv, addr) => { return key; }; -const getKeyForAddress = (wallet, password, addr) => { +const getKeyForAddress = (BitcoinLib, wallet, password, addr) => { const k = wallet.key(addr).priv; const privateKeyBase58 = password == null ? k : WalletCrypto.decryptSecretWithSecondPassword(k, password, wallet.sharedKey, wallet.pbkdf2_iterations); - return getKey(privateKeyBase58, addr); + return getKey(BitcoinLib, privateKeyBase58, addr); }; const getXPRIV = (wallet, password, accountIndex) => { @@ -34,10 +35,10 @@ const getXPRIV = (wallet, password, accountIndex) => { : WalletCrypto.decryptSecretWithSecondPassword(account.extendedPrivateKey, password, wallet.sharedKey, wallet.pbkdf2_iterations); }; -const pathToKey = (wallet, password, fullpath) => { +const pathToKey = (BitcoinLib, wallet, password, fullpath) => { const [idx, path] = fullpath.split('-'); const xpriv = getXPRIV(wallet, password, idx); - const keyring = new KeyRing(xpriv, undefined, Bitcoin); + const keyring = new KeyRing(xpriv, undefined, BitcoinLib); return keyring.privateKeyFromPath(path).keyPair; }; @@ -45,14 +46,29 @@ const isFromAccount = (selection) => { return selection.inputs[0] ? selection.inputs[0].isFromAccount() : false; }; -const signSelection = selection => { +const bitcoinSigner = (selection) => { let network = constants.getNetwork(Bitcoin); - const hashType = Bitcoin.Transaction.SIGHASH_ALL | Bitcoin.Transaction.SIGHASH_BITCOINCASHBIP143; - let tx = new Bitcoin.TransactionBuilder(network); + + let addInput = coin => tx.addInput(coin.txHash, coin.index); + let addOutput = coin => tx.addOutput(coin.address, coin.value); + let sign = (coin, i) => tx.sign(i, coin.priv); + + forEach(addInput, selection.inputs); + forEach(addOutput, selection.outputs); + addIndex(forEach)(sign, selection.inputs); + + return tx.build(); +}; + +const bitcoinCashSigner = (selection) => { + let network = constants.getNetwork(BitcoinCash); + let hashType = BitcoinCash.Transaction.SIGHASH_ALL | BitcoinCash.Transaction.SIGHASH_BITCOINCASHBIP143; + + let tx = new BitcoinCash.TransactionBuilder(network); tx.enableBitcoinCash(true); - let addInput = coin => tx.addInput(coin.txHash, coin.index, Bitcoin.Transaction.DEFAULT_SEQUENCE, new Buffer(coin.script, 'hex')); + let addInput = coin => tx.addInput(coin.txHash, coin.index, BitcoinCash.Transaction.DEFAULT_SEQUENCE, new Buffer(coin.script, 'hex')); let addOutput = coin => tx.addOutput(coin.address, coin.value); let sign = (coin, i) => tx.sign(i, coin.priv, null, hashType, coin.value); @@ -63,14 +79,15 @@ const signSelection = selection => { return tx.build(); }; -const sign = curry((password, wallet, selection) => { - const getPrivAcc = keypath => pathToKey(wallet, password, keypath); - const getPrivAddr = address => getKeyForAddress(wallet, password, address); +const sign = curry((BitcoinLib, signingFunction, password, wallet, selection) => { + const getPrivAcc = keypath => pathToKey(BitcoinLib, wallet, password, keypath); + const getPrivAddr = address => getKeyForAddress(BitcoinLib, wallet, password, address); const getKeys = isFromAccount(selection) ? getPrivAcc : getPrivAddr; const selectionWithKeys = over(compose(lensProp('inputs'), mapped, lensProp('priv')), getKeys, selection); - return signSelection(selectionWithKeys); + return signingFunction(selectionWithKeys); }); module.exports = { - sign + signBitcoin: sign(Bitcoin, bitcoinSigner), + signBitcoinCash: sign(BitcoinCash, bitcoinCashSigner) }; diff --git a/tests/__data__/signing-data.json b/tests/__data__/signing-data.json index 7d849d475..db8f48dca 100644 --- a/tests/__data__/signing-data.json +++ b/tests/__data__/signing-data.json @@ -36,7 +36,8 @@ } ] }, - "tx_hex": "01000000026c1b0fee717838e4d7c0b0fe88aa4929cc775f8b2d25f42e6783198aea1447db000000006a473044022046623d6d62db125fe4281c7888a995c572377223b50acd11eb06a095f3d5e3c80220221359d419f2241c0c7bef5530e0a2c3438364fd9fe825e914ad44f0bc6498154121031c77d382badb52767699c14366d3ef47d9538b0bd12bf75ced6b1aa37a9d1a29ffffffffa3a9c77436956511fa7da5c458e23dc1e9af53f1f48a59411e3f168c1e41e568010000006b483045022100dd869488f239422164bc1049ec2c434049b4706cc74f38daf4402f41aebf42df022066376640c814cd7a7d1ab02e35bd4246c6ee4640aa999a1ebf604d737f270c844121026a622460994a92deae67834775fe54ee652f77fe65c9f279443e277348698d14ffffffff01ca140100000000001976a914b4d4b04597645ccb38465c2983b9e83804d8381488ac00000000", + "tx_hex_btc": "01000000026c1b0fee717838e4d7c0b0fe88aa4929cc775f8b2d25f42e6783198aea1447db000000006a473044022039390ec412328a1dc93175c965b4cc2bcb7f960ae94db5f8aa5a31257602efeb022066bbfa62b33aae433e0d229b7d60c8074a064a76920b738f896ba0429c9bdebb0121031c77d382badb52767699c14366d3ef47d9538b0bd12bf75ced6b1aa37a9d1a29ffffffffa3a9c77436956511fa7da5c458e23dc1e9af53f1f48a59411e3f168c1e41e568010000006a4730440220569e70977bd2e1b452f81672fca0d1fd53a639143d6d0f1b15778aa5c1213a02022020dd2ef066eed5af684d72ae2f32601ec7bafaa5f58a1636a9ea29503790fa140121026a622460994a92deae67834775fe54ee652f77fe65c9f279443e277348698d14ffffffff01ca140100000000001976a914b4d4b04597645ccb38465c2983b9e83804d8381488ac00000000", + "tx_hex_bch": "01000000026c1b0fee717838e4d7c0b0fe88aa4929cc775f8b2d25f42e6783198aea1447db000000006a473044022046623d6d62db125fe4281c7888a995c572377223b50acd11eb06a095f3d5e3c80220221359d419f2241c0c7bef5530e0a2c3438364fd9fe825e914ad44f0bc6498154121031c77d382badb52767699c14366d3ef47d9538b0bd12bf75ced6b1aa37a9d1a29ffffffffa3a9c77436956511fa7da5c458e23dc1e9af53f1f48a59411e3f168c1e41e568010000006b483045022100dd869488f239422164bc1049ec2c434049b4706cc74f38daf4402f41aebf42df022066376640c814cd7a7d1ab02e35bd4246c6ee4640aa999a1ebf604d737f270c844121026a622460994a92deae67834775fe54ee652f77fe65c9f279443e277348698d14ffffffff01ca140100000000001976a914b4d4b04597645ccb38465c2983b9e83804d8381488ac00000000", "unspent_outputs": [ { "tx_hash": "6c1b0fee717838e4d7c0b0fe88aa4929cc775f8b2d25f42e6783198aea1447db", diff --git a/tests/bch/signer.spec.js b/tests/bch/signer.spec.js index 1b12d2250..885891ac5 100644 --- a/tests/bch/signer.spec.js +++ b/tests/bch/signer.spec.js @@ -12,8 +12,13 @@ describe('Signer', () => { let inputToCoin = compose(Coin.fromJS, addIndexToOutput(wallet.hdwallet)) let selection = cs.selectAll(55, map(inputToCoin, signingData.unspent_outputs), '1HV9RPcPAwcCEDmNET5BEWvVVgCY3Pbg7i') + it('should sign a btc transaction', () => { + let tx = signer.signBitcoin(void 0, wallet, selection) + expect(tx.toHex()).toEqual(signingData.tx_hex_btc) + }) + it('should sign a bch transaction', () => { - let tx = signer.sign(void 0, wallet, selection) - expect(tx.toHex()).toEqual(signingData.tx_hex) + let tx = signer.signBitcoinCash(void 0, wallet, selection) + expect(tx.toHex()).toEqual(signingData.tx_hex_bch) }) }) From 499209337e2447fdac9442fc86274f8b671a9b90 Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Thu, 19 Oct 2017 14:46:20 -0400 Subject: [PATCH 11/25] refactor(Cash): move coin selection and signing to src folder --- src/bch/bch-api.js | 4 ++-- src/bch/bch-payment.js | 6 +++--- src/bch/bch-spendable.js | 2 +- src/{bch => }/coin-selection.js | 0 src/{bch => }/coin.js | 0 src/{bch => }/signer.js | 8 ++++---- tests/bch/bch-payment.spec.js | 2 +- tests/bch/bch-spendable.spec.js | 2 +- tests/{bch => }/coin-selection.spec.js | 4 ++-- tests/{bch => }/coin.spec.js | 2 +- tests/{bch => }/signer.spec.js | 12 ++++++------ 11 files changed, 21 insertions(+), 21 deletions(-) rename src/{bch => }/coin-selection.js (100%) rename src/{bch => }/coin.js (100%) rename src/{bch => }/signer.js (95%) rename tests/{bch => }/coin-selection.spec.js (97%) rename tests/{bch => }/coin.spec.js (98%) rename tests/{bch => }/signer.spec.js (68%) diff --git a/src/bch/bch-api.js b/src/bch/bch-api.js index 1e8846458..85b346aec 100644 --- a/src/bch/bch-api.js +++ b/src/bch/bch-api.js @@ -1,8 +1,8 @@ /* eslint-disable semi */ -const { curry, is, prop, lensProp, compose, assoc, over, map } = require('ramda'); +const { curry, is, prop, lensProp, assoc, over, map } = require('ramda'); const { mapped } = require('ramda-lens'); const API = require('../api'); -const Coin = require('./coin.js'); +const Coin = require('../coin'); const Bitcoin = require('bitcoincashjs-lib'); const constants = require('../constants'); const Helpers = require('../helpers'); diff --git a/src/bch/bch-payment.js b/src/bch/bch-payment.js index 0a31bc043..b6a3e5e77 100644 --- a/src/bch/bch-payment.js +++ b/src/bch/bch-payment.js @@ -1,10 +1,10 @@ /* eslint-disable semi */ const { compose, clone, assoc, is, all } = require('ramda') -const Coin = require('./coin') +const Coin = require('../coin') const BchApi = require('./bch-api') const { isBitcoinAddress, isPositiveInteger } = require('../helpers') -const { selectAll, descentDraw } = require('./coin-selection') -const signer = require('./signer') +const { selectAll, descentDraw } = require('../coin-selection') +const signer = require('../signer') const isValidFrom = (from) => ( is(Number, from) || diff --git a/src/bch/bch-spendable.js b/src/bch/bch-spendable.js index 50efd5dc6..461a92bcf 100644 --- a/src/bch/bch-spendable.js +++ b/src/bch/bch-spendable.js @@ -1,6 +1,6 @@ /* eslint-disable semi */ const BchApi = require('./bch-api') -const { selectAll } = require('./coin-selection') +const { selectAll } = require('../coin-selection') class BchSpendable { constructor (bchWallet, wallet) { diff --git a/src/bch/coin-selection.js b/src/coin-selection.js similarity index 100% rename from src/bch/coin-selection.js rename to src/coin-selection.js diff --git a/src/bch/coin.js b/src/coin.js similarity index 100% rename from src/bch/coin.js rename to src/coin.js diff --git a/src/bch/signer.js b/src/signer.js similarity index 95% rename from src/bch/signer.js rename to src/signer.js index f70a936d1..4214a90a9 100644 --- a/src/bch/signer.js +++ b/src/signer.js @@ -2,10 +2,10 @@ const { curry, forEach, addIndex, lensProp, compose, over } = require('ramda'); const { mapped } = require('ramda-lens'); const Bitcoin = require('bitcoinjs-lib'); const BitcoinCash = require('bitcoincashjs-lib'); -const constants = require('../constants'); -const WalletCrypto = require('../wallet-crypto'); -const Helpers = require('../helpers'); -const KeyRing = require('../keyring'); +const constants = require('./constants'); +const WalletCrypto = require('./wallet-crypto'); +const Helpers = require('./helpers'); +const KeyRing = require('./keyring'); const getKey = (BitcoinLib, priv, addr) => { let format = Helpers.detectPrivateKeyFormat(priv); diff --git a/tests/bch/bch-payment.spec.js b/tests/bch/bch-payment.spec.js index 655b92984..40c4aac50 100644 --- a/tests/bch/bch-payment.spec.js +++ b/tests/bch/bch-payment.spec.js @@ -2,7 +2,7 @@ const { add, reduce, map, compose } = require('ramda') const BchApi = require('../../src/bch/bch-api') const BchPayment = require('../../src/bch/bch-payment') -const Coin = require('../../src/bch/coin') +const Coin = require('../../src/coin') const BlockchainWalletMock = require('../__mocks__/blockchain-wallet.mock') const addr = '19kqHHBoYbyY2bAr1SN2GuGcdSZ6fM2Qqz' diff --git a/tests/bch/bch-spendable.spec.js b/tests/bch/bch-spendable.spec.js index b500aa624..3c98c4720 100644 --- a/tests/bch/bch-spendable.spec.js +++ b/tests/bch/bch-spendable.spec.js @@ -2,7 +2,7 @@ const BitcoinCashWallet = require('../../src/bch') const BchSpendable = require('../../src/bch/bch-spendable') const BchApi = require('../../src/bch/bch-api') -const Coin = require('../../src/bch/coin') +const Coin = require('../../src/coin') const BlockchainWalletMock = require('../__mocks__/blockchain-wallet.mock') describe('BchSpendable', () => { diff --git a/tests/bch/coin-selection.spec.js b/tests/coin-selection.spec.js similarity index 97% rename from tests/bch/coin-selection.spec.js rename to tests/coin-selection.spec.js index 378c9a66e..f9ee028aa 100644 --- a/tests/bch/coin-selection.spec.js +++ b/tests/coin-selection.spec.js @@ -1,7 +1,7 @@ /* eslint-disable semi */ let { map } = require('ramda') -let cs = require('../../src/bch/coin-selection') -let Coin = require('../../src/bch/coin') +let cs = require('../src/coin-selection') +let Coin = require('../src/coin') describe('Coin Selection', () => { describe('byte sizes', () => { diff --git a/tests/bch/coin.spec.js b/tests/coin.spec.js similarity index 98% rename from tests/bch/coin.spec.js rename to tests/coin.spec.js index ef734c477..d47a5adf3 100644 --- a/tests/bch/coin.spec.js +++ b/tests/coin.spec.js @@ -1,6 +1,6 @@ /* eslint-disable semi */ const { map, reduce, curry } = require('ramda') -const Coin = require('../../src/bch/coin') +const Coin = require('../src/coin') const fold = curry((empty, xs) => reduce((acc, x) => acc.concat(x), empty, xs)) diff --git a/tests/bch/signer.spec.js b/tests/signer.spec.js similarity index 68% rename from tests/bch/signer.spec.js rename to tests/signer.spec.js index 885891ac5..e728cd920 100644 --- a/tests/bch/signer.spec.js +++ b/tests/signer.spec.js @@ -1,11 +1,11 @@ /* eslint-disable semi */ let { compose, map } = require('ramda') -let Wallet = require('../../src/blockchain-wallet') -let { addIndexToOutput } = require('../../src/bch/bch-api') -let signer = require('../../src/bch/signer') -let Coin = require('../../src/bch/coin') -let cs = require('../../src/bch/coin-selection') -let signingData = require('../__data__/signing-data.json') +let Wallet = require('../src/blockchain-wallet') +let { addIndexToOutput } = require('../src/bch/bch-api') +let signer = require('../src/signer') +let Coin = require('../src/coin') +let cs = require('../src/coin-selection') +let signingData = require('./__data__/signing-data.json') describe('Signer', () => { let wallet = new Wallet(signingData.wallet) From bdf6d506bb34c019e943a5c67286a7ae4bf7251f Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Thu, 19 Oct 2017 15:14:31 -0400 Subject: [PATCH 12/25] feat(HDWallet): add hd account consolidation method --- src/hd-wallet.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/hd-wallet.js b/src/hd-wallet.js index 0a78c75a0..1832e542e 100644 --- a/src/hd-wallet.js +++ b/src/hd-wallet.js @@ -4,10 +4,16 @@ module.exports = HDWallet; var Bitcoin = require('bitcoinjs-lib'); var assert = require('assert'); +var R = require('ramda'); var Helpers = require('./helpers'); var HDAccount = require('./hd-account'); var BIP39 = require('bip39'); var MyWallet = require('./wallet'); // This cyclic import should be avoided once the refactor is complete +var API = require('./api'); +var { addIndexToOutput } = require('./bch/bch-api'); +var { selectAll } = require('./coin-selection'); +var signer = require('./signer'); +var Coin = require('./coin'); var constants = require('./constants'); function HDWallet (object) { @@ -280,3 +286,22 @@ HDWallet.prototype.persist = function () { HDWallet.prototype.isValidAccountIndex = function (index) { return Helpers.isPositiveInteger(index) && index < this._accounts.length; }; + +HDWallet.prototype.createConsolidationPayment = function (toAccount, feePerByte, secPass) { + let outputToCoin = R.compose(Coin.fromJS, addIndexToOutput(this)); + + let createPayment = (selection, tx) => ({ + get fee () { return selection.fee; }, + publish () { return API.pushTx(tx.toHex()).then(() => ({ hash: tx.getId() })); } + }); + + let paymentFromCoins = (coins) => { + let selection = selectAll(feePerByte, coins, toAccount.receiveAddress); + let tx = signer.signBitcoin(secPass, MyWallet.wallet, selection); + return createPayment(selection, tx); + }; + + return API.getUnspent(this.xpubs) + .then(result => R.map(outputToCoin, result.unspent_outputs)) + .then(paymentFromCoins); +}; From 25dd404a300dc7b83a48197f1ff99907fda25f71 Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 23 Oct 2017 12:14:38 -0400 Subject: [PATCH 13/25] feat(ShapeShift): ability to receive to multiple btc accounts --- src/shift/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/shift/index.js b/src/shift/index.js index 581815607..90480cfc5 100644 --- a/src/shift/index.js +++ b/src/shift/index.js @@ -31,12 +31,12 @@ class ShapeShift { return this._api.getRate(coinPair) } - getQuote (coinPair, amount) { + getQuote (coinPair, amount, index) { trace('getting quote') let [from, to] = coinPair.split('_') - let withdrawalAddress = this.nextAddressForCurrency(to) - let returnAddress = this.nextAddressForCurrency(from) + let withdrawalAddress = this.nextAddressForCurrency(to, index) + let returnAddress = this.nextAddressForCurrency(from, index) return this._api.getQuote(coinPair, amount, withdrawalAddress, returnAddress) .then(Quote.fromApiResponse) @@ -121,9 +121,9 @@ class ShapeShift { return Promise.all(requests); } - nextAddressForCurrency (currency) { + nextAddressForCurrency (currency, index) { if (currency === 'btc') { - return this._wallet.hdwallet.defaultAccount.receiveAddress + return this._wallet.hdwallet.accounts[index].receiveAddress } if (currency === 'eth') { return this._wallet.eth.defaultAccount.address From d41cff41a70777836b5e5b2258c2a76df9c90a39 Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 23 Oct 2017 13:45:45 -0400 Subject: [PATCH 14/25] feat(ShapeShift): pass from, to to getQuote and getApproximateQuote, add receiveAddress to eth account --- src/eth/eth-account.js | 4 ++++ src/shift/index.js | 26 ++++++++------------------ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/eth/eth-account.js b/src/eth/eth-account.js index ee93d0ea8..954973d33 100644 --- a/src/eth/eth-account.js +++ b/src/eth/eth-account.js @@ -22,6 +22,10 @@ class EthAccount { return this._addr; } + get receiveAddress () { + return this.address; + } + get privateKey () { return this._priv; } diff --git a/src/shift/index.js b/src/shift/index.js index 90480cfc5..6811e6480 100644 --- a/src/shift/index.js +++ b/src/shift/index.js @@ -31,19 +31,22 @@ class ShapeShift { return this._api.getRate(coinPair) } - getQuote (coinPair, amount, index) { + getQuote (from, to, amount) { trace('getting quote') - let [from, to] = coinPair.split('_') - let withdrawalAddress = this.nextAddressForCurrency(to, index) - let returnAddress = this.nextAddressForCurrency(from, index) + let returnAddress = from.receiveAddress; + let withdrawalAddress = to.receiveAddress; + let coinPair = from.coinCode + '_' + to.coinCode; return this._api.getQuote(coinPair, amount, withdrawalAddress, returnAddress) .then(Quote.fromApiResponse) } - getApproximateQuote (coinPair, amount) { + getApproximateQuote (from, to, amount) { trace('getting approximate quote') + + let coinPair = from.coinCode + '_' + to.coinCode; + return this._api.getQuote(coinPair, amount) .then(Quote.fromApiResponse) } @@ -121,19 +124,6 @@ class ShapeShift { return Promise.all(requests); } - nextAddressForCurrency (currency, index) { - if (currency === 'btc') { - return this._wallet.hdwallet.accounts[index].receiveAddress - } - if (currency === 'eth') { - return this._wallet.eth.defaultAccount.address - } - if (currency === 'bch') { - return this._wallet.bch.defaultAccount.receiveAddress - } - throw new Error(`Currency '${currency}' is not supported`) - } - saveBtcWithdrawalLabel (quote) { let label = `ShapeShift order #${quote.orderId}` let account = this._wallet.hdwallet.defaultAccount From 01998a45becfb30642ecfa0ab9eb47b58c679a5c Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Mon, 23 Oct 2017 17:19:36 -0400 Subject: [PATCH 15/25] refactor(Shift): more generic creation of shift payments --- src/bch/bch-account.js | 5 +++++ src/eth/eth-account.js | 5 +++++ src/hd-account.js | 5 +++++ src/shift/index.js | 22 ++-------------------- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/bch/bch-account.js b/src/bch/bch-account.js index e4f97b3ff..3ffe0000d 100644 --- a/src/bch/bch-account.js +++ b/src/bch/bch-account.js @@ -1,5 +1,6 @@ /* eslint-disable semi */ const BchSpendable = require('./bch-spendable') +const BchShiftPayment = require('../shift/bch-payment'); const ACCOUNT_LABEL_PREFIX = 'Bitcoin Cash - ' @@ -50,6 +51,10 @@ class BchAccount extends BchSpendable { createPayment () { return super.createPayment().from(this.index, this.changeAddress) } + + createShiftPayment (wallet) { + return BchShiftPayment.fromWallet(wallet, this) + } } module.exports = BchAccount diff --git a/src/eth/eth-account.js b/src/eth/eth-account.js index 954973d33..6e4abf3ef 100644 --- a/src/eth/eth-account.js +++ b/src/eth/eth-account.js @@ -3,6 +3,7 @@ const EthTxBuilder = require('./eth-tx-builder'); const EthWalletTx = require('./eth-wallet-tx'); const API = require('../api'); const { toBigNumber, toWei, fromWei } = require('../helpers'); +const EthShiftPayment = require('../shift/eth-payment'); class EthAccount { constructor (obj) { @@ -143,6 +144,10 @@ class EthAccount { }); } + createShiftPayment (wallet) { + return EthShiftPayment.fromWallet(wallet, this); + } + static privateKeyToAddress (privateKey) { return ethUtil.toChecksumAddress(ethUtil.privateToAddress(privateKey).toString('hex')); } diff --git a/src/hd-account.js b/src/hd-account.js index afaab145b..f726bc028 100644 --- a/src/hd-account.js +++ b/src/hd-account.js @@ -8,6 +8,7 @@ var MyWallet = require('./wallet'); // This cyclic import should be avoided once var API = require('./api'); var Transaction = require('./transaction'); var constants = require('./constants'); +var BtcShiftPayment = require('./shift/btc-payment'); // HDAccount Class @@ -318,3 +319,7 @@ HDAccount.prototype.getAvailableBalance = function (feeType) { return { amount, fee: fees[feeType] }; }); }; + +HDAccount.prototype.createShiftPayment = function (wallet) { + return BtcShiftPayment.fromWallet(wallet, this); +}; diff --git a/src/shift/index.js b/src/shift/index.js index 6811e6480..53412bdd8 100644 --- a/src/shift/index.js +++ b/src/shift/index.js @@ -3,9 +3,6 @@ const { delay, asyncOnce, trace } = require('../helpers') const Api = require('./api') const Trade = require('./trade') const Quote = require('./quote') -const BtcPayment = require('./btc-payment') -const EthPayment = require('./eth-payment') -const BchPayment = require('./bch-payment') const METADATA_TYPE_SHAPE_SHIFT = 6; @@ -53,28 +50,13 @@ class ShapeShift { buildPayment (quote, fee, fromAccount) { trace('building payment') - let payment if (quote.depositAddress == null) { throw new Error('Quote is missing deposit address') } - if (fromAccount != null && fromAccount.coinCode !== quote.fromCurrency) { + if (fromAccount.coinCode !== quote.fromCurrency) { throw new Error('Sending account currency does not match quote deposit currency') } - if (quote.fromCurrency === 'btc') { - let account = fromAccount || this._wallet.hdwallet.defaultAccount - payment = BtcPayment.fromWallet(this._wallet, account) - } - if (quote.fromCurrency === 'eth') { - let account = fromAccount || this._wallet.eth.defaultAccount - payment = EthPayment.fromWallet(this._wallet, account) - } - if (quote.fromCurrency === 'bch') { - let account = fromAccount || this._wallet.bch.defaultAccount - payment = BchPayment.fromWallet(this._wallet, account) - } - if (payment == null) { - throw new Error(`Tried to build for unsupported currency ${quote.fromCurrency}`) - } + let payment = fromAccount.createShiftPayment(this._wallet) return payment.setFromQuote(quote, fee) } From cfbfdee9aa0f5736ba561c907410385c8a630b8f Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 23 Oct 2017 23:07:58 -0400 Subject: [PATCH 16/25] chore(Release): upgrade bitcoin-sfox-client --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 9618df3f4..fdb2e1496 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "bignumber.js": "^4.0.2", "bip39": "2.1.*", "bitcoin-coinify-client": "^0.7.1", - "bitcoin-sfox-client": "^0.1.11", + "bitcoin-sfox-client": "^0.1.12", "bitcoin-unocoin-client": "^0.3.4", "bitcoincashjs-lib": "https://github.com/bitcoinjs/bitcoinjs-lib#9ac221c80dbc3462d7a2392cec2045ae2b590461", "bitcoinjs-lib": "2.1.*", diff --git a/yarn.lock b/yarn.lock index 4d7fd11f8..a720f90c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1052,9 +1052,9 @@ bitcoin-ops@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/bitcoin-ops/-/bitcoin-ops-1.3.0.tgz#6b126b585537bc679b02ed499f14450cffc37e13" -bitcoin-sfox-client@^0.1.11: +bitcoin-sfox-client@^0.1.12: version "0.1.12" - resolved "https://registry.yarnpkg.com/bitcoin-sfox-client/-/bitcoin-sfox-client-0.1.12.tgz#8340b4d91585976179c1922b40b8c89a66c7ec8f" + resolved "https://registry.npmjs.org/bitcoin-sfox-client/-/bitcoin-sfox-client-0.1.12.tgz#8340b4d91585976179c1922b40b8c89a66c7ec8f" dependencies: bitcoin-exchange-client "0.2.*" From 76bc8f8ccdc916cdefdd855c17ac700afc0d77ee Mon Sep 17 00:00:00 2001 From: plondon Date: Mon, 23 Oct 2017 23:08:39 -0400 Subject: [PATCH 17/25] chore(Release): v3.39.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fdb2e1496..c8dd87ae8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-client", - "version": "3.39.2", + "version": "3.39.3", "description": "Blockchain.info JavaScript Wallet", "homepage": "https://github.com/blockchain/my-wallet-v3", "bugs": { From 99ea4ba0696c3763f2c6f29c18a3ba640945735c Mon Sep 17 00:00:00 2001 From: plondon Date: Tue, 24 Oct 2017 07:07:30 -0400 Subject: [PATCH 18/25] chore(Release): upgrade bitcoin-sfox-client --- package.json | 2 +- yarn.lock | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index c8dd87ae8..17cab1cf6 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "bignumber.js": "^4.0.2", "bip39": "2.1.*", "bitcoin-coinify-client": "^0.7.1", - "bitcoin-sfox-client": "^0.1.12", + "bitcoin-sfox-client": "^0.1.15", "bitcoin-unocoin-client": "^0.3.4", "bitcoincashjs-lib": "https://github.com/bitcoinjs/bitcoinjs-lib#9ac221c80dbc3462d7a2392cec2045ae2b590461", "bitcoinjs-lib": "2.1.*", diff --git a/yarn.lock b/yarn.lock index a720f90c2..b1d5b87ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1030,12 +1030,6 @@ bitcoin-coinify-client@^0.7.1: babelify "7.3.*" bitcoin-exchange-client "^0.5.0" -bitcoin-exchange-client@0.2.*: - version "0.2.2" - resolved "https://registry.yarnpkg.com/bitcoin-exchange-client/-/bitcoin-exchange-client-0.2.2.tgz#8d5370a3ac20a0d3fc75e8a3d76bbc285a35f7ec" - dependencies: - isomorphic-fetch "^2.2.0" - bitcoin-exchange-client@^0.5.0: version "0.5.0" resolved "https://registry.npmjs.org/bitcoin-exchange-client/-/bitcoin-exchange-client-0.5.0.tgz#e9d70ca7cd17909fbae86d79c43c4367fcda02f9" @@ -1052,11 +1046,14 @@ bitcoin-ops@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/bitcoin-ops/-/bitcoin-ops-1.3.0.tgz#6b126b585537bc679b02ed499f14450cffc37e13" -bitcoin-sfox-client@^0.1.12: - version "0.1.12" - resolved "https://registry.npmjs.org/bitcoin-sfox-client/-/bitcoin-sfox-client-0.1.12.tgz#8340b4d91585976179c1922b40b8c89a66c7ec8f" +bitcoin-sfox-client@^0.1.15: + version "0.1.15" + resolved "https://registry.npmjs.org/bitcoin-sfox-client/-/bitcoin-sfox-client-0.1.15.tgz#4283007dd538cd554aa1514344a5536814493df7" dependencies: - bitcoin-exchange-client "0.2.*" + babel-polyfill "6.16.*" + babel-preset-es2015 "6.16.*" + babelify "7.3.*" + bitcoin-exchange-client "^0.5.0" bitcoin-unocoin-client@^0.3.4: version "0.3.4" From b64bededc994c21cd7fe0d7e0206310fb8039076 Mon Sep 17 00:00:00 2001 From: plondon Date: Tue, 24 Oct 2017 07:07:47 -0400 Subject: [PATCH 19/25] chore(Release): v3.39.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 17cab1cf6..a4a902ab2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-client", - "version": "3.39.3", + "version": "3.39.4", "description": "Blockchain.info JavaScript Wallet", "homepage": "https://github.com/blockchain/my-wallet-v3", "bugs": { From 3c57c7eb0701b8f46d8f524a6b9454ae3496f8c7 Mon Sep 17 00:00:00 2001 From: plondon Date: Tue, 24 Oct 2017 07:36:58 -0400 Subject: [PATCH 20/25] chore(Release): upgrade bitcoin-sfox-client --- package.json | 2 +- yarn.lock | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a4a902ab2..1030ee86f 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "bignumber.js": "^4.0.2", "bip39": "2.1.*", "bitcoin-coinify-client": "^0.7.1", - "bitcoin-sfox-client": "^0.1.15", + "bitcoin-sfox-client": "^0.1.16", "bitcoin-unocoin-client": "^0.3.4", "bitcoincashjs-lib": "https://github.com/bitcoinjs/bitcoinjs-lib#9ac221c80dbc3462d7a2392cec2045ae2b590461", "bitcoinjs-lib": "2.1.*", diff --git a/yarn.lock b/yarn.lock index b1d5b87ce..289976c99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1036,6 +1036,12 @@ bitcoin-exchange-client@^0.5.0: dependencies: isomorphic-fetch "^2.2.0" +bitcoin-exchange-client@v0.2.*: + version "0.2.2" + resolved "https://registry.npmjs.org/bitcoin-exchange-client/-/bitcoin-exchange-client-0.2.2.tgz#8d5370a3ac20a0d3fc75e8a3d76bbc285a35f7ec" + dependencies: + isomorphic-fetch "^2.2.0" + bitcoin-exchange-client@~0.4.1: version "0.4.3" resolved "https://registry.yarnpkg.com/bitcoin-exchange-client/-/bitcoin-exchange-client-0.4.3.tgz#f2d2121a36eb9d1d18a504c1397987bfa39d7ddb" @@ -1046,14 +1052,14 @@ bitcoin-ops@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/bitcoin-ops/-/bitcoin-ops-1.3.0.tgz#6b126b585537bc679b02ed499f14450cffc37e13" -bitcoin-sfox-client@^0.1.15: - version "0.1.15" - resolved "https://registry.npmjs.org/bitcoin-sfox-client/-/bitcoin-sfox-client-0.1.15.tgz#4283007dd538cd554aa1514344a5536814493df7" +bitcoin-sfox-client@^0.1.16: + version "0.1.16" + resolved "https://registry.npmjs.org/bitcoin-sfox-client/-/bitcoin-sfox-client-0.1.16.tgz#f19161c04ce023451e2c27dc07b1a31886f16942" dependencies: babel-polyfill "6.16.*" babel-preset-es2015 "6.16.*" babelify "7.3.*" - bitcoin-exchange-client "^0.5.0" + bitcoin-exchange-client v0.2.* bitcoin-unocoin-client@^0.3.4: version "0.3.4" From e0a9e2487963ece50b5d3c76824a7f60dae01ecb Mon Sep 17 00:00:00 2001 From: plondon Date: Tue, 24 Oct 2017 07:45:37 -0400 Subject: [PATCH 21/25] chore(Release): v3.39.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1030ee86f..66ed49cf8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-client", - "version": "3.39.4", + "version": "3.39.5", "description": "Blockchain.info JavaScript Wallet", "homepage": "https://github.com/blockchain/my-wallet-v3", "bugs": { From 0abe116a99c2144c3ea9a70db2eb6c6770d33c41 Mon Sep 17 00:00:00 2001 From: plondon Date: Sun, 29 Oct 2017 19:27:15 -0400 Subject: [PATCH 22/25] chore(Release): upgrade sfox/coinify clients --- package.json | 4 ++-- yarn.lock | 20 +++++++------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 66ed49cf8..1f4d9a58c 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,8 @@ "bigi": "1.4.*", "bignumber.js": "^4.0.2", "bip39": "2.1.*", - "bitcoin-coinify-client": "^0.7.1", - "bitcoin-sfox-client": "^0.1.16", + "bitcoin-coinify-client": "^0.7.3", + "bitcoin-sfox-client": "^0.2.1", "bitcoin-unocoin-client": "^0.3.4", "bitcoincashjs-lib": "https://github.com/bitcoinjs/bitcoinjs-lib#9ac221c80dbc3462d7a2392cec2045ae2b590461", "bitcoinjs-lib": "2.1.*", diff --git a/yarn.lock b/yarn.lock index 289976c99..c1ffa9cdd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1021,9 +1021,9 @@ bip66@^1.1.0, bip66@^1.1.3: dependencies: safe-buffer "^5.0.1" -bitcoin-coinify-client@^0.7.1: - version "0.7.1" - resolved "https://registry.npmjs.org/bitcoin-coinify-client/-/bitcoin-coinify-client-0.7.1.tgz#44bc7c1910eaf1020fac0ab1b3fe3aca9337aaf3" +bitcoin-coinify-client@^0.7.3: + version "0.7.3" + resolved "https://registry.npmjs.org/bitcoin-coinify-client/-/bitcoin-coinify-client-0.7.3.tgz#1f44dbee601b1a487096d6d653ef18f0238fdb8e" dependencies: babel-polyfill "6.16.*" babel-preset-es2015 "6.16.*" @@ -1036,12 +1036,6 @@ bitcoin-exchange-client@^0.5.0: dependencies: isomorphic-fetch "^2.2.0" -bitcoin-exchange-client@v0.2.*: - version "0.2.2" - resolved "https://registry.npmjs.org/bitcoin-exchange-client/-/bitcoin-exchange-client-0.2.2.tgz#8d5370a3ac20a0d3fc75e8a3d76bbc285a35f7ec" - dependencies: - isomorphic-fetch "^2.2.0" - bitcoin-exchange-client@~0.4.1: version "0.4.3" resolved "https://registry.yarnpkg.com/bitcoin-exchange-client/-/bitcoin-exchange-client-0.4.3.tgz#f2d2121a36eb9d1d18a504c1397987bfa39d7ddb" @@ -1052,14 +1046,14 @@ bitcoin-ops@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/bitcoin-ops/-/bitcoin-ops-1.3.0.tgz#6b126b585537bc679b02ed499f14450cffc37e13" -bitcoin-sfox-client@^0.1.16: - version "0.1.16" - resolved "https://registry.npmjs.org/bitcoin-sfox-client/-/bitcoin-sfox-client-0.1.16.tgz#f19161c04ce023451e2c27dc07b1a31886f16942" +bitcoin-sfox-client@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/bitcoin-sfox-client/-/bitcoin-sfox-client-0.2.1.tgz#e534b8bf10cdf6e754dc919c166f7e5930c3b3ef" dependencies: babel-polyfill "6.16.*" babel-preset-es2015 "6.16.*" babelify "7.3.*" - bitcoin-exchange-client v0.2.* + bitcoin-exchange-client "^0.5.0" bitcoin-unocoin-client@^0.3.4: version "0.3.4" From 8cf977ca0ab947cab01f7c226849420ed0ff3e77 Mon Sep 17 00:00:00 2001 From: plondon Date: Sun, 29 Oct 2017 19:27:43 -0400 Subject: [PATCH 23/25] chore(Release): v3.39.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f4d9a58c..e20a9f8cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-client", - "version": "3.39.5", + "version": "3.39.6", "description": "Blockchain.info JavaScript Wallet", "homepage": "https://github.com/blockchain/my-wallet-v3", "bugs": { From 966939bb76248b9f3b50552fc10eddb969fae4d6 Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Tue, 31 Oct 2017 15:03:12 -0400 Subject: [PATCH 24/25] feat(Cash): treat archived imported addresses as active for bch --- src/bch/bch-imported.js | 2 +- src/blockchain-wallet.js | 8 ++++++++ tests/__mocks__/blockchain-wallet.mock.js | 1 + tests/bch/bch-imported.spec.js | 9 +++++---- tests/bch/index.spec.js | 6 +++--- tests/blockchain-wallet.spec.js | 2 ++ 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/bch/bch-imported.js b/src/bch/bch-imported.js index ab4b4d3b6..40cad431e 100644 --- a/src/bch/bch-imported.js +++ b/src/bch/bch-imported.js @@ -6,7 +6,7 @@ const sumNonNull = compose(reduce(add, 0), filter(x => x != null)) class BchImported extends BchSpendable { get addresses () { - return this._wallet.spendableActiveAddresses + return this._wallet.spendableAddresses } get label () { diff --git a/src/blockchain-wallet.js b/src/blockchain-wallet.js index 1bfeaf366..e5c1cf4c9 100644 --- a/src/blockchain-wallet.js +++ b/src/blockchain-wallet.js @@ -197,6 +197,14 @@ Object.defineProperties(Wallet.prototype, { configurable: false, get: function () { return this.activeKeys.map(function (k) { return k.address; }); } }, + 'spendableAddresses': { + configurable: false, + get: function () { + return this.keys + .filter(function (k) { return !k.isWatchOnly; }) + .map(function (k) { return k.address; }); + } + }, 'spendableActiveAddresses': { configurable: false, get: function () { diff --git a/tests/__mocks__/blockchain-wallet.mock.js b/tests/__mocks__/blockchain-wallet.mock.js index bd9d4659d..cdade38cb 100644 --- a/tests/__mocks__/blockchain-wallet.mock.js +++ b/tests/__mocks__/blockchain-wallet.mock.js @@ -17,6 +17,7 @@ class BlockchainWalletMock { this.addresses = Object.keys(addrs); this.keys = this.addresses.map(a => addrs[a]); this.activeKeys = this.keys.filter(k => !k.archived); + this.spendableAddresses = this.keys.filter(k => !k.isWatchOnly).map(k => k.address); this.spendableActiveAddresses = this.activeKeys.filter(k => !k.isWatchOnly).map(k => k.address); this.hdwallet = { diff --git a/tests/bch/bch-imported.spec.js b/tests/bch/bch-imported.spec.js index a97af697a..9dcf5b987 100644 --- a/tests/bch/bch-imported.spec.js +++ b/tests/bch/bch-imported.spec.js @@ -16,7 +16,7 @@ describe('BchImported', () => { }) it('should have: addresses', () => { - expect(imported.addresses).toEqual(['1asdf']) + expect(imported.addresses).toEqual(['1asdf', '1arch']) }) it('should have: label', () => { @@ -35,21 +35,22 @@ describe('BchImported', () => { it('should have: balance (with value)', () => { spyOn(BchSpendable.prototype, 'getAddressBalance').and.returnValue(100) - expect(imported.balance).toEqual(100) + expect(imported.balance).toEqual(200) expect(BchSpendable.prototype.getAddressBalance).toHaveBeenCalledWith('1asdf') + expect(BchSpendable.prototype.getAddressBalance).toHaveBeenCalledWith('1arch') }) it('should be able to get the available balance', () => { spyOn(BchSpendable.prototype, 'getAvailableBalance') imported.getAvailableBalance(10) - expect(BchSpendable.prototype.getAvailableBalance).toHaveBeenCalledWith(['1asdf'], 10) + expect(BchSpendable.prototype.getAvailableBalance).toHaveBeenCalledWith(['1asdf', '1arch'], 10) }) it('should be able to call createPayment()', () => { let from = jasmine.createSpy('from') spyOn(BchSpendable.prototype, 'createPayment').and.returnValue({ from }) imported.createPayment() - expect(from).toHaveBeenCalledWith(['1asdf'], '1asdf') + expect(from).toHaveBeenCalledWith(['1asdf', '1arch'], '1asdf') expect(BchSpendable.prototype.createPayment).toHaveBeenCalledWith() }) }) diff --git a/tests/bch/index.spec.js b/tests/bch/index.spec.js index 1629a2f49..5616d37d8 100644 --- a/tests/bch/index.spec.js +++ b/tests/bch/index.spec.js @@ -31,8 +31,8 @@ describe('bch', () => { expect(bch.importedAddresses).not.toEqual(null) }) - it('should not have importedAddresses if there are no spendable active addresses', () => { - wallet.spendableActiveAddresses = [] + it('should not have importedAddresses if there are no spendable addresses', () => { + wallet.spendableAddresses = [] bch = BitcoinCashWallet.fromBlockchainWallet(wallet) expect(bch.importedAddresses).toEqual(null) }) @@ -81,7 +81,7 @@ describe('bch', () => { it('should call multiaddr with all addresses and xpubs', (done) => { bch.getHistory().then(() => { - expect(BchApi.multiaddr).toHaveBeenCalledWith(['1asdf', 'xpub1', 'xpub2'], 50) + expect(BchApi.multiaddr).toHaveBeenCalledWith(['1asdf', '1arch', 'xpub1', 'xpub2'], 50) done() }) }) diff --git a/tests/blockchain-wallet.spec.js b/tests/blockchain-wallet.spec.js index 31aadbc0d..87cdc4a88 100644 --- a/tests/blockchain-wallet.spec.js +++ b/tests/blockchain-wallet.spec.js @@ -433,6 +433,8 @@ describe('Blockchain-Wallet', () => { it('defaultPbkdf2Iterations', () => expect(wallet.defaultPbkdf2Iterations).toEqual(5000)); + it('spendableAddresses', () => expect(wallet.spendableAddresses.length).toEqual(2)); + it('spendableActiveAddresses', () => expect(wallet.spendableActiveAddresses.length).toEqual(1)); }); From 890e4920d256c021b43eeb929832d0fa8f457d87 Mon Sep 17 00:00:00 2001 From: Justin Tormey Date: Thu, 2 Nov 2017 10:27:20 -0400 Subject: [PATCH 25/25] chore(Release): v3.39.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e20a9f8cc..f0ed7dbe7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blockchain-wallet-client", - "version": "3.39.6", + "version": "3.39.7", "description": "Blockchain.info JavaScript Wallet", "homepage": "https://github.com/blockchain/my-wallet-v3", "bugs": {