This commit is contained in:
callebtc
2022-12-28 03:35:45 +01:00
parent 11ec7ac51d
commit c4f74f42a3
4 changed files with 80 additions and 55 deletions

View File

@@ -222,3 +222,9 @@ class TokenMintJson(BaseModel):
class TokenJson(BaseModel): class TokenJson(BaseModel):
tokens: List[Proof] tokens: List[Proof]
mints: Optional[Dict[str, TokenMintJson]] = None 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
)

View File

@@ -19,7 +19,7 @@ from typing import Dict, List
import click import click
from loguru import logger 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.helpers import sum_proofs
from cashu.core.migrations import migrate_databases from cashu.core.migrations import migrate_databases
from cashu.core.settings import ( from cashu.core.settings import (
@@ -53,6 +53,8 @@ from .cli_helpers import (
print_mint_balances, print_mint_balances,
redeem_multimint, redeem_multimint,
verify_mints, 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 # backwards compatibility: tokens without mint information
# supports tokens of the form W3siaWQiOiJH # supports tokens of the form W3siaWQiOiJH
# LNbits token link parsing # if it's an lnbits https:// link with a token as an argument, speacial treatment
# can extract minut URL from LNbits token links like: token, url = token_from_lnbits_link(token)
# 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)
# assume W3siaWQiOiJH.. 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))] 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: except:
pass pass

View File

@@ -2,10 +2,14 @@ import os
import click 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.core.settings import CASHU_DIR
from cashu.wallet.crud import get_keyset from cashu.wallet.crud import get_keyset
from cashu.wallet.wallet import Wallet as Wallet from cashu.wallet.wallet import Wallet as Wallet
import urllib.parse
from cashu.core.settings import (
MINT_URL,
)
async def verify_mints(ctx, dtoken): async def verify_mints(ctx, dtoken):
@@ -97,19 +101,19 @@ async def get_mint_wallet(ctx):
await wallet.load_mint() await wallet.load_mint()
mint_balances = await wallet.balance_per_minturl() 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 = ( mint_nr_str = (
input(f"Select mint [1-{len(mint_balances)}, press enter for default 1]: ") input(f"Select mint [1-{len(mint_balances)}, press enter for default 1]: ")
or "1" or "1"
) )
if not mint_nr.isdigit(): if not mint_nr_str.isdigit():
raise Exception("invalid input.") raise Exception("invalid input.")
mint_nr = int(mint_nr) mint_nr = int(mint_nr_str)
else:
mint_nr = 1
mint_url = list(mint_balances.keys())[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) await mint_wallet.load_mint(keyset_id=mint_keysets.id)
return mint_wallet 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

View File

@@ -528,7 +528,7 @@ class Wallet(LedgerAPI):
""" """
# encode the token as a base64 string # encode the token as a base64 string
token_base64 = base64.urlsafe_b64encode( token_base64 = base64.urlsafe_b64encode(
json.dumps(token.dict()).encode() json.dumps(token.to_dict()).encode()
).decode() ).decode()
return token_base64 return token_base64