Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove P2SH #341

Merged
merged 3 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions cashu/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,8 @@ class Proof(BaseModel):
secret: str = "" # secret or message to be blinded and signed
C: str = "" # signature on secret, unblinded by wallet
dleq: Union[DLEQWallet, None] = None # DLEQ proof

witness: Union[None, str] = "" # witness for spending condition
# p2pksigs: Union[List[str], None] = [] # P2PK signature
# p2shscript: Union[P2SHWitness, None] = None # P2SH spending condition
# htlcpreimage: Union[str, None] = None # HTLC unlocking preimage
# htlcsignature: Union[str, None] = None # HTLC unlocking signature

# whether this proof is reserved for sending, used for coin management in the wallet
reserved: Union[None, bool] = False
# unique ID of send attempt, used for grouping pending tokens in the wallet
Expand Down
168 changes: 0 additions & 168 deletions cashu/core/script.py

This file was deleted.

1 change: 0 additions & 1 deletion cashu/core/secret.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@


class SecretKind:
P2SH = "P2SH"
P2PK = "P2PK"
HTLC = "HTLC"

Expand Down
33 changes: 1 addition & 32 deletions cashu/mint/conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,55 +15,24 @@
SigFlags,
verify_p2pk_signature,
)
from ..core.script import verify_bitcoin_script
from ..core.secret import Secret, SecretKind


class LedgerSpendingConditions:
def _verify_input_spending_conditions(self, proof: Proof) -> bool:
"""
Verify spending conditions:
Condition: P2SH - Witnesses proof.p2shscript
Condition: P2PK - Witness: proof.p2pksigs
Condition: HTLC - Witness: proof.htlcpreimage, proof.htlcsignature
"""
# P2SH

try:
secret = Secret.deserialize(proof.secret)
logger.trace(f"proof.secret: {proof.secret}")
logger.trace(f"secret: {secret}")
except Exception:
# secret is not a spending condition so we treat is a normal secret
return True
if secret.kind == SecretKind.P2SH:
p2pk_secret = P2PKSecret.from_secret(secret)
# check if locktime is in the past
now = time.time()
if p2pk_secret.locktime and p2pk_secret.locktime < now:
logger.trace(f"p2sh locktime ran out ({p2pk_secret.locktime}<{now}).")
return True
logger.trace(f"p2sh locktime still active ({p2pk_secret.locktime}>{now}).")

if (
proof.p2shscript is None
or proof.p2shscript.script is None
or proof.p2shscript.signature is None
):
# no script present although secret indicates one
raise TransactionError("no script in proof.")

# execute and verify P2SH
txin_p2sh_address, valid = verify_bitcoin_script(
proof.p2shscript.script, proof.p2shscript.signature
)
if not valid:
raise TransactionError("script invalid.")
# check if secret commits to script address
assert secret.data == str(txin_p2sh_address), (
f"secret does not contain correct P2SH address: {secret.data} is not"
f" {txin_p2sh_address}."
)
return True

# P2PK
if secret.kind == SecretKind.P2PK:
Expand Down
6 changes: 3 additions & 3 deletions cashu/wallet/api/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from pydantic import BaseModel

from ...core.base import Invoice, P2SHWitness
from ...core.base import Invoice


class PayResponse(BaseModel):
Expand Down Expand Up @@ -50,11 +50,11 @@ class PendingResponse(BaseModel):


class LockResponse(BaseModel):
P2SH: Optional[str]
P2PK: Optional[str]


class LocksResponse(BaseModel):
locks: List[P2SHWitness]
locks: List[str]


class InvoicesResponse(BaseModel):
Expand Down
12 changes: 6 additions & 6 deletions cashu/wallet/api/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from ...core.settings import settings
from ...nostr.nostr.client.client import NostrClient
from ...tor.tor import TorProxy
from ...wallet.crud import get_lightning_invoices, get_reserved_proofs, get_unused_locks
from ...wallet.crud import get_lightning_invoices, get_reserved_proofs
from ...wallet.helpers import (
deserialize_token_from_string,
init_wallet,
Expand Down Expand Up @@ -213,7 +213,7 @@ async def balance():
async def send_command(
amount: int = Query(default=..., description="Amount to send"),
nostr: str = Query(default=None, description="Send to nostr pubkey"),
lock: str = Query(default=None, description="Lock tokens (P2SH)"),
lock: str = Query(default=None, description="Lock tokens (P2PK)"),
mint: str = Query(
default=None,
description="Mint URL to send from (None for default mint)",
Expand Down Expand Up @@ -354,14 +354,14 @@ async def pending(

@router.get("/lock", name="Generate receiving lock", response_model=LockResponse)
async def lock():
address = await wallet.create_p2sh_address_and_store()
return LockResponse(P2SH=address)
pubkey = await wallet.create_p2pk_pubkey()
return LockResponse(P2PK=pubkey)


@router.get("/locks", name="Show unused receiving locks", response_model=LocksResponse)
async def locks():
locks = await get_unused_locks(db=wallet.db)
return LocksResponse(locks=locks)
pubkey = await wallet.create_p2pk_pubkey()
return LocksResponse(locks=[pubkey])


@router.get(
Expand Down
38 changes: 6 additions & 32 deletions cashu/wallet/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
get_lightning_invoices,
get_reserved_proofs,
get_seed_and_mnemonic,
get_unused_locks,
)
from ...wallet.wallet import Wallet as Wallet
from ..api.api_server import start_api_server
Expand Down Expand Up @@ -351,7 +350,7 @@ async def balance(ctx: Context, verbose):
help="Send to nostr pubkey.",
type=str,
)
@click.option("--lock", "-l", default=None, help="Lock tokens (P2SH).", type=str)
@click.option("--lock", "-l", default=None, help="Lock tokens (P2PK).", type=str)
@click.option(
"--dleq",
"-d",
Expand Down Expand Up @@ -583,26 +582,14 @@ async def pending(ctx: Context, legacy, number: int, offset: int):


@cli.command("lock", help="Generate receiving lock.")
@click.option(
"--p2sh",
"-p",
default=False,
is_flag=True,
help="Create P2SH lock.",
type=bool,
)
@click.pass_context
@coro
async def lock(ctx, p2sh):
async def lock(ctx):
wallet: Wallet = ctx.obj["WALLET"]
if p2sh:
address = await wallet.create_p2sh_address_and_store()
lock_str = f"P2SH:{address}"
print("---- Pay to script hash (P2SH) ----\n")
else:
pubkey = await wallet.create_p2pk_pubkey()
lock_str = f"P2PK:{pubkey}"
print("---- Pay to public key (P2PK) ----\n")

pubkey = await wallet.create_p2pk_pubkey()
lock_str = f"P2PK:{pubkey}"
print("---- Pay to public key (P2PK) ----\n")

print("Use a lock to receive tokens that only you can unlock.")
print("")
Expand All @@ -626,19 +613,6 @@ async def locks(ctx):
print("---- Pay to public key (P2PK) lock ----\n")
print(f"Lock: {lock_str}")
print("")
print("To see more information enter: cashu lock")
# P2SH locks
locks = await get_unused_locks(db=wallet.db)
if len(locks):
print("")
print("---- Pay to script hash (P2SH) locks ----\n")
for lock in locks:
print(f"Lock: P2SH:{lock.address}")
print(f"Script: {lock.script}")
print(f"Signature: {lock.signature}")
print("")
print("--------------------------\n")

return True


Expand Down
Loading
Loading