diff --git a/cashu/wallet/cli.py b/cashu/wallet/cli.py index e389207..e5543c2 100644 --- a/cashu/wallet/cli.py +++ b/cashu/wallet/cli.py @@ -47,7 +47,12 @@ from cashu.wallet.crud import ( ) from cashu.wallet.wallet import Wallet as Wallet -from .cli_helpers import redeem_multimint, verify_mints +from .cli_helpers import ( + redeem_multimint, + verify_mints, + print_mint_balances, + get_mint_wallet, +) async def init_wallet(wallet: Wallet): @@ -210,27 +215,7 @@ async def balance(ctx, verbose): ) print("") - # get balances per mint - mint_balances = await wallet.balance_per_minturl() - - # if we have a balance on a non-default mint, we show its URL - show_mints = False - keysets = [k for k, v in wallet.balance_per_keyset().items()] - for k in keysets: - ks = await get_keyset(id=str(k), db=wallet.db) - if ks and ks.mint_url != ctx.obj["HOST"]: - show_mints = True - - # or we have a balance on more than one mint - # show balances per mint - if len(mint_balances) > 1 or show_mints: - print(f"You have balances in {len(mint_balances)} mints:") - print("") - for k, v in mint_balances.items(): - print( - f"Mint: {k} - Balance: {v['available']} sat (pending: {v['balance']-v['available']} sat)" - ) - print("") + await print_mint_balances(ctx, wallet) if verbose: print( @@ -259,9 +244,10 @@ async def send(ctx, amount: int, lock: str, legacy: bool): p2sh = False if lock and len(lock.split("P2SH:")) == 2: p2sh = True - wallet: Wallet = ctx.obj["WALLET"] - await wallet.load_mint() - wallet.status() + + wallet = await get_mint_wallet(ctx) + await wallet.load_proofs() + _, send_proofs = await wallet.split_to_send( wallet.proofs, amount, lock, set_reserved=True ) @@ -444,6 +430,7 @@ async def pending(ctx): ) print(f"{token}\n") print(f"--------------------------\n") + print("To remove all spent tokens use: cashu burn -a") wallet.status() @@ -545,9 +532,8 @@ async def invoices(ctx): @click.pass_context @coro async def nsend(ctx, amount: int, pubkey: str, verbose: bool, yes: bool): - wallet: Wallet = ctx.obj["WALLET"] - await wallet.load_mint() - wallet.status() + wallet = await get_mint_wallet(ctx) + await wallet.load_proofs() _, send_proofs = await wallet.split_to_send( wallet.proofs, amount, set_reserved=True ) diff --git a/cashu/wallet/cli_helpers.py b/cashu/wallet/cli_helpers.py index d1084da..145dde7 100644 --- a/cashu/wallet/cli_helpers.py +++ b/cashu/wallet/cli_helpers.py @@ -2,7 +2,7 @@ import os import click -from cashu.core.base import Proof +from cashu.core.base import Proof, WalletKeyset from cashu.core.settings import CASHU_DIR from cashu.wallet.crud import get_keyset from cashu.wallet.wallet import Wallet as Wallet @@ -67,3 +67,56 @@ async def redeem_multimint(ctx, dtoken, script, signature): _, _ = await keyset_wallet.redeem( redeem_proofs, scnd_script=script, scnd_siganture=signature ) + + +async def print_mint_balances(ctx, wallet, show_mints=False): + # get balances per mint + mint_balances = await wallet.balance_per_minturl() + + # if we have a balance on a non-default mint, we show its URL + keysets = [k for k, v in wallet.balance_per_keyset().items()] + for k in keysets: + ks = await get_keyset(id=str(k), db=wallet.db) + if ks and ks.mint_url != ctx.obj["HOST"]: + show_mints = True + + # or we have a balance on more than one mint + # show balances per mint + if len(mint_balances) > 1 or show_mints: + print(f"You have balances in {len(mint_balances)} mints:") + print("") + for i, (k, v) in enumerate(mint_balances.items()): + print( + f"Mint {i+1}: {k} - Balance: {v['available']} sat (pending: {v['balance']-v['available']} sat)" + ) + print("") + + +async def get_mint_wallet(ctx): + wallet: Wallet = ctx.obj["WALLET"] + await wallet.load_mint() + + mint_balances = await wallet.balance_per_minturl() + print(mint_balances) + if len(mint_balances) == 1: + return wallet + + await print_mint_balances(ctx, wallet, show_mints=True) + + mint_nr = input( + f"Which mint do you want to use? [1-{len(mint_balances)}, default: 1] " + ) + mint_nr = "1" if mint_nr == "" else mint_nr + if not mint_nr.isdigit(): + raise Exception("invalid input.") + mint_nr = int(mint_nr) + + mint_url = list(mint_balances.keys())[mint_nr - 1] + + mint_wallet = Wallet(mint_url, os.path.join(CASHU_DIR, ctx.obj["WALLET_NAME"])) + mint_keysets: WalletKeyset = await get_keyset(mint_url=mint_url, db=mint_wallet.db) # type: ignore + print(mint_keysets.id) + # load the keys + await mint_wallet.load_mint(keyset_id=mint_keysets.id) + + return mint_wallet diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index e0124eb..76ada45 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -665,13 +665,14 @@ class Wallet(LedgerAPI): async def balance_per_minturl(self): balances = await self._get_proofs_per_minturl(self.proofs) - return { + balances_return = { key: { "balance": sum_proofs(proofs), "available": sum_proofs([p for p in proofs if not p.reserved]), } for key, proofs in balances.items() } + return dict(sorted(balances_return.items(), key=lambda item: item[1]["available"], reverse=True)) # type: ignore def proof_amounts(self): return [p["amount"] for p in sorted(self.proofs, key=lambda p: p["amount"])]