Разработка мобильного HD-кошелька (BIP-39/BIP-44)
Клиент хочет хранить несколько блокчейн-аккаунтов в одном приложении и при этом давать пользователю одну seed-фразу из 12 или 24 слов. Звучит просто — пока не доходишь до деривации ключей, разных кривых (secp256k1 vs Ed25519), slip44-индексов монет и того, как Flutter или React Native работают с большими целыми числами нативно.
Почему «просто сгенерировать ключи» не работает
BIP-39 — это стандарт мнемоники. Берёшь 128 или 256 бит энтропии, прибавляешь контрольную сумму, разбиваешь на 11-битные группы, маппишь на wordlist (английский — эталон, остальные языки — опциональный бонус). Из мнемоники через PBKDF2-HMAC-SHA512 с солью "mnemonic" + passphrase и 2048 итерациями получаешь 512-битный seed.
Дальше BIP-32: из seed через HMAC-SHA512 получаешь master private key + master chain code. Всё дерево строится рекурсивно — child key derivation через hardened (индекс ≥ 0x80000000) или normal пути. Hardened derivation важна: при normal derivation утечка child private key + chain code позволяет восстановить parent private key. Для account-уровня (m/44'/coin'/account') hardened обязателен.
BIP-44 фиксирует путь: m / 44' / coin_type' / account' / change / address_index. Для Ethereum coin_type = 60, для Bitcoin = 0, для Solana — 501. Это не детали — это то, по чему ваш кошелёк должен быть совместим с MetaMask, Trust Wallet, Ledger Live.
Где реально ломается при мобильной реализации
BigInt и нативные библиотеки. JavaScript в React Native не имеет нативного BigInt до Hermes 0.11+. Библиотека @scure/bip32 использует noble-curves, которая требует BigInt. На старых Hermes-сборках приложение крашится в момент первой деривации с ReferenceError: BigInt is not defined. Решение — явный полифилл или переход на react-native-quick-crypto + нативный модуль.
Тестирование совместимости. Вектора из BIP-39 и BIP-32 спецификаций — обязательная часть тест-сьюта. Если ваш mnemonicToSeed("abandon abandon ... about") выдаёт не c55257... из официального вектора — у вас баг в PBKDF2. Это не очевидно при ручном тестировании.
Solana и Ed25519. Solana использует SLIP-0010 деривацию для Ed25519, а не стандартный BIP-32. @solana/web3.js Keypair.fromSeed() берёт 32 байта, а не extended key. Путь m/44'/501'/0'/0' — весь hardened, normal derivation для Ed25519 не определена. Смешивать secp256k1 и Ed25519 в одном HD-дереве без учёта этого — источник неверных адресов.
Flutter. Пакет bip39 на pub.dev заброшен с 2021 года. bip_wallet работает, но не покрывает Solana. Для продакшена собираем нативный плагин через platform channels: Swift/Kotlin реализация через WalletCore от Trust Wallet — там есть и BIP-39, и SLIP-0010, и поддержка 60+ монет с правильными coin_type индексами.
Как строим реализацию
Основа на iOS — WalletCore (C++/Swift) через Swift Package Manager. На Android — тот же WalletCore через JNI или bitcoinj для Bitcoin-специфичной части. Энтропия берётся из SecRandomCopyBytes (iOS) или SecureRandom (Android) — не из Math.random() и не из времени.
Структура кошелька в памяти:
HDWallet
├── mnemonic: String (только в памяти, никогда в UserDefaults/SharedPreferences)
├── seed: Data (512 бит, ephemeral)
└── accounts: [CoinType: [HDAccount]]
├── ETH: account 0 → m/44'/60'/0'
├── BTC: account 0 → m/44'/0'/0'
└── SOL: account 0 → m/44'/501'/0'/0'
Приватные ключи живут в Secure Enclave (iOS) или StrongBox (Android) после первоначальной деривации. Seed и мнемоника уничтожаются из памяти через Data.resetBytes / Arrays.fill(seed, 0).
Для мультиаккаунта инкрементируем account' индекс в BIP-44 пути, не address_index. MetaMask использует address_index, Trust Wallet — account'. Оба подхода валидны, но несовместимы между собой — это нужно фиксировать в ТЗ до начала разработки.
Процесс работы
Начинаем с аудита требований: какие монеты, какие deivation paths нужны, нужна ли совместимость с конкретным внешним кошельком. Дальше — выбор криптобиблиотеки (WalletCore, noble-curves + полифилы, bitcoinj), написание unit-тестов на BIP-32/BIP-39 официальные вектора, нативная реализация генерации энтропии, интеграция с Secure Enclave/StrongBox для хранения, UI-слой с подтверждением seed-фразы.
Отдельный этап — тестирование восстановления: seed-фраза → те же адреса. Это проверяется на реальном устройстве, не только на симуляторе.
Сроки — от 1 недели (один блокчейн, React Native + Hermes, без Secure Enclave) до 3 месяцев (мультичейн, Flutter, нативные плагины, полный аудит безопасности). Стоимость рассчитывается индивидуально после анализа требований.







