Browse Source

Merge branch 'feat_dojo_dmt_ux' into 'develop'

improve dmt ux

See merge request dojo/samourai-dojo!165
use-env-var-docker
kenshin-samourai 4 years ago
parent
commit
54a58bbc88
  1. 2
      docker/my-dojo/.env
  2. 4
      keys/index-example.js
  3. 2
      package-lock.json
  4. 2
      package.json
  5. 16
      static/admin/dmt/addresses-tools/addresses-tools.js
  6. 2
      static/admin/dmt/blocks-rescan/blocks-rescan.html
  7. 3
      static/admin/dmt/blocks-rescan/blocks-rescan.js
  8. 1
      static/admin/dmt/index.html
  9. 3
      static/admin/dmt/pairing/pairing.js
  10. 14
      static/admin/dmt/pushtx/pushtx.js
  11. 14
      static/admin/dmt/status/status.js
  12. 3
      static/admin/dmt/txs-tools/txs-tools.js
  13. 2
      static/admin/dmt/welcome/welcome.html
  14. 61
      static/admin/dmt/xpubs-tools/xpubs-tools.js
  15. 1
      static/admin/index.html
  16. 3
      static/admin/index.js
  17. 8
      static/admin/lib/api-wrapper.js
  18. 19
      static/admin/lib/auth-utils.js
  19. 24
      static/admin/lib/errors-utils.js
  20. 9
      static/admin/lib/messages.js

2
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

4
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',

2
package-lock.json

@ -1,6 +1,6 @@
{
"name": "samourai-dojo",
"version": "1.8.0",
"version": "1.9.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

2
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": {

16
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,14 +67,13 @@ const screenAddressesToolsScript = {
this.showImportForm(false)
}
}).catch(e => {
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e))
console.log(e)
lib_errors.processError(e)
throw e
})
},
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 => {
@ -83,13 +81,12 @@ const screenAddressesToolsScript = {
lib_msg.displayInfo('Import complete')
})
}).catch(e => {
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e))
console.log(e)
lib_errors.processError(e)
})
},
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()
@ -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)
})
},

2
static/admin/dmt/blocks-rescan/blocks-rescan.html

@ -1,7 +1,7 @@
<div id="blocks-rescan">
<h1>BLOCKS RESCAN</h1>
<div class="box-context">Force the Tracker to rescan a range of blocks.</div>
<div class="box-context">Force the Tracker to rescan a small range of blocks.</div>
<div class="row box-main">
<div id="blocks-rescan-form" class="box fullwidth">

3
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('')

1
static/admin/dmt/index.html

@ -15,6 +15,7 @@
<script src="../lib/auth-utils.js"></script>
<script src="../lib/format-utils.js"></script>
<script src="../lib/messages.js"></script>
<script src="../lib/errors-utils.js"></script>
<script src="index.js"></script>
</head>

3
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
})
},

14
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,19 +23,18 @@ 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('-')
$('#pushed-count').text('-')
$('#pushed-amount').text('-')
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e))
console.log(e)
lib_errors.processError(e)
})
},
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']
@ -45,11 +44,10 @@ const pushtxScript = {
this.processedSchedTxs.add(tx['schTxid'])
}
}
lib_msg.cleanMessagesUi()
//lib_msg.cleanMessagesUi()
}
}).catch(e => {
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e))
console.log(e)
lib_errors.processError(e)
})
},

14
static/admin/dmt/status/status.js

@ -13,27 +13,26 @@ 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('&#10003;')
$('#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')
$('#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)
})
},
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']
@ -47,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('-')
@ -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)
})
},

3
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)
})
},

2
static/admin/dmt/welcome/welcome.html

@ -26,7 +26,7 @@
<span class="item-descr">Check if a transaction is found in a block or in the mempool of your full node.</span>
<span class="item">BLOCKS RESCAN</span>
<span class="item-descr">Rescan the transactions confirmed by the blocks in a given range.</span>
<span class="item-descr">Force the Tracker to rescan a small range of blocks.<br/>For large rescans you should prefer XPUB or address rescans.</span>
<span class="items-category ">HELP</span>

61
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()
@ -32,8 +33,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,14 +70,13 @@ const screenXpubsToolsScript = {
this.showImportForm(false)
}
}).catch(e => {
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e))
console.log(e)
lib_errors.processError(e)
throw e
})
},
importXpub: function() {
lib_msg.displayMessage('Processing xpub import...');
lib_msg.displayMessage('Processing xpub import. Please wait...');
const jsonData = {
'xpub': this.currentXpub,
@ -97,31 +96,71 @@ const screenXpubsToolsScript = {
return lib_api.postXpub(jsonData)
.then(result => {
// Successful import
this._searchXpub(this.currentXpub).then(() => {
lib_msg.displayInfo('Import complete')
})
}).catch(e => {
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e))
console.log(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_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e))
console.log(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) {

1
static/admin/index.html

@ -14,6 +14,7 @@
<script src="lib/api-wrapper.js"></script>
<script src="lib/auth-utils.js"></script>
<script src="lib/messages.js"></script>
<script src="lib/errors-utils.js"></script>
<script src="index.js"></script>
</head>

3
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)
}
)
}

8
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.
*/

19
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) {

24
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)
}
},
}

9
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())

Loading…
Cancel
Save