The Problem: One Address Per Customer
Blockchain payments require a unique address per transaction so the platform knows which customer sent funds. Reusing addresses leaks payment history and prevents automatic attribution.
BIP44 Derivation Path
Paychainly derives addresses from your MASTER_SEED mnemonic using the path:
m/44'/60'/0'/0/{index}
// 44' = BIP44 purpose
// 60' = ETH coin type (also used for BSC/EVM chains)
// 0' = account 0
// 0 = external chain
// index = incrementing customer index
Security Properties
- All deposit addresses are derived from a single secret (MASTER_SEED).
- The mnemonic never leaves your server — only derived private keys are used for signing.
- Address at index N can always be re-derived from the same mnemonic — no database dependency for key recovery.
Key Encryption
Withdraw wallet private keys are encrypted at rest using AES-256-CBC with WITHDRAW_WALLET_ENCRYPTION_KEY (a 32-byte hex value). The raw key is never stored.
Generating Your Mnemonic
node -e "const { ethers } = require('ethers'); console.log(ethers.Wallet.createRandom().mnemonic.phrase)"
Store this value in MASTER_SEED. Back it up securely — losing it means losing the ability to sweep funds from existing deposit addresses.
Index Management
Each new deposit address increments a counter stored in the database. The deposit_addresses table maps index → address → userId so the correct user is credited when a payment arrives.