-
-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for NUT-19 mint and wallet side #670
base: main
Are you sure you want to change the base?
Conversation
cashu/mint/ledger.py
Outdated
@@ -518,13 +520,15 @@ async def mint( | |||
*, | |||
outputs: List[BlindedMessage], | |||
quote_id: str, | |||
witness: Optional[str] = None, | |||
) -> List[BlindedSignature]: | |||
"""Mints new coins if quote with `quote_id` was paid. Ingest blind messages `outputs` and returns blind signatures `promises`. | |||
|
|||
Args: | |||
outputs (List[BlindedMessage]): Outputs (blinded messages) to sign. | |||
quote_id (str): Mint quote id. | |||
keyset (Optional[MintKeyset], optional): Keyset to use. If not provided, uses active keyset. Defaults to None. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keyset (Optional[MintKeyset], optional): Keyset to use. If not provided, uses active keyset. Defaults to None. |
outdated
cashu/mint/migrations.py
Outdated
await conn.execute( | ||
f""" | ||
ALTER TABLE {db.table_with_schema("mint_quotes")} | ||
ADD COLUMN key TEXT DEFAULT NULL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here (key
-> pubkey
)
cashu/core/crypto/nut19.py
Outdated
|
||
|
||
def construct_message(quote_id: str, outputs: List[BlindedMessage]) -> bytes: | ||
serialized_outputs = bytes.fromhex("".join([o.B_ for o in outputs])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
serialized_outputs = bytes.fromhex("".join([o.B_ for o in outputs])) | |
serialized_outputs = bytes.fromhex("".join([o.B_ for o in outputs])) |
This should be utf-8 encoded?
Nice work. One issue here is that |
I think we should move the file |
yea that was the idea. The alternative is keeping the private key separate but still storing it together with the quote in the DB. And then when we request the quote from DB also return the separate private key. |
@@ -261,6 +261,7 @@ async def request_mint_deprecated(self, amount) -> PostMintQuoteResponse: | |||
paid=False, | |||
state=MintQuoteState.unpaid.value, | |||
expiry=decoded_invoice.date + (decoded_invoice.expiry or 0), | |||
pubkey=None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pubkey=None |
Optional parameter doesn't need definition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mypy was complaining about this because it's defined as optional but doesn't have a default value.
cashu/wallet/wallet.py
Outdated
privkey = PrivateKey(bytes.fromhex(quote_key), raw=True) | ||
witness = nut19.sign_mint_quote(quote_id, outputs, privkey) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move the PrivateKey
instantiation into the nut19
submodule
cashu/wallet/wallet.py
Outdated
@@ -424,13 +429,29 @@ async def request_mint(self, amount: int, memo: Optional[str] = None) -> MintQuo | |||
Returns: | |||
MintQuote: Mint Quote | |||
""" | |||
mint_quote_response = await super().mint_quote(amount, self.unit, memo) | |||
privkey, pubkey = await self.get_quote_ephemeral_keypair() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move get_quote_ephemeral_keypair
also to nut19.py
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if we later want to add derivation from seed+counter functionality we might want to keep it inside the wallet class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general depends on the state of the wallet so...
I think it should have two separate columns |
…ot correctly escaped + pass in NUT-19 keypair to `request_mint` `request_mint_with_callback`
I moved |
Adding support for NUT-19.
Main changes:
Common:
MintQuote
has two more optional fields namedprivkey
andpubkey
nut19.py
containsconstruct_message
,sign_mint_quote
andverify_mint_quote
PostMintQuoteRequest
has one more optional field namedpubkey
PostMintRequest
has one more optional field namedpubkey
Mint:
PostMintQuoteRequest
contains apubkey
, save the public key together with the quote andrequire a BIP340 signature from said public key on the mint request's quote id and blind messages.
PostMintQuoteRequest
does not contain apubkey
while Mint is configured to require it, reject the request.Wallet:
pubkey
in thePostMintRequest
.privkey
in the quote when saving it to DB.key
, sign the quote id and the blinded message withkey