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?
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @sbddesign
  • Unknown BIP21 support
    Unknown lightning support
    Link to issue:
    Needs Testing
  • Scans BIP21 QR codes Scans BIP21
    Does not scan BIP21 QR codesDoesn't recognize lightning
    Doesn't create BIP21 QR codes
    Link to issue:Issue
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @benthecarman
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Creates BIP21 QR codes Creates

    Description

    Scans BIP21 QR codes and recognises lightning addresses. Generates BIP21 QR code without lightning parameter

    Link to issue:
    Tested by @MichaelEjila
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes

    Description

    QR code is not a valid bitcoin lightning invoice

    Link to issue:
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @john_zaprite
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes

    Description

    Asks me to select a wallet, and I can choose my lightning wallet or on-chain wallet.

    Link to issue:
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Does not scan BIP21 QR codesDoesn't recognize lightning
    Doesn't create BIP21 QR codes

    Description

    Takes user directly to on-chain payment screen.

    Link to issue:
    Tested by @pete001
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Creates BIP21 QR codes Creates

    Description

    The BTCPayServer back-office Wallet > Send page will scan BIP21 URIs; Send > Wallet is on-chain only, so lightning is N/A in this context. The POS or store front-end is capable of generating a BIP21 URI containing a BOLT11 invoice if the admin turns this feature on in the settings. Props to @bitkarrot for a previous testing attempt.

    Link to issue:
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Creates BIP21 QR codes Creates

    Description

    After the most recent update, I scanned a BIP21 QR and CashApp recognized the lightning invoice. When scanning a BIP21 QR with an expired invoice, it falls back to the on-chain address. When receiving, it generates a BIP21 QR by default.

    Link to issue:
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Doesn't create BIP21 QR codes

    Description

    Pulls in the entire string including the 'bitcoin:', but I think it sees it as an on-chain address

    Link to issue:
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Does not scan BIP21 QR codesDoesn't recognize lightning
    Doesn't create BIP21 QR codes
    Link to issue:Issue
    Tested by @jcarlolife
  • Unknown BIP21 support
    Unknown lightning support
    Link to issue:
    Needs Testing
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @moneyball
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Doesn't create BIP21 QR codes

    Description

    Can decode the QRcode that contains a BIP21 URI with bolt11 and the external onchain fallback. The URI can also be pasted, the onchain address is detected and users can send

    Link to issue:
    Tested by @theDavidCoen
  • Unknown BIP21 support
    Unknown lightning support
    Link to issue:
    Needs Testing
  • Unknown BIP21 support
    Unknown lightning support
    Link to issue:
    Needs Testing
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @antuz123
  • Scans BIP21 QR codes Scans BIP21
    Does not scan BIP21 QR codesDoesn't recognize lightning
    Creates BIP21 QR codes Creates

    Description

    The website and mobile apps do support creating a BIP21 QR code for deposits, but not with a lightning param.

    Link to issue:
    Tested by @PierreRochard
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Doesn't create BIP21 QR codes
    Link to issue:Issue
    Tested by @bosch
  • Unknown BIP21 support
    Unknown lightning support
    Link to issue:
    Needs Testing
  • Unknown BIP21 support
    Not Applicable
    Creates BIP21 QR codes Creates

    Description

    OpenNode is a Lightning Payment Provider that allows merchants to accept bitcoin. For developers, they provide an API to generate and manage generic "charges" that can be paid over either a bitcoin transaction or a lightning invoice. The charges API response object includes a `uri` field which contains a BIP21 URI + BOLT11 invoice.

    Link to issue:
    Tested by @alexlwn123
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Does not scan BIP21 QR codesDoesn't recognize lightning
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @bruteforcecat
  • Scans BIP21 QR codes Scans BIP21
    Not Applicable
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @bosch
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning

    Description

    Needed a channel open to test but seemed to read the invoice.

    Link to issue:
    Tested by @bosch
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes

    Description

    Strike has been updated to recognize the lightning param after scanning

    Link to issue:
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes
    Link to issue:
    Tested by @john_zaprite
  • Scans BIP21 QR codes Scans BIP21
    Recognizes the lightning parameterLightning
    Doesn't create BIP21 QR codes

    Description

    Zap defaults to on-chain if the included invoice is expired, but it recognizes Lightning when the invoice is still valid.

    Link to issue:Issue
    Tested by @velaia
  • Does not scan BIP21 QR codes Doesn't scan BIP21
    Does not scan BIP21 QR codesDoesn't recognize lightning
    Doesn't create BIP21 QR codes

    Description

    This looks like an on-chain QR code...

    Link to issue:
    No support. Open an issue!
    Tested by @sbddesign
  • Scans BIP21 QR codes Scans BIP21
    Does not scan BIP21 QR codesDoesn't recognize lightning
    Doesn't create BIP21 QR codes
    Link to issue:Issue
    Tested by @bosch

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.