mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-21 19:14:19 +01:00
feat: early multimint support
This commit is contained in:
@@ -36,6 +36,7 @@ from cashu.wallet.crud import (
|
||||
get_lightning_invoices,
|
||||
get_reserved_proofs,
|
||||
get_unused_locks,
|
||||
get_keyset,
|
||||
)
|
||||
from cashu.wallet.wallet import Wallet as Wallet
|
||||
|
||||
@@ -64,14 +65,6 @@ class NaturalOrderGroup(click.Group):
|
||||
)
|
||||
@click.pass_context
|
||||
def cli(ctx, host: str, walletname: str):
|
||||
# configure logger
|
||||
logger.remove()
|
||||
logger.add(sys.stderr, level="DEBUG" if DEBUG else "INFO")
|
||||
ctx.ensure_object(dict)
|
||||
ctx.obj["HOST"] = host
|
||||
ctx.obj["WALLET_NAME"] = walletname
|
||||
wallet = Wallet(ctx.obj["HOST"], os.path.join(CASHU_DIR, walletname))
|
||||
|
||||
if TOR and not TorProxy().check_platform():
|
||||
error_str = "Your settings say TOR=true but the built-in Tor bundle is not supported on your system. Please install Tor manually and set TOR=false and SOCKS_HOST=localhost and SOCKS_PORT=9050 in your Cashu config (recommended) or turn off Tor by setting TOR=false (not recommended). Cashu will not work until you edit your config file accordingly."
|
||||
error_str += "\n\n"
|
||||
@@ -83,6 +76,13 @@ def cli(ctx, host: str, walletname: str):
|
||||
)
|
||||
raise Exception(error_str)
|
||||
|
||||
# configure logger
|
||||
logger.remove()
|
||||
logger.add(sys.stderr, level="DEBUG" if DEBUG else "INFO")
|
||||
ctx.ensure_object(dict)
|
||||
ctx.obj["HOST"] = host
|
||||
ctx.obj["WALLET_NAME"] = walletname
|
||||
wallet = Wallet(ctx.obj["HOST"], os.path.join(CASHU_DIR, walletname))
|
||||
ctx.obj["WALLET"] = wallet
|
||||
asyncio.run(init_wallet(wallet))
|
||||
pass
|
||||
@@ -185,13 +185,22 @@ async def invoice(ctx, amount: int, hash: str):
|
||||
@coro
|
||||
async def balance(ctx, verbose):
|
||||
wallet: Wallet = ctx.obj["WALLET"]
|
||||
keyset_balances = wallet.balance_per_keyset()
|
||||
if len(keyset_balances) > 1:
|
||||
print(f"You have balances in {len(keyset_balances)} keysets:")
|
||||
# keyset_balances = wallet.balance_per_keyset()
|
||||
# if len(keyset_balances) > 1:
|
||||
# print(f"You have balances in {len(keyset_balances)} keysets:")
|
||||
# print("")
|
||||
# for k, v in keyset_balances.items():
|
||||
# print(
|
||||
# f"Keyset: {k or 'undefined'} Balance: {v['balance']} sat (available: {v['available']} sat)"
|
||||
# )
|
||||
# print("")
|
||||
mint_balances = await wallet.balance_per_minturl()
|
||||
if len(mint_balances) > 1:
|
||||
print(f"You have balances in {len(mint_balances)} mints:")
|
||||
print("")
|
||||
for k, v in keyset_balances.items():
|
||||
for k, v in mint_balances.items():
|
||||
print(
|
||||
f"Keyset: {k or 'undefined'} Balance: {v['balance']} sat (available: {v['available']} sat)"
|
||||
f"Mint: {k or 'undefined'} Balance: {v['balance']} sat (available: {v['available']} sat)"
|
||||
)
|
||||
print("")
|
||||
if verbose:
|
||||
@@ -221,9 +230,10 @@ async def send(ctx, amount: int, lock: str):
|
||||
wallet.proofs, amount, lock, set_reserved=True
|
||||
)
|
||||
token = await wallet.serialize_proofs(
|
||||
send_proofs, hide_secrets=True if lock and not p2sh else False
|
||||
send_proofs,
|
||||
hide_secrets=True if lock and not p2sh else False,
|
||||
include_mints=True,
|
||||
)
|
||||
print(token)
|
||||
wallet.status()
|
||||
|
||||
|
||||
@@ -249,8 +259,62 @@ async def receive(ctx, token: str, lock: str):
|
||||
signature = p2shscripts[0].signature
|
||||
else:
|
||||
script, signature = None, None
|
||||
proofs = [Proof(**p) for p in json.loads(base64.urlsafe_b64decode(token))]
|
||||
_, _ = await wallet.redeem(proofs, scnd_script=script, scnd_siganture=signature)
|
||||
|
||||
try:
|
||||
# backwards compatibility < 0.7.0: tokens without mint information
|
||||
proofs = [Proof(**p) for p in json.loads(base64.urlsafe_b64decode(token))]
|
||||
_, _ = await wallet.redeem(proofs, scnd_script=script, scnd_siganture=signature)
|
||||
except:
|
||||
dtoken = json.loads(base64.urlsafe_b64decode(token))
|
||||
assert "tokens" in dtoken, Exception("no proofs in token")
|
||||
# if there is a `mints` field in the token
|
||||
# we get the mint information in the token and load the keys of each mint
|
||||
# we then redeem the tokens for each keyset individually
|
||||
if "mints" in dtoken:
|
||||
for mint_id in dtoken.get("mints"):
|
||||
for keyset in set(dtoken["mints"][mint_id]["ks"]):
|
||||
mint_url = dtoken["mints"][mint_id]["url"]
|
||||
# init a temporary wallet object
|
||||
keyset_wallet = Wallet(
|
||||
mint_url, os.path.join(CASHU_DIR, ctx.obj["WALLET_NAME"])
|
||||
)
|
||||
|
||||
# first we check whether we know this mint already and ask the user
|
||||
mint_keysets = await get_keyset(id=keyset, db=keyset_wallet.db)
|
||||
if mint_keysets is None:
|
||||
click.confirm(
|
||||
f"Do you want to receive tokens from mint {mint_url}?",
|
||||
abort=True,
|
||||
default=True,
|
||||
)
|
||||
|
||||
# make sure that this mint indeed supports this keyset
|
||||
mint_keysets = await keyset_wallet._get_keysets(mint_url)
|
||||
if keyset in mint_keysets["keysets"]:
|
||||
# load the keys
|
||||
await keyset_wallet.load_mint(keyset_id=keyset)
|
||||
|
||||
# redeem proofs of this keyset
|
||||
redeem_proofs = [
|
||||
Proof(**p)
|
||||
for p in dtoken["tokens"]
|
||||
if Proof(**p).id == keyset
|
||||
]
|
||||
_, _ = await keyset_wallet.redeem(
|
||||
redeem_proofs, scnd_script=script, scnd_siganture=signature
|
||||
)
|
||||
keyset_wallet.db.connect()
|
||||
|
||||
# reload proofs to update the main wallet's balance
|
||||
await wallet.load_proofs()
|
||||
|
||||
else:
|
||||
# no mint information present, assume default mint
|
||||
proofs = [Proof(**p) for p in dtoken["tokens"]]
|
||||
_, _ = await wallet.redeem(
|
||||
proofs, scnd_script=script, scnd_siganture=signature
|
||||
)
|
||||
|
||||
wallet.status()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user