How two wallet parsers handle Litecoin payment requests
Twenty identical requests reveal differences in repeated amounts, decimal precision and metadata at the parsing boundary of Electrum-LTC and Cake Wallet. Exact versions, code and results are published.
Measured parsing boundary · pinned source functions, not complete wallet applications.
Sources, review record & reproducibility
Downloadable data.
Content review recorded: 2026-09-30. The review record does not identify a separate independent reviewer. An edited date above records an edit, not a new fact-check.
Sources saved with the review:
- litecoin.watch · /uploads/research/wallet-qr-20260930/README.txt
- litecoin.watch · /uploads/research/wallet-qr-20260930/SHA256SUMS.txt
- electrum-ltc.org · /
- github.com · /cake-tech/cake_wallet/blob/9fe23970c7a6e7f88e2bab88abe4e6346c732316/lib/utils/payment_request.dart
See the article body for source links and any downloadable materials. Editorial method · Corrections · Report an issue
On this page
A Litecoin payment request can look correct as text and still be interpreted differently at the next step. To find out where those differences begin, we passed the same 20 inputs through code from Electrum-LTC 4.2.2.1 and Cake Wallet v6.4.5.
The most useful finding is about repeated amounts. For amount=1&amount=2, Electrum’s URI function returned a duplicate-key error. Cake’s request-parsing function, running with Dart 3.13.5, returned the amount string 2. That is a reason to remove ambiguity from a request before sharing it.
This is a test of source-isolated parsing functions. We did not run either complete wallet, scan with a phone camera, construct a payment, sign or broadcast. A function returning an invalid amount or address does not establish that the complete application allows it. Its next screen can perform additional checks.
What we actually ran
| Implementation | Executed code | Outside the experiment |
|---|---|---|
| Electrum-LTC 4.2.2.1 | Unchanged upstream URI, Base58Check and SegWit validation function bodies, extracted through Python’s AST from the verified release archive | Full package startup, GUI, scanner, payment-request callback, signing and sending |
| Cake Wallet v6.4.5 | Unchanged constructor and PaymentRequest.fromUri factory from commit 9fe23970c7a6e7f88e2bab88abe4e6346c732316, compiled and executed with Dart 3.13.5 | Full app, fromString fallback, scanner, downstream send-screen amount/address checks, signing and sending |
The Electrum archive was checked against SHA-256 ec5dbc72f7be1c3e490cae6281f9060ff36f4c27c0df783e0e6409e66c0f33d4. Cake’s source file and generated harness have separate hashes in the downloads. Its unrelated Lightning, ERC681 and Nano dependencies were replaced by guarded adapters. None of the corpus inputs entered those dependency branches; entering an unsupported branch would abort the experiment.
We used synthetic public address hashes with no known private keys. They test encoding and checksum behavior, not custody. Never fund an address in the corpus. No real customer request or wallet secret was used. The exact text and returned fields are available in the case explorer.
Nine cases that change how you should prepare a request
| Input | Electrum function | Cake function | Practical consequence |
|---|---|---|---|
| URI with no amount | No amount | No amount text | Ask the payer to enter and verify the agreed amount. |
| Nine decimals | 12345678 litoshis | 0.123456789 | Request only amounts representable with eight decimals. |
| Negative amount | -100000000 litoshis | -1 | A returned field does not establish a valid spend. |
| Duplicate amount | Error: Duplicate Key: 'amount' | 2 | Use one amount parameter; do not depend on precedence. |
| Unknown required field | Amount plus req-invoice retained | Amount returned; req-invoice not exposed | Do not depend on a required extension unless the actual wallet enforces it. |
| UTF-8 and encoded ampersand | Label: Café & invoice 17 | No note from label | Check the destination through another trusted channel. |
| Wrong address checksum | Error: Invalid litecoin address: LLnCCHbSzfwWquEdaS5TF2Yt7uz5Qb1SZ2 | 0.125 | Address validation can happen after parsing; test the whole flow separately. |
| Wrong currency scheme | Error: Not a litecoin URI | 0.125 | A scheme returned as text is not currency validation. |
| Scientific notation | 1 litoshis | 1e-8 | Use ordinary decimal LTC amounts for portable requests. |
The full 20-case table also covers plain addresses, one-litoshi amounts, an empty amount, a decimal comma, optional metadata, an unescaped ampersand, uppercase scheme, native SegWit, an amount above supply and expiry fields. These are deliberately selected cases, not a random sample of real-world requests. We do not turn their counts into a wallet reliability score.
Repeated amount fields are an avoidable disagreement
The request litecoin:address?amount=1&amount=2 contains two instructions under one key. In this Electrum version, parsing the query detects the repeated key and raises an error. Cake’s factory reads Dart’s single-value Uri.queryParameters map; in the tested runtime it obtains the last amount value.
Neither behavior is an excuse to send an ambiguous invoice. Generate one amount field, decode the generated request and compare it with the invoice. If you receive a request with duplicates, ask for a corrected one rather than guessing which value the sender intended.
Precision can change before you see a send screen
With amount=0.123456789, Electrum returned 12345678 litoshis. Converting that integer back to LTC gives 0.12345678: the ninth decimal was truncated at this function boundary. Cake returned the original string 0.123456789. We did not test how its send screen rounds or rejects that string.
For an invoice, write an amount representable in eight decimal places. Avoid scientific notation, negative amounts and local decimal commas even when a parser happens to return them. Both tested functions returned a field for the negative-amount fixture; that observation is about parsing, not spend validation.
Required fields, labels and expiry need their own checks
Our unknown-required fixture added req-invoice=17. Electrum returned it in the parsed fields. Cake returned the address and amount without exposing that parameter in the request object. Neither result proves enforcement of a required extension by the complete application. A merchant should test the actual wallet flow before depending on an extension for acceptance.
An encoded label=Caf%C3%A9%20%26%20invoice%2017 became a readable label in Electrum. Cake’s tested factory uses message or tx_description for its note; the label fixture produced an empty note. A label can disappear without changing the destination, and a convincing label can accompany the wrong destination. Compare the full address through an authenticated channel.
The expiry fixture returned data at both boundaries. We did not establish whether either full application enforces its time and exp fields. Put quote expiry and late-payment policy in the invoice itself; do not assume an arbitrary URI field will enforce the commercial agreement.
A short preflight for merchants and payers
- Use one destination and one ordinary decimal amount in LTC. Avoid duplicated keys and unnecessary extensions.
- Decode the exact QR or URI you will share. Check every character of the destination and the eight-decimal amount against the invoice.
- Test the actual wallet version and device your payer uses, with a safe controlled procedure. Record the decoded text, populated fields and validation result separately.
- Before approving a real payment, read the destination and amount on the wallet’s trusted confirmation screen.
- After broadcast, match the actual output and apply your agreed confirmation policy. A QR scan does not prove settlement.
Our local QR inspector flags duplicates and unsupported required fields rather than choosing a payment interpretation. The payment checklist connects that preflight with request creation, transaction inspection and reconciliation.
Reproduce it and report a different result
Download the source subset, harnesses and results, verify the checksums, then follow the Python and Dart instructions. Results are also available as CSV and JSON. No package installation is needed for the source-isolated Python or generated Dart harness.
If your wallet behaves differently, record the exact version, operating system, URI text and stage where the difference occurs. Remove personal data and recovery secrets. A full-app observation can add evidence that this parser study does not provide. Submit a reproducible correction through our corrections page.
Primary references: Electrum-LTC release downloads, the pinned Cake payment-request source and BIP 21. BIP 21 is a Bitcoin specification; it supplies background for this widely used URI shape, not a guarantee about Litecoin wallet implementation.
Measured 30 September 2026. AI-assisted research, code and drafting; scripted verification, no independent human reviewer claimed. No complete-wallet safety ranking is implied.
Track Litecoin in real time
Rates for 30+ currencies. Check each tool for its latest source timestamp.
Open dashboard
