doesnt work yet
This commit is contained in:
parent
da61ade4d0
commit
5ecf198f2c
|
@ -71,7 +71,7 @@ page_container %}
|
||||||
|
|
||||||
<q-tabs v-model="tab" no-caps class="bg-dark text-white shadow-2">
|
<q-tabs v-model="tab" no-caps class="bg-dark text-white shadow-2">
|
||||||
<q-tab name="tokens" label="Tokens"></q-tab>
|
<q-tab name="tokens" label="Tokens"></q-tab>
|
||||||
<q-tab name="orders" label="Orders"></q-tab>
|
<q-tab name="invoices" label="Invoices"></q-tab>
|
||||||
<q-tab name="history" label="History"></q-tab>
|
<q-tab name="history" label="History"></q-tab>
|
||||||
</q-tabs>
|
</q-tabs>
|
||||||
<q-tab-panels v-model="tab">
|
<q-tab-panels v-model="tab">
|
||||||
|
@ -109,7 +109,7 @@ page_container %}
|
||||||
{% endraw %}
|
{% endraw %}
|
||||||
</q-table>
|
</q-table>
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="orders">
|
<q-tab-panel name="invoices">
|
||||||
<q-table
|
<q-table
|
||||||
dense
|
dense
|
||||||
flat
|
flat
|
||||||
|
@ -219,16 +219,17 @@ page_container %}
|
||||||
<div v-if="!invoiceData.bolt11">
|
<div v-if="!invoiceData.bolt11">
|
||||||
<div class="row items-center no-wrap q-mb-sm">
|
<div class="row items-center no-wrap q-mb-sm">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<span class="text-subtitle1"
|
<span class="text-subtitle1">Create a Lightning invoice</span>
|
||||||
>How much would you like to buy?</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model.number="invoiceData.amount"
|
v-model.number="invoiceData.amount"
|
||||||
label="Amount (sats) *"
|
label="Amount ({{LNBITS_DENOMINATION}}) *"
|
||||||
|
mask="#.##"
|
||||||
|
fill-mask="0"
|
||||||
|
reverse-fill-mask
|
||||||
type="number"
|
type="number"
|
||||||
class="q-mb-lg"
|
class="q-mb-lg"
|
||||||
></q-input>
|
></q-input>
|
||||||
|
@ -260,7 +261,7 @@ page_container %}
|
||||||
color="grey"
|
color="grey"
|
||||||
>Copy invoice</q-btn
|
>Copy invoice</q-btn
|
||||||
>
|
>
|
||||||
<q-btn v-else outline color="grey" @click="requestInvoice"
|
<q-btn v-else outline color="grey" @click="requestMint"
|
||||||
>Request Invoice</q-btn
|
>Request Invoice</q-btn
|
||||||
>
|
>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||||
|
@ -309,10 +310,10 @@ page_container %}
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn
|
<q-btn
|
||||||
v-if="!sendData.tokens"
|
v-if="!sendData.tokens"
|
||||||
@click="buildAndShowTokens"
|
@click="sendTokens"
|
||||||
outline
|
outline
|
||||||
color="grey"
|
color="grey"
|
||||||
>Show Tokens</q-btn
|
>Send Tokens</q-btn
|
||||||
>
|
>
|
||||||
<q-btn v-else @click="burnTokens" outline color="grey"
|
<q-btn v-else @click="burnTokens" outline color="grey"
|
||||||
>Burn Tokens</q-btn
|
>Burn Tokens</q-btn
|
||||||
|
@ -344,8 +345,8 @@ page_container %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn @click="acceptTokens" outline color="grey"
|
<q-btn @click="receiveTokens" outline color="grey"
|
||||||
>Accept Tokens</q-btn
|
>Receive Tokens</q-btn
|
||||||
>
|
>
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||||
>Close</q-btn
|
>Close</q-btn
|
||||||
|
@ -356,7 +357,7 @@ page_container %}
|
||||||
|
|
||||||
<q-dialog v-model="showPayInvoice" position="top">
|
<q-dialog v-model="showPayInvoice" position="top">
|
||||||
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
<q-card class="q-pa-lg q-pt-xl lnbits__dialog-card">
|
||||||
<div v-if="!sellData.invoice">
|
<div v-if="!payInvoiceData.invoice">
|
||||||
<div class="row items-center no-wrap q-mb-sm">
|
<div class="row items-center no-wrap q-mb-sm">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<span class="text-subtitle1"
|
<span class="text-subtitle1"
|
||||||
|
@ -367,7 +368,7 @@ page_container %}
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
v-model="sellData.bolt11"
|
v-model="payInvoiceData.bolt11"
|
||||||
label="Paste invoice"
|
label="Paste invoice"
|
||||||
type="textarea"
|
type="textarea"
|
||||||
class="q-mb-lg"
|
class="q-mb-lg"
|
||||||
|
@ -375,24 +376,25 @@ page_container %}
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="q-mb-lg">
|
<div v-else class="q-mb-lg">
|
||||||
{% raw %}
|
{% raw %}
|
||||||
<strong>Amount:</strong> {{ sellData.invoice.sat }}
|
<strong>Amount:</strong> {{ payInvoiceData.invoice.sat }}
|
||||||
<strong>sats</strong><br />
|
<strong>sats</strong><br />
|
||||||
<strong>Description:</strong> {{ sellData.invoice.description }}<br />
|
<strong>Description:</strong> {{ payInvoiceData.invoice.description
|
||||||
<strong>Expire date:</strong> {{ sellData.invoice.expireDate }}<br />
|
}}<br />
|
||||||
<strong>Expired:</strong> {{ sellData.invoice.expired }}<br />
|
<strong>Expire date:</strong> {{ payInvoiceData.invoice.expireDate
|
||||||
<strong>Hash:</strong> {{ sellData.invoice.hash }} {% endraw %}
|
}}<br />
|
||||||
|
<strong>Expired:</strong> {{ payInvoiceData.invoice.expired }}<br />
|
||||||
|
<strong>Hash:</strong> {{ payInvoiceData.invoice.hash }} {% endraw
|
||||||
|
%}
|
||||||
</div>
|
</div>
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn
|
<q-btn
|
||||||
v-if="!sellData.invoice"
|
v-if="!payInvoiceData.invoice"
|
||||||
@click="checkInvoice"
|
@click="checkInvoice"
|
||||||
outline
|
outline
|
||||||
color="grey"
|
color="grey"
|
||||||
>Check Invoice</q-btn
|
>Check Invoice</q-btn
|
||||||
>
|
>
|
||||||
<q-btn v-else outline color="grey" @click="sellTokens"
|
<q-btn v-else outline color="grey" @click="melt">Pay invoice</q-btn>
|
||||||
>Sell Token</q-btn
|
|
||||||
>
|
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||||
>Close</q-btn
|
>Close</q-btn
|
||||||
>
|
>
|
||||||
|
@ -458,7 +460,7 @@ page_container %}
|
||||||
bolt11: '',
|
bolt11: '',
|
||||||
hash: ''
|
hash: ''
|
||||||
},
|
},
|
||||||
sellData: {
|
payInvoiceData: {
|
||||||
invoice: '',
|
invoice: '',
|
||||||
bolt11: ''
|
bolt11: ''
|
||||||
},
|
},
|
||||||
|
@ -475,6 +477,7 @@ page_container %}
|
||||||
showPayInvoice: false,
|
showPayInvoice: false,
|
||||||
showSendTokens: false,
|
showSendTokens: false,
|
||||||
showReceiveTokens: false,
|
showReceiveTokens: false,
|
||||||
|
promises: [],
|
||||||
tokens: [],
|
tokens: [],
|
||||||
tab: 'tokens',
|
tab: 'tokens',
|
||||||
|
|
||||||
|
@ -614,7 +617,7 @@ page_container %}
|
||||||
},
|
},
|
||||||
|
|
||||||
tokenList: function () {
|
tokenList: function () {
|
||||||
const x = this.tokens
|
const x = this.proofs
|
||||||
.filter(t => t.promises?.length)
|
.filter(t => t.promises?.length)
|
||||||
.map(t => t.blindedMessages)
|
.map(t => t.blindedMessages)
|
||||||
.flat()
|
.flat()
|
||||||
|
@ -636,7 +639,7 @@ page_container %}
|
||||||
},
|
},
|
||||||
|
|
||||||
balance: function () {
|
balance: function () {
|
||||||
return this.tokens
|
return this.proofs
|
||||||
.filter(t => t.promises?.length)
|
.filter(t => t.promises?.length)
|
||||||
.map(t => t.blindedMessages)
|
.map(t => t.blindedMessages)
|
||||||
.flat()
|
.flat()
|
||||||
|
@ -891,8 +894,8 @@ page_container %}
|
||||||
|
|
||||||
showPayInvoiceDialog: function () {
|
showPayInvoiceDialog: function () {
|
||||||
console.log('### showPayInvoiceDialog')
|
console.log('### showPayInvoiceDialog')
|
||||||
this.sellData.invoice = ''
|
this.payInvoiceData.invoice = ''
|
||||||
this.sellData.bolt11 = ''
|
this.payInvoiceData.bolt11 = ''
|
||||||
this.showPayInvoice = true
|
this.showPayInvoice = true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -909,31 +912,6 @@ page_container %}
|
||||||
this.showReceiveTokens = true
|
this.showReceiveTokens = true
|
||||||
},
|
},
|
||||||
|
|
||||||
requestInvoice: async function () {
|
|
||||||
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()
|
|
||||||
const amounts = splitAmount(this.invoiceData.amount)
|
|
||||||
await this.requestTokens(amounts, this.invoiceData.hash)
|
|
||||||
this.tab = 'orders'
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
checkXXXXXX: async function () {
|
checkXXXXXX: async function () {
|
||||||
for (const invoice of this.invoicesCashu) {
|
for (const invoice of this.invoicesCashu) {
|
||||||
if (invoice.status === 'pending') {
|
if (invoice.status === 'pending') {
|
||||||
|
@ -955,24 +933,72 @@ page_container %}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
recheckInvoice: async function (hash) {
|
//////////////////////// MINT //////////////////////////////////////////
|
||||||
console.log('### recheckInvoice.hash', hash)
|
|
||||||
const tokens = this.tokens.find(bt => bt.hash === hash)
|
|
||||||
console.log('### recheckInvoice.tokens', tokens)
|
|
||||||
if (!tokens) {
|
|
||||||
console.error('####### no token for hash', hash)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const promises = await this.fetchPromisesFromMint(
|
|
||||||
hash,
|
|
||||||
tokens.blindedMessages
|
|
||||||
)
|
|
||||||
if (promises && promises.length) {
|
|
||||||
tokens.promises = promises
|
|
||||||
tokens.status = 'paid'
|
|
||||||
this.storeTokens()
|
|
||||||
|
|
||||||
const invoice = this.invoicesCashu.find(bo => bo.hash === hash)
|
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)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mintApi: async function (amounts, payment_hash) {
|
||||||
|
console.log('### promises', payment_hash)
|
||||||
|
try {
|
||||||
|
let secrets = generateSecrets(amounts)
|
||||||
|
let {blinded_messages, rs} = constructOutputs(amounts, secrets)
|
||||||
|
const {promises} = await LNbits.api.request(
|
||||||
|
'POST',
|
||||||
|
`/cashu/api/v1/${this.mintId}/mint?payment_hash=${payment_hash}`,
|
||||||
|
'',
|
||||||
|
{
|
||||||
|
blinded_messages: blinded_messages
|
||||||
|
}
|
||||||
|
)
|
||||||
|
console.log('### promises data', promises)
|
||||||
|
return promises
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mint: async function (amount, payment_hash) {
|
||||||
|
try {
|
||||||
|
const split = splitAmount(amount)
|
||||||
|
const proofs = await mintApi(split, payment_hash)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
LNbits.utils.notifyApiError(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
recheckInvoice: async function (payment_hash) {
|
||||||
|
console.log('### recheckInvoice.hash', payment_hash)
|
||||||
|
const invoice = this.invoicesCashu.find(i => i.hash === payment_hash)
|
||||||
|
const amounts = splitAmount(invoice.amount)
|
||||||
|
const newTokens = await this.buildTokens(amounts, payment_hash)
|
||||||
|
const promises = await this.mint(invoice.amount, payment_hash)
|
||||||
|
if (promises && promises.length) {
|
||||||
|
newTokens.promises = promises
|
||||||
|
newTokens.status = 'paid'
|
||||||
|
this.proofs.push(newTokens)
|
||||||
|
this.storeProofs()
|
||||||
invoice.status = 'paid'
|
invoice.status = 'paid'
|
||||||
this.storeinvoicesCashu()
|
this.storeinvoicesCashu()
|
||||||
}
|
}
|
||||||
|
@ -980,56 +1006,116 @@ page_container %}
|
||||||
|
|
||||||
requestTokens: async function (amounts, paymentHash) {
|
requestTokens: async function (amounts, paymentHash) {
|
||||||
const newTokens = await this.buildTokens(amounts, paymentHash)
|
const newTokens = await this.buildTokens(amounts, paymentHash)
|
||||||
this.tokens.push(newTokens)
|
// this.proofs.push(newTokens)
|
||||||
this.storeTokens()
|
// this.storeProofs()
|
||||||
console.log('### this.tokens', this.tokens)
|
// console.log('### this.proofs', this.proofs)
|
||||||
// await this.fetchPromisesFromMint(paymentHash, newTokens.newTokens)
|
// await this.mint(paymentHash, newTokens.newTokens)
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchPromisesFromMint: async function (hash, blindedMessages) {
|
generateSecrets: async function (amounts) {
|
||||||
console.log('### promises', hash, blindedMessages)
|
const secrets = []
|
||||||
try {
|
for (let i = 0; i < amounts.length; i++) {
|
||||||
const {data} = await LNbits.api.request(
|
const secret = nobleSecp256k1.utils.randomBytes(32)
|
||||||
'POST',
|
secrets.push(encodedSecret)
|
||||||
`/cashu/api/v1/${this.mintId}/mint?payment_hash=${hash}`,
|
|
||||||
'',
|
|
||||||
{
|
|
||||||
blinded_messages: blindedMessages
|
|
||||||
}
|
}
|
||||||
|
return secrets
|
||||||
|
},
|
||||||
|
constructOutputs: async function (amounts, secrets) {
|
||||||
|
const blindedMessages = []
|
||||||
|
const randomBlindingFactors = []
|
||||||
|
for (let i = 0; i < amounts.length; i++) {
|
||||||
|
const {B_, r} = await step1Bob(secret)
|
||||||
|
blindedMessages.push(B_)
|
||||||
|
randomBlindingFactors.push(r)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
blindedMessages,
|
||||||
|
randomBlindingFactors
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
constructProofs: function (promises, secrets, rs) {
|
||||||
|
const proofs = []
|
||||||
|
for (let i = 0; i < promises.length; i++) {
|
||||||
|
let {amount, C, secret} = promiseToProof(
|
||||||
|
promises[i].amount,
|
||||||
|
promises[i]['C_'],
|
||||||
|
promises[i].secret,
|
||||||
|
promises[i].randomBlindingFactor
|
||||||
)
|
)
|
||||||
console.log('### promises data', data)
|
|
||||||
return data
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
}
|
}
|
||||||
|
return proofs
|
||||||
},
|
},
|
||||||
|
|
||||||
buildAndShowTokens: async function () {
|
promiseToProof: function (amount, C_hex, secret, randomBlindingFactor) {
|
||||||
|
const C_ = nobleSecp256k1.Point.fromHex(C_hex)
|
||||||
|
const A = this.keys[amount]
|
||||||
|
const C = step3Bob(
|
||||||
|
C_,
|
||||||
|
randomBlindingFactor,
|
||||||
|
nobleSecp256k1.Point.fromHex(A)
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
amount,
|
||||||
|
C: C.toHex(true),
|
||||||
|
secret
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buildTokens: async function (amounts, paymentHash) {
|
||||||
|
const blindedMessages = []
|
||||||
|
const secrets = []
|
||||||
|
const randomBlindingFactors = []
|
||||||
|
for (let i = 0; i < amounts.length; i++) {
|
||||||
|
const secret = nobleSecp256k1.utils.randomBytes(32)
|
||||||
|
// const secret = nobleSecp256k1.utils.hexToBytes('0000000000000000000000000000000000000000000000000000000000000003')
|
||||||
|
// todo: base64Url
|
||||||
|
const encodedSecret = uint8ToBase64.encode(secret)
|
||||||
|
secrets.push(encodedSecret)
|
||||||
|
const {B_, randomBlindingFactor} = await step1Bob(secret)
|
||||||
|
randomBlindingFactors.push(randomBlindingFactor)
|
||||||
|
blindedMessages.push({amount: amounts[i], B_: B_})
|
||||||
|
}
|
||||||
|
|
||||||
|
const newTokens = {
|
||||||
|
hash: paymentHash,
|
||||||
|
blindedMessages,
|
||||||
|
randomBlindingFactors,
|
||||||
|
secrets,
|
||||||
|
status: 'pending'
|
||||||
|
}
|
||||||
|
return newTokens
|
||||||
|
},
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
sendTokens: async function () {
|
||||||
const amounts = splitAmount(this.sendData.amount)
|
const amounts = splitAmount(this.sendData.amount)
|
||||||
const sendTokens = []
|
const sendTokens = []
|
||||||
for (const amount of amounts) {
|
sendTokens.push(this.proofs)
|
||||||
const token = this.findTokenForAmount(amount)
|
// for (const amount of amounts) {
|
||||||
if (token) {
|
// const token = this.findTokenForAmount(amount)
|
||||||
sendTokens.push(token)
|
// if (token) {
|
||||||
} else {
|
// sendTokens.push(token)
|
||||||
this.$q.notify({
|
// } else {
|
||||||
timeout: 5000,
|
// this.$q.notify({
|
||||||
type: 'warning',
|
// timeout: 5000,
|
||||||
message: `Cannot select amount for denomination ${amount}`
|
// type: 'warning',
|
||||||
})
|
// message: `Cannot select amount for denomination ${amount}`
|
||||||
|
// })
|
||||||
|
// this.sendData.tokens = ''
|
||||||
|
// this.sendData.tokensBase64 = ''
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// }
|
||||||
this.sendData.tokens = ''
|
this.sendData.tokens = ''
|
||||||
this.sendData.tokensBase64 = ''
|
this.sendData.tokensBase64 = ''
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log('### sendTokens', sendTokens)
|
console.log('### sendTokens', sendTokens)
|
||||||
this.sendData.tokens = sendTokens.map(t => {
|
this.sendData.tokens = sendTokens.map((token, tokenIndex) => {
|
||||||
return this.promiseToProof(
|
return this.promiseToProof(
|
||||||
t.promise.amount,
|
token.promises[tokenIndex].amount,
|
||||||
t.promise['C_'],
|
token.promises[tokenIndex]['C_'],
|
||||||
t.secret,
|
token.promises[tokenIndex].secret,
|
||||||
t.randomBlindingFactor
|
token.promises[tokenIndex].randomBlindingFactor
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
console.log('### this.sendData.tokens', this.sendData.tokens)
|
console.log('### this.sendData.tokens', this.sendData.tokens)
|
||||||
|
@ -1038,7 +1124,7 @@ page_container %}
|
||||||
|
|
||||||
burnTokens: function () {
|
burnTokens: function () {
|
||||||
for (const sentToken of this.sendData.tokens) {
|
for (const sentToken of this.sendData.tokens) {
|
||||||
for (const token of this.tokens) {
|
for (const token of this.proofs) {
|
||||||
if (token.status === 'paid') {
|
if (token.status === 'paid') {
|
||||||
const secretIndex = token.secrets.findIndex(
|
const secretIndex = token.secrets.findIndex(
|
||||||
s => s === sentToken.secret
|
s => s === sentToken.secret
|
||||||
|
@ -1058,12 +1144,12 @@ page_container %}
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
message: 'Tokens burned'
|
message: 'Tokens burned'
|
||||||
})
|
})
|
||||||
this.storeTokens()
|
this.storeProofs()
|
||||||
this.showSendTokens = false
|
this.showSendTokens = false
|
||||||
console.log('### this.tokens', this.tokens)
|
console.log('### this.proofs', this.proofs)
|
||||||
},
|
},
|
||||||
|
|
||||||
acceptTokens: async function () {
|
receiveTokens: async function () {
|
||||||
this.showReceiveTokens = false
|
this.showReceiveTokens = false
|
||||||
console.log('### receive tokens', this.receiveData.tokensBase64)
|
console.log('### receive tokens', this.receiveData.tokensBase64)
|
||||||
if (this.receiveData.tokensBase64) {
|
if (this.receiveData.tokensBase64) {
|
||||||
|
@ -1097,8 +1183,8 @@ page_container %}
|
||||||
// Object.assign(newTokens[i], promises)
|
// Object.assign(newTokens[i], promises)
|
||||||
// }
|
// }
|
||||||
console.log('newTokens 2', newTokens)
|
console.log('newTokens 2', newTokens)
|
||||||
this.tokens.push(newTokens)
|
this.proofs.push(newTokens)
|
||||||
this.storeTokens()
|
this.storeProofs()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
LNbits.utils.notifyApiError(error)
|
LNbits.utils.notifyApiError(error)
|
||||||
|
@ -1107,7 +1193,7 @@ page_container %}
|
||||||
},
|
},
|
||||||
|
|
||||||
findTokenForAmount: function (amount) {
|
findTokenForAmount: function (amount) {
|
||||||
for (const token of this.tokens) {
|
for (const token of this.proofs) {
|
||||||
const index = token.promises?.findIndex(p => p.amount === amount)
|
const index = token.promises?.findIndex(p => p.amount === amount)
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
return {
|
return {
|
||||||
|
@ -1119,37 +1205,10 @@ page_container %}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
constructProof: function (token) {},
|
|
||||||
|
|
||||||
buildTokens: async function (amounts, paymentHash) {
|
|
||||||
const blindedMessages = []
|
|
||||||
const secrets = []
|
|
||||||
const randomBlindingFactors = []
|
|
||||||
for (let i = 0; i < amounts.length; i++) {
|
|
||||||
const secret = nobleSecp256k1.utils.randomBytes(32)
|
|
||||||
// const secret = nobleSecp256k1.utils.hexToBytes('0000000000000000000000000000000000000000000000000000000000000003')
|
|
||||||
// todo: base64Url
|
|
||||||
const encodedSecret = uint8ToBase64.encode(secret)
|
|
||||||
secrets.push(encodedSecret)
|
|
||||||
const {B_, randomBlindingFactor} = await step1Bob(secret)
|
|
||||||
randomBlindingFactors.push(randomBlindingFactor)
|
|
||||||
blindedMessages.push({amount: amounts[i], B_: B_})
|
|
||||||
}
|
|
||||||
|
|
||||||
const newTokens = {
|
|
||||||
hash: paymentHash,
|
|
||||||
blindedMessages,
|
|
||||||
randomBlindingFactors,
|
|
||||||
secrets,
|
|
||||||
status: 'pending'
|
|
||||||
}
|
|
||||||
return newTokens
|
|
||||||
},
|
|
||||||
|
|
||||||
checkInvoice: function () {
|
checkInvoice: function () {
|
||||||
console.log('#### checkInvoice')
|
console.log('#### checkInvoice')
|
||||||
try {
|
try {
|
||||||
const invoice = decode(this.sellData.bolt11)
|
const invoice = decode(this.payInvoiceData.bolt11)
|
||||||
|
|
||||||
const cleanInvoice = {
|
const cleanInvoice = {
|
||||||
msat: invoice.human_readable_part.amount,
|
msat: invoice.human_readable_part.amount,
|
||||||
|
@ -1177,10 +1236,13 @@ page_container %}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sellData.invoice = cleanInvoice
|
this.payInvoiceData.invoice = cleanInvoice
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('#### this.sellData.invoice', this.sellData.invoice)
|
console.log(
|
||||||
|
'#### this.payInvoiceData.invoice',
|
||||||
|
this.payInvoiceData.invoice
|
||||||
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.$q.notify({
|
this.$q.notify({
|
||||||
timeout: 5000,
|
timeout: 5000,
|
||||||
|
@ -1191,10 +1253,10 @@ page_container %}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
sellTokens: async function () {
|
melt: async function () {
|
||||||
console.log('#### sell tokens')
|
console.log('#### sell tokens')
|
||||||
const amount = this.sellData.invoice.sat
|
const amount = this.payInvoiceData.invoice.sat
|
||||||
const paidTokens = this.tokens.filter(t => t.promises?.length)
|
const paidTokens = this.proofs.filter(t => t.promises?.length)
|
||||||
console.log('### paidTokens', paidTokens)
|
console.log('### paidTokens', paidTokens)
|
||||||
const proofs = paidTokens.map(token => {
|
const proofs = paidTokens.map(token => {
|
||||||
return token.promises.map((promise, promiseIndex) => {
|
return token.promises.map((promise, promiseIndex) => {
|
||||||
|
@ -1215,7 +1277,7 @@ page_container %}
|
||||||
const payload = {
|
const payload = {
|
||||||
proofs: proofs.flat(),
|
proofs: proofs.flat(),
|
||||||
amount,
|
amount,
|
||||||
invoice: this.sellData.bolt11
|
invoice: this.payInvoiceData.bolt11
|
||||||
}
|
}
|
||||||
console.log('#### payload', JSON.stringify(payload))
|
console.log('#### payload', JSON.stringify(payload))
|
||||||
try {
|
try {
|
||||||
|
@ -1237,22 +1299,6 @@ page_container %}
|
||||||
|
|
||||||
// C_hex = promise['C_']
|
// C_hex = promise['C_']
|
||||||
// amount = promise.amount
|
// amount = promise.amount
|
||||||
promiseToProof: function (amount, C_hex, secret, randomBlindingFactor) {
|
|
||||||
const C_ = nobleSecp256k1.Point.fromHex(C_hex)
|
|
||||||
const A = this.keys[amount]
|
|
||||||
|
|
||||||
const C = step3Bob(
|
|
||||||
C_,
|
|
||||||
randomBlindingFactor,
|
|
||||||
nobleSecp256k1.Point.fromHex(A)
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
|
||||||
amount,
|
|
||||||
secret,
|
|
||||||
C: C.toHex(true)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
fetchMintKeys: async function () {
|
fetchMintKeys: async function () {
|
||||||
const {data} = await LNbits.api.request(
|
const {data} = await LNbits.api.request(
|
||||||
|
@ -1269,10 +1315,10 @@ page_container %}
|
||||||
JSON.stringify(this.invoicesCashu)
|
JSON.stringify(this.invoicesCashu)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
storeTokens: function () {
|
storeProofs: function () {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
'cashu.tokens',
|
'cashu.proofs',
|
||||||
JSON.stringify(this.tokens, bigIntStringify)
|
JSON.stringify(this.proofs, bigIntStringify)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1330,9 +1376,9 @@ page_container %}
|
||||||
this.invoicesCashu = JSON.parse(
|
this.invoicesCashu = JSON.parse(
|
||||||
localStorage.getItem('cashu.invoicesCashu') || '[]'
|
localStorage.getItem('cashu.invoicesCashu') || '[]'
|
||||||
)
|
)
|
||||||
this.tokens = JSON.parse(localStorage.getItem('cashu.tokens') || '[]')
|
this.proofs = JSON.parse(localStorage.getItem('cashu.proofs') || '[]')
|
||||||
console.log('### invoicesCashu', this.invoicesCashu)
|
console.log('### invoicesCashu', this.invoicesCashu)
|
||||||
console.table('### tokens', this.tokens)
|
console.table('### tokens', this.proofs)
|
||||||
console.log('#### this.mintId', this.mintId)
|
console.log('#### this.mintId', this.mintId)
|
||||||
console.log('#### this.mintName', this.mintName)
|
console.log('#### this.mintName', this.mintName)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user