From c4f74f42a335e31d9cf38f29fbd94989a51dd48b Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Wed, 28 Dec 2022 03:35:45 +0100 Subject: [PATCH] refactor --- cashu/core/base.py | 6 +++ cashu/wallet/cli.py | 51 +++++-------------------- cashu/wallet/cli_helpers.py | 76 +++++++++++++++++++++++++++++++------ cashu/wallet/wallet.py | 2 +- 4 files changed, 80 insertions(+), 55 deletions(-) diff --git a/cashu/core/base.py b/cashu/core/base.py index 2f2e3dd..78dfc86 100644 --- a/cashu/core/base.py +++ b/cashu/core/base.py @@ -222,3 +222,9 @@ class TokenMintJson(BaseModel): class TokenJson(BaseModel): tokens: List[Proof] mints: Optional[Dict[str, TokenMintJson]] = None + + def to_dict(self): + return dict( + tokens=[p.to_dict() for p in self.tokens], + mints={k: v.dict() for k, v in self.mints.items()}, # type: ignore + ) diff --git a/cashu/wallet/cli.py b/cashu/wallet/cli.py index 927f506..4b6901e 100644 --- a/cashu/wallet/cli.py +++ b/cashu/wallet/cli.py @@ -19,7 +19,7 @@ from typing import Dict, List import click from loguru import logger -from cashu.core.base import Proof, TokenJson, TokenMintJson +from cashu.core.base import Proof from cashu.core.helpers import sum_proofs from cashu.core.migrations import migrate_databases from cashu.core.settings import ( @@ -53,6 +53,8 @@ from .cli_helpers import ( print_mint_balances, redeem_multimint, verify_mints, + token_from_lnbits_link, + proofs_to_token, ) @@ -300,51 +302,16 @@ async def receive(ctx, token: str, lock: str): # backwards compatibility: tokens without mint information # supports tokens of the form W3siaWQiOiJH - # LNbits token link parsing - # can extract minut URL from LNbits token links like: - # https://lnbits.server/cashu/wallet?mint_id=aMintId&recv_token=W3siaWQiOiJHY2... - - def parse_lnbits_link(link): - url, token = "", "" - if len(link.split("&recv_token=")) == 2: - # extract URL params - params = urllib.parse.parse_qs(link.split("?")[1]) - # extract URL - if "mint_id" in params: - url = ( - link.split("?")[0].split("/wallet")[0] - + "/api/v1/" - + params["mint_id"][0] - ) - # extract token - token = params["recv_token"][0] - return token, url - else: - return link, "" - - token, url = parse_lnbits_link(token) + # if it's an lnbits https:// link with a token as an argument, speacial treatment + token, url = token_from_lnbits_link(token) # assume W3siaWQiOiJH.. token - # trows an error if the desirialization with the old format doesn't work + # next line trows an error if the desirialization with the old format doesn't + # work and we can assume it's the new format proofs = [Proof(**p) for p in json.loads(base64.urlsafe_b64decode(token))] - token = await wallet.serialize_proofs( - proofs, - include_mints=False, - ) - - # if it was not an lnbits link - url = url or ( - input(f"Enter mint URL (press enter for default {MINT_URL}): ") or MINT_URL - ) - - # and add url and keyset id to token - token_object: TokenJson = await wallet._make_token(proofs, include_mints=False) - token_object.mints = {} - keysets = list(set([p.id for p in proofs])) - assert keysets is not None, "no keysets" - token_object.mints[url] = TokenMintJson(url=url, ks=keysets) # type: ignore - token = await wallet._serialize_token_base64(token_object) + # we take the proofs parsed from the old format token and produce a new format token with it + token = await proofs_to_token(wallet, proofs, url) except: pass diff --git a/cashu/wallet/cli_helpers.py b/cashu/wallet/cli_helpers.py index 4a6a0fb..6cf8930 100644 --- a/cashu/wallet/cli_helpers.py +++ b/cashu/wallet/cli_helpers.py @@ -2,10 +2,14 @@ import os import click -from cashu.core.base import Proof, WalletKeyset +from cashu.core.base import Proof, WalletKeyset, TokenJson, TokenMintJson from cashu.core.settings import CASHU_DIR from cashu.wallet.crud import get_keyset from cashu.wallet.wallet import Wallet as Wallet +import urllib.parse +from cashu.core.settings import ( + MINT_URL, +) async def verify_mints(ctx, dtoken): @@ -97,19 +101,19 @@ async def get_mint_wallet(ctx): await wallet.load_mint() mint_balances = await wallet.balance_per_minturl() - # if there is only one mint, use it - if len(mint_balances) == 1: - return wallet - await print_mint_balances(ctx, wallet, show_mints=True) + if len(mint_balances) > 1: + await print_mint_balances(ctx, wallet, show_mints=True) - mint_nr = ( - input(f"Select mint [1-{len(mint_balances)}, press enter for default 1]: ") - or "1" - ) - if not mint_nr.isdigit(): - raise Exception("invalid input.") - mint_nr = int(mint_nr) + mint_nr_str = ( + input(f"Select mint [1-{len(mint_balances)}, press enter for default 1]: ") + or "1" + ) + if not mint_nr_str.isdigit(): + raise Exception("invalid input.") + mint_nr = int(mint_nr_str) + else: + mint_nr = 1 mint_url = list(mint_balances.keys())[mint_nr - 1] @@ -121,3 +125,51 @@ async def get_mint_wallet(ctx): await mint_wallet.load_mint(keyset_id=mint_keysets.id) return mint_wallet + + +# LNbits token link parsing +# can extract minut URL from LNbits token links like: +# https://lnbits.server/cashu/wallet?mint_id=aMintId&recv_token=W3siaWQiOiJHY2... +def token_from_lnbits_link(link): + url, token = "", "" + if len(link.split("&recv_token=")) == 2: + # extract URL params + params = urllib.parse.parse_qs(link.split("?")[1]) + # extract URL + if "mint_id" in params: + url = ( + link.split("?")[0].split("/wallet")[0] + + "/api/v1/" + + params["mint_id"][0] + ) + # extract token + token = params["recv_token"][0] + return token, url + else: + return link, "" + + +async def proofs_to_token(wallet, proofs, url: str): + """ + Ingests proofs and + """ + # and add url and keyset id to token + token: TokenJson = await wallet._make_token(proofs, include_mints=False) + token.mints = {} + + # get keysets of proofs + keysets = list(set([p.id for p in proofs])) + assert keysets is not None, "no keysets" + + # check whether we know the mint urls for these proofs + for k in keysets: + ks = await get_keyset(id=k, db=wallet.db) + url = ks.mint_url if ks is not None else None + + url = url or ( + input(f"Enter mint URL (press enter for default {MINT_URL}): ") or MINT_URL + ) + + token.mints[url] = TokenMintJson(url=url, ks=keysets) # type: ignore + token_serialized = await wallet._serialize_token_base64(token) + return token_serialized diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index 76ada45..378308d 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -528,7 +528,7 @@ class Wallet(LedgerAPI): """ # encode the token as a base64 string token_base64 = base64.urlsafe_b64encode( - json.dumps(token.dict()).encode() + json.dumps(token.to_dict()).encode() ).decode() return token_base64