BIP: Layer: Applications Title: Bitcoin Request URI Scheme Author: Aleksandar Dinkov <[email protected]> Type: Standards Track Created: 2019-08-26
This BIP is inspired by BIP20 (by Luke Dashjr), BIP21 (by Nils Schneider) and most of all - FatURI (by _unwriter)
This BIP proposes a URI scheme for making a wallet complete the missing pieces of a Bitcoin transaction. The URI provides the transaction outputs, while the wallet provides the inputs (pays for it).
It represents a payment request as described in BIP-270, and aims to replace the URI scheme described in BIP-272. This URI scheme is an alternative way to pass the payment request information, to the HTTP requests described in BIP-270.
This proposal enables wallets to make payments to a non-standard script without needing to know how that script was designed.
The purpose of this URI scheme is to enable users to easily make Bitcoin transactions of various types by simply clicking links on webpages.
Websites and Applications are advised to NOT display QR codes for this URI scheme. The URIs will contain a lot of information and that would make them unpractical to display and scan.
Instead, the URIs should be displayed as clickable links and buttons.
Bitcoin URIs follow the general format for URIs as set forth in RFC 3986. The path component consists of a JSON object for a payment request.
Elements of the path 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.
bitcoinRequestUrn = "bitcoin:?" requiredParams [ "&" optionalParamsOfBIP270 ] [ "&" extendedParameters ] requiredParams = reqSvParam "&" requiredParamsOfBIP270 reqSvParam = "req-bip275" requiredParamsOfBIP270 = the required parameters of BIP-270 Payment Request optionalParamsOfBIP270 = the optional parameters of BIP-270 Payment Request extendedParameters = any extra parameters that can be added to a BIP-270 Payment Request
The scheme component ("bitcoin:") is case-insensitive, and implementations must accept any combination of uppercase and lowercase letters. The rest of the URI is case-sensitive, including the query parameter keys.
Parameter | Required | Description |
---|---|---|
req-bip275 | Yes | an empty parameter, signaling that this is a BIP-275 URI. |
The scheme should not contain any of the BIP-0021 parameters. If any of them are present in a URI containing a "req-bip275" parameter, they MUST be ignored.
The URL query keys (everything after the ":?") do not need to be ordered in a specific way. Any ordering is fine.
BIP-275 URIs can use query keys from BIPs that extend the BIP-270 payment requests with (or without) required properties (like "req-{propName}").
These URIs are quite long so it is impractical to put them in QR codes. Clients should instead register themselves as handlers for the 'bitcoin' URI scheme.
Once clients receive a URI signal, they will see the "req-bip275" property. If they cannot handle BIP-275 URIs they should signal to the user that they consider the URI invalid, as described in both BIP-21 and in BIP-270.
If they can handle BIP-275 URIs, they should get all parameters of the URI and treat it exactly as they would treat a Payment Request object received from a BIP-270 server.
This BIP is just as forward compatible as BIP-270 is. Thanks to the required parameters, future BIPs can add more properties to Payment requests (both BIP270 and BIP275 ones).
It builds upon BIP-21, but thanks to the "req-bip275" parameter, older wallets will know that this is a new (incompatible) scheme and incorrect sends will not happen. (Read more about "req-" parameters in BIP-0021)
The main reasons for reusing the "bitcoin" scheme name, instead of creating a new one are the great future-proofing of BIP-0021 (through required parameters) and the fact that the "bitcoin:" scheme is a globally recognized standard for bitcoin URIs (for example - it is a whitelisted protocol in all modern browsers).
The main advantage over BIP-272 is that it is no longer necessary to make the initial GET request to the server, in order to use BIP-270 P2P payments. This is good in multiple ways:
- Custom payment requests can be created by just writing a string, instead of needing to expose an additional HTTPS endpoint.
- Security and Privacy concerns - users can decide if they want to pay or not, without needing to announce the fact that they are considering the payment through the initial GET request.
- Record Keeping - BIP-275 URIs carry the payment information in them, meaning that it is possible to recover payment data even if the Payment Server no longer exists.
- paymentUrl = https://example.com/payments
- network = bitcoin
[ { "amount":1000000, "script":"76a914808a0e92d0d42b650f083dd223d556b410699d6f88ac" } ]
- bitcoin:?req-bip275&paymentUrl=https%3A%2F%2Fexample.com%2Fpayments&network=bitcoin&outputs=%5B%7B%22amount%22%3A1000000%2C%22script%22%3A%2276a914808a0e92d0d42b650f083dd223d556b410699d6f88ac%22%7D%5D
- paymentUrl = https://example.com/payments
- network = bitcoin
[ { "amount":1000000, "script":"76a914808a0e92d0d42b650f083dd223d556b410699d6f88ac" }, { "amount": 1000000, "script": "76a914eb280a7c70784b5136119cb889e024d22437ed4c88ac" } ]
- bitcoin:?req-bip275&paymentUrl=https%3A%2F%2Fexample.com%2Fpayments&network=bitcoin&outputs=%5B%7B%22amount%22%3A1000000%2C%22script%22%3A%2276a914808a0e92d0d42b650f083dd223d556b410699d6f88ac%22%7D%2C%7B%22amount%22%3A1000000%2C%22script%22%3A%2276a914eb280a7c70784b5136119cb889e024d22437ed4c88ac%22%7D%5D
- paymentUrl = https://example.com/payments
- network = bitcoin
[ { "amount":0.00, "script": "006a2231394878696756345179427633744870515663554551797131707a5a56646f4175740e62697462746e20697320636f6f6c0a746578742f706c61696e" } ]
- bitcoin:?req-bip275&paymentUrl=https%3A%2F%2Fexample.com%2Fpayments&network=bitcoin&outputs=%5B%7B%22amount%22%3A0%2C%22script%22%3A%22006a2231394878696756345179427633744870515663554551797131707a5a56646f4175740e62697462746e20697320636f6f6c0a746578742f706c61696e%22%7D%5D
This hex script is "1 OP_ADD 3 OP_EQUAL" (which basically means "x + 1 = 3")
- paymentUrl = https://example.com/payments
- network = bitcoin
[ { "amount":1000000, "script":"010193010387" } ]
- bitcoin:%5B%7B%22amount%22%3A1000000%2C%22script%22%3A%22010193010387%22%7D%5D?req-bip275&paymentUrl=https%3A%2F%2Fexample.com%2Fpayments&network=bitcoin&outputs=
- paymentUrl = https://example.com/payments
- network = bitcoin
- memo = Payment to Aleks
- merchantData = { "userID"="VGhlIFRpbWVzIDAzL0phbi8yMDA5IENoYW5jZWxsb3Igb24gYnJpbmsgb2Ygc2Vjb25kIGJhaWxvdXQgZm9yIGJhbmtzLg==" }
[ { "amount":1000000, "script":"76a914808a0e92d0d42b650f083dd223d556b410699d6f88ac" } ]
- bitcoin:?req-bip275&paymentUrl=https%3A%2F%2Fexample.com%2Fpayments&network=bitcoin&outputs=%5B%7B%22amount%22%3A1000000%2C%22script%22%3A%2276a914808a0e92d0d42b650f083dd223d556b410699d6f88ac%22%7D%5D&memo=Payment%20to%20Aleks&merchantData=%7B%22userID%22%3D%22VGhlIFRpbWVzIDAzL0phbi8yMDA5IENoYW5jZWxsb3Igb24gYnJpbmsgb2Ygc2Vjb25kIGJhaWxvdXQgZm9yIGJhbmtzLg%3D%3D%22%7D
- None yet...