-
Notifications
You must be signed in to change notification settings - Fork 55
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
On chain mint and melt #194
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,11 +1,12 @@ | ||||||
NUT-18: Mint tokens Bitcoin On-Chain | ||||||
NUT-22: Mint tokens Bitcoin On-Chain | ||||||
========================== | ||||||
|
||||||
`optional` | ||||||
|
||||||
`depends on: [NUT-19][19]` | ||||||
--- | ||||||
|
||||||
This NUT describes the process of minting tokens on Bitcoin On-Chain analog to NUT-04 for Bitcoin Lightning. | ||||||
This NUT describes the process of minting tokens on Bitcoin On-Chain analog to [NUT-04][04] for Bitcoin Lightning. | ||||||
|
||||||
# Mint quote | ||||||
|
||||||
|
@@ -20,7 +21,8 @@ The wallet of `Alice` includes the following `PostMintQuoteBtcOnchainRequest` da | |||||
```json | ||||||
{ | ||||||
"amount": <int>, | ||||||
"unit": <str_enum["sat"]> | ||||||
"unit": <str_enum["sat"]>, | ||||||
"pubkey": <str> | ||||||
} | ||||||
``` | ||||||
with the requested `amount` and the `unit`. | ||||||
|
@@ -31,41 +33,41 @@ The wallet of `Alice` includes the following `PostMintQuoteBtcOnchainRequest` da | |||||
{ | ||||||
"quote": <str>, | ||||||
"address": <str>, | ||||||
"state": <str_enum[STATE]>, | ||||||
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.
Suggested change
since in other places throughout this NUT |
||||||
"expiry": <int> | ||||||
"expiry": <int>, | ||||||
"unconfirmed_amount", <int>, | ||||||
"amount_paid": <int>, | ||||||
"amount_issued": <int>, | ||||||
"pubkey": <str> | ||||||
} | ||||||
``` | ||||||
|
||||||
Where `quote` is the quote ID and `address` is the payment request to fulfill. | ||||||
|
||||||
`state` is an enum string field with possible values `"UNPAID"`, `"PAID"`, `"PENDING"`, `"ISSUED"`: | ||||||
- `"UNPAID"` means that the quote's request has not been paid yet. | ||||||
- `"PAID"` means that the request has been paid. | ||||||
- `"PENDING"` means that the quote is currently being issued. | ||||||
- `"ISSUED"` means that the quote has already been issued. | ||||||
Where `quote` is the quote ID and `request` is the bitcoin onchain address. `expiry` is the Unix timestamp until which the mint quote is valid. `unconfirmed_amount` is the value of UTXOs in sats that has not met the minimum confirmations set in the info endpoint. `amount_paid` is the amount that has been paid to the mint via the onchain address. `amount_issued` is the amount of ecash that has been issued for the given mint quote. `amount_paid` - `amount_issued` represents the amount of ecash a wallet can still mint. | ||||||
|
||||||
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. | ||||||
**Note**: Any UTXOs with a value less than the `min_amount` in the info response will not be added to the `amount_paid` value and will be considered dust. Ecash cannot be minted for these UTXOs. | ||||||
|
||||||
## 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" | ||||||
curl -X POST https://mint.host:3338/v1/mint/quote/btconchain -d '{"amount": 10, "unit": "sat", "pubkey": "03d56ce4e446a85bbdaa547b4ec2b073d40ff802831352b8272b7dd7a4de5a7cac"}' -H "Content-Type: application/json" | ||||||
``` | ||||||
|
||||||
Response of `Bob`: | ||||||
|
||||||
```json | ||||||
{ | ||||||
"quote": "DSGLX9kevM...", | ||||||
"address": "bc1qkyfgd7mus7ykfd7qkwakq75qsf7rtm...", | ||||||
"state": "UNPAID", | ||||||
"expiry": 1701704757 | ||||||
"request": "bc1q...", | ||||||
"expiry": 1701704757, | ||||||
"amount_paid": 0, | ||||||
"amount_issued": 0, | ||||||
"pubkey": "03d56ce4e446a85bbdaa547b4ec2b073d40ff802831352b8272b7dd7a4de5a7cac" | ||||||
} | ||||||
``` | ||||||
|
||||||
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. | ||||||
The wallet **MUST** store 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 | ||||||
|
||||||
|
@@ -83,6 +85,23 @@ Example request of `Alice` with curl: | |||||
curl -X GET https://mint.host:3338/v1/mint/quote/btconchain/DSGLX9kevM... | ||||||
``` | ||||||
|
||||||
Response of `Bob`: | ||||||
|
||||||
```json | ||||||
{ | ||||||
"quote": "DSGLX9kevM...", | ||||||
"request": "bc1q...", | ||||||
"expiry": 1701704757, | ||||||
"amount_paid": 0, | ||||||
"amount_issued": 0, | ||||||
"pubkey": "03d56ce4e446a85bbdaa547b4ec2b073d40ff802831352b8272b7dd7a4de5a7cac" | ||||||
} | ||||||
``` | ||||||
|
||||||
### Witness | ||||||
|
||||||
In order to mint ecash the wallet **MUST** include a signature as defined in [NUT-19][19]. | ||||||
|
||||||
Comment on lines
+101
to
+103
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 can be moved to the |
||||||
# 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`). | ||||||
|
@@ -96,10 +115,12 @@ The wallet `Alice` includes the following `PostMintBtcOnchainRequest` data in it | |||||
```json | ||||||
{ | ||||||
"quote": <str>, | ||||||
"outputs": <Array[BlindedMessage]> | ||||||
"outputs": <Array[BlindedMessage]>, | ||||||
"witness": <str> | ||||||
} | ||||||
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. Here as well. It's not clear if this NUT requires a Mint that requires NUT-19 signatures or only supports them. |
||||||
``` | ||||||
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 `quote` is the quote ID from the previous step and `outputs` are `BlindedMessages` (see [NUT-00][00]) that the wallet requests signatures on. The sum of the outputs must equal the amount that can be minted (`amount_paid` - `amount_issued`). `witness` is the signature on the mint quote id as defined above. | ||||||
|
||||||
The mint `Bob` then responds with a `PostMintBtcOnchainResponse`: | ||||||
|
||||||
|
@@ -130,7 +151,8 @@ curl -X POST https://mint.host:3338/v1/mint/btconchain -H "Content-Type: applica | |||||
"id": "009a1f293253e41e", | ||||||
"B_": "0288d7649652d0a83fc9c966c969fb217f15904431e61a44b14999fabc1b5d9ac6" | ||||||
} | ||||||
] | ||||||
], | ||||||
"witness": "d4b386f21f7aa7172f0994ee6e4dd966539484247ea71c99b81b8e09b1bb2acbc0026a43c221fd773471dc30d6a32b04692e6837ddaccf0830a63128308e4ee0" | ||||||
}' | ||||||
``` | ||||||
|
||||||
|
@@ -178,8 +200,7 @@ Upon receiving the `BlindSignatures` from the mint `Bob`, the wallet of `Alice` | |||||
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 | ||||||
{ | ||||||
"18": { | ||||||
"supported": true, | ||||||
"22": { | ||||||
"methods": [ | ||||||
{ | ||||||
"method": "btconchain", | ||||||
|
@@ -188,7 +209,8 @@ The settings for this nut indicate the supported method-unit pairs for minting a | |||||
"max_amount": 1000000, | ||||||
"min_confirmations": 3 | ||||||
} | ||||||
] | ||||||
], | ||||||
"disabled": false, | ||||||
} | ||||||
} | ||||||
``` | ||||||
|
@@ -206,3 +228,4 @@ The settings for this nut indicate the supported method-unit pairs for minting a | |||||
[10]: 10.md | ||||||
[11]: 11.md | ||||||
[12]: 12.md | ||||||
[19]: 19.md |
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.
NUT-19 says this should be optional, depending on whether or not the
MintInfo
requires it.