feat: sell fixed amount token

This commit is contained in:
Vlad Stan 2022-10-11 13:51:35 +03:00 committed by dni ⚡
parent 0a9503b557
commit d8be5d7b7c
4 changed files with 72 additions and 75 deletions

View file

@ -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(

View file

@ -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:

View file

@ -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) {
return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
}
const uint8ToBase64 = (function (exports) {
'use strict'
var fromCharCode = String.fromCharCode
var encode = function encode(uint8array) {
var output = []
for (var i = 0, length = uint8array.length; i < length; i++) {
output.push(fromCharCode(uint8array[i]))
}
return btoa(output.join(''))
} }
function escapeBase64Url (str) { var asCharCode = function asCharCode(c) {
return str.replace(/\+/g, '-') return c.charCodeAt(0)
.replace(/\//g, '_')
.replace(/=/g, '')
} }
const uint8ToBase64 = (function (exports) { var decode = function decode(chars) {
'use strict'; return Uint8Array.from(atob(chars), asCharCode)
}
var fromCharCode = String.fromCharCode; exports.decode = decode
var encode = function encode(uint8array) { exports.encode = encode
var output = [];
for (var i = 0, length = uint8array.length; i < length; i++) { return exports
output.push(fromCharCode(uint8array[i])); })({})
}
return btoa(output.join(''));
};
var asCharCode = function asCharCode(c) {
return c.charCodeAt(0);
};
var decode = function decode(chars) {
return Uint8Array.from(atob(chars), asCharCode);
};
exports.decode = decode;
exports.encode = encode;
return exports;
}({}));

View file

@ -787,7 +787,7 @@ page_container %}
const secret = nobleSecp256k1.utils.randomBytes(32) const secret = nobleSecp256k1.utils.randomBytes(32)
// const secret = nobleSecp256k1.utils.hexToBytes('0000000000000000000000000000000000000000000000000000000000000003') // const secret = nobleSecp256k1.utils.hexToBytes('0000000000000000000000000000000000000000000000000000000000000003')
// todo: base64Url // todo: base64Url
const encodedSecret = uint8ToBase64.encode(secret) const encodedSecret = uint8ToBase64.encode(secret)
secrets.push(encodedSecret) secrets.push(encodedSecret)
const {B_, randomBlindingFactor} = await step1Bob(secret) const {B_, randomBlindingFactor} = await step1Bob(secret)
randomBlindingFactors.push(randomBlindingFactor) randomBlindingFactors.push(randomBlindingFactor)
@ -852,47 +852,45 @@ 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
console.log('#### C_', C_) console.log('#### C_', C_)
console.log('#### A', A) console.log('#### A', A)
const C = step3Bob( const C = step3Bob(
C_, C_,
randomBlindingFactor, randomBlindingFactor,
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 () {