mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-21 11:04:19 +01:00
show used locks
This commit is contained in:
@@ -7,6 +7,16 @@ from pydantic import BaseModel
|
|||||||
class P2SHScript(BaseModel):
|
class P2SHScript(BaseModel):
|
||||||
script: str
|
script: str
|
||||||
signature: 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):
|
class Proof(BaseModel):
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from itertools import groupby
|
|||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
import click
|
import click
|
||||||
from bech32 import bech32_decode, bech32_encode, convertbits
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
import cashu.core.bolt11 as bolt11
|
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.bolt11 import Invoice
|
||||||
from cashu.core.helpers import fee_reserve
|
from cashu.core.helpers import fee_reserve
|
||||||
from cashu.core.migrations import migrate_databases
|
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.core.settings import CASHU_DIR, DEBUG, LIGHTNING, MINT_URL, VERSION, ENV_FILE
|
||||||
from cashu.wallet import migrations
|
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
|
from cashu.wallet.wallet import Wallet as Wallet
|
||||||
|
|
||||||
|
|
||||||
@@ -235,10 +233,11 @@ async def pay(ctx, invoice: str):
|
|||||||
@click.pass_context
|
@click.pass_context
|
||||||
@coro
|
@coro
|
||||||
async def lock(ctx):
|
async def lock(ctx):
|
||||||
alice_privkey = step0_carol_privkey()
|
wallet: Wallet = ctx.obj["WALLET"]
|
||||||
txin_redeemScript = step0_carol_checksig_redeemscrip(alice_privkey.pub)
|
p2shscript = await wallet.create_p2sh_lock()
|
||||||
txin_p2sh_address = step1_carol_create_p2sh_address(txin_redeemScript)
|
txin_p2sh_address = p2shscript.address
|
||||||
# print("Redeem script:", txin_redeemScript.__repr__())
|
txin_redeemScript_b64 = p2shscript.script
|
||||||
|
txin_signature_b64 = p2shscript.signature
|
||||||
print("---- Pay to script hash (P2SH) ----\n")
|
print("---- Pay to script hash (P2SH) ----\n")
|
||||||
print("Use a lock to receive coins that only you can unlock.")
|
print("Use a lock to receive coins that only you can unlock.")
|
||||||
print("")
|
print("")
|
||||||
@@ -248,10 +247,6 @@ async def lock(ctx):
|
|||||||
f"Send coins to this lock:\n\ncashu send <amount> --lock P2SH:{txin_p2sh_address}"
|
f"Send coins to this lock:\n\ncashu send <amount> --lock P2SH:{txin_p2sh_address}"
|
||||||
)
|
)
|
||||||
print("")
|
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(
|
print(
|
||||||
"!!! The command below is private. Do not share. You have to remember it. Do not lose. !!!\n"
|
"!!! 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.")
|
@cli.command("info", help="Information about Cashu wallet.")
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
@coro
|
@coro
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import time
|
import time
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from cashu.core.base import Proof
|
from cashu.core.base import Proof, P2SHScript
|
||||||
from cashu.core.db import Connection, Database
|
from cashu.core.db import Connection, Database
|
||||||
|
|
||||||
|
|
||||||
@@ -113,3 +113,50 @@ async def secret_used(
|
|||||||
(secret),
|
(secret),
|
||||||
)
|
)
|
||||||
return rows is not None
|
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)),
|
||||||
|
)
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ from cashu.core.base import (
|
|||||||
Proof,
|
Proof,
|
||||||
SplitPayload,
|
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.db import Database
|
||||||
from cashu.core.secp import PublicKey
|
from cashu.core.secp import PublicKey
|
||||||
from cashu.core.settings import DEBUG
|
from cashu.core.settings import DEBUG
|
||||||
@@ -28,6 +34,7 @@ from cashu.wallet.crud import (
|
|||||||
secret_used,
|
secret_used,
|
||||||
store_proof,
|
store_proof,
|
||||||
update_proof_reserved,
|
update_proof_reserved,
|
||||||
|
store_p2sh,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -194,9 +201,6 @@ class LedgerAPI:
|
|||||||
|
|
||||||
return fst_proofs, snd_proofs
|
return fst_proofs, snd_proofs
|
||||||
|
|
||||||
async def create_p2sh_lock(self, secrets: List[str]):
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def check_spendable(self, proofs: List[Proof]):
|
async def check_spendable(self, proofs: List[Proof]):
|
||||||
payload = CheckPayload(proofs=proofs)
|
payload = CheckPayload(proofs=proofs)
|
||||||
return_dict = requests.post(
|
return_dict = requests.post(
|
||||||
@@ -334,6 +338,21 @@ class Wallet(LedgerAPI):
|
|||||||
filter(lambda p: p["secret"] not in invalidate_secrets, self.proofs)
|
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
|
@property
|
||||||
def balance(self):
|
def balance(self):
|
||||||
return sum(p["amount"] for p in self.proofs)
|
return sum(p["amount"] for p in self.proofs)
|
||||||
|
|||||||
Reference in New Issue
Block a user