diff --git a/cashu/core/base.py b/cashu/core/base.py index 072d2a8e..9ac14185 100644 --- a/cashu/core/base.py +++ b/cashu/core/base.py @@ -101,12 +101,12 @@ class Proof(BaseModel): time_created: Union[None, str] = "" time_reserved: Union[None, str] = "" derivation_path: Union[None, str] = "" # derivation path of the proof - mint_id: Union[ - None, str - ] = None # holds the id of the mint operation that created this proof - melt_id: Union[ - None, str - ] = None # holds the id of the melt operation that destroyed this proof + mint_id: Union[None, str] = ( + None # holds the id of the mint operation that created this proof + ) + melt_id: Union[None, str] = ( + None # holds the id of the melt operation that destroyed this proof + ) def __init__(self, **data): super().__init__(**data) @@ -194,6 +194,15 @@ class BlindedSignature(BaseModel): C_: str # Hex-encoded signature dleq: Optional[DLEQ] = None # DLEQ proof + @classmethod + def from_row(cls, row: Row): + return cls( + id=row["id"], + amount=row["amount"], + C_=row["C_"], + dleq=DLEQ(e=row["e"], s=row["s"]), + ) + class BlindedMessages(BaseModel): # NOTE: not used in Pydantic validation diff --git a/cashu/core/errors.py b/cashu/core/errors.py index d36614a4..c843028d 100644 --- a/cashu/core/errors.py +++ b/cashu/core/errors.py @@ -63,7 +63,8 @@ class KeysetNotFoundError(KeysetError): detail = "keyset not found" code = 12001 - def __init__(self): + def __init__(self, keyset_id: Optional[str] = None): + self.detail = f"keyset {keyset_id} not found" super().__init__(self.detail, code=self.code) diff --git a/cashu/mint/crud.py b/cashu/mint/crud.py index 5169236a..234e5f9e 100644 --- a/cashu/mint/crud.py +++ b/cashu/mint/crud.py @@ -243,7 +243,7 @@ async def store_promise( await (conn or db).execute( f""" INSERT INTO {table_with_schema(db, 'promises')} - (amount, B_b, C_b, e, s, id, created) + (amount, B_, C_, e, s, id, created) VALUES (?, ?, ?, ?, ?, ?, ?) """, ( @@ -267,11 +267,11 @@ async def get_promise( row = await (conn or db).fetchone( f""" SELECT * from {table_with_schema(db, 'promises')} - WHERE B_b = ? + WHERE B_ = ? """, (str(B_),), ) - return BlindedSignature(amount=row[0], C_=row[2], id=row[3]) if row else None + return BlindedSignature.from_row(row) if row else None async def get_spent_proofs( self, diff --git a/cashu/mint/migrations.py b/cashu/mint/migrations.py index 14fc5ab1..f46f48a5 100644 --- a/cashu/mint/migrations.py +++ b/cashu/mint/migrations.py @@ -690,8 +690,8 @@ async def m017_foreign_keys_proof_tables(db: Database): CREATE TABLE IF NOT EXISTS {table_with_schema(db, 'promises_new')} ( amount INTEGER NOT NULL, id TEXT, - B_b TEXT NOT NULL, - C_b TEXT NOT NULL, + B_ TEXT NOT NULL, + C_ TEXT NOT NULL, e TEXT, s TEXT, created TIMESTAMP, @@ -700,13 +700,13 @@ async def m017_foreign_keys_proof_tables(db: Database): FOREIGN KEY (mint_quote) REFERENCES {table_with_schema(db, 'mint_quotes')}(quote), - UNIQUE (B_b) + UNIQUE (B_) ); """ ) await conn.execute( - f"INSERT INTO {table_with_schema(db, 'promises_new')} (amount, id, B_b, C_b, id, e, s, created) SELECT amount, id, B_b, C_b, id, e, s, created FROM {table_with_schema(db, 'promises')}" + f"INSERT INTO {table_with_schema(db, 'promises_new')} (amount, id, B_, C_, id, e, s, created) SELECT amount, id, B_b, C_b, id, e, s, created FROM {table_with_schema(db, 'promises')}" ) await conn.execute(f"DROP TABLE {table_with_schema(db, 'promises')}") await conn.execute( diff --git a/cashu/mint/router.py b/cashu/mint/router.py index cd7b6cf8..c055bf6f 100644 --- a/cashu/mint/router.py +++ b/cashu/mint/router.py @@ -25,7 +25,7 @@ PostSplitRequest, PostSplitResponse, ) -from ..core.errors import CashuError +from ..core.errors import KeysetNotFoundError from ..core.settings import settings from ..mint.startup import ledger from .limit import limiter @@ -142,7 +142,7 @@ async def keyset_keys(keyset_id: str) -> KeysResponse: keyset = ledger.keysets.get(keyset_id) if keyset is None: - raise CashuError(code=0, detail="keyset not found") + raise KeysetNotFoundError(keyset_id) keyset_for_response = KeysResponseKeyset( id=keyset.id, diff --git a/tests/test_wallet_restore.py b/tests/test_wallet_restore.py index 7670b5c2..9064235d 100644 --- a/tests/test_wallet_restore.py +++ b/tests/test_wallet_restore.py @@ -172,6 +172,11 @@ async def test_restore_wallet_after_mint(wallet3: Wallet): await wallet3.restore_promises_from_to(0, 20) assert wallet3.balance == 64 + # expect that DLEQ proofs are restored + assert all([p.dleq for p in wallet3.proofs]) + assert all([p.dleq.e for p in wallet3.proofs]) # type: ignore + assert all([p.dleq.s for p in wallet3.proofs]) # type: ignore + @pytest.mark.asyncio async def test_restore_wallet_with_invalid_mnemonic(wallet3: Wallet):