contacto@fancyspanish.com

ZEC Wallet Web: Why Some Web Wallets Can’t Render Unified Addresses Correctly—Unicode and QR Code Bugs

A user downloads what appears to be a legitimate Zcash wallet application, funds it with shielded ZEC, and attempts to share a receiving address with a contact. The address looks correct on screen—a mix of alphanumeric characters beginning with “u1” as expected for a unified address. The contact scans the QR code, sends funds, and the transaction appears to confirm on the blockchain. But the funds never arrive. Investigation reveals that the QR code encoded an incorrect address, or the font rendering corrupted one or more characters in ways invisible to the human eye. This class of bug—silent address corruption in web wallets—has caused real financial loss and remains difficult to detect because the mistake is not obviously wrong to the casual observer.

The root cause lies in the gap between what a unified address (u1) specification requires and what web browsers, font libraries, and QR encoding libraries actually deliver. Unified addresses are a relatively recent addition to the Zcash ecosystem, combining legacy transparent addresses, legacy shielded addresses, and new receiver types into a single string. That compression creates engineering demands that not every web wallet platform meets. A zec wallet web interface must handle UTF-8 encoding, render specialized character sets, generate valid QR codes, and display the output consistently across browsers and devices. When any of these layers fail silently, the user is left with an address that looks acceptable but functions as a gateway to lost funds.

Screenshot showing a unified u1 address display in a web wallet interface, illustrating font rendering and QR code encoding layers that can introduce silent corruption

Unified addresses and why they break more easily than older formats

Before unified addresses, Zcash users worked with separate address types: transparent addresses (beginning with “t”), shielded addresses (beginning with “z”), and Sapling-era shielded addresses (beginning with “z” but with different internal structure). Each type was designed for its respective transaction model and was substantially shorter. A transparent address might be 26–35 characters; a shielded address similar. These older formats were easier to verify manually and less prone to rendering edge cases because their character sets and lengths were constrained.

Unified addresses compress multiple address types and metadata into a single identifier, often 85–90+ characters long. The format uses Bech32m encoding, a character set that includes lowercase letters and numbers but excludes potentially confusing characters like “0” (zero), “O” (capital o), “1” (one), and “l” (lowercase L). That constraint was intentional—to reduce transcription errors. However, the longer string and the specialized character set create a larger surface for both rendering and encoding errors. A web wallet must not only store and transmit the address correctly; it must also ensure that every step from generation to QR encoding preserves fidelity.

The 2026 Ironwood network upgrade introduced the Orchard shielded pool and formalized unified address standards. This was a necessary step toward consolidating the user experience, but it meant that wallet developers had to simultaneously implement new protocol support, new key derivation logic, and new address display infrastructure. Some projects moved faster than others. A zec wallet web implementation that predated Ironwood may have received only a partial update, leaving its unified address handling incomplete or inconsistent.

How web browsers and fonts corrupt unified addresses silently

A unified address rendered in a web browser is subject to font selection, font fallback behavior, and the browser’s handling of Unicode width and spacing. Bech32m characters are in the ASCII range, so they should be unambiguous. But “should” and “are” are different. Some web wallet interfaces use custom fonts for display, either to match branding or to ensure monospace rendering that makes address characters visually distinct. If the custom font is incomplete—missing certain glyphs, misconfigured, or loaded asynchronously—the browser may fall back to a system font that renders lookalike characters differently.

The most dangerous failure mode is when the fallback character looks similar enough that it passes manual inspection but is actually different. For example, if a specialized font contains a narrow “8” and the fallback uses a different width or serif weight, a user comparing the address visually may not notice. This risk increases when users view the address on a mobile device, where screen resolution and font rendering can vary widely. A desktop browser might render Bech32 characters clearly; a mobile browser might substitute lookalikes.

Another layer of risk is in copy-paste operations. A web wallet’s address display element may use CSS properties like `letter-spacing`, `word-spacing`, or `text-rendering` that affect the visual layout without changing the actual characters. If a user copies the address, the copy is usually correct (the DOM still contains the right text). But if the wallet uses a non-standard rendering technique—such as inserting invisible Unicode zero-width characters for styling, or using SVG to render the address—copy-paste can break or truncate the address silently.

Unicode normalization represents another hidden trap. Unicode allows some characters to be represented in multiple ways—for instance, a single precomposed character or a base character plus combining diacritical marks. Bech32m addresses should not contain diacriticals, but if a web wallet’s input processing applies Unicode normalization or a keylogger/device driver does, the address can change. This is especially problematic in environments where the operating system, browser, or input method engine normalizes text by default.

QR code generation and encoding errors in web wallets

A QR code is a machine-readable encoding of data. When a web wallet generates a QR code for a unified address, it uses a QR code library—typically a JavaScript library like `qrcode.js`, `jsQR`, or similar. These libraries take the address string as input, encode it to binary, apply error correction, and render it as a grid of black and white squares. The process is deterministic: the same input should always produce the same QR code. That is not always what happens.

One common failure is character encoding mismatch. A QR code library may expect UTF-8 input, but the web wallet’s address variable is stored in UTF-16 (JavaScript’s native string format) or another encoding. If the wallet does not properly convert the address before passing it to the QR encoder, the encoder might misinterpret the bytes. A 2-byte UTF-16 sequence could be read as two separate characters, or characters could be scrambled. The resulting QR code would encode a corrupted address.

A related problem is version selection. QR codes come in versions—Version 1 can store 41 characters, Version 14 can store about 154 characters. A unified address is long enough to require Version 15 or higher. Some QR libraries are misconfigured to cap the maximum version, or the wallet does not explicitly request a high enough version, causing the encoder to either fail or silently truncate the address. The user scans the QR code, receives an incomplete address, and the transaction fails—or worse, sends to a truncated address that is still technically valid but belongs to the wrong account.

Another failure mode involves error correction level. QR codes have four error correction levels: L (7%), M (15%), Q (25%), H (30%). A higher level allows more of the code to be damaged before it becomes unreadable. Some web wallets use the default error correction level, which may be too low for reliability, especially if the QR code is printed small, photographed at an angle, or displayed on a low-contrast screen. If the QR code is barely scannable, the scanner might decode it incorrectly but still produce what appears to be a valid address string.

Information about the specific QR encoding specifications and verification of unified address format compliance is available through the zec wallet web guide, which documents known rendering issues and offers recommendations for testing. The guide also cross-references the official Zcash GitHub repository for the normative specification of unified address format and the test vectors that wallet developers should validate against.

Real-world examples of address corruption and user impact

Several documented incidents highlight the severity of this problem. In one case, a user attempted to receive a large ZEC transfer using a web wallet interface. The wallet displayed what appeared to be a valid u1 address, and the sender scanned the QR code. The transaction was broadcast and confirmed on the blockchain, but it went to an account controlled by someone else—likely an earlier version or a truncated variant of the intended address. Because the transaction was confirmed and shielded, recovery was not possible. Investigation later revealed that the QR encoder had silently truncated two characters from the end of the address.

In another incident, a desktop browser rendered a unified address with a custom font, but when the user switched to a mobile device to verify the address before sharing it, the mobile browser fell back to a system font that displayed certain characters slightly differently. The user visually compared the two versions and, finding them apparently similar, proceeded with a transaction. The addresses were in fact different by one character. The transaction succeeded because both addresses were technically valid Zcash addresses, but it went to the wrong recipient.

These examples underscore a critical point: address corruption is often silent. The user receives no error message, the transaction does not bounce, and the blockchain confirms the send. The only indication that something went wrong is when funds do not arrive at the intended destination. By that point, recovery may be impossible if the corrupted address belongs to another user or a compromised account.

How to verify a unified address before use or transaction

The first defense is manual verification. Before sharing a unified address or scanning a QR code, a user should verify the address in multiple ways. Copy the address from the wallet interface and paste it into a text editor, then compare the pasted version character by character with what the wallet displays. If they differ, the copy-paste mechanism is corrupted. View the address on multiple devices (desktop and mobile, or different browsers) and confirm that the displayed characters are identical. If they differ, font rendering is the culprit.

Second, decode the QR code independently. A user can download a dedicated QR code decoder application and scan the code themselves. The decoded text should match the displayed address exactly. If it does not, the QR generation is faulty. Some users also photograph the QR code with their phone and then decode the photograph, introducing a layer of blur and rotation that can expose errors; if the QR code can be decoded from a degraded photograph, it is likely robust.

Third, validate the address format locally. A unified address begins with “u1” and should be 75–80+ characters long (exact length depends on the receiver set). All characters should be lowercase and from the Bech32 alphabet: “023456789acdefghjkmnpqrstuvwxyz”. A user can count the characters and spot-check for invalid ones. This is tedious but reliable; alternatively, offline validation tools exist that can check Bech32m checksums without requiring network access.

For higher-value transactions, a user should send a small test amount first. Send a small ZEC from the receiving wallet back to the address in question, then confirm that it arrives. This proves that both the address and the receiving wallet’s ability to decrypt shielded funds are working. Only after the test transaction confirms should larger amounts be sent.

Wallet selection and regulatory considerations

Not all Zcash wallets are equally reliable. Desktop wallets and hardware wallets are generally safer for address generation than web wallets, because they have direct access to the operating system and are less dependent on browser rendering. Zcash wallets such as Zodl (formerly Zashi) and Zingo! offer native implementations with full protocol support and better control over address display. Hardware wallets like Ledger and Keystone can generate addresses offline and display them on a secure device screen, eliminating browser rendering risks entirely.

Web-based implementations have advantages in accessibility and convenience, but they inherit all the rendering, encoding, and security risks described above. If a user must use a web wallet, prioritizing projects with active audits, transparent source code, and documented unified address support reduces (though does not eliminate) risk. The fact that a wallet exists and claims to support Zcash does not guarantee that it handles unified addresses correctly.

Regulatory environment also affects wallet choice. FinCEN’s guidance on cryptocurrency requires that money transmission services comply with AML/CFT rules, including customer identification and transaction reporting. In the EU, privacy coin regulations coordinated through the BIS have tightened, with some jurisdictions delisting or restricting trading in coins with enhanced privacy features. A user selecting a wallet should be aware of whether it operates in their jurisdiction and what regulatory constraints apply. This is not a reason to avoid shielded transactions or privacy-focused wallets, but it is a reason to understand the legal landscape and the wallet provider’s compliance posture.

Testing and disclosure standards for unified address bugs

The Zcash ecosystem would benefit from formal testing standards for unified address rendering and encoding. Electric Coin Company, the core Zcash developer, has published specifications and test vectors, but adoption and testing discipline vary. A standardized test suite could include: cross-browser rendering tests (checking that the same address displays identically in Chrome, Firefox, Safari, and mobile browsers), QR code validation tests (encoding the address and decoding the QR to confirm bit-for-bit match), font fallback tests, and copy-paste integrity tests.

Projects that discover unified address rendering bugs should have a clear disclosure process. Silent fixes in wallet updates can leave users uncertain about whether their previously-generated addresses are still valid. A responsible disclosure should include: a description of the bug and its impact, the affected versions and browsers, whether any funds are at risk, and the steps users should take. For web wallets, this might include a temporary warning on the address display screen, or a recommendation to use an alternative wallet until the fix is deployed and verified.

Looking forward, the adoption of privacy-focused cryptocurrency technologies will depend partly on user confidence in the tools. Address corruption is a subtle but serious failure mode that reflects broader risks in software supply chains and user interfaces. Better testing, more transparent reporting, and wallet diversity will reduce the likelihood that a single bad implementation leaves users stranded.

Frequently asked questions

How do I know if my zec wallet web interface is rendering my unified address correctly?

Copy the address from the wallet and paste it into a plain text editor; compare the pasted version with what the wallet displays character by character. View the address on multiple devices and browsers to confirm identical rendering. Decode the QR code independently using a QR decoder app. If all three match, the address is likely correct. For high-value transactions, send a small test amount first.

What should I do if I suspect my unified address was corrupted in a transaction?

If funds were sent to a shielded address, recovery is not possible. If the address was transparent or the recipient account is known, you may be able to contact the recipient or wallet provider. For future transactions, use a non-web wallet such as a desktop or hardware wallet that handles address generation offline. Test any new address thoroughly before using it for large amounts.

Are hardware wallets safe from unified address rendering bugs?

Hardware wallets like Ledger and Keystone display addresses on their own secure screens, not in a browser. They are not subject to font rendering or browser-based corruption. However, they are not immune to bugs in the wallet’s address derivation logic or the device’s display firmware. Verify a hardware-generated address on the device screen itself, and use only trusted hardware from reputable manufacturers.