You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
313 lines
9.9 KiB
313 lines
9.9 KiB
const screenXpubsToolsScript = {
|
|
|
|
explorerInfo: null,
|
|
currentXpub: null,
|
|
isReimport: false,
|
|
rescanStatusTimerId: null,
|
|
|
|
initPage: function() {
|
|
this.getExplorerInfo()
|
|
// Sets the event handlers
|
|
$('#btn-xpub-search-go').click(() => {this.searchXpub()})
|
|
$('#btn-xpub-details-reset').click(() => {this.showSearchForm()})
|
|
$('#btn-xpub-details-rescan').click(() => {this.showRescanForm()})
|
|
$('#btn-xpub-details-delete').click(() => {this.showDeletionForm()})
|
|
$('#btn-xpub-rescan-go').click(() => {this.rescanXpub()})
|
|
$('#btn-xpub-rescan-cancel').click(() => {this.hideRescanForm()})
|
|
$('#btn-xpub-delete-go').click(() => {this.deleteXpub()})
|
|
$('#btn-xpub-delete-cancel').click(() => {this.hideDeletionForm()})
|
|
$('#btn-xpub-import-go').click(() => {this.importXpub()})
|
|
$('#btn-xpub-details-retype').click(() => {this.showImportForm(true)})
|
|
$('#btn-xpub-import-cancel').click(() => {this.hideImportForm(this.isReimport)})
|
|
$('#xpubs-tool').keyup(evt => {
|
|
if (evt.keyCode === 13) {
|
|
this.searchXpub()
|
|
}
|
|
})
|
|
},
|
|
|
|
preparePage: function() {
|
|
this.hideRescanForm()
|
|
this.hideDeletionForm()
|
|
this.showSearchForm()
|
|
$("#xpub").focus()
|
|
},
|
|
|
|
getExplorerInfo: function() {
|
|
lib_api.getExplorerPairingInfo().then(explorerInfo => {
|
|
this.explorerInfo = explorerInfo
|
|
}).catch(e => {
|
|
lib_errors.processError(e)
|
|
})
|
|
},
|
|
|
|
searchXpub: function() {
|
|
lib_msg.displayMessage('Search in progress...');
|
|
const xpub = $('#xpub').val()
|
|
this.currentXpub = xpub
|
|
return this._searchXpub(xpub).then(() => {
|
|
lib_msg.cleanMessagesUi()
|
|
})
|
|
},
|
|
|
|
_searchXpub: function(xpub) {
|
|
return lib_api.getXpubInfo(xpub).then(xpubInfo => {
|
|
if (xpubInfo && xpubInfo['tracked']) {
|
|
this.setXpubDetails(xpubInfo)
|
|
this.showXpubDetails()
|
|
const jsonData = {'active': xpub}
|
|
return lib_api.getWallet(jsonData).then(walletInfo => {
|
|
// Display the txs
|
|
const txs = walletInfo['txs']
|
|
for (let tx of txs)
|
|
this.setTxDetails(tx)
|
|
// Display the UTXOs
|
|
const utxos = walletInfo['unspent_outputs'].sort((a,b) => {
|
|
return a['confirmations'] - b['confirmations']
|
|
})
|
|
$('#xpub-nb-utxos').text(utxos.length)
|
|
for (let utxo of utxos)
|
|
this.setUtxoDetails(utxo)
|
|
})
|
|
} else {
|
|
lib_msg.displayErrors('xpub not found')
|
|
this.showImportForm(false)
|
|
}
|
|
}).catch(e => {
|
|
lib_errors.processError(e)
|
|
throw e
|
|
})
|
|
},
|
|
|
|
importXpub: function() {
|
|
lib_msg.displayMessage('Processing xpub import. Please wait...');
|
|
|
|
const jsonData = {
|
|
'xpub': this.currentXpub,
|
|
'type': 'restore',
|
|
'force': true
|
|
}
|
|
|
|
const derivType = $('#import-deriv-type').val()
|
|
if (derivType == 'bip49' || derivType == 'bip84') {
|
|
jsonData['segwit'] = derivType
|
|
} else if (derivType == 'auto') {
|
|
if (this.currentXpub.startsWith('ypub'))
|
|
jsonData['segwit'] = 'bip49'
|
|
else if (this.currentXpub.startsWith('zpub'))
|
|
jsonData['segwit'] = 'bip84'
|
|
}
|
|
|
|
try {
|
|
lib_api.postXpub(jsonData)
|
|
// Wait for import completion and display progress
|
|
this.checkRescanStatus(() => {
|
|
this._searchXpub(this.currentXpub).then(() => {
|
|
lib_msg.displayInfo('Import complete')
|
|
})
|
|
})
|
|
} catch(e) {
|
|
lib_errors.processError(e)
|
|
}
|
|
},
|
|
|
|
rescanXpub: function() {
|
|
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)
|
|
|
|
try {
|
|
lib_api.getXpubRescan(this.currentXpub, lookahead, startIdx)
|
|
// Wait for rescan completion and display progress
|
|
this.checkRescanStatus(() => {
|
|
this.hideRescanForm()
|
|
this._searchXpub(this.currentXpub).then(() => {
|
|
lib_msg.displayInfo('Rescan complete')
|
|
})
|
|
})
|
|
} catch(e) {
|
|
lib_errors.processError(e)
|
|
}
|
|
},
|
|
|
|
deleteXpub: function() {
|
|
lib_msg.displayMessage('Deleting a xpub. Please wait...')
|
|
return lib_api.getXpubDelete(this.currentXpub)
|
|
.then(result => {
|
|
this.currentXpub = null
|
|
this.preparePage()
|
|
lib_msg.displayInfo('Xpub successfully deleted')
|
|
}).catch(e => {
|
|
lib_errors.processError(e)
|
|
})
|
|
},
|
|
|
|
checkRescanStatus: function(callback) {
|
|
this.rescanStatusTimerId = setTimeout(() => {
|
|
lib_api.getXpubRescanStatus(this.currentXpub)
|
|
.then(result => {
|
|
const data = result['data']
|
|
if (data['import_in_progress']) {
|
|
const lblOp = (data['status'] == 'rescan') ? 'Rescan' : 'Import'
|
|
const lblHits = (data['status'] == 'rescan') ? 'hits detected' : 'transactions imported'
|
|
const msg = `${lblOp} in progress (${data['hits']} ${lblHits})`
|
|
lib_msg.displayMessage(msg)
|
|
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)
|
|
})
|
|
}, 1000)
|
|
},
|
|
|
|
setXpubDetails: function(xpubInfo) {
|
|
$('tr.tx-row').remove()
|
|
$('tr.utxo-row').remove()
|
|
|
|
$('#xpub-value').text(this.currentXpub)
|
|
$('#xpub-import-date').text(xpubInfo['created'])
|
|
$('#xpub-deriv-type').text(xpubInfo['derivation'])
|
|
$('#xpub-nb-txs').text(xpubInfo['n_tx'])
|
|
$('#xpub-nb-utxos').text('-')
|
|
const balance = parseInt(xpubInfo['balance']) / 100000000
|
|
$('#xpub-balance').text(`${balance} BTC`)
|
|
$('#xpub-deriv-account').text(xpubInfo['account'])
|
|
$('#xpub-deriv-depth').text(xpubInfo['depth'])
|
|
$('#xpub-idx-unused-ext').text(xpubInfo['unused']['external'])
|
|
$('#xpub-idx-derived-ext').text(xpubInfo['derived']['external'])
|
|
$('#xpub-idx-unused-int').text(xpubInfo['unused']['internal'])
|
|
$('#xpub-idx-derived-int').text(xpubInfo['derived']['internal'])
|
|
},
|
|
|
|
setTxDetails: function(tx) {
|
|
const txid = tx['hash']
|
|
const txidDisplay = `${txid.substring(0,50)}...`
|
|
const amount = parseInt(tx['result']) / 100000000
|
|
const amountLabel = amount < 0 ? amount : `+${amount}`
|
|
const amountStyle = amount < 0 ? 'amount-sent' : 'amount-received'
|
|
const date = lib_fmt.unixTsToLocaleString(tx['time'])
|
|
const txUrl = lib_cmn.getExplorerTxUrl(txid, this.explorerInfo)
|
|
|
|
const newRow = `<tr class="tx-row"><td colspan="2"> </td></tr>
|
|
<tr class="tx-row">
|
|
<td class="table-label" colspan="2">
|
|
<a href="${txUrl}" target="_blank">${txidDisplay}</a>
|
|
</td>
|
|
</tr>
|
|
<tr class="tx-row">
|
|
<td class="table-label">Amount</td>
|
|
<td class="table-value ${amountStyle}">${amountLabel} BTC</td>
|
|
</tr>
|
|
<tr class="tx-row">
|
|
<td class="table-label">Block height</td>
|
|
<td class="table-value">${tx['block_height']}</td>
|
|
</tr>
|
|
<tr class="tx-row">
|
|
<td class="table-label">Date</td>
|
|
<td class="table-value">${date}</td>
|
|
</tr>`
|
|
|
|
$('#xpub-table-list-txs tr:last').after(newRow)
|
|
},
|
|
|
|
setUtxoDetails: function(utxo) {
|
|
const txid = utxo['tx_hash']
|
|
const txidVout = `${txid.substring(0,50)}...:${utxo['tx_output_n']}`
|
|
const amount = parseInt(utxo['value']) / 100000000
|
|
const txUrl = lib_cmn.getExplorerTxUrl(txid, this.explorerInfo)
|
|
|
|
const newRow = `<tr class="utxo-row"><td colspan="2"> </td></tr>
|
|
<tr class="utxo-row">
|
|
<td class="table-label" colspan="2">
|
|
<a href="${txUrl}" target="_blank">${txidVout}</a>
|
|
</td>
|
|
</tr>
|
|
<tr class="utxo-row">
|
|
<td class="table-label">Amount</td>
|
|
<td class="table-value">${amount} BTC</td>
|
|
</tr>
|
|
<tr class="utxo-row">
|
|
<td class="table-label">Address</td>
|
|
<td class="table-value">${utxo['addr']}</td>
|
|
</tr>
|
|
<tr class="utxo-row">
|
|
<td class="table-label">Confirmations</td>
|
|
<td class="table-value">${utxo['confirmations']}</td>
|
|
</tr>`
|
|
|
|
$('#xpub-table-list-utxos tr:last').after(newRow)
|
|
},
|
|
|
|
showSearchForm: function() {
|
|
$('#xpubs-tool-details').hide()
|
|
$('#xpubs-tool-import').hide()
|
|
$('#xpub').val('')
|
|
$('#xpubs-tool-search-form').show()
|
|
lib_msg.cleanMessagesUi()
|
|
},
|
|
|
|
showImportForm: function(isReimport) {
|
|
this.isReimport = isReimport
|
|
|
|
$('#xpubs-tool-search-form').hide()
|
|
$('#xpubs-tool-details').hide()
|
|
|
|
if (isReimport) {
|
|
$('#import-deriv-first-import-msg').hide()
|
|
$('#import-deriv-reimport-msg').show()
|
|
} else {
|
|
$('#import-deriv-reimport-msg').hide()
|
|
$('#import-deriv-first-import-msg').show()
|
|
}
|
|
|
|
const xpubLen = this.currentXpub.length
|
|
const xpubShortLbl = `"${this.currentXpub.substring(0, 20)}...${this.currentXpub.substring(xpubLen-20, xpubLen)}"`
|
|
$('#import-xpub').text(xpubShortLbl)
|
|
$('#xpubs-tool-import').show()
|
|
},
|
|
|
|
hideImportForm: function(isReimport) {
|
|
if (isReimport)
|
|
this.showXpubDetails()
|
|
else
|
|
this.showSearchForm()
|
|
},
|
|
|
|
showXpubDetails: function() {
|
|
$('#xpubs-tool-search-form').hide()
|
|
$('#xpubs-tool-import').hide()
|
|
$('#xpubs-tool-details').show()
|
|
},
|
|
|
|
showRescanForm: function() {
|
|
$('#xpubs-tool-actions').hide()
|
|
$('#xpubs-rescans-actions').show()
|
|
lib_msg.cleanMessagesUi()
|
|
},
|
|
|
|
hideRescanForm: function() {
|
|
$('#xpubs-rescans-actions').hide()
|
|
$('#xpubs-tool-actions').show()
|
|
},
|
|
|
|
showDeletionForm: function() {
|
|
$('#xpubs-tool-actions').hide()
|
|
$('#xpubs-deletion-actions').show()
|
|
lib_msg.cleanMessagesUi()
|
|
},
|
|
|
|
hideDeletionForm: function() {
|
|
$('#xpubs-deletion-actions').hide()
|
|
$('#xpubs-tool-actions').show()
|
|
},
|
|
|
|
}
|
|
|
|
screenScripts.set('#screen-xpubs-tools', screenXpubsToolsScript)
|
|
|