From c9fe459eeef17be9a4cfe93667c96af8ef914aea Mon Sep 17 00:00:00 2001 From: kenshin-samourai Date: Fri, 2 Oct 2020 17:48:11 +0200 Subject: [PATCH 1/7] bump dojo version --- docker/my-dojo/.env | 2 +- keys/index-example.js | 4 ++-- package-lock.json | 2 +- package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docker/my-dojo/.env b/docker/my-dojo/.env index 8dd6548..f42db71 100644 --- a/docker/my-dojo/.env +++ b/docker/my-dojo/.env @@ -13,7 +13,7 @@ COMPOSE_CONVERT_WINDOWS_PATHS=1 DOJO_VERSION_TAG=1.9.0 DOJO_DB_VERSION_TAG=1.2.0 DOJO_BITCOIND_VERSION_TAG=1.8.0 -DOJO_NODEJS_VERSION_TAG=1.8.0 +DOJO_NODEJS_VERSION_TAG=1.9.0 DOJO_NGINX_VERSION_TAG=1.5.0 DOJO_TOR_VERSION_TAG=1.5.0 DOJO_EXPLORER_VERSION_TAG=1.3.0 diff --git a/keys/index-example.js b/keys/index-example.js index 7e6c98a..902b4ad 100644 --- a/keys/index-example.js +++ b/keys/index-example.js @@ -15,7 +15,7 @@ module.exports = { /* * Dojo version */ - dojoVersion: '1.8.0', + dojoVersion: '1.9.0', /* * Bitcoind */ @@ -232,7 +232,7 @@ module.exports = { * Testnet parameters */ testnet: { - dojoVersion: '1.8.0', + dojoVersion: '1.9.0', bitcoind: { rpc: { user: 'user', diff --git a/package-lock.json b/package-lock.json index da87e85..aa42406 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "samourai-dojo", - "version": "1.8.0", + "version": "1.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d2b4d14..e05353f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "samourai-dojo", - "version": "1.8.0", + "version": "1.9.0", "description": "Backend server for Samourai Wallet", "main": "accounts/index.js", "scripts": { From 1b005818ad1b27435002c084fbce2b2c8437b005 Mon Sep 17 00:00:00 2001 From: kenshin-samourai Date: Fri, 2 Oct 2020 17:52:02 +0200 Subject: [PATCH 2/7] redirect to sign in page if auth as expired or is invalid --- .../dmt/addresses-tools/addresses-tools.js | 12 ++++------ .../admin/dmt/blocks-rescan/blocks-rescan.js | 3 +-- static/admin/dmt/index.html | 1 + static/admin/dmt/pairing/pairing.js | 3 +-- static/admin/dmt/pushtx/pushtx.js | 6 ++--- static/admin/dmt/status/status.js | 6 ++--- static/admin/dmt/txs-tools/txs-tools.js | 3 +-- static/admin/dmt/xpubs-tools/xpubs-tools.js | 12 ++++------ static/admin/index.html | 1 + static/admin/index.js | 3 +-- static/admin/lib/auth-utils.js | 19 +++++++++++---- static/admin/lib/errors-utils.js | 24 +++++++++++++++++++ static/admin/lib/messages.js | 9 ------- 13 files changed, 57 insertions(+), 45 deletions(-) create mode 100644 static/admin/lib/errors-utils.js diff --git a/static/admin/dmt/addresses-tools/addresses-tools.js b/static/admin/dmt/addresses-tools/addresses-tools.js index ccc302c..c03c3ed 100644 --- a/static/admin/dmt/addresses-tools/addresses-tools.js +++ b/static/admin/dmt/addresses-tools/addresses-tools.js @@ -30,8 +30,7 @@ const screenAddressesToolsScript = { lib_api.getExplorerPairingInfo().then(explorerInfo => { this.explorerInfo = explorerInfo }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, @@ -68,8 +67,7 @@ const screenAddressesToolsScript = { this.showImportForm(false) } }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) throw e }) }, @@ -83,8 +81,7 @@ const screenAddressesToolsScript = { lib_msg.displayInfo('Import complete') }) }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, @@ -97,8 +94,7 @@ const screenAddressesToolsScript = { lib_msg.displayInfo('Rescan complete') }) }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, diff --git a/static/admin/dmt/blocks-rescan/blocks-rescan.js b/static/admin/dmt/blocks-rescan/blocks-rescan.js index 0d47447..19b9bb8 100644 --- a/static/admin/dmt/blocks-rescan/blocks-rescan.js +++ b/static/admin/dmt/blocks-rescan/blocks-rescan.js @@ -32,8 +32,7 @@ const screenBlocksRescanScript = { const msg = `successfully rescanned blocks between height ${fromHeightRes} and height ${toHeightRes}` lib_msg.displayInfo(msg) }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }).then(() => { $('#rescan-from-height').val('') $('#rescan-to-height').val('') diff --git a/static/admin/dmt/index.html b/static/admin/dmt/index.html index 3140759..0237e01 100644 --- a/static/admin/dmt/index.html +++ b/static/admin/dmt/index.html @@ -15,6 +15,7 @@ + diff --git a/static/admin/dmt/pairing/pairing.js b/static/admin/dmt/pairing/pairing.js index 56d2ef6..4073473 100644 --- a/static/admin/dmt/pairing/pairing.js +++ b/static/admin/dmt/pairing/pairing.js @@ -27,8 +27,7 @@ const screenPairingScript = { lib_msg.cleanMessagesUi() return result }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) return result }) }, diff --git a/static/admin/dmt/pushtx/pushtx.js b/static/admin/dmt/pushtx/pushtx.js index 514d44d..1efbb00 100644 --- a/static/admin/dmt/pushtx/pushtx.js +++ b/static/admin/dmt/pushtx/pushtx.js @@ -29,8 +29,7 @@ const pushtxScript = { $('#pushed-uptime').text('-') $('#pushed-count').text('-') $('#pushed-amount').text('-') - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, @@ -48,8 +47,7 @@ const pushtxScript = { lib_msg.cleanMessagesUi() } }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, diff --git a/static/admin/dmt/status/status.js b/static/admin/dmt/status/status.js index e893b97..b1c1ee4 100644 --- a/static/admin/dmt/status/status.js +++ b/static/admin/dmt/status/status.js @@ -27,8 +27,7 @@ const statusScript = { $('#tracker-status-ind').css('color', '#f77c7c') $('#tracker-uptime').text('-') $('#tracker-chaintip').text('-') - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, @@ -58,8 +57,7 @@ const statusScript = { $('#node-network').text('-') $('#node-conn').text('-') $('#node-relay-fee').text('-') - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, diff --git a/static/admin/dmt/txs-tools/txs-tools.js b/static/admin/dmt/txs-tools/txs-tools.js index b6e992e..6bf7f0e 100644 --- a/static/admin/dmt/txs-tools/txs-tools.js +++ b/static/admin/dmt/txs-tools/txs-tools.js @@ -24,8 +24,7 @@ const screenTxsToolsScript = { lib_api.getExplorerPairingInfo().then(explorerInfo => { this.explorerInfo = explorerInfo }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, diff --git a/static/admin/dmt/xpubs-tools/xpubs-tools.js b/static/admin/dmt/xpubs-tools/xpubs-tools.js index b8967d5..b179079 100644 --- a/static/admin/dmt/xpubs-tools/xpubs-tools.js +++ b/static/admin/dmt/xpubs-tools/xpubs-tools.js @@ -32,8 +32,7 @@ const screenXpubsToolsScript = { lib_api.getExplorerPairingInfo().then(explorerInfo => { this.explorerInfo = explorerInfo }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, @@ -70,8 +69,7 @@ const screenXpubsToolsScript = { this.showImportForm(false) } }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) throw e }) }, @@ -101,8 +99,7 @@ const screenXpubsToolsScript = { lib_msg.displayInfo('Import complete') }) }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, @@ -119,8 +116,7 @@ const screenXpubsToolsScript = { lib_msg.displayInfo('Rescan complete') }) }).catch(e => { - lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) - console.log(e) + lib_errors.processError(e) }) }, diff --git a/static/admin/index.html b/static/admin/index.html index f66f05d..5073354 100644 --- a/static/admin/index.html +++ b/static/admin/index.html @@ -14,6 +14,7 @@ + diff --git a/static/admin/index.js b/static/admin/index.js index fd8980d..1349deb 100644 --- a/static/admin/index.js +++ b/static/admin/index.js @@ -33,8 +33,7 @@ function login() { } }, function (jqxhr) { - let msg = lib_msg.extractJqxhrErrorMsg(jqxhr) - lib_msg.displayErrors(msg) + lib_errors.processError(jqxhr) } ) } diff --git a/static/admin/lib/auth-utils.js b/static/admin/lib/auth-utils.js index d357971..656a3d7 100644 --- a/static/admin/lib/auth-utils.js +++ b/static/admin/lib/auth-utils.js @@ -9,6 +9,9 @@ const lib_auth = { /* SessionStorage Key used for refresh token */ SESSION_STORE_REFRESH_TOKEN: 'refresh_token', + /* SessionStorage Key used for the timestamp of the refresh token */ + SESSION_STORE_REFRESH_TOKEN_TS: 'refresh_token_ts', + /* JWT Scheme */ JWT_SCHEME: 'Bearer', @@ -43,6 +46,8 @@ const lib_auth = { * Stores refresh token in session storage */ setRefreshToken: function(token) { + const now = new Date(); + sessionStorage.setItem(this.SESSION_STORE_REFRESH_TOKEN_TS, now.getTime()) sessionStorage.setItem(this.SESSION_STORE_REFRESH_TOKEN, token) }, @@ -56,17 +61,23 @@ const lib_auth = { const now = new Date(); const atts = sessionStorage.getItem(this.SESSION_STORE_ACCESS_TOKEN_TS) - const timeElapsed = (now.getTime() - atts) / 1000 + let timeElapsed = (now.getTime() - atts) / 1000 // Refresh the access token if more than 5mn if (timeElapsed > 300) { - const dataJson = { - 'rt': this.getRefreshToken() + // Check if refresh token has expired or is about to expire + const rtts = sessionStorage.getItem(this.SESSION_STORE_REFRESH_TOKEN_TS) + if ((now.getTime() - rtts) / 1000 > 7200 - 60) { + // Force user to sign in again + this.logout() + return } let self = this - let deferred = lib_api.refreshToken(dataJson) + let deferred = lib_api.refreshToken({ + 'rt': this.getRefreshToken() + }) deferred.then( function (result) { diff --git a/static/admin/lib/errors-utils.js b/static/admin/lib/errors-utils.js new file mode 100644 index 0000000..e32c528 --- /dev/null +++ b/static/admin/lib/errors-utils.js @@ -0,0 +1,24 @@ +const lib_errors = { + + // Extract jqxhr error message + extractJqxhrErrorMsg: function(jqxhr) { + let hasErrorMsg = ('responseJSON' in jqxhr) && + (jqxhr['responseJSON'] != null) && + ('error' in jqxhr['responseJSON']) + + return hasErrorMsg ? jqxhr['responseJSON']['error'] : jqxhr.statusText + }, + + // Manage errors + processError: function(e) { + const errorMsg = this.extractJqxhrErrorMsg(e) + // Redirect to sign in page if authentication error + if (errorMsg == 'Invalid JSON Web Token' || errorMsg == 'Missing JSON Web Token') { + lib_auth.logout() + } else { + lib_msg.displayErrors(errorMsg) + console.log(e) + } + }, + +} diff --git a/static/admin/lib/messages.js b/static/admin/lib/messages.js index 8518491..b08adbb 100644 --- a/static/admin/lib/messages.js +++ b/static/admin/lib/messages.js @@ -1,14 +1,5 @@ const lib_msg = { - // Extracts jqxhr error message - extractJqxhrErrorMsg: function(jqxhr) { - let hasErrorMsg = ('responseJSON' in jqxhr) && - (jqxhr['responseJSON'] != null) && - ('error' in jqxhr['responseJSON']) - - return hasErrorMsg ? jqxhr['responseJSON']['error'] : jqxhr.statusText - }, - // UI functions addTextinID: function(text, id){ $(id).html(text.toUpperCase()) From d009be01f0aa1323ad5f8c09f7febcc33ca84ad6 Mon Sep 17 00:00:00 2001 From: kenshin-samourai Date: Fri, 2 Oct 2020 17:58:30 +0200 Subject: [PATCH 3/7] update description of blocks rescan --- static/admin/dmt/blocks-rescan/blocks-rescan.html | 2 +- static/admin/dmt/welcome/welcome.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/static/admin/dmt/blocks-rescan/blocks-rescan.html b/static/admin/dmt/blocks-rescan/blocks-rescan.html index b99a52f..80738b3 100644 --- a/static/admin/dmt/blocks-rescan/blocks-rescan.html +++ b/static/admin/dmt/blocks-rescan/blocks-rescan.html @@ -1,7 +1,7 @@

BLOCKS RESCAN

-
Force the Tracker to rescan a range of blocks.
+
Force the Tracker to rescan a small range of blocks.
diff --git a/static/admin/dmt/welcome/welcome.html b/static/admin/dmt/welcome/welcome.html index 4584cda..ac78347 100644 --- a/static/admin/dmt/welcome/welcome.html +++ b/static/admin/dmt/welcome/welcome.html @@ -26,7 +26,7 @@ Check if a transaction is found in a block or in the mempool of your full node. BLOCKS RESCAN - Rescan the transactions confirmed by the blocks in a given range. + Force the Tracker to rescan a small range of blocks.
For large rescans you should prefer XPUB or address rescans.
HELP From a1a1055e4060d68b9351f5b6efaae1b187c64a2d Mon Sep 17 00:00:00 2001 From: kenshin-samourai Date: Fri, 2 Oct 2020 22:20:39 +0200 Subject: [PATCH 4/7] update messages displayed by addresses tool --- static/admin/dmt/addresses-tools/addresses-tools.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/admin/dmt/addresses-tools/addresses-tools.js b/static/admin/dmt/addresses-tools/addresses-tools.js index c03c3ed..c8c4dbb 100644 --- a/static/admin/dmt/addresses-tools/addresses-tools.js +++ b/static/admin/dmt/addresses-tools/addresses-tools.js @@ -73,7 +73,7 @@ const screenAddressesToolsScript = { }, importAddress: function() { - lib_msg.displayMessage('Processing address import...'); + lib_msg.displayMessage('Processing address import. Please wait...'); const jsonData = {'active': this.currentAddress} return lib_api.getWallet(jsonData) .then(result => { @@ -86,7 +86,7 @@ const screenAddressesToolsScript = { }, rescanAddress: function() { - lib_msg.displayMessage('Processing address rescan...'); + lib_msg.displayMessage('Processing address rescan. Please wait...'); return lib_api.getAddressRescan(this.currentAddress) .then(result => { this.hideRescanForm() From b06e57ee68a5dec0193cfa06687f375ad1a5586b Mon Sep 17 00:00:00 2001 From: kenshin-samourai Date: Fri, 2 Oct 2020 22:21:13 +0200 Subject: [PATCH 5/7] deactivate messages displayed by pushtx and status screens --- static/admin/dmt/pushtx/pushtx.js | 8 ++++---- static/admin/dmt/status/status.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/static/admin/dmt/pushtx/pushtx.js b/static/admin/dmt/pushtx/pushtx.js index 1efbb00..6472e3b 100644 --- a/static/admin/dmt/pushtx/pushtx.js +++ b/static/admin/dmt/pushtx/pushtx.js @@ -15,7 +15,7 @@ const pushtxScript = { }, refreshPushTxStatus: function() { - lib_msg.displayMessage('Loading PushTx status info...'); + //lib_msg.displayMessage('Loading PushTx status info...'); lib_api.getPushtxStatus().then(pushTxStatus => { if (pushTxStatus) { const data = pushTxStatus['data'] @@ -23,7 +23,7 @@ const pushtxScript = { $('#pushed-uptime').text(uptime) $('#pushed-count').text(data['push']['count']) $('#pushed-amount').text(data['push']['amount']) - lib_msg.cleanMessagesUi() + //lib_msg.cleanMessagesUi() } }).catch(e => { $('#pushed-uptime').text('-') @@ -34,7 +34,7 @@ const pushtxScript = { }, refreshScheduledTxsList: function() { - lib_msg.displayMessage('Loading PushTx orchestrator status info...'); + //lib_msg.displayMessage('Loading PushTx orchestrator status info...'); lib_api.getOrchestratorStatus().then(orchestrStatus => { if(orchestrStatus) { const data = orchestrStatus['data'] @@ -44,7 +44,7 @@ const pushtxScript = { this.processedSchedTxs.add(tx['schTxid']) } } - lib_msg.cleanMessagesUi() + //lib_msg.cleanMessagesUi() } }).catch(e => { lib_errors.processError(e) diff --git a/static/admin/dmt/status/status.js b/static/admin/dmt/status/status.js index b1c1ee4..d9e5e78 100644 --- a/static/admin/dmt/status/status.js +++ b/static/admin/dmt/status/status.js @@ -13,14 +13,14 @@ const statusScript = { }, refreshApiStatus: function() { - lib_msg.displayMessage('Loading API status info...'); + //lib_msg.displayMessage('Loading API status info...'); return lib_api.getApiStatus().then(apiStatus => { if (apiStatus) { $('#tracker-status-ind').html('✓') $('#tracker-status-ind').css('color', '#76d776') $('#tracker-uptime').text(apiStatus['uptime']) $('#tracker-chaintip').text(apiStatus['blocks']) - lib_msg.cleanMessagesUi() + //lib_msg.cleanMessagesUi() } }).catch(e => { $('#tracker-status-ind').text('X') @@ -32,7 +32,7 @@ const statusScript = { }, refreshPushTxStatus: function() { - lib_msg.displayMessage('Loading Tracker status info...'); + //lib_msg.displayMessage('Loading Tracker status info...'); lib_api.getPushtxStatus().then(pushTxStatus => { if (pushTxStatus) { const data = pushTxStatus['data'] @@ -46,7 +46,7 @@ const statusScript = { $('#node-network').text(network) $('#node-conn').text(data['bitcoind']['conn']) $('#node-relay-fee').text(data['bitcoind']['relayfee']) - lib_msg.cleanMessagesUi() + //lib_msg.cleanMessagesUi() } }).catch(e => { $('#node-status-ind').text('-') From 515eca1652c1159edb40ffd6e3083776e5eb0408 Mon Sep 17 00:00:00 2001 From: kenshin-samourai Date: Fri, 2 Oct 2020 22:21:48 +0200 Subject: [PATCH 6/7] add getXpubRescanStatus() method to api wrapper --- static/admin/lib/api-wrapper.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/static/admin/lib/api-wrapper.js b/static/admin/lib/api-wrapper.js index 9a3b43b..47f492d 100644 --- a/static/admin/lib/api-wrapper.js +++ b/static/admin/lib/api-wrapper.js @@ -110,6 +110,14 @@ const lib_api = { ) }, + /** + * Gets the status of a xpub rescan + */ + getXpubRescanStatus: function(xpub) { + let uri = this.baseUri + '/xpub/' + xpub + '/import/status' + return this.sendGetUriEncoded(uri, {}) + }, + /** * Notifies the server of the new HD account for tracking. */ From 485cd12d3edba9ad5fc046fb7569aa49086d76e8 Mon Sep 17 00:00:00 2001 From: kenshin-samourai Date: Fri, 2 Oct 2020 22:22:26 +0200 Subject: [PATCH 7/7] improve management of timeouts during xpub imports and rescans --- static/admin/dmt/xpubs-tools/xpubs-tools.js | 53 +++++++++++++++++++-- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/static/admin/dmt/xpubs-tools/xpubs-tools.js b/static/admin/dmt/xpubs-tools/xpubs-tools.js index b179079..7f02d1c 100644 --- a/static/admin/dmt/xpubs-tools/xpubs-tools.js +++ b/static/admin/dmt/xpubs-tools/xpubs-tools.js @@ -3,6 +3,7 @@ const screenXpubsToolsScript = { explorerInfo: null, currentXpub: null, isReimport: false, + rescanStatusTimerId: null, initPage: function() { this.getExplorerInfo() @@ -75,7 +76,7 @@ const screenXpubsToolsScript = { }, importXpub: function() { - lib_msg.displayMessage('Processing xpub import...'); + lib_msg.displayMessage('Processing xpub import. Please wait...'); const jsonData = { 'xpub': this.currentXpub, @@ -95,31 +96,73 @@ const screenXpubsToolsScript = { return lib_api.postXpub(jsonData) .then(result => { + // Successful import this._searchXpub(this.currentXpub).then(() => { lib_msg.displayInfo('Import complete') }) }).catch(e => { - lib_errors.processError(e) + // Check if import has timeout'd or if we have an error + if (e['status'] == 502 || e['status'] == 504) { + // Wait for import completion + this.checkRescanStatus(() => { + this._searchXpub(this.currentXpub).then(() => { + lib_msg.displayInfo('Import complete') + }) + }) + } else { + lib_errors.processError(e) + } }) }, rescanXpub: function() { - lib_msg.displayMessage('Processing xpub rescan...'); + lib_msg.displayMessage('Processing xpub rescan. Please wait...'); let startIdx = $('#rescan-start-idx').val() startIdx = (startIdx == null) ? 0 : parseInt(startIdx) let lookahead = $('#rescan-lookahead').val() lookahead = (lookahead == null) ? 100 : parseInt(lookahead) return lib_api.getXpubRescan(this.currentXpub, lookahead, startIdx) - .then(result => { + .then(() => { + // Successful rescan this.hideRescanForm() this._searchXpub(this.currentXpub).then(() => { lib_msg.displayInfo('Rescan complete') }) }).catch(e => { - lib_errors.processError(e) + // Check if rescan has timeout'd or if we have an error + if (e['status'] == 502 || e['status'] == 504) { + // Wait for rescan completion + this.checkRescanStatus(() => { + this.hideRescanForm() + this._searchXpub(this.currentXpub).then(() => { + lib_msg.displayInfo('Rescan complete') + }) + }) + } else { + lib_errors.processError(e) + } }) }, + checkRescanStatus: function(callback) { + this.rescanStatusTimerId = setTimeout(() => { + lib_api.getXpubRescanStatus(this.currentXpub) + .then(result => { + if (result['data']['import_in_progress']) { + lib_msg.displayMessage('Rescan in progress. Please wait...'); + return this.checkRescanStatus(callback) + } else { + clearTimeout(this.rescanStatusTimerId) + return callback() + } + }).catch(e => { + lib_errors.processError(e) + lib_msg.displayMessage('Rescan in progress. Please wait...'); + return this.checkRescanStatus(callback) + }) + }, 10000) + }, + setXpubDetails: function(xpubInfo) { $('tr.tx-row').remove() $('tr.utxo-row').remove()