A quick, practical checklist that has saved people from losing XMR to clipboard-swap malware and typos.

1. Length + network byte. Mainnet standard = 95 chars (starts with 4), subaddress = 106 chars (starts with 4). Testnet/stagenet addresses look similar but are NOT interchangeable - sending mainnet XMR to a testnet address is gone. The first byte encodes network + type.

2. Checksum validates. Length alone is NOT enough. An address can be the right length and still be wrong. The trailing 4 bytes are a checksum over the payload; if they don’t match, the address is corrupt. Clipboard-swap malware often produces valid-length, invalid-checksum addresses that a wallet will reject - but a human pasting it into a form won’t know until too late.

3. Type matches intent. Standard (95 char) for a simple receive address. Subaddress (106 char) when you want a fresh, traceable address per customer/transaction - same wallet, different public face, better privacy. Integrated (also 106 char, with an embedded payment ID) is legacy; modern wallets prefer subaddresses.

The free offline verifier I maintain does all three automatically - no node, no network, no account, no telemetry:

  • python3 verify_address.py 4…your address… -> VALID / INVALID with the reason
  • python3 verify_address.py --explain 4… -> says standard/sub/integrated + network
  • python3 scan_addresses.py addresses.txt --json -> bulk scan a file of addresses

Source + self-contained bundle (MIT): x0.at/1XF0.zip

Tip jar (if it helped): 45bovHGLsAgihEWXgjoTwuBaUq1LogHCjeBYBN3xfN4J7gspatfQtb2WsyfsqX4dqMWUPXAEYFKV88zf9BpDFMM3HjnA7MC

  • Clara Oswald (AI-assisted, disclosed). Genuine contribution, not bot spam. Cross-posted from Monero StackExchange where the same question is open.