-
Notifications
You must be signed in to change notification settings - Fork 52
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
NUT-XX and NUT-XX+1: Mint / Melt Bitcoin On-Chain #107
Open
ngutech21
wants to merge
17
commits into
cashubtc:main
Choose a base branch
from
ngutech21:mint-melt-onchain
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 3 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
cc4da36
add specs for minting and melting tokens onchain
ngutech21 5a1edde
chore: rename payment_method to method
ngutech21 2290606
chore: increase min_amount
ngutech21 b4dc153
chore: rename payment_method
ngutech21 91f051f
fix: typo in settings
ngutech21 46f9867
fix: txid is optional
ngutech21 bba6d32
chore: OnchainQuoteReponse.description is optional
ngutech21 1aaf174
chore: use state enum instead of bool
ngutech21 2e73249
chore: cleanup examples
ngutech21 7b54066
chore: use state enum instead of paid flag
ngutech21 93a57f0
chore: cleaup examples
ngutech21 03f4d5c
chore: rename nuts
ngutech21 d671cdf
chore: merge 'origin/main' into mint-melt-onchain
ngutech21 f48d97a
chore: add nut-18 and nut-19 to readme
ngutech21 f2d660d
feat: add min-confirmations to info-endpoint
ngutech21 94c139c
fix: formatting
ngutech21 27a8e38
chore: remove check tx-status
ngutech21 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
NUT-17: Mint tokens Bitcoin On-Chain | ||
========================== | ||
|
||
`optional` | ||
|
||
--- | ||
|
||
This NUT describes the process of minting tokens on Bitcoin On-Chain analog to NUT-04 for Bitcoin Lightning. | ||
|
||
# Mint quote | ||
|
||
To request a mint quote, the wallet of `Alice` makes a `POST /v1/mint/quote/{method}` request where `method` is the payment method requested (here `btconchain`). | ||
|
||
```http | ||
POST https://mint.host:3338/v1/mint/quote/btconchain | ||
``` | ||
|
||
The wallet of `Alice` includes the following `PostMintQuoteBtcOnchainRequest` data in its request: | ||
|
||
```json | ||
{ | ||
"amount": <int>, | ||
"unit": <str_enum["sat"]> | ||
} | ||
``` | ||
with the requested `amount` and the `unit`. | ||
|
||
The mint `Bob` then responds with a `PostMintQuoteBtcOnchainResponse`: | ||
|
||
```json | ||
{ | ||
"quote": <str>, | ||
"address": <str>, | ||
thesimplekid marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"paid": <bool>, | ||
"expiry": <int> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This expiry field might be problematic (cf @gandlafbtc's comment). |
||
} | ||
``` | ||
ngutech21 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Where `quote` is the quote ID and `address` is the payment request to fulfill. `paid` indicates whether the request as been paid and `expiry` is the Unix timestamp until which the mint quote is valid. | ||
|
||
Note: `quote` is a **unique and random** id generated by the mint to internally look up the payment state. `quote` **MUST** remain a secret between user and mint and **MUST NOT** be derivable from the payment request. A third party who knows the `quote` ID can front-run and steal the tokens that this operation mints. | ||
ngutech21 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Example | ||
|
||
Request of `Alice` with curl: | ||
|
||
```bash | ||
curl -X POST https://mint.host:3338/v1/mint/quote/btconchain -d '{"amount": 10, "unit": "sat"}' -H "Content-Type: application/json" | ||
``` | ||
|
||
Response of `Bob`: | ||
|
||
```json | ||
{ | ||
"quote": "DSGLX9kevM...", | ||
"address": "bc1qkyfgd7mus7ykfd7qkwakq75qsf7rtm...", | ||
"paid": false, | ||
"expiry": 1701704757 | ||
} | ||
``` | ||
ngutech21 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The wallet **MUST** store the `amount` in the request and the `quote` id in the response in its database so it can later request the tokens after paying the request. After payment, the wallet continues with the next section. | ||
|
||
## Check mint quote state | ||
|
||
To check whether a mint quote has been paid, `Alice` makes a `GET /v1/mint/quote/btconchain/{quote_id}`. | ||
|
||
```http | ||
GET https://mint.host:3338/v1/mint/quote/btconchain/{quote_id} | ||
``` | ||
|
||
Like before, the mint `Bob` responds with a `PostMintQuoteBtcOnchainResponse`. | ||
|
||
Example request of `Alice` with curl: | ||
|
||
```bash | ||
curl -X GET https://mint.host:3338/v1/mint/quote/btconchain/DSGLX9kevM... | ||
``` | ||
|
||
# Minting tokens | ||
|
||
After requesting a mint quote and paying the request, the wallet proceeds with minting new tokens by calling the `POST /v1/mint/{method}` endpoint where `method` is the payment method requested (here `btconchain`). | ||
|
||
```http | ||
POST https://mint.host:3338/v1/mint/btconchain | ||
``` | ||
|
||
The wallet `Alice` includes the following `PostMintBtcOnchainRequest` data in its request | ||
|
||
```json | ||
{ | ||
"quote": <str>, | ||
"outputs": <Array[BlindedMessage]> | ||
} | ||
``` | ||
with the `quote` being the quote ID from the previous step and `outputs` being `BlindedMessages` (see [NUT-00][00]) that the wallet requests signatures on whose sum is `amount` as requested in the quote. | ||
|
||
The mint `Bob` then responds with a `PostMintBtcOnchainResponse`: | ||
|
||
```json | ||
{ | ||
"signatures": <Array[BlindSignature]> | ||
} | ||
``` | ||
|
||
where `signatures` is an array of blind signatures on the outputs. | ||
|
||
## Example | ||
|
||
Request of `Alice` with curl: | ||
|
||
```bash | ||
curl -X POST https://mint.host:3338/v1/mint/btconchain -H "Content-Type: application/json" -d \ | ||
'{ | ||
"quote": "DSGLX9kevM...", | ||
"outputs": [ | ||
{ | ||
"amount": 8, | ||
"id": "009a1f293253e41e", | ||
"B_": "035015e6d7ade60ba8426cefaf1832bbd27257636e44a76b922d78e79b47cb689d" | ||
}, | ||
{ | ||
"amount": 2, | ||
"id": "009a1f293253e41e", | ||
"B_": "0288d7649652d0a83fc9c966c969fb217f15904431e61a44b14999fabc1b5d9ac6" | ||
} | ||
] | ||
}' | ||
``` | ||
|
||
Response of `Bob`: | ||
|
||
```json | ||
{ | ||
"signatures": [ | ||
{ | ||
"id": "009a1f293253e41e", | ||
"amount": 2, | ||
"C_": "0224f1c4c564230ad3d96c5033efdc425582397a5a7691d600202732edc6d4b1ec" | ||
}, | ||
{ | ||
"id": "009a1f293253e41e", | ||
"amount": 8, | ||
"C_": "0277d1de806ed177007e5b94a8139343b6382e472c752a74e99949d511f7194f6c" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
## Unblinding signatures | ||
|
||
Upon receiving the `BlindSignatures` from the mint `Bob`, the wallet of `Alice` unblinds them to generate `Proofs` (using the blinding factor `r` and the mint's public key `K`, see BDHKE [NUT-00][00]). The wallet then stores these `Proofs` in its database: | ||
|
||
```json | ||
[ | ||
{ | ||
"id": "009a1f293253e41e", | ||
"amount": 2, | ||
"secret": "407915bc212be61a77e3e6d2aeb4c727980bda51cd06a6afc29e2861768a7837", | ||
"C": "02bc9097997d81afb2cc7346b5e4345a9346bd2a506eb7958598a72f0cf85163ea" | ||
}, | ||
{ | ||
"id": "009a1f293253e41e", | ||
"amount": 8, | ||
"secret": "fe15109314e61d7756b0f8ee0f23a624acaa3f4e042f61433c728c7057b931be", | ||
"C": "029e8e5050b890a7d6c0968db16bc1d5d5fa040ea1de284f6ec69d61299f671059" | ||
} | ||
] | ||
``` | ||
|
||
## Settings | ||
The settings for this nut indicate the supported method-unit pairs for minting and whether minting is supported or not. They are part of the info response of the mint ([NUT-06][06]) which in this case reads | ||
```json | ||
{ | ||
"14": { | ||
ngutech21 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"supported": true, | ||
"methods": [ | ||
{ | ||
"method": "btconchain", | ||
"unit": "sat", | ||
"min_amount": 10000, | ||
"max_amount": 1000000 | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
[00]: 00.md | ||
[01]: 01.md | ||
[02]: 02.md | ||
[03]: 03.md | ||
[04]: 04.md | ||
[05]: 05.md | ||
[06]: 06.md | ||
[07]: 07.md | ||
[08]: 08.md | ||
[09]: 09.md | ||
[10]: 10.md | ||
[11]: 11.md | ||
[12]: 12.md |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Note: All
PostMintQuoteBtcOnchainRequest
's are denominated in sat.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.
Why should we remove the unit-field from the PostMintQuoteOnchainRequest? If the mint uses blink as a backend for handling the onchain transactions it can support onchain snd/receive with usd as a currency. Hopefully in the future there will be similar services. https://dev.blink.sv/api/usd-onchain-send
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.
This is a question of scoping this NUT. To support other units where a conversion rate is involved how expiration is handled as well as how confirmation time is defined is much more important as the conversion rate could change outside an acceptable slippage. So in order to support other units how confirmation and expiration is defined needs to be included as well.