show used locks

This commit is contained in:
callebtc
2022-10-03 01:31:48 +02:00
parent cd89321561
commit 1b43966544
4 changed files with 106 additions and 15 deletions

View File

@@ -7,6 +7,16 @@ from pydantic import BaseModel
class P2SHScript(BaseModel):
script: str
signature: str
address: str = None
@classmethod
def from_row(cls, row: Row):
return cls(
address=row[0],
script=row[1],
signature=row[2],
used=row[3],
)
class Proof(BaseModel):

View File

@@ -12,7 +12,6 @@ from itertools import groupby
from operator import itemgetter
import click
from bech32 import bech32_decode, bech32_encode, convertbits
from loguru import logger
import cashu.core.bolt11 as bolt11
@@ -20,10 +19,9 @@ from cashu.core.base import Proof
from cashu.core.bolt11 import Invoice
from cashu.core.helpers import fee_reserve
from cashu.core.migrations import migrate_databases
from cashu.core.script import *
from cashu.core.settings import CASHU_DIR, DEBUG, LIGHTNING, MINT_URL, VERSION, ENV_FILE
from cashu.wallet import migrations
from cashu.wallet.crud import get_reserved_proofs
from cashu.wallet.crud import get_reserved_proofs, get_unused_locks
from cashu.wallet.wallet import Wallet as Wallet
@@ -235,10 +233,11 @@ async def pay(ctx, invoice: str):
@click.pass_context
@coro
async def lock(ctx):
alice_privkey = step0_carol_privkey()
txin_redeemScript = step0_carol_checksig_redeemscrip(alice_privkey.pub)
txin_p2sh_address = step1_carol_create_p2sh_address(txin_redeemScript)
# print("Redeem script:", txin_redeemScript.__repr__())
wallet: Wallet = ctx.obj["WALLET"]
p2shscript = await wallet.create_p2sh_lock()
txin_p2sh_address = p2shscript.address
txin_redeemScript_b64 = p2shscript.script
txin_signature_b64 = p2shscript.signature
print("---- Pay to script hash (P2SH) ----\n")
print("Use a lock to receive coins that only you can unlock.")
print("")
@@ -248,10 +247,6 @@ async def lock(ctx):
f"Send coins to this lock:\n\ncashu send <amount> --lock P2SH:{txin_p2sh_address}"
)
print("")
txin_signature = step2_carol_sign_tx(txin_redeemScript, alice_privkey).scriptSig
txin_redeemScript_b64 = base64.urlsafe_b64encode(txin_redeemScript).decode()
txin_signature_b64 = base64.urlsafe_b64encode(txin_signature).decode()
print(
"!!! The command below is private. Do not share. You have to remember it. Do not lose. !!!\n"
)
@@ -260,6 +255,26 @@ async def lock(ctx):
)
@cli.command("locks", help="Show all receiving locks.")
@click.pass_context
@coro
async def locks(ctx):
wallet: Wallet = ctx.obj["WALLET"]
locks = await get_unused_locks(db=wallet.db)
if len(locks):
print("")
print(f"--------------------------\n")
for l in locks:
print(f"Address: {l.address}")
print(f"Script: {l.script}")
print(f"Signature: {l.signature}")
print("")
print(f"Receive: cashu receive <coin> --unlock {l.script}:{l.signature}")
print("")
print(f"--------------------------\n")
return True
@cli.command("info", help="Information about Cashu wallet.")
@click.pass_context
@coro

View File

@@ -1,7 +1,7 @@
import time
from typing import Optional
from cashu.core.base import Proof
from cashu.core.base import Proof, P2SHScript
from cashu.core.db import Connection, Database
@@ -113,3 +113,50 @@ async def secret_used(
(secret),
)
return rows is not None
async def store_p2sh(
p2sh: P2SHScript,
db: Database,
conn: Optional[Connection] = None,
):
await (conn or db).execute(
"""
INSERT INTO p2sh
(address, script, signature, used)
VALUES (?, ?, ?, ?)
""",
(p2sh.address, p2sh.script, p2sh.signature, False),
)
async def get_unused_locks(
db: Database,
conn: Optional[Connection] = None,
):
rows = await (conn or db).fetchall(
"""
SELECT * from p2sh
WHERE used = 0
"""
)
return [P2SHScript.from_row(r) for r in rows]
async def update_p2sh_used(
p2sh: P2SHScript,
used: bool,
db: Database = None,
conn: Optional[Connection] = None,
):
clauses = []
values = []
clauses.append("used = ?")
values.append(used)
await (conn or db).execute(
f"UPDATE proofs SET {', '.join(clauses)} WHERE address = ?",
(*values, str(p2sh.address)),
)

View File

@@ -18,6 +18,12 @@ from cashu.core.base import (
Proof,
SplitPayload,
)
from cashu.core.script import (
step0_carol_privkey,
step0_carol_checksig_redeemscrip,
step1_carol_create_p2sh_address,
step2_carol_sign_tx,
)
from cashu.core.db import Database
from cashu.core.secp import PublicKey
from cashu.core.settings import DEBUG
@@ -28,6 +34,7 @@ from cashu.wallet.crud import (
secret_used,
store_proof,
update_proof_reserved,
store_p2sh,
)
@@ -194,9 +201,6 @@ class LedgerAPI:
return fst_proofs, snd_proofs
async def create_p2sh_lock(self, secrets: List[str]):
return None
async def check_spendable(self, proofs: List[Proof]):
payload = CheckPayload(proofs=proofs)
return_dict = requests.post(
@@ -334,6 +338,21 @@ class Wallet(LedgerAPI):
filter(lambda p: p["secret"] not in invalidate_secrets, self.proofs)
)
async def create_p2sh_lock(self):
alice_privkey = step0_carol_privkey()
txin_redeemScript = step0_carol_checksig_redeemscrip(alice_privkey.pub)
txin_p2sh_address = step1_carol_create_p2sh_address(txin_redeemScript)
txin_signature = step2_carol_sign_tx(txin_redeemScript, alice_privkey).scriptSig
txin_redeemScript_b64 = base64.urlsafe_b64encode(txin_redeemScript).decode()
txin_signature_b64 = base64.urlsafe_b64encode(txin_signature).decode()
p2shScript = P2SHScript(
script=txin_redeemScript_b64,
signature=txin_signature_b64,
address=str(txin_p2sh_address),
)
await store_p2sh(p2shScript, db=self.db)
return p2shScript
@property
def balance(self):
return sum(p["amount"] for p in self.proofs)