lnbits-legend/lnbits/extensions/watchonly/static/js/index.js

850 lines
26 KiB
JavaScript
Raw Normal View History

2022-07-22 16:27:35 +03:00
const watchOnly = async () => {
Vue.component(VueQrcode.name, VueQrcode)
2022-07-22 18:01:47 +03:00
await walletConfig('static/components/wallet-config/wallet-config.html')
await walletList('static/components/wallet-list/wallet-list.html')
await addressList('static/components/address-list/address-list.html')
2022-07-25 15:34:41 +03:00
await history('static/components/history/history.html')
await utxoList('static/components/utxo-list/utxo-list.html')
2022-07-25 20:03:48 +03:00
await feeRate('static/components/fee-rate/fee-rate.html')
2022-07-26 10:11:29 +03:00
await sendTo('static/components/send-to/send-to.html')
2022-07-25 17:37:06 +03:00
await payment('static/components/payment/payment.html')
2022-07-26 10:44:36 +03:00
//emplate static/components/payment/payment.html
//lnbits/extensions/watchonly/static/components/payment/payment.html
2022-07-22 16:27:35 +03:00
Vue.filter('reverse', function (value) {
// slice to make a copy of array, then reverse the copy
return value.slice().reverse()
})
2022-07-22 16:27:35 +03:00
new Vue({
el: '#vue',
mixins: [windowMixin],
data: function () {
return {
DUST_LIMIT: 546,
filter: '', // todo: remove?
2022-07-22 16:27:35 +03:00
scan: {
scanning: false,
scanCount: 0,
scanIndex: 0
},
2022-07-22 16:27:35 +03:00
currentAddress: null,
2022-07-22 16:27:35 +03:00
tab: 'addresses',
2022-07-22 16:27:35 +03:00
config: {
data: {
mempool_endpoint: 'https://mempool.space',
receive_gap_limit: 20,
change_gap_limit: 5
},
2022-07-22 16:27:35 +03:00
show: false
},
2022-07-22 16:27:35 +03:00
serial: {
selectedPort: null,
writableStreamClosed: null,
writer: null,
readableStreamClosed: null,
reader: null,
showAdvancedConfig: false,
receivedData: '',
config: {}
},
hww: {
password: null,
showPassword: false,
mnemonic: null,
showMnemonic: false,
authenticated: false,
showPasswordDialog: false,
showWipeDialog: false,
showRestoreDialog: false,
showConsole: false,
showSignedPsbt: false,
sendingPsbt: false,
signingPsbt: false,
psbtSent: false
},
2022-07-22 16:27:35 +03:00
qrCodeDialog: {
show: false,
data: null
},
...tables,
...tableData,
walletAccounts: [],
addresses: [],
history: [],
showAddress: false,
2022-07-25 17:37:06 +03:00
addressNote: '',
2022-07-26 10:44:36 +03:00
showPayment: false
2022-07-22 16:27:35 +03:00
}
},
methods: {
//################### CONFIG ###################
2022-07-20 16:57:32 +03:00
2022-07-22 16:27:35 +03:00
//################### WALLETS ###################
getWalletName: function (walletId) {
const wallet = this.walletAccounts.find(wl => wl.id === walletId)
return wallet ? wallet.title : 'unknown'
},
2022-07-22 16:27:35 +03:00
//################### ADDRESSES ###################
2022-07-22 16:27:35 +03:00
updateAmountForAddress: async function (addressData, amount = 0) {
try {
const wallet = this.g.user.wallets[0]
addressData.amount = amount
if (!addressData.isChange) {
const addressWallet = this.walletAccounts.find(
w => w.id === addressData.wallet
)
if (
2022-07-22 16:27:35 +03:00
addressWallet &&
addressWallet.address_no < addressData.addressIndex
) {
2022-07-22 16:27:35 +03:00
addressWallet.address_no = addressData.addressIndex
}
}
2022-07-22 16:27:35 +03:00
2022-07-26 11:31:23 +03:00
// todo: account deleted
2022-07-22 16:27:35 +03:00
await LNbits.api.request(
'PUT',
`/watchonly/api/v1/address/${addressData.id}`,
wallet.adminkey,
{amount}
)
} catch (err) {
addressData.error = 'Failed to refresh amount for address'
this.$q.notify({
type: 'warning',
message: `Failed to refresh amount for address ${addressData.address}`,
timeout: 10000
})
LNbits.utils.notifyApiError(err)
}
},
updateNoteForAddress: async function (addressData, note) {
try {
const wallet = this.g.user.wallets[0]
await LNbits.api.request(
'PUT',
`/watchonly/api/v1/address/${addressData.id}`,
wallet.adminkey,
{note: addressData.note}
)
const updatedAddress =
this.addresses.find(a => a.id === addressData.id) || {}
2022-07-22 16:27:35 +03:00
updatedAddress.note = note
} catch (err) {
LNbits.utils.notifyApiError(err)
}
},
2022-07-22 16:27:35 +03:00
//################### ADDRESS HISTORY ###################
addressHistoryFromTxs: function (addressData, txs) {
const addressHistory = []
txs.forEach(tx => {
const sent = tx.vin
.filter(
vin => vin.prevout.scriptpubkey_address === addressData.address
)
.map(vin => mapInputToSentHistory(tx, addressData, vin))
2022-07-22 16:27:35 +03:00
const received = tx.vout
.filter(vout => vout.scriptpubkey_address === addressData.address)
.map(vout => mapOutputToReceiveHistory(tx, addressData, vout))
addressHistory.push(...sent, ...received)
})
2022-07-22 16:27:35 +03:00
return addressHistory
},
2022-07-25 15:34:41 +03:00
2022-07-22 16:27:35 +03:00
markSameTxAddressHistory: function () {
this.history
2022-07-22 16:27:35 +03:00
.filter(s => s.sent)
.forEach((el, i, arr) => {
if (el.isSubItem) return
2022-07-22 16:27:35 +03:00
const sameTxItems = arr.slice(i + 1).filter(e => e.txId === el.txId)
if (!sameTxItems.length) return
sameTxItems.forEach(e => {
e.isSubItem = true
})
2022-07-22 16:27:35 +03:00
el.totalAmount =
el.amount + sameTxItems.reduce((t, e) => (t += e.amount || 0), 0)
el.sameTxItems = sameTxItems
})
2022-07-22 16:27:35 +03:00
},
showAddressHistoryDetails: function (addressHistory) {
addressHistory.expanded = true
},
2022-07-22 16:27:35 +03:00
//################### PAYMENT ###################
2022-07-26 10:11:29 +03:00
2022-07-22 16:27:35 +03:00
initPaymentData: async function () {
if (!this.payment.show) return
await this.$refs.addressList.refreshAddresses()
2022-07-22 16:27:35 +03:00
},
2022-07-25 19:37:16 +03:00
2022-07-22 16:27:35 +03:00
goToPaymentView: async function () {
2022-07-25 17:37:06 +03:00
this.showPayment = true
2022-07-22 16:27:35 +03:00
await this.initPaymentData()
},
2022-07-26 10:11:29 +03:00
2022-07-22 16:27:35 +03:00
//################### PSBT ###################
extractTxFromPsbt: async function (psbtBase64) {
2022-07-20 16:57:32 +03:00
const wallet = this.g.user.wallets[0]
2022-07-22 16:27:35 +03:00
try {
const {data} = await LNbits.api.request(
'PUT',
'/watchonly/api/v1/psbt/extract',
wallet.adminkey,
{
psbtBase64,
inputs: this.payment.tx.inputs
}
)
return data
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Cannot finalize PSBT!',
timeout: 10000
})
LNbits.utils.notifyApiError(error)
}
},
updateSignedPsbt: async function (value) {
this.payment.psbtBase64Signed = value
2022-07-22 16:27:35 +03:00
const data = await this.extractTxFromPsbt(this.payment.psbtBase64Signed)
if (data) {
this.payment.signedTx = JSON.parse(data.tx_json)
this.payment.signedTxHex = data.tx_hex
} else {
this.payment.signedTx = null
this.payment.signedTxHex = null
}
},
broadcastTransaction: async function () {
try {
const wallet = this.g.user.wallets[0]
const {data} = await LNbits.api.request(
'POST',
'/watchonly/api/v1/tx',
wallet.adminkey,
{tx_hex: this.payment.signedTxHex}
)
this.payment.sentTxId = data
2022-07-22 16:27:35 +03:00
this.$q.notify({
type: 'positive',
message: 'Transaction broadcasted!',
caption: `${data}`,
timeout: 10000
})
2022-07-22 16:27:35 +03:00
this.hww.psbtSent = false
this.payment.psbtBase64Signed = null
this.payment.signedTxHex = null
this.payment.signedTx = null
this.payment.psbtBase64 = null
2022-07-22 16:27:35 +03:00
await this.scanAddressWithAmount()
} catch (error) {
this.payment.sentTxId = null
2022-07-21 17:09:57 +03:00
this.$q.notify({
type: 'warning',
2022-07-22 16:27:35 +03:00
message: 'Failed to broadcast!',
caption: `${error}`,
2022-07-21 17:09:57 +03:00
timeout: 10000
})
2022-07-22 16:27:35 +03:00
}
},
//################### SERIAL PORT ###################
checkSerialPortSupported: function () {
if (!navigator.serial) {
this.$q.notify({
type: 'warning',
message: 'Serial port communication not supported!',
caption:
'Make sure your browser supports Serial Port and that you are using HTTPS.',
timeout: 10000
})
return false
}
return true
},
openSerialPort: async function () {
if (!this.checkSerialPortSupported()) return
console.log('### openSerialPort', this.serial.selectedPort)
try {
navigator.serial.addEventListener('connect', event => {
console.log('### navigator.serial event: connected!', event)
2022-07-13 17:56:12 +03:00
})
2022-07-22 16:27:35 +03:00
navigator.serial.addEventListener('disconnect', () => {
this.hww.authenticated = false
this.$q.notify({
type: 'warning',
message: 'Disconnected from Serial Port!',
timeout: 10000
})
})
this.serial.selectedPort = await navigator.serial.requestPort()
// Wait for the serial port to open.
await this.serial.selectedPort.open({baudRate: 9600})
this.startSerialPortReading()
2022-07-22 16:27:35 +03:00
const textEncoder = new TextEncoderStream()
this.serial.writableStreamClosed = textEncoder.readable.pipeTo(
this.serial.selectedPort.writable
)
2022-07-22 16:27:35 +03:00
this.serial.writer = textEncoder.writable.getWriter()
} catch (error) {
2022-07-22 16:27:35 +03:00
this.serial.selectedPort = null
this.$q.notify({
type: 'warning',
2022-07-22 16:27:35 +03:00
message: 'Cannot open serial port!',
caption: `${error}`,
timeout: 10000
})
}
2022-07-22 16:27:35 +03:00
},
closeSerialPort: async function () {
try {
console.log('### closeSerialPort', this.serial.selectedPort)
if (this.serial.writer) this.serial.writer.close()
if (this.serial.writableStreamClosed)
await this.serial.writableStreamClosed
if (this.serial.reader) this.serial.reader.cancel()
if (this.serial.readableStreamClosed)
await this.serial.readableStreamClosed.catch(() => {
/* Ignore the error */
})
if (this.serial.selectedPort) await this.serial.selectedPort.close()
this.serial.selectedPort = null
this.$q.notify({
type: 'positive',
2022-07-22 16:27:35 +03:00
message: 'Serial port disconnected!',
timeout: 5000
})
} catch (error) {
this.serial.selectedPort = null
console.log('### error', error)
this.$q.notify({
type: 'warning',
message: 'Cannot close serial port!',
caption: `${error}`,
timeout: 10000
})
}
2022-07-22 16:27:35 +03:00
},
2022-07-22 16:27:35 +03:00
startSerialPortReading: async function () {
const port = this.serial.selectedPort
2022-07-22 16:27:35 +03:00
while (port && port.readable) {
const textDecoder = new TextDecoderStream()
this.serial.readableStreamClosed = port.readable.pipeTo(
textDecoder.writable
)
2022-07-22 16:27:35 +03:00
this.serial.reader = textDecoder.readable.getReader()
const readStringUntil = readFromSerialPort(this.serial)
2022-07-22 16:27:35 +03:00
try {
while (true) {
const {value, done} = await readStringUntil('\n')
console.log('### value', value)
if (value) {
this.handleSerialPortResponse(value)
this.updateSerialPortConsole(value)
}
console.log('### startSerialPortReading DONE', done)
if (done) return
}
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Serial port communication error!',
caption: `${error}`,
timeout: 10000
})
}
2022-07-22 16:27:35 +03:00
}
console.log('### startSerialPortReading port', port)
},
2022-07-22 16:27:35 +03:00
handleSerialPortResponse: function (value) {
const msg = value.split(' ')
if (msg[0] == COMMAND_SIGN_PSBT) this.handleSignResponse(msg[1])
else if (msg[0] == COMMAND_PASSWORD) this.handleLoginResponse(msg[1])
else if (msg[0] == COMMAND_PASSWORD_CLEAR)
this.handleLogoutResponse(msg[1])
else if (msg[0] == COMMAND_SEND_PSBT)
this.handleSendPsbtResponse(msg[1])
else if (msg[0] == COMMAND_WIPE) this.handleWipeResponse(msg[1])
else console.log('### handleSerialPortResponse', value)
},
updateSerialPortConsole: function (value) {
this.serial.receivedData += value + '\n'
const textArea = document.getElementById(
'watchonly-serial-port-data-input'
)
if (textArea) textArea.scrollTop = textArea.scrollHeight
},
sharePsbtWithAnimatedQRCode: async function () {
console.log('### sharePsbtWithAnimatedQRCode')
},
//################### HARDWARE WALLET ###################
hwwShowPasswordDialog: async function () {
try {
this.hww.showPasswordDialog = true
await this.serial.writer.write(COMMAND_PASSWORD + '\n')
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to connect to Hardware Wallet!',
caption: `${error}`,
timeout: 10000
})
}
},
hwwShowWipeDialog: async function () {
try {
this.hww.showWipeDialog = true
await this.serial.writer.write(COMMAND_WIPE + '\n')
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to connect to Hardware Wallet!',
caption: `${error}`,
timeout: 10000
})
}
},
hwwShowRestoreDialog: async function () {
try {
this.hww.showRestoreDialog = true
await this.serial.writer.write(COMMAND_WIPE + '\n')
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to connect to Hardware Wallet!',
caption: `${error}`,
timeout: 10000
})
}
},
hwwLogin: async function () {
try {
await this.serial.writer.write(
COMMAND_PASSWORD + ' ' + this.hww.password + '\n'
)
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to send password to Hardware Wallet!',
caption: `${error}`,
timeout: 10000
})
} finally {
this.hww.showPasswordDialog = false
this.hww.password = null
this.hww.showPassword = false
}
},
handleLoginResponse: function (res = '') {
this.hww.authenticated = res.trim() === '1'
if (this.hww.authenticated) {
this.$q.notify({
type: 'positive',
message: 'Login successfull!',
timeout: 10000
})
} else {
this.$q.notify({
type: 'warning',
message: 'Wrong password, try again!',
timeout: 10000
})
}
2022-07-22 16:27:35 +03:00
},
hwwLogout: async function () {
try {
await this.serial.writer.write(COMMAND_PASSWORD_CLEAR + '\n')
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to logout from Hardware Wallet!',
caption: `${error}`,
timeout: 10000
})
}
},
handleLogoutResponse: function (res = '') {
this.hww.authenticated = !(res.trim() === '1')
if (this.hww.authenticated) {
this.$q.notify({
type: 'warning',
message: 'Failed to logout from Hardware Wallet',
timeout: 10000
})
}
},
hwwExecuteDefaultCommand: function () {
if (this.hww.authenticated) {
this.hwwSendPsbt()
} else {
this.hwwShowPasswordDialog()
}
},
hwwSendPsbt: async function () {
try {
this.hww.sendingPsbt = true
await this.serial.writer.write(
COMMAND_SEND_PSBT + ' ' + this.payment.psbtBase64 + '\n'
)
this.$q.notify({
type: 'positive',
message: 'Data sent to serial port device!',
timeout: 5000
})
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to send data to serial port!',
caption: `${error}`,
timeout: 10000
})
}
},
handleSendPsbtResponse: function (res = '') {
this.hww.psbtSent = true
this.hww.sendingPsbt = false
},
hwwSignPsbt: async function () {
try {
this.hww.signingPsbt = true
await this.serial.writer.write(COMMAND_SIGN_PSBT + '\n')
this.$q.notify({
type: 'positive',
message: 'PSBT signed!',
timeout: 5000
})
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to sign PSBT!',
caption: `${error}`,
timeout: 10000
})
}
},
handleSignResponse: function (res = '') {
this.hww.signingPsbt = false
this.updateSignedPsbt(res)
if (this.hww.authenticated) {
this.$q.notify({
type: 'positive',
message: 'Transaction Signed',
timeout: 10000
})
}
},
hwwHelp: async function () {
try {
await this.serial.writer.write(COMMAND_HELP + '\n')
this.$q.notify({
type: 'positive',
message: 'Check display or console for details!',
timeout: 5000
})
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to ask for help!',
caption: `${error}`,
timeout: 10000
})
}
},
hwwWipe: async function () {
try {
this.hww.showWipeDialog = false
await this.serial.writer.write(
COMMAND_WIPE + ' ' + this.hww.password + '\n'
)
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to ask for help!',
caption: `${error}`,
timeout: 10000
})
} finally {
this.hww.password = null
this.hww.showPassword = false
}
},
handleWipeResponse: function (res = '') {
const wiped = res.trim() === '1'
console.log('### wiped', wiped)
if (wiped) {
this.$q.notify({
type: 'positive',
message: 'Wallet wiped!',
timeout: 10000
})
} else {
this.$q.notify({
type: 'warning',
message: 'Failed to wipe wallet!',
caption: `${error}`,
timeout: 10000
})
}
},
hwwShowSeed: async function () {
try {
await this.serial.writer.write(COMMAND_SEED + '\n')
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to show seed!',
caption: `${error}`,
timeout: 10000
})
}
},
hwwRestore: async function () {
try {
await this.serial.writer.write(
COMMAND_RESTORE + ' ' + this.hww.mnemonic + '\n'
)
await this.serial.writer.write(
COMMAND_PASSWORD + ' ' + this.hww.password + '\n'
)
} catch (error) {
this.$q.notify({
type: 'warning',
message: 'Failed to restore from seed!',
caption: `${error}`,
timeout: 10000
})
} finally {
this.hww.showRestoreDialog = false
this.hww.mnemonic = null
this.hww.showMnemonic = false
this.hww.password = null
this.hww.showPassword = false
}
},
//################### UTXOs ###################
scanAllAddresses: async function () {
await this.$refs.addressList.refreshAddresses()
this.history = []
let addresses = this.addresses
2022-07-22 16:27:35 +03:00
this.utxos.data = []
this.utxos.total = 0
// Loop while new funds are found on the gap adresses.
// Use 1000 limit as a safety check (scan 20 000 addresses max)
for (let i = 0; i < 1000 && addresses.length; i++) {
await this.updateUtxosForAddresses(addresses)
const oldAddresses = this.addresses.slice()
await this.$refs.addressList.refreshAddresses()
const newAddresses = this.addresses.slice()
2022-07-22 16:27:35 +03:00
// check if gap addresses have been extended
addresses = newAddresses.filter(
newAddr => !oldAddresses.find(oldAddr => oldAddr.id === newAddr.id)
)
if (addresses.length) {
this.$q.notify({
type: 'positive',
message: 'Funds found! Scanning for more...',
timeout: 10000
})
}
}
},
scanAddressWithAmount: async function () {
this.utxos.data = []
this.utxos.total = 0
this.history = []
const addresses = this.addresses.filter(a => a.hasActivity)
2022-07-22 16:27:35 +03:00
await this.updateUtxosForAddresses(addresses)
},
scanAddress: async function (addressData) {
this.updateUtxosForAddresses([addressData])
this.$q.notify({
2022-07-22 16:27:35 +03:00
type: 'positive',
message: 'Address Rescanned',
timeout: 10000
})
2022-07-22 16:27:35 +03:00
},
updateUtxosForAddresses: async function (addresses = []) {
this.scan = {scanning: true, scanCount: addresses.length, scanIndex: 0}
try {
for (addrData of addresses) {
const addressHistory = await this.getAddressTxsDelayed(addrData)
// remove old entries
this.history = this.history.filter(
2022-07-22 16:27:35 +03:00
h => h.address !== addrData.address
)
2022-07-25 15:34:41 +03:00
// add new entries
this.history.push(...addressHistory)
this.history.sort((a, b) => (!a.height ? -1 : b.height - a.height))
2022-07-22 16:27:35 +03:00
this.markSameTxAddressHistory()
if (addressHistory.length) {
// search only if it ever had any activity
const utxos = await this.getAddressTxsUtxoDelayed(
addrData.address
)
this.updateUtxosForAddress(addrData, utxos)
}
this.scan.scanIndex++
}
} catch (error) {
console.error(error)
this.$q.notify({
type: 'warning',
message: 'Failed to scan addresses',
timeout: 10000
})
} finally {
this.scan.scanning = false
}
},
updateUtxosForAddress: function (addressData, utxos = []) {
const wallet =
this.walletAccounts.find(w => w.id === addressData.wallet) || {}
const newUtxos = utxos.map(utxo =>
mapAddressDataToUtxo(wallet, addressData, utxo)
)
// remove old utxos
this.utxos.data = this.utxos.data.filter(
u => u.address !== addressData.address
)
// add new utxos
this.utxos.data.push(...newUtxos)
if (utxos.length) {
this.utxos.data.sort((a, b) => b.sort - a.sort)
this.utxos.total = this.utxos.data.reduce(
(total, y) => (total += y?.amount || 0),
0
)
}
const addressTotal = utxos.reduce(
(total, y) => (total += y?.value || 0),
0
)
2022-07-22 16:27:35 +03:00
this.updateAmountForAddress(addressData, addressTotal)
},
// todo: move/dedup
2022-07-22 16:27:35 +03:00
getTotalSelectedUtxoAmount: function () {
const total = this.utxos.data
.filter(u => u.selected)
.reduce((t, a) => t + (a.amount || 0), 0)
return total
},
2022-07-22 16:27:35 +03:00
//################### MEMPOOL API ###################
getAddressTxsDelayed: async function (addrData) {
const {
bitcoin: {addresses: addressesAPI}
} = mempoolJS()
2022-07-22 16:27:35 +03:00
const fn = async () =>
addressesAPI.getAddressTxs({
address: addrData.address
})
const addressTxs = await retryWithDelay(fn)
return this.addressHistoryFromTxs(addrData, addressTxs)
},
2022-07-22 16:27:35 +03:00
getAddressTxsUtxoDelayed: async function (address) {
const {
bitcoin: {addresses: addressesAPI}
} = mempoolJS()
2022-07-22 16:27:35 +03:00
const fn = async () =>
addressesAPI.getAddressTxsUtxo({
address
})
return retryWithDelay(fn)
},
fetchTxHex: async function (txId) {
const {
bitcoin: {transactions: transactionsAPI}
} = mempoolJS()
2022-07-22 16:27:35 +03:00
try {
const response = await transactionsAPI.getTxHex({txid: txId})
return response
} catch (error) {
this.$q.notify({
type: 'warning',
message: `Failed to fetch transaction details for tx id: '${txId}'`,
timeout: 10000
})
LNbits.utils.notifyApiError(error)
throw error
}
},
2022-07-22 16:27:35 +03:00
//################### OTHER ###################
2022-07-22 16:27:35 +03:00
openQrCodeDialog: function (addressData) {
this.currentAddress = addressData
this.addressNote = addressData.note || ''
this.showAddress = true
2022-07-22 16:27:35 +03:00
},
searchInTab: function (tab, value) {
this.tab = tab
this[`${tab}Table`].filter = value
},
2022-07-22 16:27:35 +03:00
satBtc(val, showUnit = true) {
2022-07-22 18:01:47 +03:00
return satOrBtc(val, showUnit, this.config.data.sats_denominated)
2022-07-22 16:27:35 +03:00
},
updateAccounts: async function (accounts) {
this.walletAccounts = accounts
// await this.refreshAddressesxx() // todo: automatic now?
2022-07-25 11:24:02 +03:00
await this.scanAddressWithAmount()
},
showAddressDetails: function (addressData) {
this.openQrCodeDialog(addressData)
},
2022-07-25 15:34:41 +03:00
handleAddressesUpdated: async function (addresses) {
this.addresses = addresses
2022-07-25 15:34:41 +03:00
await this.scanAddressWithAmount()
2022-07-26 10:44:36 +03:00
}
},
2022-07-22 16:27:35 +03:00
created: async function () {
if (this.g.user.wallets.length) {
2022-07-25 15:34:41 +03:00
// await this.$refs.addressList.refreshAddresses()
2022-07-22 16:27:35 +03:00
await this.scanAddressWithAmount()
}
}
2022-07-22 16:27:35 +03:00
})
}
watchOnly()