diff --git a/cashu/core/base.py b/cashu/core/base.py index a120572..26eaf9a 100644 --- a/cashu/core/base.py +++ b/cashu/core/base.py @@ -232,12 +232,12 @@ class TokenMintJson(BaseModel): ks: List[str] -class TokenJson(BaseModel): - tokens: List[Proof] +class TokenV2(BaseModel): + proofs: List[Proof] mints: Optional[Dict[str, TokenMintJson]] = None def to_dict(self): return dict( - tokens=[p.to_dict() for p in self.tokens], + proofs=[p.to_dict() for p in self.proofs], mints={k: v.dict() for k, v in self.mints.items()}, # type: ignore ) diff --git a/cashu/wallet/cli_helpers.py b/cashu/wallet/cli_helpers.py index 0d6b6e8..df7162f 100644 --- a/cashu/wallet/cli_helpers.py +++ b/cashu/wallet/cli_helpers.py @@ -3,7 +3,7 @@ import urllib.parse import click -from cashu.core.base import Proof, TokenJson, TokenMintJson, WalletKeyset +from cashu.core.base import Proof, TokenV2, TokenMintJson, WalletKeyset from cashu.core.settings import CASHU_DIR, MINT_URL from cashu.wallet.crud import get_keyset from cashu.wallet.wallet import Wallet as Wallet @@ -152,7 +152,7 @@ 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: TokenV2 = await wallet._make_token(proofs, include_mints=False) token.mints = {} # get keysets of proofs diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index fabc839..e797025 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -26,7 +26,7 @@ from cashu.core.base import ( PostMintResponse, Proof, SplitRequest, - TokenJson, + TokenV2, TokenMintJson, WalletKeyset, ) @@ -497,11 +497,11 @@ class Wallet(LedgerAPI): async def _make_token(self, proofs: List[Proof], include_mints=True): """ - Takes list of proofs and produces a TokenJson by looking up + Takes list of proofs and produces a TokenV2 by looking up the keyset id and mint URLs from the database. """ # build token - token = TokenJson(tokens=proofs) + token = TokenV2(proofs=proofs) # add mint information to the token, if requested if include_mints: @@ -530,9 +530,9 @@ class Wallet(LedgerAPI): token.mints = mints return token - async def _serialize_token_base64(self, token: TokenJson): + async def _serialize_token_base64(self, token: TokenV2): """ - Takes a TokenJson and serializes it in urlsafe_base64. + Takes a TokenV2 and serializes it in urlsafe_base64. """ # encode the token as a base64 string token_base64 = base64.urlsafe_b64encode( diff --git a/docs/specs/00.md b/docs/specs/00.md index 7957895..6761d70 100644 --- a/docs/specs/00.md +++ b/docs/specs/00.md @@ -66,9 +66,14 @@ A list of `Proof`'s. In general, this will be used for most operations instead o ## 0.2 - Methods ### Serialization of `Proofs` -To send and receive `Proofs`, wallets serialize them in a `base64_urlsafe` format. -Example: +To send and receive `Proofs`, wallets serialize them in a `base64_urlsafe` format. There are two versions of the serialization format. + +#### 0.2.1 - V1 tokens + +This token format is a list of `Proof`s. Each `Proof` contains the keyset id in the field `id` that can be used by a wallet to identify the mint of this token. A wallet that encounters an unknown `id`, it CAN ask the user to enter the mint url of this yet unknown mint. The wallet SHOULD explicity ask the user whether they trust the mint. + +##### Example JSON: ```json [ @@ -86,8 +91,45 @@ Example: } ``` -becomes +When serialized, this becomes: ``` W3siaWQiOiAiRFNBbDludnZ5ZnZhIiwgImFtb3VudCI6IDgsICJzZWNyZXQiOiAiRGJSS0l5YTBldGR3STVzRkFOMEFYUSIsICJDIjogIjAyZGY3ZjJmYzI5NjMxYjcxYTFkYjExYzE2M2IwYjFjYjQwNDQ0YWEyYjNkMjUzZDQzYjY4ZDc3YTcyZWQyZDYyNSJ9LCB7ImlkIjogIkRTQWw5bnZ2eWZ2YSIsICJhbW91bnQiOiAxNiwgInNlY3JldCI6ICJkX1BQYzVLcHVBQjJNNjBXWUFXNS1RIiwgIkMiOiAiMDI3MGUwYTM3ZjdhMGIyMWVhYjQzYWY3NTFkZDNjMDNmNjFmMDRjNjI2YzA0NDhmNjAzZjFkMWY1YWU1YTdkN2U2In1d +``` + +#### 0.2.2 - V2 tokens + +This token format includes information about the mint as well. The field `proofs` is like a V1 token. Additionally, the field `mints` can include a list of multiple mints from which the `proofs` are from. The `url` field is the URL of the mint. `ks` is a list of the keyset IDs belonging to this mint. All keyset IDs of the `proofs` must be present here to allow a wallet to map each proof to a mint. + +##### Example JSON: + +```json +{ + "proofs": [ + { + "id": "DSAl9nvvyfva", + "amount": 2, + "secret": "bdYCbHGONundLeYvv1P5dQ", + "C": "02e6117fb1b1633a8c1657ed34ab25ecf8d4974091179c4773ec59f85f4e3991cf" + }, + { + "id": "DSAl9nvvyfva", + "amount": 8, + "secret": "KxyUPt5Mur_-RV8pCECJ6A", + "C": "03b9dcdb7f195e07218b95b7c2dadc8289159fc44047439830f765b8c50bfb6bda" + } + ], + "mints": { + "MINT_NAME": { + "url": "http://server.host:3339", + "ks": ["DSAl9nvvyfva"] + } + } +} +``` + +When serialized, this becomes: + +``` +eyJwcm9vZnMiOlt7ImlkIjoiRFNBbDludnZ5ZnZhIiwiYW1vdW50IjoyLCJzZWNyZXQiOiJiZFlDYkhHT051bmRMZVl2djFQNWRRIiwiQyI6IjAyZTYxMTdmYjFiMTYzM2E4YzE2NTdlZDM0YWIyNWVjZjhkNDk3NDA5MTE3OWM0NzczZWM1OWY4NWY0ZTM5OTFjZiJ9LHsiaWQiOiJEU0FsOW52dnlmdmEiLCJhbW91bnQiOjgsInNlY3JldCI6Ikt4eVVQdDVNdXJfLVJWOHBDRUNKNkEiLCJDIjoiMDNiOWRjZGI3ZjE5NWUwNzIxOGI5NWI3YzJkYWRjODI4OTE1OWZjNDQwNDc0Mzk4MzBmNzY1YjhjNTBiZmI2YmRhIn1dLCJtaW50cyI6eyJNSU5UX05BTUUiOnsidXJsIjoiaHR0cDovL3NlcnZlci5ob3N0OjMzMzkiLCJrcyI6WyJEU0FsOW52dnlmdmEiXX19fQ== ``` \ No newline at end of file