From 46c5ef298d119fc2c1af32804fad6ec67e49d0b1 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Sun, 2 Oct 2022 22:05:09 +0200 Subject: [PATCH] multiple sends to address through random secret --- cashu/mint/ledger.py | 36 +++++++++++++++----------- cashu/wallet/cli.py | 52 +++++++++++++++++++++++-------------- cashu/wallet/wallet.py | 59 +++++++++++++++++++++++------------------- 3 files changed, 87 insertions(+), 60 deletions(-) diff --git a/cashu/mint/ledger.py b/cashu/mint/ledger.py index 452020c..797618d 100644 --- a/cashu/mint/ledger.py +++ b/cashu/mint/ledger.py @@ -16,9 +16,14 @@ from cashu.core.secp import PrivateKey, PublicKey from cashu.core.settings import LIGHTNING, MAX_ORDER from cashu.core.split import amount_split from cashu.lightning import WALLET -from cashu.mint.crud import (get_lightning_invoice, get_proofs_used, - invalidate_proof, store_lightning_invoice, - store_promise, update_lightning_invoice) +from cashu.mint.crud import ( + get_lightning_invoice, + get_proofs_used, + invalidate_proof, + store_lightning_invoice, + store_promise, + update_lightning_invoice, +) class Ledger: @@ -104,19 +109,20 @@ class Ledger: txin_p2sh_address, valid = verify_script( proof.script.script, proof.script.signature ) - # if len(proof.script) < 16: - # raise Exception("Script error: not long enough.") - # if ( - # hashlib.sha256(proof.script.encode("utf-8")).hexdigest() - # != proof.secret.split("P2SH:")[1] - # ): - # raise Exception("Script error: script hash not valid.") - print( - f"Script {proof.script.script.__repr__()} {'valid' if valid else 'invalid'}." - ) if valid: - print(f"{idx}:P2SH:{txin_p2sh_address}") - proof.secret = f"{idx}:P2SH:{txin_p2sh_address}" + # check if secret commits to script address + # format: P2SH:
: + assert len(proof.secret.split(":")) == 3, "secret format wrong" + assert proof.secret.split(":")[1] == str( + txin_p2sh_address + ), f"secret does not contain P2SH address: {proof.secret.split(':')[1]}!={txin_p2sh_address}" + # print( + # f"Script {proof.script.script.__repr__()} {'valid' if valid else 'invalid'}." + # ) + # if valid: + # print(f"{idx}:P2SH:{txin_p2sh_address}") + # print("proof.secret", proof.secret) + # proof.secret = f"{idx}:P2SH:{txin_p2sh_address}" return valid def _verify_outputs( diff --git a/cashu/wallet/cli.py b/cashu/wallet/cli.py index 66979d8..7ab0468 100755 --- a/cashu/wallet/cli.py +++ b/cashu/wallet/cli.py @@ -101,22 +101,23 @@ async def balance(ctx): @cli.command("send", help="Send tokens.") @click.argument("amount", type=int) -@click.option( - "--secret", "-s", default=None, help="Token spending condition.", type=str -) +@click.option("--lock", "-l", default=None, help="Token lock (P2SH address).", type=str) @click.pass_context @coro -async def send(ctx, amount: int, secret: str): - if secret and len(secret) < 22: - print("Error: secret has to be at least 22 characters long.") +async def send(ctx, amount: int, lock: str): + if lock and len(lock) < 22: + print("Error: lock has to be at least 22 characters long.") return + p2sh = False + if len(lock.split("P2SH:")) == 2: + p2sh = True wallet: Wallet = ctx.obj["WALLET"] wallet.load_mint() wallet.status() - _, send_proofs = await wallet.split_to_send(wallet.proofs, amount, secret) + _, send_proofs = await wallet.split_to_send(wallet.proofs, amount, lock) await wallet.set_reserved(send_proofs, reserved=True) token = await wallet.serialize_proofs( - send_proofs, hide_secrets=True if secret else False + send_proofs, hide_secrets=True if lock and not p2sh else False ) print(token) wallet.status() @@ -124,19 +125,23 @@ async def send(ctx, amount: int, secret: str): @cli.command("receive", help="Receive tokens.") @click.argument("token", type=str) -@click.option("--secret", "-s", default=None, help="Token secret.", type=str) -@click.option("--script", default=None, help="Unlock script.", type=str) -@click.option("--signature", default=None, help="Script signature.", type=str) +# @click.option("--secret", "-s", default=None, help="Token secret.", type=str) +@click.option("--unlock", "-u", default=None, help="Unlock script.", type=str) +# @click.option("--signature", default=None, help="Script signature.", type=str) @click.pass_context @coro -async def receive(ctx, token: str, secret: str, script: str, signature: str): +async def receive(ctx, token: str, unlock: str): wallet: Wallet = ctx.obj["WALLET"] wallet.load_mint() wallet.status() + if unlock: + assert ( + len(unlock.split(":")) == 2 + ), "unlock format wrong, expected