diff --git a/lnbits/extensions/cashu/static/js/wallet.js b/lnbits/extensions/cashu/static/js/wallet.js deleted file mode 100644 index 832b075d6..000000000 --- a/lnbits/extensions/cashu/static/js/wallet.js +++ /dev/null @@ -1,1104 +0,0 @@ -var currentDateStr = function () { - return Quasar.utils.date.formatDate(new Date(), 'YYYY-MM-DD HH:mm') -} -var mapMint = function (obj) { - obj.date = Quasar.utils.date.formatDate( - new Date(obj.time * 1000), - 'YYYY-MM-DD HH:mm' - ) - obj.fsat = new Intl.NumberFormat(LOCALE).format(obj.amount) - obj.cashu = ['/cashu/', obj.id].join('') - return obj -} - -Vue.component(VueQrcode.name, VueQrcode) - -new Vue({ - el: '#vue', - mixins: [windowMixin], - data: function () { - return { - tickershort: '', - name: '', - - mintId: '', - mintName: '', - keys: '', - invoicesCashu: [], - invoiceData: { - amount: 0, - memo: '', - bolt11: '', - hash: '' - }, - invoiceCheckListener: () => {}, - payInvoiceData: { - // invoice: '', - bolt11: '', - // camera: { - // show: false, - // camera: 'auto' - // } - show: false, - invoice: null, - lnurlpay: null, - lnurlauth: null, - data: { - request: '', - amount: 0, - comment: '' - }, - paymentChecker: null, - camera: { - show: false, - camera: 'auto' - } - }, - sendData: { - amount: 0, - memo: '', - tokens: '', - tokensBase64: '' - }, - receiveData: { - tokensBase64: '' - }, - showInvoiceDetails: false, - showPayInvoice: false, - showSendTokens: false, - showReceiveTokens: false, - promises: [], - tokens: [], - tab: 'tokens', - - receive: { - show: false, - status: 'pending', - paymentReq: null, - paymentHash: null, - minMax: [0, 2100000000000000], - lnurl: null, - units: ['sat'], - unit: 'sat', - data: { - amount: null, - memo: '' - } - }, - parse: { - show: false, - invoice: null, - lnurlpay: null, - lnurlauth: null, - data: { - request: '', - amount: 0, - comment: '' - }, - paymentChecker: null, - camera: { - show: false, - camera: 'auto' - } - }, - payments: [], - invoicesTable: { - columns: [ - { - name: 'status', - align: 'left', - label: '', - field: 'status' - }, - { - name: 'amount', - align: 'left', - label: 'Amount', - field: 'amount' - }, - { - name: 'memo', - align: 'left', - label: 'Memo', - field: 'memo', - sortable: true - }, - { - name: 'date', - align: 'left', - label: 'Date', - field: 'date', - sortable: true - }, - { - name: 'hash', - align: 'right', - label: 'Hash', - field: 'hash', - sortable: true - } - ], - pagination: { - sortBy: 'date', - descending: true, - rowsPerPage: 5 - }, - filter: null - }, - - tokensTable: { - columns: [ - { - name: 'value', - align: 'left', - label: 'Value ({{LNBITS_DENOMINATION}})', - field: 'value', - sortable: true - }, - { - name: 'count', - align: 'left', - label: 'Count', - field: 'count', - sortable: true - }, - { - name: 'sum', - align: 'left', - label: 'Sum ({{LNBITS_DENOMINATION}})', - field: 'sum', - sortable: true - } - // { - // name: 'memo', - // align: 'left', - // label: 'Memo', - // field: 'memo', - // sortable: true - // } - ], - pagination: { - rowsPerPage: 5 - }, - filter: null - }, - - paymentsChart: { - show: false - }, - disclaimerDialog: { - show: false, - location: window.location - }, - - credit: 0, - newName: '' - } - }, - computed: { - formattedBalance: function () { - return this.balance / 100 - }, - - canPay: function () { - if (!this.payInvoiceData.invoice) return false - return this.payInvoiceData.invoice.sat <= this.balance - }, - pendingPaymentsExist: function () { - return this.payments.findIndex(payment => payment.pending) !== -1 - }, - - balance: function () { - return this.proofs - .map(t => t) - .flat() - .reduce((sum, el) => (sum += el.amount), 0) - } - }, - filters: { - msatoshiFormat: function (value) { - return LNbits.utils.formatSat(value / 1000) - } - }, - methods: { - getBalance: function () { - return this.proofs - .map(t => t) - .flat() - .reduce((sum, el) => (sum += el.amount), 0) - }, - getTokenList: function () { - const x = this.proofs - .map(t => t.amount) - .reduce((acc, amount) => { - acc[amount] = acc[amount] + amount || 1 - return acc - }, {}) - return Object.keys(x).map(k => ({ - value: k, - count: x[k], - sum: k * x[k] - })) - }, - - paymentTableRowKey: function (row) { - return row.payment_hash + row.amount - }, - closeCamera: function () { - this.payInvoiceData.camera.show = false - }, - showCamera: function () { - this.payInvoiceData.camera.show = true - }, - showChart: function () { - this.paymentsChart.show = true - this.$nextTick(() => { - generateChart(this.$refs.canvas, this.payments) - }) - }, - focusInput(el) { - this.$nextTick(() => this.$refs[el].focus()) - }, - showReceiveDialog: function () { - this.receive.show = true - this.receive.status = 'pending' - this.receive.paymentReq = null - this.receive.paymentHash = null - this.receive.data.amount = null - this.receive.data.memo = null - this.receive.unit = 'sat' - this.receive.paymentChecker = null - this.receive.minMax = [0, 2100000000000000] - this.receive.lnurl = null - this.focusInput('setAmount') - }, - showParseDialog: function () { - this.payInvoiceData.show = true - this.payInvoiceData.invoice = null - this.payInvoiceData.lnurlpay = null - this.payInvoiceData.lnurlauth = null - this.payInvoiceData.data.request = '' - this.payInvoiceData.data.comment = '' - this.payInvoiceData.data.paymentChecker = null - this.payInvoiceData.camera.show = false - this.focusInput('pasteInput') - }, - showDisclaimerDialog: function () { - this.disclaimerDialog.show = true - }, - - closeReceiveDialog: function () { - setTimeout(() => { - clearInterval(this.receive.paymentChecker) - }, 10000) - }, - closeParseDialog: function () { - setTimeout(() => { - clearInterval(this.payInvoiceData.paymentChecker) - }, 10000) - }, - onPaymentReceived: function (paymentHash) { - this.fetchPayments() - this.fetchBalance() - - if (this.receive.paymentHash === paymentHash) { - this.receive.show = false - this.receive.paymentHash = null - clearInterval(this.receive.paymentChecker) - } - }, - createInvoice: function () { - this.receive.status = 'loading' - if (LNBITS_DENOMINATION != 'sats') { - this.receive.data.amount = this.receive.data.amount * 100 - } - LNbits.api - .createInvoice( - this.receive.data.amount, - this.receive.data.memo, - this.receive.unit, - this.receive.lnurl && this.receive.lnurl.callback - ) - .then(response => { - this.receive.status = 'success' - this.receive.paymentReq = response.data.payment_request - this.receive.paymentHash = response.data.payment_hash - - if (response.data.lnurl_response !== null) { - if (response.data.lnurl_response === false) { - response.data.lnurl_response = `Unable to connect` - } - - if (typeof response.data.lnurl_response === 'string') { - // failure - this.$q.notify({ - timeout: 5000, - type: 'warning', - message: `${this.receive.lnurl.domain} lnurl-withdraw call failed.`, - caption: response.data.lnurl_response - }) - return - } else if (response.data.lnurl_response === true) { - // success - this.$q.notify({ - timeout: 5000, - message: `Invoice sent to ${this.receive.lnurl.domain}!`, - spinner: true - }) - } - } - - clearInterval(this.receive.paymentChecker) - setTimeout(() => { - clearInterval(this.receive.paymentChecker) - }, 40000) - }) - .catch(err => { - LNbits.utils.notifyApiError(err) - this.receive.status = 'pending' - }) - }, - decodeQR: function (res) { - this.payInvoiceData.data.request = res - this.decodeRequest() - this.payInvoiceData.camera.show = false - }, - decodeRequest: function () { - this.payInvoiceData.show = true - let req = this.payInvoiceData.data.request.toLowerCase() - if ( - this.payInvoiceData.data.request.toLowerCase().startsWith('lightning:') - ) { - this.payInvoiceData.data.request = this.payInvoiceData.data.request.slice( - 10 - ) - } else if ( - this.payInvoiceData.data.request.toLowerCase().startsWith('lnurl:') - ) { - this.payInvoiceData.data.request = this.payInvoiceData.data.request.slice( - 6 - ) - } else if (req.indexOf('lightning=lnurl1') !== -1) { - this.payInvoiceData.data.request = this.payInvoiceData.data.request - .split('lightning=')[1] - .split('&')[0] - } - - if ( - this.payInvoiceData.data.request.toLowerCase().startsWith('lnurl1') || - this.payInvoiceData.data.request.match(/[\w.+-~_]+@[\w.+-~_]/) - ) { - return - } - - let invoice - try { - invoice = decode(this.payInvoiceData.data.request) - } catch (error) { - this.$q.notify({ - timeout: 3000, - type: 'warning', - message: error + '.', - caption: '400 BAD REQUEST' - }) - this.payInvoiceData.show = false - throw error - return - } - - let cleanInvoice = { - msat: invoice.human_readable_part.amount, - sat: invoice.human_readable_part.amount / 1000, - fsat: LNbits.utils.formatSat(invoice.human_readable_part.amount / 1000) - } - - _.each(invoice.data.tags, tag => { - if (_.isObject(tag) && _.has(tag, 'description')) { - if (tag.description === 'payment_hash') { - cleanInvoice.hash = tag.value - } else if (tag.description === 'description') { - cleanInvoice.description = tag.value - } else if (tag.description === 'expiry') { - var expireDate = new Date( - (invoice.data.time_stamp + tag.value) * 1000 - ) - cleanInvoice.expireDate = Quasar.utils.date.formatDate( - expireDate, - 'YYYY-MM-DDTHH:mm:ss.SSSZ' - ) - cleanInvoice.expired = false // TODO - } - } - }) - - this.payInvoiceData.invoice = Object.freeze(cleanInvoice) - }, - payInvoice: function () { - let dismissPaymentMsg = this.$q.notify({ - timeout: 0, - message: 'Processing payment...' - }) - }, - payLnurl: function () { - let dismissPaymentMsg = this.$q.notify({ - timeout: 0, - message: 'Processing payment...' - }) - }, - authLnurl: function () { - let dismissAuthMsg = this.$q.notify({ - timeout: 10, - message: 'Performing authentication...' - }) - }, - - deleteWallet: function (walletId, user) { - LNbits.utils - .confirmDialog('Are you sure you want to delete this wallet?') - .onOk(() => { - LNbits.href.deleteWallet(walletId, user) - }) - }, - fetchPayments: function () { - return - }, - fetchBalance: function () {}, - exportCSV: function () { - // status is important for export but it is not in paymentsTable - // because it is manually added with payment detail link and icons - // and would cause duplication in the list - let columns = this.paymentsTable.columns - columns.unshift({ - name: 'pending', - align: 'left', - label: 'Pending', - field: 'pending' - }) - LNbits.utils.exportCSV(columns, this.payments) - }, - - /////////////////////////////////// WALLET /////////////////////////////////// - showInvoicesDialog: async function () { - console.log('##### showInvoicesDialog') - this.invoiceData.amount = 0 - this.invoiceData.bolt11 = '' - this.invoiceData.hash = '' - this.invoiceData.memo = '' - this.showInvoiceDetails = true - }, - - showInvoiceDialog: function (data) { - console.log('##### showInvoiceDialog') - this.invoiceData = _.clone(data) - this.showInvoiceDetails = true - }, - - showPayInvoiceDialog: function () { - console.log('### showPayInvoiceDialog') - this.payInvoiceData.invoice = '' - this.payInvoiceData.data.request = '' - this.showPayInvoice = true - this.payInvoiceData.camera.show = false - }, - - showSendTokensDialog: function () { - this.sendData.tokens = '' - this.sendData.tokensBase64 = '' - this.sendData.amount = 0 - this.sendData.memo = '' - this.showSendTokens = true - }, - - showReceiveTokensDialog: function () { - this.receiveData.tokensBase64 = '' - this.showReceiveTokens = true - }, - - //////////////////////// MINT ////////////////////////////////////////// - requestMintButton: async function () { - await this.requestMint() - console.log('this is your invoice BEFORE') - console.log(this.invoiceData) - this.invoiceCheckListener = setInterval(async () => { - try { - console.log('this is your invoice AFTER') - console.log(this.invoiceData) - await this.recheckInvoice(this.invoiceData.hash, false) - clearInterval(this.invoiceCheckListener) - this.invoiceData.bolt11 = '' - this.showInvoiceDetails = false - navigator.vibrate(200) - this.$q.notify({ - timeout: 5000, - type: 'positive', - message: 'Payment received' - }) - } catch (error) { - console.log('not paid yet') - } - }, 3000) - }, - - requestMint: async function () { - // gets an invoice from the mint to get new tokens - try { - const {data} = await LNbits.api.request( - 'GET', - `/cashu/api/v1/${this.mintId}/mint?amount=${this.invoiceData.amount}` - ) - console.log('### data', data) - - this.invoiceData.bolt11 = data.pr - this.invoiceData.hash = data.hash - this.invoicesCashu.push({ - ..._.clone(this.invoiceData), - date: currentDateStr(), - status: 'pending' - }) - this.storeinvoicesCashu() - this.tab = 'invoices' - return data - } catch (error) { - console.error(error) - LNbits.utils.notifyApiError(error) - throw error - } - }, - mintApi: async function (amounts, payment_hash, verbose = true) { - console.log('### promises', payment_hash) - try { - let secrets = await this.generateSecrets(amounts) - let {blindedMessages, rs} = await this.constructOutputs( - amounts, - secrets - ) - const promises = await LNbits.api.request( - 'POST', - `/cashu/api/v1/${this.mintId}/mint?payment_hash=${payment_hash}`, - '', - { - blinded_messages: blindedMessages - } - ) - console.log('### promises data', promises.data) - let proofs = await this.constructProofs(promises.data, secrets, rs) - return proofs - } catch (error) { - console.error(error) - if (verbose) { - LNbits.utils.notifyApiError(error) - } - throw error - } - }, - mint: async function (amount, payment_hash, verbose = true) { - try { - const split = splitAmount(amount) - const proofs = await this.mintApi(split, payment_hash, verbose) - if (!proofs.length) { - throw 'could not mint' - } - this.proofs = this.proofs.concat(proofs) - this.storeProofs() - await this.setInvoicePaid(payment_hash) - return proofs - } catch (error) { - console.error(error) - if (verbose) { - LNbits.utils.notifyApiError(error) - } - throw error - } - }, - setInvoicePaid: async function (payment_hash) { - const invoice = this.invoicesCashu.find(i => i.hash === payment_hash) - invoice.status = 'paid' - this.storeinvoicesCashu() - }, - recheckInvoice: async function (payment_hash, verbose = true) { - console.log('### recheckInvoice.hash', payment_hash) - const invoice = this.invoicesCashu.find(i => i.hash === payment_hash) - try { - proofs = await this.mint(invoice.amount, invoice.hash, verbose) - return proofs - } catch (error) { - console.log('Invoice still pending') - throw error - } - }, - - generateSecrets: async function (amounts) { - const secrets = [] - for (let i = 0; i < amounts.length; i++) { - const secret = nobleSecp256k1.utils.randomBytes(32) - secrets.push(secret) - } - return secrets - }, - - constructOutputs: async function (amounts, secrets) { - const blindedMessages = [] - const rs = [] - for (let i = 0; i < amounts.length; i++) { - const {B_, r} = await step1Alice(secrets[i]) - blindedMessages.push({amount: amounts[i], B_: B_}) - rs.push(r) - } - return { - blindedMessages, - rs - } - }, - - constructProofs: function (promises, secrets, rs) { - const proofs = [] - for (let i = 0; i < promises.length; i++) { - const encodedSecret = uint8ToBase64.encode(secrets[i]) - let {id, amount, C, secret} = this.promiseToProof( - promises[i].id, - promises[i].amount, - promises[i]['C_'], - encodedSecret, - rs[i] - ) - proofs.push({id, amount, C, secret}) - } - return proofs - }, - - promiseToProof: function (id, amount, C_hex, secret, r) { - const C_ = nobleSecp256k1.Point.fromHex(C_hex) - const A = this.keys[amount] - const C = step3Alice( - C_, - nobleSecp256k1.utils.hexToBytes(r), - nobleSecp256k1.Point.fromHex(A) - ) - return { - id, - amount, - C: C.toHex(true), - secret - } - }, - - sumProofs: function (proofs) { - return proofs.reduce((s, t) => (s += t.amount), 0) - }, - splitToSend: async function (proofs, amount, invlalidate = false) { - // splits proofs so the user can keep firstProofs, send scndProofs - try { - const spendableProofs = proofs.filter(p => !p.reserved) - if (this.sumProofs(spendableProofs) < amount) { - throw new Error('balance too low.') - } - let {fristProofs, scndProofs} = await this.split( - spendableProofs, - amount - ) - - // set scndProofs in this.proofs as reserved - const usedSecrets = proofs.map(p => p.secret) - for (let i = 0; i < this.proofs.length; i++) { - if (usedSecrets.includes(this.proofs[i].secret)) { - this.proofs[i].reserved = true - } - } - if (invlalidate) { - // delete tokens from db - this.proofs = fristProofs - // add new fristProofs, scndProofs to this.proofs - this.storeProofs() - } - - return {fristProofs, scndProofs} - } catch (error) { - console.error(error) - LNbits.utils.notifyApiError(error) - throw error - } - }, - - split: async function (proofs, amount) { - try { - if (proofs.length == 0) { - throw new Error('no proofs provided.') - } - let {fristProofs, scndProofs} = await this.splitApi(proofs, amount) - // delete proofs from this.proofs - const usedSecrets = proofs.map(p => p.secret) - this.proofs = this.proofs.filter(p => !usedSecrets.includes(p.secret)) - // add new fristProofs, scndProofs to this.proofs - this.proofs = this.proofs.concat(fristProofs).concat(scndProofs) - this.storeProofs() - return {fristProofs, scndProofs} - } catch (error) { - console.error(error) - LNbits.utils.notifyApiError(error) - throw error - } - }, - splitApi: async function (proofs, amount) { - try { - const total = this.sumProofs(proofs) - const frst_amount = total - amount - const scnd_amount = amount - const frst_amounts = splitAmount(frst_amount) - const scnd_amounts = splitAmount(scnd_amount) - const amounts = _.clone(frst_amounts) - amounts.push(...scnd_amounts) - let secrets = await this.generateSecrets(amounts) - if (secrets.length != amounts.length) { - throw new Error('number of secrets does not match number of outputs.') - } - let {blindedMessages, rs} = await this.constructOutputs( - amounts, - secrets - ) - const payload = { - amount, - proofs, - outputs: { - blinded_messages: blindedMessages - } - } - - console.log('payload', JSON.stringify(payload)) - - const {data} = await LNbits.api.request( - 'POST', - `/cashu/api/v1/${this.mintId}/split`, - '', - payload - ) - const frst_rs = rs.slice(0, frst_amounts.length) - const frst_secrets = secrets.slice(0, frst_amounts.length) - const scnd_rs = rs.slice(frst_amounts.length) - const scnd_secrets = secrets.slice(frst_amounts.length) - const fristProofs = this.constructProofs( - data.fst, - frst_secrets, - frst_rs - ) - const scndProofs = this.constructProofs(data.snd, scnd_secrets, scnd_rs) - - return {fristProofs, scndProofs} - } catch (error) { - console.error(error) - LNbits.utils.notifyApiError(error) - throw error - } - }, - - redeem: async function () { - this.showReceiveTokens = false - console.log('### receive tokens', this.receiveData.tokensBase64) - try { - if (this.receiveData.tokensBase64.length == 0) { - throw new Error('no tokens provided.') - } - const tokensJson = atob(this.receiveData.tokensBase64) - const proofs = JSON.parse(tokensJson) - const amount = proofs.reduce((s, t) => (s += t.amount), 0) - let {fristProofs, scndProofs} = await this.split(proofs, amount) - // HACK: we need to do this so the balance updates - this.proofs = this.proofs.concat([]) - navigator.vibrate(200) - this.$q.notify({ - timeout: 5000, - type: 'positive', - message: 'Tokens received' - }) - } catch (error) { - console.error(error) - LNbits.utils.notifyApiError(error) - throw error - } - // } - }, - - sendTokens: async function () { - // keep firstProofs, send scndProofs - let {fristProofs, scndProofs} = await this.splitToSend( - this.proofs, - this.sendData.amount, - true - ) - this.sendData.tokens = '' - this.sendData.tokensBase64 = '' - this.sendData.tokens = scndProofs - console.log('### this.sendData.tokens', this.sendData.tokens) - this.sendData.tokensBase64 = btoa(JSON.stringify(this.sendData.tokens)) - navigator.vibrate(200) - }, - checkFees: async function (payment_request) { - const payload = { - pr: payment_request - } - console.log('#### payload', JSON.stringify(payload)) - try { - const {data} = await LNbits.api.request( - 'POST', - `/cashu/api/v1/${this.mintId}/checkfees`, - '', - payload - ) - console.log('#### checkFees', payment_request, data.fee) - return data.fee - } catch (error) { - console.error(error) - LNbits.utils.notifyApiError(error) - throw error - } - }, - melt: async function () { - // todo: get fees from server and add to inputs - console.log('#### pay lightning') - const amount_invoice = this.payInvoiceData.invoice.sat - const amount = - amount_invoice + - (await this.checkFees(this.payInvoiceData.data.request)) - console.log( - '#### amount invoice', - amount_invoice, - 'amount with fees', - amount - ) - // if (amount > balance()) { - // LNbits.utils.notifyApiError('Balance too low') - // return - // } - let {fristProofs, scndProofs} = await this.splitToSend( - this.proofs, - amount - ) - const payload = { - proofs: scndProofs.flat(), - amount, - invoice: this.payInvoiceData.data.request - } - console.log('#### payload', JSON.stringify(payload)) - try { - const {data} = await LNbits.api.request( - 'POST', - `/cashu/api/v1/${this.mintId}/melt`, - '', - payload - ) - navigator.vibrate(200) - this.$q.notify({ - timeout: 5000, - type: 'positive', - message: 'Invoice paid' - }) - // delete tokens from db - this.proofs = fristProofs - // add new fristProofs, scndProofs to this.proofs - this.storeProofs() - console.log({ - amount: -amount, - bolt11: this.payInvoiceData.data.request, - hash: this.payInvoiceData.data.hash, - memo: this.payInvoiceData.data.memo - }) - this.invoicesCashu.push({ - amount: -amount, - bolt11: this.payInvoiceData.data.request, - hash: this.payInvoiceData.data.hash, - memo: this.payInvoiceData.data.memo, - date: currentDateStr(), - status: 'paid' - }) - this.storeinvoicesCashu() - this.tab = 'invoices' - - this.payInvoiceData.invoice = false - this.payInvoiceData.show = false - } catch (error) { - console.error(error) - LNbits.utils.notifyApiError(error) - throw error - } - }, - - recheckPendingInvoices: async function () { - for (const invoice of this.invoicesCashu) { - if (invoice.status === 'pending' && invoice.sat > 0) { - this.recheckInvoice(invoice.hash, false) - } - } - }, - - fetchMintKeys: async function () { - const {data} = await LNbits.api.request( - 'GET', - `/cashu/api/v1/${this.mintId}/keys` - ) - this.keys = data - localStorage.setItem( - this.mintKey(this.mintId, 'keys'), - JSON.stringify(data) - ) - }, - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - findTokenForAmount: function (amount) { - for (const token of this.proofs) { - const index = token.promises?.findIndex(p => p.amount === amount) - if (index >= 0) { - return { - promise: token.promises[index], - secret: token.secrets[index], - r: token.rs[index] - } - } - } - }, - - checkInvoice: function () { - console.log('#### checkInvoice') - try { - const invoice = decode(this.payInvoiceData.data.request) - - const cleanInvoice = { - msat: invoice.human_readable_part.amount, - sat: invoice.human_readable_part.amount / 1000, - fsat: LNbits.utils.formatSat( - invoice.human_readable_part.amount / 1000 - ) - } - - _.each(invoice.data.tags, tag => { - if (_.isObject(tag) && _.has(tag, 'description')) { - if (tag.description === 'payment_hash') { - cleanInvoice.hash = tag.value - } else if (tag.description === 'description') { - cleanInvoice.description = tag.value - } else if (tag.description === 'expiry') { - var expireDate = new Date( - (invoice.data.time_stamp + tag.value) * 1000 - ) - cleanInvoice.expireDate = Quasar.utils.date.formatDate( - expireDate, - 'YYYY-MM-DDTHH:mm:ss.SSSZ' - ) - cleanInvoice.expired = false // TODO - } - } - - this.payInvoiceData.invoice = cleanInvoice - }) - - console.log( - '#### this.payInvoiceData.invoice', - this.payInvoiceData.invoice - ) - } catch (error) { - this.$q.notify({ - timeout: 5000, - type: 'warning', - message: 'Could not decode invoice', - caption: error + '' - }) - throw error - } - }, - - storeinvoicesCashu: function () { - localStorage.setItem( - this.mintKey(this.mintId, 'invoicesCashu'), - JSON.stringify(this.invoicesCashu) - ) - }, - storeProofs: function () { - localStorage.setItem( - this.mintKey(this.mintId, 'proofs'), - JSON.stringify(this.proofs, bigIntStringify) - ) - }, - - mintKey: function (mintId, key) { - // returns a key for the local storage - // depending on the current mint - return 'cashu.' + mintId + '.' + key - } - }, - watch: { - payments: function () { - this.balance() - } - }, - - created: function () { - let params = new URL(document.location).searchParams - - // get mint - if (params.get('mint_id')) { - this.mintId = params.get('mint_id') - this.$q.localStorage.set('cashu.mint', params.get('mint_id')) - } else if (this.$q.localStorage.getItem('cashu.mint')) { - this.mintId = this.$q.localStorage.getItem('cashu.mint') - } else { - this.$q.notify({ - color: 'red', - message: 'No mint set!' - }) - } - - // get name - if (params.get('mint_name')) { - this.mintName = params.get('mint_name') - this.$q.localStorage.set( - this.mintKey(this.mintId, 'mintName'), - this.mintName - ) - } else if (this.$q.localStorage.getItem('cashu.name')) { - this.mintName = this.$q.localStorage.getItem('cashu.name') - } - - // get ticker - if ( - !params.get('tsh') && - !this.$q.localStorage.getItem(this.mintKey(this.mintId, 'tickershort')) - ) { - this.$q.localStorage.set(this.mintKey(this.mintId, 'tickershort'), 'sats') - this.tickershort = 'sats' - } else if (params.get('tsh')) { - this.$q.localStorage.set( - this.mintKey(this.mintId, 'tickershort'), - params.get('tsh') - ) - this.tickershort = params.get('tsh') - } else if ( - this.$q.localStorage.getItem(this.mintKey(this.mintId, 'tickershort')) - ) { - this.tickershort = this.$q.localStorage.getItem( - this.mintKey(this.mintId, 'tickershort') - ) - } - - const keysJson = localStorage.getItem(this.mintKey(this.mintId, 'keys')) - if (!keysJson) { - this.fetchMintKeys() - } else { - this.keys = JSON.parse(keysJson) - } - - this.invoicesCashu = JSON.parse( - localStorage.getItem(this.mintKey(this.mintId, 'invoicesCashu')) || '[]' - ) - this.proofs = JSON.parse( - localStorage.getItem(this.mintKey(this.mintId, 'proofs')) || '[]' - ) - console.log('### invoicesCashu', this.invoicesCashu) - console.table('### tokens', this.proofs) - console.log('#### this.mintId', this.mintId) - console.log('#### this.mintName', this.mintName) - - this.recheckPendingInvoices() - } -}) diff --git a/lnbits/extensions/cashu/templates/cashu/wallet.html b/lnbits/extensions/cashu/templates/cashu/wallet.html index 7ec994372..88af72caf 100644 --- a/lnbits/extensions/cashu/templates/cashu/wallet.html +++ b/lnbits/extensions/cashu/templates/cashu/wallet.html @@ -625,5 +625,1107 @@ - + {% endblock %}