Skip to content
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-18: Payment Requests #124

Merged
merged 27 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions 18.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# NUT-XX: Payment Requests
callebtc marked this conversation as resolved.
Show resolved Hide resolved

`optional`

---

This NUT introduces a standardised format for payment requests, that supply a sending wallet with all information necessary to complete the transaction. This enables many use-cases where a transaction is better initiated by the receiver (e.g. point of sale).

## Flow
Copy link
Contributor

@ok300 ok300 Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it would be helpful to indicate in the Flow at which point user interaction or confirmation is needed (from the payer side), and if there is anything the app must / should show to the user before confirmation, similar to LNURL-pay / LNURL-withdraw.


1. Receiver creates a payment request, encodes it and displays it to the sender
2. Sender scans the request and constructs a matching token
3. Sender sends the token according to the transport specified in the payment request
4. Receiver receives the token and finalises the transaction

## Payment Request

A Payment Request is defined as follows

```json
{
"i": str <optional>,
callebtc marked this conversation as resolved.
Show resolved Hide resolved
"a": int <optional>,
"u": str <optional>,
"r": bool <optional>,
"m": Array[str] <optional>,
"d": str <optional>,
"t": Array[Transport]
}
```

while Transport is defined as

- `i`: Payment id to be included in the payment payload
callebtc marked this conversation as resolved.
Show resolved Hide resolved
- `a`: The amount of the requested payment
- `u`: The unit of the requested payment (MUST be set if `a` is set)
- `s`: Whether the payment request is for single use
- `m`: A set of mints from which the payment is requested
- `d`: A human readable description that the sending wallet will display after scanning the request
- `t`: The method of transport chosen to transmit the payment (can be multiple, sorted by preference)

## Transport

Transport specifies methods for sending the ecash to the receiver. A transport consists of a type and a target.

```json
{
"t": str,
"a": str,
"g": Array[Array[str, str]] <optional>
}
```

- t: type of Transport
- a: target of Transport
- g: optional tags for the Transport

### Transport types

The supported transport types are:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which are the transport types? Looks like a list was intended here, but missing.


### Tags

Tags are an optional array of `[tag, value, value, ...]` tuples that can be used to specify additional features about the transport. A single tag can have multiple values.

#### Nostr

- type: `nostr`
- target: `<nprofile>`
- tags: `[["n", "17"]]`

The `n` tag specifies the NIPs the receiver supports. At least one tag value MUST be specified. For [NIP-17](https://github.com/nostr-protocol/nips/blob/master/17.md) direct messages, the sender sends a `PaymentRequestPayload` as the message content.

[NIP-04](https://github.com/nostr-protocol/nips/blob/master/04.md) SHOULDNT be used because it is deprecated and reveals metadata about sender and receiver public keys.

#### HTTP POST

- type: `post`
- target: `<endpoint url>`

The execute the payment, the sender makes a `POST` request to the specified endpoint URL with the `PaymentRequestPayload` as the body.

## Payment payload

If not specified otherwise, the payload sent to the receiver is a `PaymentRequestPayload` JSON serialized object as follows:

```json
{
"id": str <optional>,
"memo": str <optional>,
"mint": str,
"unit": <str_enum>,
"proofs": Array<Proof>
}
```

Here, `id` is the payment id (corresponding to `i` in request), `memo` is an optional memo to be sent to the receiver with the payment, `mint` is the mint URL from which the ecash is from, `unit` is the unit of the payment, and `proofs` is an array of proofs (see [NUT-00][00], can also include DLEQ proofs).

## Encoded Request

The payment request is serialized using CBOR, encoded in `base64_urlsafe`, together with a prefix `creq` and a version `A`:

`"creq" + "A" + base64(CBOR(PaymentRequest))`

_Example_

```sh
creqAaVhQRVhVWNzYXRhTXgiaHR0cHM6Ly9taW50Lm1pbmliaXRzLmNhc2gvQml0Y29pbmFEeCNQbGVzYXNlIHBheSB0aGUgdmVyeSBmaXJzdCBjYXNodSBwcmFUgaJhVGVub3N0cmJUYXhGbnByb2ZpbGUxcXFzZG11cDZlMno2bWNwZXVlNno2a2wwOGhlNDloY2VuNXhucmMzdG5wdncwbWRndGplbWgwc3V4YTBrag
```

[00]: 00.md
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ Wallets and mints `MUST` implement all mandatory specs and `CAN` implement optio
| [12][12] | DLEQ proofs | [Nutshell][py], [cdk-cli] | [Nutshell][py], [cdk-mintd], [nutmix] |
| [13][13] | Deterministic secrets | [Nutshell][py], [Moksha][moksha], [cashu-ts][ts], [cdk-cli], [gonuts] | - |
| [14][14] | Hashed Timelock Contracts (HTLCs) | [Nutshell][py], [cdk-cli] | [Nutshell][py], [cdk-mintd], [nutmix] |
| [15][15] | Partial multi-path payments (MPP) | [Nutshell][py] | [Nutshell][py], [nutmix] |
| [15][15] | Partial multi-path payments (MPP) | [Nutshell][py] | [Nutshell][py] |
| [16][16] | Animated QR codes | [Cashu.me][cashume] | - |
| [17][17] | WebSocket subscriptions | [Nutshell][py] | [Nutshell][py] |
| [18][18] | Payment requests | [Cashu.me][cashume], [Boardwalk][bwc] | - |

#### Wallets:

Expand All @@ -45,7 +46,7 @@ Wallets and mints `MUST` implement all mandatory specs and `CAN` implement optio
- [Nutstash][ns]
- [Cashu.me][cashume]
- [Gonuts][gonuts]
- [Boardwalk Cash][bwc]
- [Boardwalk][bwc]

#### Mints:

Expand Down Expand Up @@ -87,3 +88,4 @@ Wallets and mints `MUST` implement all mandatory specs and `CAN` implement optio
[15]: 15.md
[16]: 16.md
[17]: 17.md
[18]: 18.md