-
Notifications
You must be signed in to change notification settings - Fork 1
Add BIP-321 payment methods #2
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
Merged
Merged
Changes from all commits
Commits
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 hidden or 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,160 @@ | ||
| NWC-321 | ||
| ====== | ||
|
|
||
| BIP-321 Lightning Payments | ||
| -------------------------- | ||
|
|
||
| `draft` `optional` | ||
|
|
||
| ## Summary | ||
|
|
||
| This specification defines two optional Nostr Wallet Connect methods for BIP-321: | ||
|
|
||
| - `pay` pays a Lightning payment instruction from a BIP-321 URI. | ||
| - `receive` creates a BIP-321 URI that contains one or more Lightning payment instructions. | ||
|
|
||
| ## Motivation | ||
|
|
||
| BIP-321 can put multiple payment instructions in one Bitcoin payment URI. | ||
|
|
||
| This format lets a client use one payment interface for BOLT11 invoices and BOLT12 offers. The wallet selects the instruction that it supports. | ||
|
|
||
| These methods are separate from the NWC core because BIP-321 and BOLT12 support are not available in all wallets. | ||
|
|
||
| ## Dependencies | ||
|
|
||
| Implementations of this specification use: | ||
|
|
||
| - [BIP-321](https://github.com/bitcoin/bips/blob/master/bip-0321.mediawiki) for Bitcoin payment URIs. | ||
| - [BOLT11](https://github.com/lightning/bolts/blob/master/11-payment-encoding.md) for `lightning` instructions. | ||
| - [BOLT12](https://github.com/lightning/bolts/blob/master/12-offer-encoding.md) for `lno` instructions. | ||
|
|
||
| ## Discovery | ||
|
|
||
| A wallet service advertises each supported method in its NWC info event and `get_info` response. | ||
|
|
||
| A wallet service can implement `pay`, `receive`, or both methods. An implementation of `pay` MUST support `lightning` or `lno` instructions. | ||
|
|
||
| An implementation of `receive` MUST return at least one `lightning` or `lno` instruction. | ||
|
|
||
| ## BIP-321 processing | ||
|
|
||
| The wallet service MUST parse the URI according to BIP-321. | ||
|
|
||
| The wallet service MUST make sure that the Bitcoin network matches before payment. It MUST reject a payment instruction for a different network. | ||
|
|
||
| A URI can contain `lightning`, `lno`, or both instruction types. | ||
|
|
||
| If the URI contains multiple supported instructions, the wallet service MUST select and pay only one instruction. | ||
|
|
||
| The wallet service MUST report the selected instruction in `instruction_type`. | ||
|
|
||
| The wallet service can support other BIP-321 payment instructions. Support for other instructions is outside this specification. | ||
|
|
||
| The wallet service MUST reject a URI if it cannot select a supported payment instruction. It MUST also reject unknown required parameters as BIP-321 specifies. | ||
|
|
||
| The wallet service MUST apply the BIP-321 rules for `pop` and `req-pop`. The NWC response does not replace a required proof-of-payment callback. | ||
|
|
||
| If the wallet service cannot safely open a `req-pop` URI, it MUST reject the request before payment. | ||
|
|
||
| ## Methods | ||
|
|
||
| ### `pay` | ||
|
|
||
| Pays one Lightning payment instruction from a BIP-321 URI. | ||
|
|
||
| Request: | ||
|
|
||
| ```yaml | ||
| { | ||
| "method": "pay", | ||
| "params": { | ||
| "payment": "bitcoin:?lno=lno1...", // BIP-321 URI, required | ||
| "amount": 123000, // amount in msats, required if the selected instruction has no amount | ||
| "payer_note": "string", // payer-provided message, optional | ||
| "metadata": {} // optional metadata as defined in 06.md | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The wallet service MUST reject conflicting or invalid amounts before payment. | ||
|
|
||
| If `payer_note` is not empty, the selected instruction MUST support payer-provided messages. The wallet service MUST deliver the note or reject the request before payment. | ||
|
|
||
| For a BOLT12 offer, the wallet service performs the invoice request and invoice retrieval. | ||
|
|
||
| Response: | ||
|
|
||
| ```yaml | ||
| { | ||
| "result_type": "pay", | ||
| "result": { | ||
| "transaction_id": "string", // wallet-scoped transaction identifier | ||
| "state": "settled", // "pending", "settled", or "failed" | ||
| "instruction_type": "bolt12", // "bolt11" or "bolt12" | ||
| "amount": 123000, // paid amount in msats | ||
| "fees_paid": 1000, // paid fees in msats | ||
| "payment_hash": "string", // optional if unavailable | ||
| "preimage": "string", // optional if unavailable | ||
| "payer_proof": "lnp1...", // BOLT12 payer proof, optional if unavailable | ||
| "txid": "string", // on-chain transaction identifier, optional if unavailable | ||
| "failure_reason": "string", // optional unless state is "failed" | ||
| "created_at": unixtimestamp, | ||
| "settled_at": unixtimestamp // optional unless state is "settled" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The `transaction_id` MUST identify the same transaction in later wallet records. | ||
|
|
||
| Errors: | ||
|
|
||
| - `BAD_REQUEST`: The URI or another parameter is invalid. | ||
| - `UNSUPPORTED_PAYMENT_INSTRUCTION`: The wallet cannot select a supported payment instruction. | ||
| - `UNSUPPORTED_NETWORK`: The selected instruction uses a different Bitcoin network. | ||
| - `PAYMENT_FAILED`: The wallet attempted the payment, but the payment failed. | ||
|
|
||
| The wallet service can also return applicable NWC core errors. | ||
|
|
||
| ### `receive` | ||
|
|
||
| Creates a BIP-321 URI that the client can give to a payer. | ||
|
|
||
| Request: | ||
|
|
||
| ```yaml | ||
| { | ||
| "method": "receive", | ||
| "params": { | ||
| "amount": 123000, // amount in msats, optional; omit or use null for a variable amount | ||
| "description": "string", // optional | ||
| "metadata": {} // optional metadata as defined in 06.md | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The wallet service selects the receive instruction or instructions. A client that needs a specific instruction type uses a method for that type. | ||
|
|
||
| Response: | ||
|
|
||
| ```yaml | ||
| { | ||
| "result_type": "receive", | ||
| "result": { | ||
| "bip321": "bitcoin:?lightning=lnbc...&lno=lno1...", // BIP-321 URI | ||
| "transaction_id": "string", // wallet-scoped transaction identifier, optional | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The `bip321` value MUST contain one or more wallet-selected receive instructions. Each instruction MUST use the wallet service Bitcoin network. | ||
|
|
||
| If `amount` is absent or null, the returned URI MUST accept an amount from the payer. | ||
|
|
||
| If `description` is present, the wallet service MUST include it in each selected instruction that supports descriptions. | ||
|
|
||
| Errors: | ||
|
|
||
| - `BAD_REQUEST`: A parameter is invalid. | ||
|
|
||
| The wallet service can also return applicable NWC core errors. | ||
This file contains hidden or 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
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.
Should this be called
pay_bip321?I think of "pay" as the highest-level, most general "here's a payable thing, pay it" API possible.
Here are all the things that the
payendpoint supports in our SDK, for example:bitcoin:bc1...lightning:ln...lnbc1...lno1...bc1...₿username@lexe.appusername@lexe.applnurl1...orlnurlp://domain.com/pathThere 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.
Originally was but everyone thought it'd be better to do as just pay as we hope to move this to be the standard function you call
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 guess this shifts the work of payment uri parsing and resolution from the NWC client to the server, which makes more sense and is more secure anyway - better to have clients make the resolution requests rather than have the server (which is holding the keys and the Lightning funds) open direct TCP connections to potentially-malicious webservers. And BIP 321 is flexible enough to support this - everything I listed above can be first resolved into a more direct form (HBA -> offer for example) and then passed into
payas a BIP 321 URI.