Skip to main content
OpenQRS
Tools
Current language: English
100% Private

Crypto wallet QR code generator

100% Private & Local — Your data never leaves your browser. These QR codes are permanent and will never expire.

Crypto wallet settings

Sets the URI scheme and how the amount is written. An address sent on the wrong network is usually unrecoverable.

Paste it from your wallet's receive screen. Typing it by hand is how addresses go wrong.

Paste the Bitcoin receiving address from your wallet's receive screen.

Optional, in whole coins — BTC, ETH, SOL, LTC or DOGE. Use a full stop, no thousands separator, no ticker symbol.

A short name for the recipient. Wallets that support it show this beside the address.

A note shown to the payer. It is display text only and is not written into the transaction.

Design

Module shape
Presets
Corner frame
Add a centre logo
Choose an image, or drop one herePNG, JPEG, WebP or GIF, up to 1000 KB

The image is read in this page and embedded in the code as a data: URL. It is not uploaded, and it stays inside the file you download.

More design options

The dark half of the code. Keep it well below the background in lightness.

Covers the quiet zone as well as the gaps between modules. A transparent background leaves it out of the file, so nothing is drawn with it.

Contrast 11.5:1 between the modules and the background.

Presets

PNG and WebP keep an alpha channel; the SVG simply omits the background rectangle. Whatever the code is placed on becomes the light half of the contrast.

Gradient

A gradient fills the dark modules only. Its lighter end sets the contrast a scanner actually gets, so both ends have to stay dark.

The second colour, used only while a gradient is selected. It is measured for contrast alongside the first.

45°

Degrees clockwise from a left-to-right sweep. A radial gradient spreads from the centre outwards, so the angle applies to a linear one only.

Module shape

Rounded shapes cover less of each cell. The centre stays covered, which is where a decoder samples, but a small print of a dense code reads more reliably as squares.

Corner frame

The ring of the three finder patterns.

Corner centre

The eye inside each finder pattern.

4 modules

The blank margin around the code, measured in modules. 4 is the specified minimum.

Higher recovery survives more damage and costs capacity, so the same content produces a denser symbol.

A logo sits at the centre and holds the level at H. Its width limit follows the symbol: 14% on the smallest code, 30% on a dense one.

Live preview & export

Export

Export

Raster, for screens

Complete the form to enable the downloads.

Export size and encoded text
Payload
Nothing encoded yet
Symbol
Not built yet
Recovery
H

Waiting for input

Export size

Between 64 and 4096 pixels. Exporting at 1024 px.

Encoded text

Build a scannable receiving code for one of five networks, with an optional amount and note. The address is used exactly as you type it and is never sent anywhere.

When someone scans it

A wallet app reads the URI, pre-fills the recipient, and shows any amount and note as an editable payment request. Nothing is signed or sent until the payer confirms it in their own wallet.

What each network's URI looks like

Bitcoin, Litecoin and Dogecoin all use the BIP-21 shape: the scheme name, a colon, the address, and optional query parameters. The amount is written in whole coins as a decimal — amount=0.005 means five thousandths of a bitcoin — and the label and message are percent-encoded.

Ethereum uses EIP-681, where the value parameter is denominated in wei rather than ether. The specification encourages scientific notation, so 0.25 ETH is written as value=2.5e17. There are no label or message parameters in EIP-681, which is why those two fields disappear when you select Ethereum.

Solana Pay defines its own transfer request: solana: followed by the base58 recipient key, with amount in SOL and optional label and message. The specification caps the amount at nine decimal places, which is SOL's precision, and requires wallets to reject a URI carrying more.

The address is encoded exactly as you enter it, including its case. Bech32 Bitcoin addresses are case-insensitive and could be uppercased to fit the QR alphanumeric mode and shrink the symbol, but legacy base58 addresses are case-sensitive and uppercasing one destroys it. Applying that optimisation only sometimes is the kind of conditional behaviour that produces a broken code in the one case nobody tested, so it is not applied at all.

  • bitcoin:bc1q…?amount=0.005&label=Riverside%20Bookshop
  • ethereum:0x…?value=2.5e17
  • solana:7xKX…?amount=1.5&label=Riverside%20Bookshop

The amount is a request, not a commitment

Every scheme here treats the amount as a suggestion to the sending wallet. Many wallets pre-fill the field and let the payer edit it before signing. Some ignore the parameter entirely and open with an empty amount. None of them are obliged to honour it, and there is no mechanism in a QR code that could make them.

BIP-21 does define a req- prefix for parameters a wallet must understand or reject, but that governs whether the wallet parses the URI, not whether the human pays the figure. Treat a printed amount as a convenience that saves typing, and reconcile what actually arrived against what you asked for.

Amounts also do not carry an invoice reference. The message field is display text for the payer; it is not written into the transaction and does not reach you with the funds. Matching an incoming payment to an order means using a fresh address per order, which a single printed code cannot do.

Verify the address before the code leaves your screen

This site cannot verify an address. It checks only that what you entered matches the character set and rough length of the network you selected, which catches an obvious paste error and nothing more. It cannot tell whether the address belongs to you, whether the wallet still exists, or whether the string was substituted between your wallet and this field. There is no lookup to make, because there is no network request on this page at all.

Address-swapping malware is a real and ordinary threat: clipboard hijackers watch for a copied wallet address and replace it with the attacker's. The substituted address is well-formed, so it passes every format check, and the resulting code is perfectly valid — for someone else. Transfers on these networks are final, there is no chargeback, and no support desk can pull the funds back.

The defence is short and non-negotiable. After the code renders, scan it with the phone you would use to pay, and compare the address the wallet shows against your wallet's receive screen character by character — the first and last six characters catch most substitutions, the full string catches the rest. Then send a small test amount to yourself before the code is printed at scale. Do this again after any reprint from a saved file.

Questions and answers

Does the code hold my private key or seed phrase?

No, and never enter either into any web page. This tool takes a receiving address, which is public information you are meant to share. A private key or recovery phrase gives away control of the wallet itself, and no legitimate generator, exchange or support agent has any reason to ask for one.

Can a damaged or dirty printed code send funds to the wrong address?

No. QR codes carry Reed-Solomon error correction, and the decoder either reconstructs the exact original string or fails outright — it does not return a plausible but different address. Damage beyond the recovery capacity produces a scan failure, which is safe. The real risk is a wrong address encoded correctly in the first place.

Why does the Ethereum option hide the label and message fields?

Because EIP-681 does not define them. Adding parameters a specification does not describe means wallets either ignore them or treat the URI as malformed, and a malformed URI is worse than a missing label. BIP-21 and Solana Pay both define label and message, so the fields appear for those four networks.

Will this work for a token rather than the native coin?

Not from this page. ERC-20 transfers under EIP-681 need a contract address and a function call in the URI, and Solana Pay needs an spl-token mint parameter — both are easy to get subtly wrong in ways that lose funds. Use your wallet's own request feature, which knows the token's decimals and contract.

How a static QR code works

Every code on this site is static: the payload is written into the black and white modules themselves. Nothing is looked up when the code is read, no server of ours takes part, and no subscription holds the printed code up. The same property is the limit — once it is printed, what it contains cannot be changed.

Three things then decide whether a printed code reads: how many bytes the payload came to, which recovery level absorbs the damage, and how wide a single module ends up on paper. These guides work through each of them with the numbers.