-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
BIP 321: URI Scheme (Replace BIP 21 with a new BIP containing information about more modern usage of it) #1555
base: master
Are you sure you want to change the base?
Changes from 4 commits
8a93e77
ab95193
ff71934
836ef06
fff9ae9
62e166e
fe591e5
7fba7a4
6be4d54
37404d4
3527ddd
869b99a
d7c021a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,166 @@ | ||||||||||||
<pre> | ||||||||||||
BIP: XXXX | ||||||||||||
Layer: Applications | ||||||||||||
Title: URI Scheme | ||||||||||||
Author: Matt Corallo <[email protected]> | ||||||||||||
Comments-Summary: No comments yet. | ||||||||||||
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-XXXX | ||||||||||||
Status: Proposed | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
Type: Standards Track | ||||||||||||
Created: 2024-07-13 | ||||||||||||
</pre> | ||||||||||||
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. Missing License header, and should probably have a Replaces header:
Suggested change
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. I cannot assign this document a license given a substantial portion was written by @luke-jr. I'm happy to assign my contributions whatever license he wants for his. 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. Ah apologies, BIP 20 is licensed. 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. If this |
||||||||||||
|
||||||||||||
This BIP is a modification of [[bip-0021.mediawiki|BIP 0021]] to add information about the modern usage of bitcoin: URIs as well as provide forward-looking guidance on how to incorporate new payment instructions. BIP 21 was based on BIP 20, which was, in turn based off an earlier document by Nils Schneider. | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
|
||||||||||||
==Abstract== | ||||||||||||
This BIP proposes a URI scheme for making Bitcoin payments. | ||||||||||||
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. "making payments"?
Suggested change
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. Went with This BIP proposes a URI scheme for describing Bitcoin payment receipt information. |
||||||||||||
|
||||||||||||
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. Th Copyright section is missing. Judging from the header:
Suggested change
|
||||||||||||
==Motivation== | ||||||||||||
The purpose of this URI scheme is to enable users to easily make payments by simply clicking links on webpages or scanning QR Codes. | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
|
||||||||||||
==Specification== | ||||||||||||
|
||||||||||||
=== General rules for handling (important!) === | ||||||||||||
|
||||||||||||
Bitcoin clients MUST NOT act on URIs without getting the user's authorization. | ||||||||||||
They SHOULD require the user to manually approve each payment individually, though in some cases they MAY allow the user to automatically make this decision. | ||||||||||||
|
||||||||||||
=== Operating system integration === | ||||||||||||
Graphical bitcoin clients SHOULD register themselves as the handler for the "bitcoin:" URI scheme by default, if no other handler is already registered. If there is already a registered handler, they MAY prompt the user to change it once when they first run the client. | ||||||||||||
|
||||||||||||
=== General Format === | ||||||||||||
|
||||||||||||
Bitcoin URIs follow the general format for URIs as set forth in RFC 3986. The path component consists of a bitcoin address, and the query component provides additional payment options. | ||||||||||||
|
||||||||||||
Elements of the query component may contain characters outside the valid range. These must first be encoded according to UTF-8, and then each octet of the corresponding UTF-8 sequence must be percent-encoded as described in RFC 3986. | ||||||||||||
|
||||||||||||
=== ABNF grammar === | ||||||||||||
|
||||||||||||
(See also [[#Simpler syntax|a simpler representation of syntax]]) | ||||||||||||
|
||||||||||||
bitcoinurn = "bitcoin:" [ bitcoinaddress ] [ "?" bitcoinparams ] | ||||||||||||
bitcoinaddress = *base58 / *bech32 / *bech32m | ||||||||||||
bitcoinparams = bitcoinparam [ "&" bitcoinparams ] | ||||||||||||
bitcoinparam = [ amountparam / labelparam / messageparam / otherparam / reqparam ] | ||||||||||||
amountparam = "amount=" *digit [ "." *digit ] | ||||||||||||
labelparam = "label=" *qchar | ||||||||||||
messageparam = "message=" *qchar | ||||||||||||
otherparam = qchar *qchar [ "=" *qchar ] | ||||||||||||
reqparam = "req-" qchar *qchar [ "=" *qchar ] | ||||||||||||
|
||||||||||||
Here, "qchar" corresponds to valid characters of an RFC 3986 URI query component, excluding the "=" and "&" characters, which this BIP takes as separators. | ||||||||||||
|
||||||||||||
The scheme component ("bitcoin:") is case-insensitive, and implementations must accept any combination of uppercase and lowercase letters. The query parameter keys are also case-insensitive. Query parameter values and bitcoin address fields may be case-sensitive depending on their content. | ||||||||||||
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. It’s a good change, but please mention the case-insensitivity of query parameter keys in the Backwards Compatibility section, since BIP 21 specified query parameter keys to be case-sensitive. |
||||||||||||
|
||||||||||||
=== Bitcoin Address === | ||||||||||||
|
||||||||||||
The bitcoinaddress body MUST be either a base58 P2SH or P2PKH address, bech32 Segwit version 0 address, bech32m Segwit address, or empty. Future address formats SHOULD instead be placed in query keys as optional payment instructions to provide backwards compatibility during upgrade cycles. After new address types are near-universally supported, or for recipients wishing to avoid a standard on-chain fallback, the bitcoinaddress part of the URI MAY be left empty. | ||||||||||||
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.
Some of this last sentence repeats prior specification parts and the rest could probably be in Rationale 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 section describes normative behavior so we can't move it (otherwise its not clear you can set the address part empty), not sure which parts are redundant with elsewhere, aside from the ABNF grammar, but I prefer to have it in text as well. 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. I’m not sure what I exactly meant back then. Either way, it’s not clear to me why this mentions "After new address types are near-universally supported". If the receiver wants to only offer specific optional payment methods even while they are not broadly supported, that’s up to the receiver.
Suggested change
|
||||||||||||
|
||||||||||||
=== Query Keys === | ||||||||||||
|
||||||||||||
The following keys are defined generally and apply to any URI regardless of payment instructions: | ||||||||||||
|
||||||||||||
*label: Label for that address (e.g. name of receiver) | ||||||||||||
*address: bitcoin address | ||||||||||||
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. What is the "address" query key used for, if all base58, bech32, and bech32m addresses are permitted in the body, and new payment instructions using bech32[m] should use the HRP? Is the intent to provide a fall-back address from the set of addresses permitted in the body, in case the address in the body is not supported by the sender’s client? Alternatively, should the body contain the type that is most likely to be supported by the client? Is there a way for the receiver to express which address type they’d prefer if multiple were provided? If I wanted to express a preference for P2TR, have a P2WPKH fallback, and for people from the last decade also provide a P2PKH address, how would I do that?
|
||||||||||||
*message: message that describes the transaction to the user ([[#Examples|see examples below]]) | ||||||||||||
|
||||||||||||
The following keys are currently defined for payment instructions of various forms: | ||||||||||||
|
||||||||||||
*lightning: Lightning BOLT 11 invoices | ||||||||||||
*lno: Lightning BOLT12 offers | ||||||||||||
*sp: Silent Payment addresses | ||||||||||||
|
||||||||||||
New payment instructions using bech32 or bech32m encodings SHOULD reuse their address format's Human Readable Part as the parameter key. | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
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. In the discussion on this PR, some reviewers were suggesting using If you meant to propose that
Suggested change
|
||||||||||||
|
||||||||||||
==== Transfer amount ==== | ||||||||||||
|
||||||||||||
If an amount is provided, it MUST be specified in decimal BTC. | ||||||||||||
All amounts MUST contain no commas and use a period (.) as the separating character to separate whole numbers and decimal fractions. | ||||||||||||
I.e. amount=50.00 or amount=50 is treated as 50 BTC, and amount=50,000.00 is invalid. | ||||||||||||
|
||||||||||||
Bitcoin clients MAY display the amount in any format that is not intended to deceive the user. | ||||||||||||
They SHOULD choose a format that is foremost least confusing, and only after that most reasonable given the amount requested. | ||||||||||||
For example, so long as the majority of users work in BTC units, values should always be displayed in BTC by default, even if mBTC or TBC would otherwise be a more logical interpretation of the amount. | ||||||||||||
== Rationale == | ||||||||||||
|
||||||||||||
===Payment identifiers, not person identifiers=== | ||||||||||||
Best practices are that a unique address should be used for every transaction on-chain. | ||||||||||||
Therefore, a URI which contains an on-chain payment address MUST NOT represent an exchange of personal information, but a one-time payment instruction. URIs which represent only reusable non-address-reusing payment instructions (like Lightning BOLT12 offers or Silent Payments) MAY be reused as a wallet sees fit. | ||||||||||||
|
||||||||||||
===Accessibility (URI scheme name)=== | ||||||||||||
Should someone from the outside happen to see such a URI, the URI scheme name already gives a description. | ||||||||||||
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 sentence is confusing. Who is someone from the outside? What is "such a URI"? 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. I just removed this section. I don't think we need to justify the use of the bitcoin: prefix these days lol. |
||||||||||||
A quick search should then do the rest to help them find the resources needed to make their payment. | ||||||||||||
Other proposed names sound much more cryptic; the chance that someone googles that out of curiosity are much slimmer. | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
Also, very likely, what he will find are mostly technical specifications - not the best introduction to bitcoin. | ||||||||||||
|
||||||||||||
==Forward compatibility== | ||||||||||||
Variables which are prefixed with a req- are considered required. If a client does not implement any variables which are prefixed with req-, it MUST consider the entire URI invalid. Any other variables which are not implemented, but which are not prefixed with a req-, can be safely ignored. | ||||||||||||
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. Did you mean "query parameters" instead of variables here? |
||||||||||||
|
||||||||||||
As future new address types should be added using query parameters rather than the `bitcoinaddress` field, URIs can seamlessly support many payment instructions while senders only support legacy instructions. This allows for senders to be able to pay newer recipients while still allowing the use of more modern payment instruction formats. | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
|
||||||||||||
==Backward compatibility== | ||||||||||||
As this BIP is written, several clients already implement a bitcoin: URI scheme similar to this one, however usually without the additional "req-" prefix requirement. Thus, it is recommended that additional variables prefixed with req- not be used in a mission-critical way until a grace period of 6 months from the finalization of this BIP has passed in order to allow client developers to release new versions, and users of old clients to upgrade. | ||||||||||||
|
||||||||||||
Compared to BIP 21, this document describes standard query parameters containing payment instructions, allows bech32 and bech32m `bitcoinaddress` fields, and allow for future URIs with an empty `bitcoinaddress` field. Use of bech32 and bech32m `bitcoinaddress` fields were long-since common practice in 2024, and the `lightning` query parameter storing BOLT 11 payment instructions became common practice in the year or three leading up to 2024. Inclusion of standard query parameters was added to provide guidance on query parameter usage going forward. | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
|
||||||||||||
Any existing BIP 21 implementation should automatically be fully compliant with this BIP, as the changes only describe existing practice or impact future address format inclusion. | ||||||||||||
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. As mentioned above, BIP 21 required query parameters to be case-sensitive
while this proposal allows them to be any case. This should be mentioned in the Backward Compatibility section. |
||||||||||||
|
||||||||||||
== Appendix == | ||||||||||||
|
||||||||||||
=== Simpler syntax === | ||||||||||||
|
||||||||||||
This section is non-normative and does not cover all possible syntax. | ||||||||||||
Please see the BNF grammar above for the normative syntax. | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
|
||||||||||||
[foo] means optional, <bar> are placeholders | ||||||||||||
|
||||||||||||
<nowiki>bitcoin:<address>[?amount=<amount>][?label=<label>][?message=<message>]</nowiki> | ||||||||||||
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 section confuses me. It feels like I’m missing some context. Is this supposed to provide a simplified syntax for some part of the implementers? Who is supposed to use the simplified syntax? Under what circumstances should this syntax be used? What are the trade-offs? |
||||||||||||
|
||||||||||||
=== Examples === | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
|
||||||||||||
Just the address: | ||||||||||||
bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W | ||||||||||||
|
||||||||||||
Address with name: | ||||||||||||
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
|
||||||||||||
bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?label=Luke-Jr | ||||||||||||
|
||||||||||||
Request 20.30 BTC to "Luke-Jr": | ||||||||||||
bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=20.3&label=Luke-Jr | ||||||||||||
|
||||||||||||
Request 50 BTC with message: | ||||||||||||
bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=50&label=Luke-Jr&message=Donation%20for%20project%20xyz | ||||||||||||
|
||||||||||||
Request funds to be paid over lightning to a BOLT 11 invoice with a fallback to on-chain payments: | ||||||||||||
bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?lightning=lnbc420bogusinvoice | ||||||||||||
|
||||||||||||
Request funds to be paid over lightning to a BOLT 11 invoice with no fallback: | ||||||||||||
bitcoin:?lightning=lnbc420bogusinvoice | ||||||||||||
|
||||||||||||
Request funds to be paid over lightning to a BOLT 12 offer with no fallback: | ||||||||||||
bitcoin:?lno=lno1bogusoffer | ||||||||||||
|
||||||||||||
Request funds to be paid over lightning to a BOLT 12 offer or silent payments address with no fallback: | ||||||||||||
bitcoin:?lno=lno1bogusoffer&sp=sp1qsilentpayment | ||||||||||||
|
||||||||||||
Request funds to be paid to a silent payments address with no fallback: | ||||||||||||
bitcoin:?sp=sp1qsilentpayment | ||||||||||||
|
||||||||||||
Request funds to be paid to a silent payments address with a fallback: | ||||||||||||
bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?sp=sp1qsilentpayment | ||||||||||||
|
||||||||||||
Some future version that has variables which are (currently) not understood and required and thus invalid: | ||||||||||||
bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-somethingyoudontunderstand=50&req-somethingelseyoudontget=999 | ||||||||||||
|
||||||||||||
Some future version that has variables which are (currently) not understood but not required and thus valid: | ||||||||||||
bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?somethingyoudontunderstand=50&somethingelseyoudontget=999 | ||||||||||||
|
||||||||||||
Characters must be URI encoded properly. | ||||||||||||
|
||||||||||||
== Reference Implementations == | ||||||||||||
=== Bitcoin clients === | ||||||||||||
* Bitcoin-Qt supports the old version of Bitcoin URIs (ie without the req- prefix), with Windows and KDE integration as of commit 70f55355e29c8e45b607e782c5d76609d23cc858. | ||||||||||||
|
||||||||||||
=== Libraries === | ||||||||||||
* Javascript - https://github.com/bitcoinjs/bip21 | ||||||||||||
* Java - https://github.com/SandroMachado/BitcoinPaymentURI | ||||||||||||
* Swift - https://github.com/SandroMachado/BitcoinPaymentURISwift | ||||||||||||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
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.
Did you want to use the exact same title?
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.
Yea, I don't see why we'd change it.