Blog / Engineering

HD Wallets and Per-User Deposit Addresses

Why payment systems give each user a deposit address, how deterministic derivation makes that possible without a key per user, and the mistake that loses funds.

9 min read

ENGINEERING HD Wallets and Per-User Deposit Addresses CARD NETWORK

In short

Hierarchical deterministic wallets let a system derive unlimited addresses from one seed, so every user can have their own deposit address without storing a key each. Done properly the server holds no spending keys at all.

A payment system that accepts crypto deposits has to answer one question: how do you know whose money just arrived?

One shared address makes this nearly impossible. Every deposit lands in the same place and attribution depends on the sender attaching a memo — which they frequently do not, and which is a support burden every time it goes wrong. Per-user addresses make attribution structural: the address the money arrived at identifies the account, with nothing for the user to get right.

The problem with a key per user

Generating an independent key pair per user works and scales badly. Every key must be stored, backed up and protected; losing one loses those funds permanently; and backup grows without bound.

Hierarchical deterministic wallets — BIP32, with the path convention from BIP44 — solve this. From a single seed you derive a tree of key pairs. Any address can be regenerated from the seed and its path, so what needs backing up is one seed phrase rather than a growing set of keys.

What a derivation path means

A path like m/44'/60'/0'/0/17 reads left to right:

SegmentMeaning
mThe master key, derived from the seed
44'The BIP44 convention. The apostrophe means hardened derivation
60'Coin type 60 — Ethereum and EVM-compatible chains
0'Account index. Separate accounts partition uses
0Change level. External addresses by convention
17The address index — the 18th address in this branch

The path is the durable fact. Hand it to any wallet that accepts a custom derivation path, with the seed, and you recover the account — on any machine, years later, with no dependency on the system that created it.

Separating purposes with accounts

The account level is more useful than it looks. Different purposes should live in different branches so that funds are never confused and can be swept independently.

ON5 uses account 0 for user deposit addresses and account 1 for activation payments. Same seed, two entirely separate address spaces, and a clear answer to which branch any given address belongs to.

Watch-only: the part that matters most

BIP32 has a property that is genuinely valuable for a payment system: from an extended public key — an xpub — you can derive every public address in a branch, but no private keys at all.

That allows a deployment where the server watching for deposits holds no spending capability whatsoever. If it is fully compromised, the attacker learns which addresses to watch and can move nothing.

ModeServer holdsIf compromised
Watch-only (xpub)Extended public keyAddresses are exposed. No funds can move.
Hot (seed)The seed phraseEvery user's funds can be swept immediately.

Hot mode is sometimes necessary — automated sweeping requires signing. If you run it, treat the host as a hot wallet: minimal access, no seed in application logs, and an explicit decision rather than a default.

The mistake that loses money

This one is worth stating precisely, because it produces addresses that look completely normal.

BIP32 gives you a 33-byte compressed public key. An Ethereum address is the last 20 bytes of the keccak-256 hash of the 64-byte uncompressed key. Hash the compressed bytes instead and you get a well-formed, checksummed address that passes every validation — and that nobody on earth holds the private key for.

Funds sent there are unrecoverable. Not difficult to recover: unrecoverable, because the key does not exist.

One address, several chains

EVM chains share an address format, so one derived address is valid on Ethereum, BNB Smart Chain, Base and other EVM networks simultaneously. That is why ON5 shows a single deposit address that works across all supported chains.

The trade-off is that it makes wrong-network deposits easier: the address accepts a transfer on any EVM chain, whether or not the programme scans that chain. If it is not scanned, it is not credited. Saying which networks are supported, prominently and next to the address, is the only mitigation that works.

Operational essentials

  • Record the path with the address. Recovering funds later means knowing exactly where an address came from.
  • Never reuse an index across users. Attribution depends on uniqueness.
  • Keep an address lookup tool. When treasury needs to reach a specific user's funds, the path is the answer, not a key export.
  • Verify against a test vector in CI. As above — this is the one that matters.

Frequently asked questions

What is an HD wallet?

A hierarchical deterministic wallet derives an unlimited tree of key pairs from a single seed, so a system can give every user their own address while backing up only one seed phrase.

What does a derivation path like m/44'/60'/0'/0/17 mean?

Master key, BIP44 convention, coin type 60 for EVM chains, account index, change level, and address index. The path plus the seed recovers the account in any compatible wallet.

What is a watch-only wallet?

A deployment where the server holds an extended public key and can derive addresses to watch but holds no private keys, so a full compromise exposes addresses without allowing any funds to move.

Why do some derived Ethereum addresses have no recoverable key?

Because the address was computed from the 33-byte compressed public key instead of the 64-byte uncompressed key. The result is a valid-looking address nobody holds the key for. A test against a published vector catches it.

Can one deposit address work across several chains?

Yes. EVM chains share an address format, so a single derived address is valid on all of them. The risk is deposits sent on a chain the programme does not scan, which are not credited.

Issue your first card on ON5

Fund an account with USDT or USDC and issue a branded Visa or Mastercard virtual card. The minimum is $5.

Open the dashboard

Related reading