> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mycryptoserver.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Address Derivation

> How unique deposit addresses are generated from the merchant seed

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](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) hierarchical deterministic (HD) wallets. One BIP-39 mnemonic phrase (12 or 24 words) generates an entire tree of addresses.

### Derivation paths

| Chain                      | Path                             |
| -------------------------- | -------------------------------- |
| EVM (Ethereum, Base, etc.) | `m/44'/60'/0'/0/{index}`         |
| Solana                     | `m/44'/501'/{index}'/0'`         |
| Bitcoin                    | `m/84'/0'/0'/0/{index}` (P2WPKH) |

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.
