BlindedMessages is now List[BlindedMessage] (no blinded_messages field) and PostMintRequest (new) is now with outputs field

This commit is contained in:
callebtc
2023-01-14 21:23:06 +01:00
parent f0f12a442c
commit 3cbdebf5a5
9 changed files with 171 additions and 67 deletions

View File

@@ -41,6 +41,27 @@ class Proof(BaseModel):
self.__setattr__(key, val)
class Proofs(BaseModel):
# NOTE: not used in Pydantic validation
__root__: List[Proof]
class BlindedMessage(BaseModel):
amount: int
B_: str
class BlindedSignature(BaseModel):
id: Union[str, None] = None
amount: int
C_: str
class BlindedMessages(BaseModel):
# NOTE: not used in Pydantic validation
__root__: List[BlindedMessage] = []
# ------- LIGHTNING INVOICE -------
@@ -72,10 +93,8 @@ class KeysetsResponse(BaseModel):
# ------- API: MINT -------
class BlindedSignature(BaseModel):
id: Union[str, None] = None
amount: int
C_: str
class PostMintRequest(BaseModel):
outputs: List[BlindedMessage]
class PostMintResponseLegacy(BaseModel):
@@ -108,32 +127,10 @@ class GetMeltResponse(BaseModel):
# ------- API: SPLIT -------
class BlindedMessage(BaseModel):
amount: int
B_: str
class BlindedMessages(BaseModel):
blinded_messages: List[BlindedMessage] = []
class SplitRequest(BaseModel):
proofs: List[Proof]
amount: int
output_data: Union[
BlindedMessages, None
] = None # backwards compatibility with clients that called this output_data and not outputs < v0.2.2
outputs: Union[BlindedMessages, None] = None
def __init__(self, **data):
super().__init__(**data)
self.backwards_compatibility_v021()
def backwards_compatibility_v021(self):
# before v0.2.2: output_data, after: outputs
if self.output_data:
self.outputs = self.output_data
self.output_data = None
outputs: Union[List[BlindedMessage], None] = None
class PostSplitResponse(BaseModel):

View File

@@ -4,7 +4,7 @@ from fastapi import APIRouter
from secp256k1 import PublicKey
from cashu.core.base import (
BlindedMessages,
BlindedMessage,
BlindedSignature,
CheckFeesRequest,
CheckFeesResponse,
@@ -14,6 +14,7 @@ from cashu.core.base import (
KeysetsResponse,
KeysResponse,
MeltRequest,
PostMintRequest,
PostMintResponse,
PostSplitResponse,
SplitRequest,
@@ -68,7 +69,7 @@ async def request_mint(amount: int = 0) -> GetMintResponse:
@router.post("/mint")
async def mint(
mint_request: BlindedMessages,
payload: PostMintRequest,
payment_hash: Union[str, None] = None,
) -> Union[PostMintResponse, CashuError]:
"""
@@ -77,9 +78,7 @@ async def mint(
Call this endpoint after `GET /mint`.
"""
try:
promises = await ledger.mint(
mint_request.blinded_messages, payment_hash=payment_hash
)
promises = await ledger.mint(payload.outputs, payment_hash=payment_hash)
blinded_signatures = PostMintResponse(promises=promises)
return blinded_signatures
except Exception as exc:
@@ -124,8 +123,7 @@ async def split(
proofs = payload.proofs
amount = payload.amount
# NOTE: backwards compatibility with clients < v0.2.2
outputs = payload.outputs.blinded_messages if payload.outputs else None
outputs = payload.outputs or None
assert outputs, Exception("no outputs provided.")
try:

View File

@@ -14,7 +14,6 @@ import cashu.core.b_dhke as b_dhke
import cashu.core.bolt11 as bolt11
from cashu.core.base import (
BlindedMessage,
BlindedMessages,
BlindedSignature,
CheckFeesRequest,
CheckRequest,
@@ -23,6 +22,7 @@ from cashu.core.base import (
KeysetsResponse,
MeltRequest,
P2SHScript,
PostMintRequest,
PostMintResponse,
PostMintResponseLegacy,
Proof,
@@ -162,20 +162,20 @@ class LedgerAPI:
@staticmethod
def _construct_outputs(amounts: List[int], secrets: List[str]):
"""Takes a list of amounts and secrets and returns outputs.
Outputs are blinded messages `payloads` and blinding factors `rs`"""
Outputs are blinded messages `outputs` and blinding factors `rs`"""
assert len(amounts) == len(
secrets
), f"len(amounts)={len(amounts)} not equal to len(secrets)={len(secrets)}"
payloads: BlindedMessages = BlindedMessages()
outputs: List[BlindedMessage] = []
rs = []
for secret, amount in zip(secrets, amounts):
B_, r = b_dhke.step1_alice(secret)
rs.append(r)
payload: BlindedMessage = BlindedMessage(
output: BlindedMessage = BlindedMessage(
amount=amount, B_=B_.serialize().hex()
)
payloads.blinded_messages.append(payload)
return payloads, rs
outputs.append(output)
return outputs, rs
async def _check_used_secrets(self, secrets):
for s in secrets:
@@ -251,11 +251,12 @@ class LedgerAPI:
"""Mints new coins and returns a proof of promise."""
secrets = [self._generate_secret() for s in range(len(amounts))]
await self._check_used_secrets(secrets)
payloads, rs = self._construct_outputs(amounts, secrets)
outputs, rs = self._construct_outputs(amounts, secrets)
outputs_payload = PostMintRequest(outputs=outputs)
self.s = self._set_requests()
resp = self.s.post(
self.url + "/mint",
json=payloads.dict(),
json=outputs_payload.dict(),
params={"payment_hash": payment_hash},
)
resp.raise_for_status()
@@ -303,8 +304,8 @@ class LedgerAPI:
amounts
), "number of secrets does not match number of outputs"
await self._check_used_secrets(secrets)
payloads, rs = self._construct_outputs(amounts, secrets)
split_payload = SplitRequest(proofs=proofs, amount=amount, outputs=payloads)
outputs, rs = self._construct_outputs(amounts, secrets)
split_payload = SplitRequest(proofs=proofs, amount=amount, outputs=outputs)
# construct payload
def _splitrequest_include_fields(proofs):