feat: sell fixed amount token
This commit is contained in:
parent
0a9503b557
commit
d8be5d7b7c
4 changed files with 72 additions and 75 deletions
|
|
@ -71,7 +71,7 @@ async def melt(cashu: Cashu, proofs: List[Proof], invoice: str):
|
||||||
|
|
||||||
fees_msat = await check_fees(cashu.wallet, invoice_obj)
|
fees_msat = await check_fees(cashu.wallet, invoice_obj)
|
||||||
assert total_provided >= amount + fees_msat / 1000, Exception(
|
assert total_provided >= amount + fees_msat / 1000, Exception(
|
||||||
"provided proofs not enough for Lightning payment."
|
f"Provided proofs (${total_provided} sats) not enough for Lightning payment ({amount + fees_msat} sats)."
|
||||||
)
|
)
|
||||||
|
|
||||||
await pay_invoice(
|
await pay_invoice(
|
||||||
|
|
|
||||||
|
|
@ -33,20 +33,22 @@ def derive_pubkeys(keys: List[PrivateKey]):
|
||||||
# async required?
|
# async required?
|
||||||
async def verify_proof(master_prvkey: str, proofs_used: Set[str], proof: Proof):
|
async def verify_proof(master_prvkey: str, proofs_used: Set[str], proof: Proof):
|
||||||
"""Verifies that the proof of promise was issued by this ledger."""
|
"""Verifies that the proof of promise was issued by this ledger."""
|
||||||
# if proof.secret in proofs_used:
|
if proof.secret in proofs_used:
|
||||||
# raise Exception(f"tokens already spent. Secret: {proof.secret}")
|
raise Exception(f"tokens already spent. Secret: {proof.secret}")
|
||||||
|
|
||||||
secret_key = derive_keys(master_prvkey)[
|
secret_key = derive_keys(master_prvkey)[
|
||||||
proof.amount
|
proof.amount
|
||||||
] # Get the correct key to check against
|
] # Get the correct key to check against
|
||||||
C = PublicKey(bytes.fromhex(proof.C), raw=True)
|
C = PublicKey(bytes.fromhex(proof.C), raw=True)
|
||||||
secret = base64.urlsafe_b64decode(proof.secret)
|
secret = base64.standard_b64decode(proof.secret)
|
||||||
print('### secret', secret)
|
print('### secret', secret)
|
||||||
validMintSig = verify(secret_key, C, secret)
|
validMintSig = verify(secret_key, C, secret)
|
||||||
if validMintSig != True:
|
if validMintSig != True:
|
||||||
raise Exception(f"tokens not valid. Secret: {proof.secret}")
|
raise Exception(f"tokens not valid. Secret: {proof.secret}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def verify_split_amount(amount: int):
|
def verify_split_amount(amount: int):
|
||||||
"""Split amount like output amount can't be negative or too big."""
|
"""Split amount like output amount can't be negative or too big."""
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,37 @@
|
||||||
function unescapeBase64Url (str) {
|
function unescapeBase64Url(str) {
|
||||||
return (str + '==='.slice((str.length + 3) % 4))
|
return (str + '==='.slice((str.length + 3) % 4))
|
||||||
.replace(/-/g, '+')
|
.replace(/-/g, '+')
|
||||||
.replace(/_/g, '/')
|
.replace(/_/g, '/')
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeBase64Url (str) {
|
function escapeBase64Url(str) {
|
||||||
return str.replace(/\+/g, '-')
|
return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
|
||||||
.replace(/\//g, '_')
|
}
|
||||||
.replace(/=/g, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8ToBase64 = (function (exports) {
|
const uint8ToBase64 = (function (exports) {
|
||||||
'use strict';
|
'use strict'
|
||||||
|
|
||||||
var fromCharCode = String.fromCharCode;
|
var fromCharCode = String.fromCharCode
|
||||||
var encode = function encode(uint8array) {
|
var encode = function encode(uint8array) {
|
||||||
var output = [];
|
var output = []
|
||||||
|
|
||||||
for (var i = 0, length = uint8array.length; i < length; i++) {
|
for (var i = 0, length = uint8array.length; i < length; i++) {
|
||||||
output.push(fromCharCode(uint8array[i]));
|
output.push(fromCharCode(uint8array[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
return btoa(output.join(''));
|
return btoa(output.join(''))
|
||||||
};
|
}
|
||||||
|
|
||||||
var asCharCode = function asCharCode(c) {
|
var asCharCode = function asCharCode(c) {
|
||||||
return c.charCodeAt(0);
|
return c.charCodeAt(0)
|
||||||
};
|
}
|
||||||
|
|
||||||
var decode = function decode(chars) {
|
var decode = function decode(chars) {
|
||||||
return Uint8Array.from(atob(chars), asCharCode);
|
return Uint8Array.from(atob(chars), asCharCode)
|
||||||
};
|
}
|
||||||
|
|
||||||
exports.decode = decode;
|
exports.decode = decode
|
||||||
exports.encode = encode;
|
exports.encode = encode
|
||||||
|
|
||||||
return exports;
|
return exports
|
||||||
|
})({})
|
||||||
}({}));
|
|
||||||
|
|
|
||||||
|
|
@ -852,19 +852,19 @@ page_container %}
|
||||||
sellTokens: async function () {
|
sellTokens: async function () {
|
||||||
console.log('#### sell tokens')
|
console.log('#### sell tokens')
|
||||||
const amount = this.sellData.invoice.sat
|
const amount = this.sellData.invoice.sat
|
||||||
const token = this.tokens
|
const paidTokens = this.tokens.filter(t => t.promises?.length)
|
||||||
.filter(t => t.promises?.length)
|
console.log('### paidTokens', paidTokens)
|
||||||
.find(t => t.promises.find(b => b.amount === amount))
|
const proofs = paidTokens.map(token => {
|
||||||
console.log('### token', token)
|
// const promiseIndex = token.promises
|
||||||
if (token) {
|
// .map(p => `${p.amount}`)
|
||||||
const promiseIndex = token.promises
|
// .indexOf(`${amount}`)
|
||||||
.map(p => `${p.amount}`)
|
return token.promises.map((promise, promiseIndex) => {
|
||||||
.indexOf(`${amount}`)
|
// const promise = token.promises[promiseIndex]
|
||||||
const promise = token.promises[promiseIndex]
|
|
||||||
console.log('### promise', promise)
|
console.log('### promise', promise)
|
||||||
|
|
||||||
const secret = token.secrets[promiseIndex]
|
const secret = token.secrets[promiseIndex]
|
||||||
const randomBlindingFactor = token.randomBlindingFactors[promiseIndex]
|
const randomBlindingFactor =
|
||||||
|
token.randomBlindingFactors[promiseIndex]
|
||||||
|
|
||||||
const C_ = nobleSecp256k1.Point.fromHex(promise['C_'])
|
const C_ = nobleSecp256k1.Point.fromHex(promise['C_'])
|
||||||
const A = this.keys[promise.amount] // todo
|
const A = this.keys[promise.amount] // todo
|
||||||
|
|
@ -878,21 +878,19 @@ page_container %}
|
||||||
nobleSecp256k1.Point.fromHex(A)
|
nobleSecp256k1.Point.fromHex(A)
|
||||||
)
|
)
|
||||||
|
|
||||||
const proofs = [
|
return {
|
||||||
{
|
amount: promise.amount,
|
||||||
amount,
|
|
||||||
secret,
|
secret,
|
||||||
C: C.toHex(true)
|
C: C.toHex(true)
|
||||||
}
|
}
|
||||||
]
|
})
|
||||||
|
})
|
||||||
const payload = {
|
const payload = {
|
||||||
proofs,
|
proofs: proofs.flat(),
|
||||||
amount,
|
amount,
|
||||||
invoice: this.sellData.bolt11
|
invoice: this.sellData.bolt11
|
||||||
}
|
}
|
||||||
console.log('#### payload', JSON.stringify(payload))
|
console.log('#### payload', JSON.stringify(payload))
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchMintKeys: async function () {
|
fetchMintKeys: async function () {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue