Користувач втратив seed-фразу — 12 слів, записаних на клаптику паперу. Рахунок на $200k заморожено назавжди. Некастодіальний гаманець повинен виключати такі сценарії архітектурно: приватний ключ шифрується і зберігається лише на пристрої, відновлення можливе тільки за мнемонікою. Ми в True Tech розробляємо некастодіальні криптогаманці протягом багатьох років, реалізували 15+ проєктів для iOS та Android. Наш досвід показує: головне — коректна реалізація BIP-стандартів та безпечне зберігання seed.
Чому некастодіальний гаманець — єдиний безпечний вибір?
Найпоширеніша проблема — втрата seed-фрази. Користувачі не роблять бекап, втрачають листок або зберігають у хмарі без шифрування. Друга проблема — несумісність: нестандартна деривація позбавляє можливості відновити адреси в інших гаманцях. Третя — витік приватного ключа при зберіганні у відкритому вигляді. Крім того, неправильний розрахунок gas (EIP-1559) збільшує комісії в 2–5 разів, а відсутність WalletConnect ізолює гаманець від DeFi-екосистеми. Всі ці проблеми вирішуються архітектурно.
Чому BIP39/32/44 — обов'язковий фундамент?
Починаємо з мнемонічної фрази. BIP39 визначає список з 2048 слів та алгоритм генерації 512-бітного seed з 12 або 24 слів + опціональної passphrase через PBKDF2-HMAC-SHA512 (2048 ітерацій). Seed → master key через BIP32 HMAC-SHA512. Ієрархічна деривація ключів за шляхом BIP44: m/44'/60'/0'/0/0 — перша Ethereum адреса, m/44'/0'/0'/0/0 — перша Bitcoin адреса. Чому це критично: користувач повинен мати можливість відновити всі свої адреси в будь-якому іншому сумісному гаманці (MetaMask, Trust Wallet, Ledger) за однією мнемонікою. Відступ від стандарту позбавляє користувача цієї можливості.
Генерація мнемоніки на Android:
// BitcoinJ або Web3j для BIP39
val entropy = ByteArray(16) // 128 біт → 12 слів
SecureRandom().nextBytes(entropy)
val mnemonic = MnemonicCode.INSTANCE.toMnemonic(entropy)
// ["word1", "word2", ..., "word12"]
// seed з мнемоніки
val seed = MnemonicCode.toSeed(mnemonic, "") // без passphrase
val masterKey = HDKeyDerivation.createMasterPrivateKey(seed)
Контрольна сума мнемоніки (останнє слово або його частина) — обов'язкова валідація при імпорті. Користувачі регулярно вводять помилки.
iOS, Swift:
// WalletCore від Trust Wallet — чудова бібліотека для iOS/Android
let wallet = HDWallet(strength: 128, passphrase: "")
let mnemonic = wallet.mnemonic // 12 слів
let ethAddress = wallet.getAddressForCoin(coin: .ethereum)
Trust Wallet Core (WalletCore) — open source, підтримує 60+ блокчейнів, реалізує всі BIP стандарти. Використовується в Trust Wallet, Argent, і десятках інших гаманців. Для нового некастодіального гаманця — стандартний вибір основи. WalletCore в 2 рази прискорює розробку порівняно з самостійною реалізацією.
Як забезпечити безпечне зберігання ключів?
Ключ не можна зберігати у відкритому вигляді ніде: ні у файлі, ні в SharedPreferences, ні в базі даних. Схема:
- Користувач створює PIN або налаштовує біометрію
- Генерується випадковий ключ шифрування (AES-256), захищений Android Keystore / iOS Secure Enclave з прив'язкою до біометрії
- Seed шифрується цим ключем
- Зашифрований blob зберігається в зашифрованій БД (SQLCipher) або EncryptedSharedPreferences
При біометричній аутентифікації:
val cryptoObject = BiometricPrompt.CryptoObject(cipher) // cipher прив'язаний до ключа в Keystore
biometricPrompt.authenticate(promptInfo, cryptoObject)
// в onAuthenticationSucceeded:
val decryptedSeed = result.cryptoObject?.cipher?.doFinal(encryptedSeed)
Приватний ключ у розшифрованому вигляді живе в пам'яті лише на час підписання транзакції. Після — обнуляємо масив байт, GC не гарантує звільнення, тому явний Arrays.fill(keyBytes, 0.toByte()).
Як інтегруватися з блокчейнами та DeFi?
Для Ethereum-сумісних мереж (ETH, BSC, Polygon, Arbitrum, Optimism) — Web3j (Android) або web3.swift (iOS). Для Bitcoin — BitcoinJ. Для Solana — Solana Mobile Stack SDK. Для TON — ton-kotlin або TonConnect. Підключення до мережі через RPC провайдер: Infura, Alchemy, QuickNode. Для приватності — власна нода (але дорого в підтримці) або використання декількох провайдерів з fallback.
Відправка ETH транзакції:
val credentials = Credentials.create(privateKeyHex)
val nonce = web3j.ethGetTransactionCount(
credentials.address,
DefaultBlockParameterName.PENDING
).send().transactionCount
val rawTransaction = RawTransaction.createEtherTransaction(
nonce,
gasPrice,
gasLimit,
toAddress,
amountInWei
)
val signedTransaction = TransactionEncoder.signMessage(rawTransaction, chainId, credentials)
val txHash = web3j.ethSendRawTransaction(
Numeric.toHexString(signedTransaction)
).send().transactionHash
Приватний ключ використовується тільки для TransactionEncoder.signMessage — підпис відбувається локально, в мережу йде лише підписана транзакція без ключа.
EIP-1559 та розрахунок газу
З London hardfork (EIP-1559) транзакції мають maxFeePerGas і maxPriorityFeePerGas замість простого gasPrice. Правильний розрахунок: eth_feeHistory RPC метод для аналізу останніх блоків, алгоритм підбору maxPriorityFeePerGas (tip) на основі перцентилів. MetaMask використовує 50-й перцентиль пріоритетних комісій з останніх 5 блоків як базову пораду. Показувати користувачеві три варіанти (slow/normal/fast) з оцінкою часу підтвердження — стандартний UX. Неправильний розрахунок збільшує вартість транзакції до 30%.
WalletConnect для dApps
Без WalletConnect гаманець ізольований від екосистеми DeFi. WalletConnect v2 (Sign API) — протокол для зв'язку між гаманцем і dApp через relay сервер. Реалізація: WalletConnect Swift SDK (iOS), WalletConnect Kotlin SDK (Android). Сесія встановлюється через QR-код або deep link:
- dApp генерує URI:
wc:...@2?relay-protocol=irn&symKey=... - Користувач сканує QR в гаманці
- Встановлюється E2E-зашифрована сесія через relay
- dApp запитує
eth_sendTransaction→ користувач бачить деталі → підписує
Seed phrase backup flow
UX seed backup — критична частина. Користувачі втрачають гроші через втрату seed. Правильний флоу:
- Показати мнемоніку — запитати підтвердження, що записав
- Верифікація: показати 3 випадкових слова з фрази, попросити ввести порядкові номери
- Нагадувати про бекап в онбордингу та періодично
Забороняємо скріншоти на екрані з seed через
FLAG_SECURE/ iOSUIScreen.capturedDidChangeNotification.
Мультичейн та токени
ERC-20 токени не потребують окремих ключів — та ж Ethereum адреса. Баланс через balanceOf(address) виклик контракту. Список токенів — через CoinGecko API або Trust Wallet Assets репозиторій (відкритий список з іконками для 10000+ токенів). NFT (ERC-721, ERC-1155) — ownerOf(tokenId) / balanceOf(address, id). Метадані через tokenURI → IPFS або HTTP.
Порівняння методів зберігання ключів
| Метод | Безпека | Швидкість | Сумісність |
|---|---|---|---|
| Android Keystore + AES-256 | Висока (TEE) | Швидко | Тільки Android |
| iOS Secure Enclave + AES-256 | Висока (SEP) | Швидко | Тільки iOS |
| Бібліотека Keychain (iOS) | Середня (залежить від jailbreak) | Швидко | Тільки iOS |
| EncryptedSharedPreferences + Keystore | Висока | Швидко | Android |
Процес розробки та терміни
Аналітика та проектування — узгодження функціональних вимог, вибір блокчейнів, архітектури. Реалізація — написання коду генерації ключів, зберігання, підписання. Інтеграція — підключення RPC, WalletConnect, фіатних шлюзів (опціонально). Тестування — пентести, симуляції втрати seed, перевірка на сумісність. Деплой — публікація в App Store та Google Play, налаштування CI/CD.
В результаті ви отримуєте вихідний код гаманця під iOS та/або Android, повну документацію з архітектури та безпеки, доступ до репозиторію та CI-пайплайнів, інтеграцію з обраними блокчейнами, налаштування WalletConnect v2, допомогу з публікацією в сторах, навчання команди замовника (2 дні) та гарантійну підтримку 3 місяці.
Базовий некастодіальний гаманець (Ethereum + ERC-20 + WalletConnect + seed backup) — 2–4 місяці. Додавання кожного нового блокчейну з повною інтеграцією — 2–4 тижні. Вартість розраховується індивідуально.
Некастодіальний гаманець у більшості юрисдикцій не вимагає ліцензії — користувач сам керує своїми ключами. Але якщо додається обмін валют (swap), fiat on-ramp — ситуація змінюється. Консультація з юристом щодо регулювання обов'язкова перед запуском з такими функціями. Ми гарантуємо, що ваш продукт відповідатиме найкращим практикам безпеки та вимогам App Store Review Guidelines.
Докладніше про BIP44
BIP44 визначає ієрархію ключів з урахуванням різних криптовалют та акаунтів. Шлях m/44'/coin'/account'/change/address. coin' для Ethereum — 60', для Bitcoin — 0'. account' — рахунок користувача, change — зовнішні/внутрішні адреси. Це забезпечує стандартну детерміновану генерацію всіх адрес.Отримайте консультацію щодо вашого проєкту — зв'яжіться з нами. Замовте розробку гаманця з гарантованою безпекою.







