# CryptoWallet API — Deployment Bundle (v5.0 custodial) Multi-chain **custodial** wallet API (ETH / BSC / BTC / TRX / SOL). - Сервер генерит mnemonic, хранит зашифрованной (AES-256-GCM, master-key из HashiCorp Vault) - Сервер сам подписывает tx по запросу юзера (юзер на клиенте жмёт "подтвердить") Auth — JWT (BITOK), секреты — HashiCorp Vault (AppRole). ## Pre-deploy setup (один раз навсегда) ```bash # 1. Master-key в Vault vault kv put dev-secrets/crypto/master key=$(openssl rand -hex 32) # 2. DB schema psql -h 72.56.9.76 -U postgres_user -d postgres -f cryptowallet-schema.sql ``` ⚠️ **Master-key менять нельзя** — все existing encrypted_mnemonic станут нерасшифровываемыми. Сервис логирует WARN если в Vault ключ изменился. ## Deploy ```bash scp -P 2222 -r deployserver/ server@176.124.213.102:~/cryptowallet/ ssh server@176.124.213.102 -p 2222 cd ~/cryptowallet && cp .env.example .env && nano .env && ./start.sh ``` В `.env` обязательны: `VAULT_ADDR`, `VAULT_ROLE_ID`, `VAULT_SECRET_ID`, `JWT_ISSUER`, `JWT_AUDIENCE`, `CORS_ORIGINS`. ## Endpoints (24) | Method | Path | Описание | |---|---|---| | GET | /api/health | Liveness (public) | | GET | /api/docs | Swagger UI | | POST | **/api/wallets/create** | **Сервер создаёт коша** (no body, returns addresses) | | GET | /api/wallets | Список адресов юзера | | POST | **/api/wallets/mnemonic/reveal** | Reveal seed (body confirm + 5/час) | | GET | /api/wallets/{chain}/balance | Баланс | | GET | /api/wallets/{chain}/transactions | История tx | | POST | **/api/wallets/{chain}/send** | **Сервер подписывает + broadcast** | | ... | /api/btc/* /api/tron/* /api/sol/* /api/bsc/* /api/relay/* | Proxy endpoints | ## Security highlights - **AES-256-GCM** для encrypted_mnemonic (12-byte random IV, 16-byte auth tag, fail-secure) - **Master-key set-once** (rotation запрещена) - **Race-safe createWallet**: `db.transaction` + `UPDATE WHERE encrypted_mnemonic IS NULL` - **TRX MITM defense**: local recompute txID + verify raw_data перед подписью - **EVM gas cap** 500 gwei (применён к tx, не только check) - **Address checksum validation** (BTC bitcoinjs-lib, TRX bs58check, SOL PublicKey, EVM EIP-55) - **assertAddressMatch** — derived(mnemonic, path) === DB.address перед подписью - **SOL confirmTransaction** — ждём подтверждения - **BTC** P2WPKH bech32, fee fallback 15 sat/vB + 1.1x safety, dust 294, broadcast 20s timeout - **POST mnemonic/reveal** + CSRF + body confirm token + 5/час + audit-log - **Logger sanitization**: password/token/mnemonic/hex64/BIP39-phrase patterns - **Audit log** `logs/audit.log` (wallet.create / wallet.send / mnemonic.reveal) - **Hourly key rotation**: JWT keys + CSRF secret из Vault (master-key НЕ ротируется) - **Fail-fast**: сервис не стартует без master-key, JWT_ISSUER, JWT_AUDIENCE ## Update / Rebuild ```bash scp -P 2222 -r deployserver/apps server@176.124.213.102:~/cryptowallet/ ssh server@176.124.213.102 -p 2222 'cd cryptowallet && docker compose up -d --build' ```