Unified QRs for Bitcoin

No more on-chain and lightning UI tabs. No more wallet interoperability issues. A simple, backwards-compatible way to request bitcoin for on-chain and lightning.

The Problem

Asking users to choose between on-chain and lightning payments can be confusing — but it's been necessary to maintain interoperability between wallets.

Most wallets either take a lightning-only or on-chain-only approach. Wallets that support both use a tab or toggle for switching between the two formats.

What if we could simplify this so the user doesn't have to make these choices? And how might we do this in a way that maintains interoperability between wallets?

Problematic UI

A Solution

BIP21 Payment URIs with an optional lightning parameter

BIP-21 defines a URI scheme for creating a “payment link”. By default, it includes an on-chain address to send funds to.

BIP-21 was designed to be extensible. The spec allows for optional parameters in the URI. Why can’t one of these parameters be used to include a BOLT 11 invoice, or even a BOLT 12 offer in the future?

Graphic representing a single, unified BIP-21 QR code

Examples

Note that every example features uppercase `bech32` strings (bitcoin addresses, invoices, and offers). When a QR code is encoded in mixed mode, it can use alphanumeric mode for the uppercase strings to reduce the resolution of the QR code and make it more easily readable by devices.

Unified QRs for Bitcoin

BIP21 URI with BOLT 11 invoice

BIP21 URI with BOLT 11 invoice

This includes an on-chain address and a BOLT 11 invoice. It is easily backwards compatible, but is quite large.

Raw Data

bitcoin:BC1QYLH3U67J673H6Y6ALV70M0PL2YZ53TZHVXGG7U?amount=0.00001&label=sbddesign%3A%20For%20lunch%20Tuesday&message=For%20lunch%20Tuesday&lightning=LNBC10U1P3PJ257PP5YZTKWJCZ5FTL5LAXKAV23ZMZEKAW37ZK6KMV80PK4XAEV5QHTZ7QDPDWD3XGER9WD5KWM36YPRX7U3QD36KUCMGYP282ETNV3SHJCQZPGXQYZ5VQSP5USYC4LK9CHSFP53KVCNVQ456GANH60D89REYKDNGSMTJ6YW3NHVQ9QYYSSQJCEWM5CJWZ4A6RFJX77C490YCED6PEMK0UPKXHY89CMM7SCT66K8GNEANWYKZGDRWRFJE69H9U5U0W57RRCSYSAS7GADWMZXC8C6T0SPJAZUP6

BIP21 URI with BOLT 12 offer

BIP21 URI with BOLT 12 offer

While BOLT 12 is not widely implemented yet, we can see that using an offer instead of an invoice reduces the QR code size significantly.

Raw Data

bitcoin:BC1QYLH3U67J673H6Y6ALV70M0PL2YZ53TZHVXGG7U?amount=0.00001&label=sbddesign%3A%20For%20lunch%20Tuesday&message=For%20lunch%20Tuesday&lightning=LNO1PG257ENXV4EZQCNEYPE82UM50YNHXGRWDAJX283QFWDPL28QQMC78YMLVHMXCSYWDK5WRJNJ36JRYG488QWLRNZYJCZS

Standard QR Codes

BIP21 URI with On-chain address

BIP21 URI with On-chain address

A standard BIP 21 URI, for reference. This has the smallest QR code, but will not work with lightning.

Raw Data

bitcoin:BC1QYLH3U67J673H6Y6ALV70M0PL2YZ53TZHVXGG7U?amount=0.00001&label=sbddesign%3A%20For%20lunch%20Tuesday&message=For%20lunch%20Tuesday

BOLT 11 Invoice

BOLT 11 Invoice

BOLT 11 invoice QR codes are already significantly large, even without the additional data of the BIP21 URI.

Raw Data

LNBC10U1P3PJ257PP5YZTKWJCZ5FTL5LAXKAV23ZMZEKAW37ZK6KMV80PK4XAEV5QHTZ7QDPDWD3XGER9WD5KWM36YPRX7U3QD36KUCMGYP282ETNV3SHJCQZPGXQYZ5VQSP5USYC4LK9CHSFP53KVCNVQ456GANH60D89REYKDNGSMTJ6YW3NHVQ9QYYSSQJCEWM5CJWZ4A6RFJX77C490YCED6PEMK0UPKXHY89CMM7SCT66K8GNEANWYKZGDRWRFJE69H9U5U0W57RRCSYSAS7GADWMZXC8C6T0SPJAZUP6

Why this technique?

BIP21 is an existing and agreed-upon standard. Most existing on-chain bitcoin wallets already support BIP21. When these wallets scan the QR code on the right, they will retrieve an on-chain address and ignore the Lightning invoice.

For Lightning wallets, adding support should be simple. They just need to know where to look for the Lightning invoice in the BIP21 URI. Wallets can also give a choice of on-chain and Lightning, if the wallet supports both.

This technique is even mentioned in the BOLT 11 spec!

Sample of a BIP21 and BOLT11 QR code
Flowchart of a decision tree for how a BIP21 QR should be interpreted

The Plan

Adoption of the a unified BIP21 QR code for bitcoin is as simple as getting more Lightning wallets, exchanges, and other bitcoin services to support it. See below for the current list of support. You can help by testing your favorite wallets and services for support, or by implementing this BIP21 support in a wallet or service that does not have support.

The most important next step is getting wallets and services to support scanning BIP21 QR codes.

Once there is wide support for scanning in place, wallets projects can decide if they want to roll out support for generating BIP 21 QR codes. Likely, most projects will not default to generating BIP21 QR codes if there is not wide support for scanning BIP21 QR codes first.

How to contribute

How to test a wallet

Testing a wallet or service is easy. Choose a bitcoin app from the list below that has not been tested yet, or choose one that is not on the list. Then, open the app, scan the QR code below, and see what happens.

BIP21 QR code with a BOLT 11 Lightning invoice

Interpreting what you see

  • If the app is an on-chain only wallet:
    • If the app fails to scan the QR code, then it can NOT scan BIP21 QR codes. Lightning is not applicable in this case.
    • If the app successfully scans the QR code and recognizes the "bc1q..." address, then it CAN scan BIP21 QR codes. Lightning is not applicable in this case.
  • If the app supports Lightning:
    • If the app scans the QR code but tries to initiate an on-chain payment using the "bc1q..." address, then it CAN scan the BIP21 QR code but can NOT recognize lightning.
    • If the app scans the QR code and tries to initiate a Lightning payment, then it CAN scan the BIP21 QR code and CAN recognize Lightning.

Optional: you may also document if the app is capable of creating a BIP21 payment URI when you request a payment. The way to determine if a QR code is a BIP21 URI is to decode the QR and see if it begins with

bitcoin:
. If this is too advanced for you or you are otherwise unsure, you can simply say "I'm not sure" for this detail; this will most commonly be a no for most wallets today.

Once you have your results, submit a PR to update the wallet_support.json file on GitHub. If you are not comfortable working with the code, then simply file an issue in our GitHub repo or message us in #unified-qr-code on Slack.

How to implement support

Here's a list of references to help with implementation and testing.

Software and services supporting BIP21

Defining support

Can the wallet or service scan a BIP21 QR code?
Can the wallet or service recognize the lightning parameter in the BIP21 URI?
Can the wallet generate it's own BIP21 QR code?
Is there an open issue or discussion about adding this feature?

    Hardware Support

    BIP21 QR codes that contain Lightning invoices can get very large. Here is documentation on how different mobile devices fare when attempting to scan these large QR codes.

    These results differ from the results above. Here, we are simply checking if an app is capable of reading the very large QR code, and disregarding whether or not it notices the Lightning invoice.

    iPhone XS

    Samsung Galaxy A12

    • Scans the QR

      Description

      Works very good. It is capable of reading the QR from a surprising distance. If the QR takes up a quarter to a half the width of the screen, it will take a second to refocus and then scan. The closer the QR is to the camera, the faster it works.

      Tested by 
      @sbddesign

    iPhone 11

    iPhone 8

    Common Questions & Concerns

    QR code size is very large

    The QR becomes large enough to cause scanning difficulties with some devices. This is a valid concern. In fact, BOLT 11 invoices alone also have scan-ability issues on some devices.

    BOLT12 offers can significantly reduce the size of the QR code. Additionally, techniques like animated QR codes or NFC could help avoid scanning problems.

    Does this take away choice from the user?

    In many situations, the user already lacks a choice in the matter. For example:

    • If the sending user has an on-chain-only wallet, then they have no choice: they can only pay on-chain.
    • If the sending user has a Lightning-only wallet, then they have no choice: they can only pay via Lightning.

    For wallets that support both on-chain and Lightning, it would be helpful to the user to default to the option that offers the lowest fees, which in most cases is going to be Lightning.

    In edge cases where the on-chain fees are actually lower than Lightning, then the wallet could opt to send on-chain or even present the user which a choice: "You can save X amount on fees, but this transaction will take longer to confirm. Is this OK?"

    Follow along

    Leave feedback and participate in the conversation on GitHub or in the Bitcoin Design slack workspace in the #unified-qr-code channel.