mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-23 19:54:18 +01:00
Determinstic secrets / ecash restore (#131)
* first working version but some sats go missing * back at it * make format * restore to main * move mint database * fix some tests * make format * remove old _construct_outputs we reintroduced in merge with main * add type annotations * add wallet private key to tests * wallet: load proofs * fix tests * _generate_secrets with deterministic generation (temporary) * allow wallet initialization with custom private key * add pk to wallet api test * mint scope=module * remove private_key from test_wallet.py to see if it helps with the github tests * readd private keys to tests * workflow without env * add more private key! * readd env * ledger scope session * add default private key for testing * generate private keys if not available * testing * its working!!! * first iteration of bip32 working * get mint info and add many type annotations * tests * fix tests with bip32 * restore from multiple mints * disable profiler * make format * failed POST /mint do not increment secret counter * store derivation path in each token * fix tests * refactor migrations so private keys can be generated by the wallet with .with_db() classmethod * start fixing tests * all tests passing except those that need to set a specific private key * bip39 mnemonic to seed - with db but restore doesnt work yet with custom seed * mnemonic restore works * enter mnemonic in cli * fix tests to use different mnemonic * properly ask user for seed input * tests: dont ask for inputs * try to fix tests * fix cashu -d * fixing * bump version and add more text to mnemonic enter * add more comments * add many more comments and type annotations in the wallet * dont print generated mnemonic and dont wait for input * fix test * does this fix tests? * sigh.... * make format * do not restore from an initialized wallet * fix mnemonics * fix nitpicks * print wallet name if nonstandard wallet * fix merge error and remove comments * poetry lock and requirements * remove unused code * fix tests * mnemonic.lower() and add keyset id if not present for backwards compat * edit comment
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import json
|
||||
import time
|
||||
from typing import Any, List, Optional
|
||||
from typing import Any, List, Optional, Tuple
|
||||
|
||||
from ..core.base import Invoice, KeyBase, P2SHScript, Proof, WalletKeyset
|
||||
from ..core.db import Connection, Database
|
||||
@@ -14,10 +14,17 @@ async def store_proof(
|
||||
await (conn or db).execute(
|
||||
"""
|
||||
INSERT INTO proofs
|
||||
(id, amount, C, secret, time_created)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
(id, amount, C, secret, time_created, derivation_path)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(proof.id, proof.amount, str(proof.C), str(proof.secret), int(time.time())),
|
||||
(
|
||||
proof.id,
|
||||
proof.amount,
|
||||
str(proof.C),
|
||||
str(proof.secret),
|
||||
int(time.time()),
|
||||
proof.derivation_path,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -62,10 +69,17 @@ async def invalidate_proof(
|
||||
await (conn or db).execute(
|
||||
"""
|
||||
INSERT INTO proofs_used
|
||||
(amount, C, secret, time_used, id)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
(amount, C, secret, time_used, id, derivation_path)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(proof.amount, str(proof.C), str(proof.secret), int(time.time()), proof.id),
|
||||
(
|
||||
proof.amount,
|
||||
str(proof.C),
|
||||
str(proof.secret),
|
||||
int(time.time()),
|
||||
proof.id,
|
||||
proof.derivation_path,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -329,6 +343,52 @@ async def update_lightning_invoice(
|
||||
)
|
||||
|
||||
|
||||
async def bump_secret_derivation(
|
||||
db: Database,
|
||||
keyset_id: str,
|
||||
by: int = 1,
|
||||
skip: bool = False,
|
||||
conn: Optional[Connection] = None,
|
||||
):
|
||||
rows = await (conn or db).fetchone(
|
||||
"SELECT counter from keysets WHERE id = ?", (keyset_id,)
|
||||
)
|
||||
# if no counter for this keyset, create one
|
||||
if not rows:
|
||||
await (conn or db).execute(
|
||||
"UPDATE keysets SET counter = ? WHERE id = ?",
|
||||
(
|
||||
0,
|
||||
keyset_id,
|
||||
),
|
||||
)
|
||||
counter = 0
|
||||
else:
|
||||
counter = int(rows[0])
|
||||
|
||||
if not skip:
|
||||
await (conn or db).execute(
|
||||
f"UPDATE keysets SET counter = counter + {by} WHERE id = ?",
|
||||
(keyset_id,),
|
||||
)
|
||||
return counter
|
||||
|
||||
|
||||
async def set_secret_derivation(
|
||||
db: Database,
|
||||
keyset_id: str,
|
||||
counter: int,
|
||||
conn: Optional[Connection] = None,
|
||||
):
|
||||
await (conn or db).execute(
|
||||
"UPDATE keysets SET counter = ? WHERE id = ?",
|
||||
(
|
||||
counter,
|
||||
keyset_id,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def set_nostr_last_check_timestamp(
|
||||
db: Database,
|
||||
timestamp: int,
|
||||
@@ -351,3 +411,41 @@ async def get_nostr_last_check_timestamp(
|
||||
("dm",),
|
||||
)
|
||||
return row[0] if row else None
|
||||
|
||||
|
||||
async def get_seed_and_mnemonic(
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> Optional[Tuple[str, str]]:
|
||||
row = await (conn or db).fetchone(
|
||||
f"""
|
||||
SELECT seed, mnemonic from seed
|
||||
""",
|
||||
)
|
||||
return (
|
||||
(
|
||||
row[0],
|
||||
row[1],
|
||||
)
|
||||
if row
|
||||
else None
|
||||
)
|
||||
|
||||
|
||||
async def store_seed_and_mnemonic(
|
||||
db: Database,
|
||||
seed: str,
|
||||
mnemonic: str,
|
||||
conn: Optional[Connection] = None,
|
||||
):
|
||||
await (conn or db).execute(
|
||||
f"""
|
||||
INSERT INTO seed
|
||||
(seed, mnemonic)
|
||||
VALUES (?, ?)
|
||||
""",
|
||||
(
|
||||
seed,
|
||||
mnemonic,
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user