diff --git a/A3.md b/A3.md new file mode 100644 index 0000000000..77bdec1d3f --- /dev/null +++ b/A3.md @@ -0,0 +1,132 @@ +# NIP-A3 + +## payto: Payment Targets (RFC-8905) + +### Event Kind + +This NIP defines `kind:10133` for payment target events. This kind is **replaceable**. + +`optional` `author:atxmj` + +This NIP standardizes payment and tip invocations using the [RFC-8905 (payto:) URI scheme](https://www.rfc-editor.org/rfc/rfc8905.html) for payment targets. + +### Broadcasting + +Clients *may* allow users to specify payment targets consisting of `type` and `authority` values to generate a kind `10133` event with `payto` tags for payment or tip invocations. + +**Client Implementation:** +1. Allow users to input `type` and `authority` pairs +2. Validate inputs according to the rules below +3. Optionally warn users if a `type` is not recognized (but allow submission) +4. Broadcast the event with `payto` tags + +#### Tag Format + +Payment targets are specified using `payto` tags with the following structure: + +```text +["payto", "", "", "", "", ...] +``` + +Where: +- The first element is always the literal string `"payto"` +- The second element is the payment `type` (e.g., `"bitcoin"`, `"lightning"`) +- The third element is the `authority` (e.g., address, username) +- Additional elements are optional and reserved for future RFC-8905 features + +Clients **must** understand elements 0–2; they **may ignore** any additional elements for forward compatibility. + +#### Validation + +- `type`: Lowercase letters (a-z), digits (0-9), and hyphens (-). Types are case-insensitive; normalize to lowercase. +- `authority`: URL-safe; URL-encode special characters. Format depends on the payment system. +- Clients may perform additional payment-system-specific validation for recognized types. + +### Broadcasting Example + +```json +{ + "pubkey": "afc93622eb4d79c0fb75e56e0c14553f7214b0a466abeba14cb38968c6755e6a", + "kind": 10133, + "content": "", + "tags": [ + ["payto", "bitcoin", "bc1qxq66e0t8d7ugdecwnmv58e90tpry23nc84pg9k"], + ["payto", "nano", "nano_1dctqbmqxfppo9pswbm6kg9d4s4mbraqn8i4m7ob9gnzz91aurmuho48jx3c"], + ["payto", "unknowntype", "l7tbta5b9xze6ckkfc99uohzxd009b0r"] + ], + ... +} +``` + +### Recommended Payment Target Types + +| Payment Target Type | Long Stylization | Short Stylization | Symbol | References | +| :------------------ | :---------------- | :---------------- | :----- | :--------- | +| bitcoin | Bitcoin | BTC | ₿ | https://bitcoin.design/ | +| cashme | Cash App | Cash App | $,£ | https://cash.app/press | +| ethereum | Ethereum | ETH | Ξ | https://ethereum.org/assets/#brand | +| lightning | Lightning Network | LBTC | 丰 | https://github.com/shocknet/bitcoin-lightning-logo | +| monero | Monero | XMR | ɱ | https://www.getmonero.org/press-kit/ | +| nano | Nano | XNO | Ӿ | https://nano.org/en/currency | +| revolut | Revolut | Revolut | N/A | https://revolut.me | +| venmo | Venmo | Venmo | $ | https://venmo.com/pay | + +### Observation + +For each `payto` tag in kind `10133` events, clients *should* assemble a `payto:///` URI and render it as a button or link. + +**Client Implementation:** +1. Parse each `payto` tag from the event +2. Optionally validate `type` and `authority` fields and filter invalid tags +3. Assemble full `payto:///` URIs +4. For **recognized** types, render with associated icons and stylization from the table above +5. For **unrecognized** types, either ignore or use generic stylization +6. If multiple targets exist, render the first one, all of them, or a dropdown selector + +### Observation Example + +```json +{ + "pubkey": "afc93622eb4d79c0fb75e56e0c14553f7214b0a466abeba14cb38968c6755e6a", + "kind": 10133, + "content": "", + "tags": [ + ["payto", "bitcoin", "bc1qxq66e0t8d7ugdecwnmv58e90tpry23nc84pg9k"], + ["payto", "nano", "nano_1dctqbmqxfppo9pswbm6kg9d4s4mbraqn8i4m7ob9gnzz91aurmuho48jx3c"], + ["payto", "unknowntype", "l7tbta5b9xze6ckkfc99uohzxd009b0r"] + ], + ... +} +``` + +Assembled URIs: +- `payto://bitcoin/bc1qxq66e0t8d7ugdecwnmv58e90tpry23nc84pg9k` (recognized) +- `payto://nano/nano_1dctqbmqxfppo9pswbm6kg9d4s4mbraqn8i4m7ob9gnzz91aurmuho48jx3c` (recognized) +- `payto://unknowntype/l7tbta5b9xze6ckkfc99uohzxd009b0r` (unrecognized) + +## Implementation Notes + +### Integration with NIP-57 Zaps + +Clients may use `payto` lightning entries as an alternative or complement to `lud16` for zap functionality. The `authority` field should contain a Lightning address (e.g., `user@wallet.example.com`) or LNURL. + +Example: + +```json +[ + { + "kind": 0, + "content": "{\"lud16\":\"user@wallet.example.com\"}", + "pubkey": "..." + }, + { + "kind": 10133, + "content": "", + "tags": [ + ["payto", "lightning", "user@wallet.example.com"], + ["payto", "bitcoin", "bc1q..."] + ], + "pubkey": "..." + } +] +``` \ No newline at end of file diff --git a/README.md b/README.md index ccae3aa006..d463ddcb99 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos - [NIP-C0: Code Snippets](C0.md) - [NIP-C7: Chats](C7.md) - [NIP-EE: E2EE Messaging using MLS Protocol](EE.md) +- [NIP-A3: payto: Payment Targets (RFC-8905)](A3.md) ## Event Kinds | kind | description | NIP | @@ -211,6 +212,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos | `10051` | KeyPackage Relays List | [EE](EE.md) | | `10063` | User server list | [Blossom][blossom] | | `10096` | File storage server list | [96](96.md) (deprecated) | +| `10133` | Payment Targets | [A3](A3.md) | | `10166` | Relay Monitor Announcement | [66](66.md) | | `10312` | Room Presence | [53](53.md) | | `10377` | Proxy Announcement | [Nostr Epoxy][nostr-epoxy] |