diff --git a/app/browser/api/ledger.js b/app/browser/api/ledger.js index 81e9c10fe0a..b0af3635e63 100644 --- a/app/browser/api/ledger.js +++ b/app/browser/api/ledger.js @@ -50,8 +50,8 @@ let visitsByPublisher = {} let bootP let quitP const _internal = { - verboseP: process.env.LEDGER_VERBOSE || true, - debugP: process.env.LEDGER_DEBUG || true, + verboseP: process.env.LEDGER_VERBOSE || false, + debugP: process.env.LEDGER_DEBUG || false, ruleset: { raw: [], cooked: [] @@ -154,14 +154,18 @@ const notifications = { }, notifications.pollingInterval, state) }, onLaunch: (state) => { - if (hasFunds(state)) { - // One time conversion of funds - const isNewInstall = state.get('firstRunTimestamp') === state.getIn(['migrations', 'batMercuryTimestamp']) - const hasUpgradedWallet = state.getIn(['migrations', 'batMercuryTimestamp']) !== state.getIn(['migrations', 'btcToBatTimestamp']) - if (!isNewInstall && !hasUpgradedWallet) { - module.exports.transitionWalletToBat(state) - } + if (!getSetting(settings.PAYMENTS_ENABLED)) { + return + } + // One time conversion of wallet + const isNewInstall = state.get('firstRunTimestamp') === state.getIn(['migrations', 'batMercuryTimestamp']) + const hasUpgradedWallet = state.getIn(['migrations', 'batMercuryTimestamp']) !== state.getIn(['migrations', 'btcToBatTimestamp']) + if (!isNewInstall && !hasUpgradedWallet) { + module.exports.transitionWalletToBat(state) + } + + if (hasFunds(state)) { // Don't bother processing the rest, which are only notifications. if (!getSetting(settings.PAYMENTS_NOTIFICATIONS)) { return @@ -1476,16 +1480,18 @@ const roundtrip = (params, options, callback) => { console.log('>>> ' + (body || '').split('\n').join('\n>>> ')) } - if (err) return callback(err) + if (err) return callback(err, response) if (Math.floor(response.statusCode / 100) !== 2) { - return callback(new Error('HTTP response ' + response.statusCode) + ' for ' + params.method + ' ' + params.path) + return callback( + new Error('HTTP response ' + response.statusCode + ' for ' + params.method + ' ' + params.path), + response) } try { payload = rawP ? body : (response.statusCode !== 204) ? JSON.parse(body) : null } catch (err) { - return callback(err) + return callback(err, response) } try { @@ -1946,8 +1952,16 @@ const onInitRead = (state, parsedData) => { try { let timeUntilReconcile clientprep() + + const options = Object.assign({}, clientOptions) + try { + if (parsedData.properties.wallet.keychains.user) { + options.version = 'v1' + } + } catch (ex) {} + client = ledgerClient(parsedData.personaId, - underscore.extend(parsedData.options, {roundtrip: roundtrip}, clientOptions), + underscore.extend(parsedData.options, {roundtrip: roundtrip}, options), parsedData) // Scenario: User enables Payments, disables it, waits 30+ days, then @@ -1970,7 +1984,7 @@ const onInitRead = (state, parsedData) => { }) } } catch (ex) { - console.error('ledger client creation error: ', ex) + console.error('ledger client creation error(1): ', ex) return state } @@ -2222,28 +2236,44 @@ const deleteSynopsis = () => { synopsis.publishers = {} } +let newClient = null const transitionWalletToBat = (state) => { - let newClient + let newPaymentId, result - try { - clientprep() - newClient = ledgerClient(null, underscore.extend({roundtrip: roundtrip}, clientOptions), null) - } catch (ex) { - console.error('exception during ledger client creation: ', ex) + if (newClient === true) return + + if (!newClient) { + try { + clientprep() + newClient = ledgerClient(null, underscore.extend({roundtrip: roundtrip}, clientOptions), null) + } catch (ex) { + return console.error('ledger client creation error(2): ', ex) + } + } + + newPaymentId = newClient.getPaymentId() + if (!newPaymentId) { + newClient.sync((err, result, delayTime) => { + if (err) { + return console.log('ledger client error(3): ' + JSON.stringify(err, null, 2) + (err.stack ? ('\n' + err.stack) : '')) + } + + if (typeof delayTime === 'undefined') delayTime = random.randomInt({ min: 1, max: 500 }) + + setTimeout(() => transitionWalletToBat(state), delayTime) + }) return } try { - // TODO: this line is breaking - // exception during ledger client transition: TypeError: Cannot read property 'wallet' of undefined - client.transition(newClient.properties.wallet.paymentId, (err) => { + client.transition(newPaymentId, (err, properties) => { if (err) { console.error('ledger client transition error: ', err) } else { - // save previous client transactions - newClient.state.transactions = client.state.transactions - // persist client's state, overwriting the old state + result = newClient.transitioned(properties) client = newClient + newClient = true + appActions.onLedgerCallback(result, random.randomInt({ min: miliseconds.minute, max: 10 * miliseconds.minute })) appActions.onBitcoinToBatTransitioned() } }) diff --git a/package-lock.json b/package-lock.json index 3bb40dd699d..e37fd1cf1f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,11 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/node": { + "version": "6.0.88", + "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.88.tgz", + "integrity": "sha512-bYDPZTX0/s1aihdjLuAgogUAT5M+TpoWChEMea2p0yOcfn5bu3k6cJb9cp6nw268XeSNIGGr+4+/8V5K6BGzLQ==" + }, "7zip-bin": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-2.2.4.tgz", @@ -20,11 +25,6 @@ "dev": true, "optional": true }, - "@types/node": { - "version": "6.0.88", - "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.88.tgz", - "integrity": "sha512-bYDPZTX0/s1aihdjLuAgogUAT5M+TpoWChEMea2p0yOcfn5bu3k6cJb9cp6nw268XeSNIGGr+4+/8V5K6BGzLQ==" - }, "abab": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", @@ -1441,13 +1441,13 @@ } }, "bat-client": { - "version": "0.9.20", - "resolved": "https://registry.npmjs.org/bat-client/-/bat-client-0.9.20.tgz", - "integrity": "sha512-cp3G6j14N3267YPqyWLSv2tIwnlAp3AffDMunCEdN0rmVBKlLAnjZG0zsspSHl1zwRwMGkpEsKM3phnzdlTiJg==", + "version": "0.9.22", + "resolved": "https://registry.npmjs.org/bat-client/-/bat-client-0.9.22.tgz", + "integrity": "sha512-KI3qY/xxsII1/7X/okXJSa3TO4vP97x8/Yo3Ae6ncP0+8TTZaBSWe892i/2hRm5GbI0D1WHHUE0dmXA0ZBjcvg==", "requires": { "bat-balance": "0.9.8", "bat-publisher": "0.9.4", - "bitgo": "4.7.0", + "bitgo": "4.9.0", "brave-crypto": "0.0.1", "http-request-signature": "0.0.2", "joi": "11.1.1", @@ -1704,9 +1704,9 @@ "integrity": "sha1-pUd/AOM/Knbtwgmq8mvwk5SjeM8=" }, "bitgo": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/bitgo/-/bitgo-4.7.0.tgz", - "integrity": "sha512-ibPNges48EnIvjGBR7GSTxq9wh5oaBJSAnC9kmbgG4V8V1QmHwue9cGp0VENA5oqZSvaO9bZZ+o3DVAB6T7pfg==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/bitgo/-/bitgo-4.9.0.tgz", + "integrity": "sha512-+Kkw2TmISShLTTBYmKf9HVk12At3k3adnyAEwF8CI+9lKBwHnSeGecYMUcboqCvkL6UNxh/VTunQRWdd5PGzpg==", "requires": { "argparse": "0.1.16", "assert": "0.4.9", @@ -7655,22 +7655,22 @@ } } }, - "string-width": { - "version": "1.0.2", + "string_decoder": { + "version": "1.0.1", "bundled": true, "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "safe-buffer": "5.0.1" } }, - "string_decoder": { - "version": "1.0.1", + "string-width": { + "version": "1.0.2", "bundled": true, "dev": true, "requires": { - "safe-buffer": "5.0.1" + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" } }, "stringstream": { @@ -14076,6 +14076,14 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -14086,14 +14094,6 @@ "strip-ansi": "3.0.1" } }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -17943,6 +17943,11 @@ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -17972,11 +17977,6 @@ "ipaddr.js": "1.4.0" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", diff --git a/package.json b/package.json index 36e894652a4..538c99e1729 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "aphrodite": "1.1.0", "async": "^2.0.1", "bat-balance": "^0.9.8", - "bat-client": "^0.9.20", + "bat-client": "^0.9.22", "bat-publisher": "^0.9.4", "bignumber.js": "^4.0.4", "bloodhound-js": "brave/bloodhound", diff --git a/test/unit/app/browser/api/ledgerTest.js b/test/unit/app/browser/api/ledgerTest.js index ed68b20b43b..0e26d376c32 100644 --- a/test/unit/app/browser/api/ledgerTest.js +++ b/test/unit/app/browser/api/ledgerTest.js @@ -20,8 +20,12 @@ describe('ledger api unit tests', function () { let paymentsEnabled let paymentsNotifications let ledgerClient + + // spies let ledgerTransitionSpy + let ledgerTransitionedSpy let onBitcoinToBatTransitionedSpy + let onLedgerCallbackSpy before(function () { this.clock = sinon.useFakeTimers() @@ -49,6 +53,7 @@ describe('ledger api unit tests', function () { }) mockery.registerMock('../../../js/actions/appActions', appActions) onBitcoinToBatTransitionedSpy = sinon.spy(appActions, 'onBitcoinToBatTransitioned') + onLedgerCallbackSpy = sinon.spy(appActions, 'onLedgerCallback') // ledger client stubbing ledgerClient = sinon.stub() @@ -68,11 +73,17 @@ describe('ledger api unit tests', function () { transition: function (paymentId, callback) { callback() }, + getPaymentId: function () { + return 'payementIdGoesHere' + }, properties: { wallet: { paymentId: 12345 } }, + transitioned: function () { + return {} + }, state: { transactions: [] } @@ -80,6 +91,7 @@ describe('ledger api unit tests', function () { ledgerClient.prototype.boolion = function (value) { return false } ledgerClient.prototype.getWalletPassphrase = function (state) {} ledgerTransitionSpy = sinon.spy(lc, 'transition') + ledgerTransitionedSpy = sinon.spy(lc, 'transitioned') ledgerClient.returns(lc) mockery.registerMock('bat-client', ledgerClient) @@ -134,6 +146,8 @@ describe('ledger api unit tests', function () { const batState = ledgerApi.onBootStateFile(defaultAppState) ledgerTransitionSpy.reset() onBitcoinToBatTransitionedSpy.reset() + onLedgerCallbackSpy.reset() + ledgerTransitionedSpy.reset() ledgerClient.reset() ledgerApi.transitionWalletToBat(batState) }) @@ -143,8 +157,16 @@ describe('ledger api unit tests', function () { it('calls client.transition', function () { assert(ledgerTransitionSpy.calledOnce) }) - it('calls AppActions.onBitcoinToBatTransitioned', function () { - assert(onBitcoinToBatTransitionedSpy.calledOnce) + describe('when transition completes', function () { + it('calls client.transitioned', function () { + assert(ledgerTransitionedSpy.calledOnce) + }) + it('calls AppActions.onLedgerCallback', function () { + assert(onLedgerCallbackSpy.calledOnce) + }) + it('calls AppActions.onBitcoinToBatTransitioned', function () { + assert(onBitcoinToBatTransitionedSpy.calledOnce) + }) }) }) @@ -340,13 +362,13 @@ describe('ledger api unit tests', function () { paymentsEnabled = true paymentsNotifications = true }) - it('does not call ledger.transitionWalletToBat', function () { + it('calls ledger.transitionWalletToBat', function () { const ledgerStateWithoutBalance = ledgerStateWithBalance .setIn(['ledger', 'info', 'balance'], 0) .setIn(['migrations', 'batMercuryTimestamp'], 32145) .setIn(['migrations', 'btcToBatTimestamp'], 32145) ledgerApi.notifications.onLaunch(ledgerStateWithoutBalance) - assert(transitionWalletToBatSpy.notCalled) + assert(transitionWalletToBatSpy.calledOnce) }) }) @@ -375,7 +397,7 @@ describe('ledger api unit tests', function () { }) }) - describe('when payment notifications are enabled, payments are enabled, user has funds, user had wallet before BAT Mercury, and user not been shown message yet', function () { + describe('when payments are enabled and user had wallet before BAT Mercury', function () { before(function () { paymentsEnabled = true paymentsNotifications = true