Skip to main content
Every checkout session gets a unique deposit address. This is fundamental to the non-custodial design: the merchant controls the seed, and every address is deterministically derived from it — no third party can generate or predict the addresses.

HD wallet (BIP-44)

My Crypto Server uses BIP-44 hierarchical deterministic (HD) wallets. One BIP-39 mnemonic phrase (12 or 24 words) generates an entire tree of addresses.

Derivation paths

The index is the session’s derivation index — an auto-incrementing counter stored in the database. Session 1 gets index 0, session 2 gets index 1, and so on. Each session always uses the same address — the index is allocated at creation and never reused.

Seed storage

The mnemonic is provided during initial setup via the dashboard’s setup wizard. It is:
  1. Never stored in plaintext.
  2. Encrypted with AES-256-GCM using a key derived from scrypt(MASTER_PASSPHRASE, salt=fingerprint).
  3. The encrypted blob is stored in the database.
MASTER_PASSPHRASE is the only secret you need to keep to recover your seed. Loss of the passphrase means loss of access to the encrypted seed.

Verification

After entering your seed, the dashboard derives the first 3 addresses and shows them. Verify these match what your hardware wallet or Metamask shows for the same mnemonic — this confirms derivation is working correctly before you go live.

Why unique addresses?

Using a unique address per session:
  • Makes payment detection unambiguous — a transfer to address X can only belong to session Y.
  • Prevents session confusion if a customer pays twice for the same link.
  • Lets the on-chain history of each address be independently auditable.
After a session is paid and swept, that address is retired. The sweep moves all funds out, leaving it empty for easy auditing.

Adding new chains

Each chain has a ChainAdapter implementation. To support a new chain, register it in src/lib/chain/registry.ts and implement the adapter interface (deriveAddress, getHead, fetchTransfersTo, checkFinality, sweepNative). The rest of the pipeline is chain-agnostic.