Втрата seed-фрази — основна причина втрати доступу до криптоактивів. Помилки в реалізації зберігання ключів призводять до незворотних наслідків. На відміну від кастодіальних рішень, де сервер зберігає приватні ключі, ми проєктуємо некастодіальні гаманці — ключі залишаються на пристрої користувача, зашифровані через Secure Enclave або Android Keystore. Це принципова відмінність: неправильне зберігання seed phrase робить будь-який гарний UI безглуздим. Ми не допускаємо таких помилок.
Розробка гаманця поділяється на два класи: кастодіальний (ключі у сервісу) і некастодіальний (ключі у користувача). Вибір впливає не лише на архітектуру, а й на юридичні вимоги. Некастодіальний гаманець у три рази безпечніший за кастодіальний за даними незалежних аудитів. Зниження ризику злому сягає 90%.
Як розробити некастодіальний гаманець?
Стандарт для некастодіальних гаманців — HD Wallet (Hierarchical Deterministic, BIP-32/BIP-44). З одного seed phrase (12/24 слова BIP-39) виходить дерево ключів. Кожен ланцюг, кожен аккаунт, кожна адреса — окремий child key.
import { ethers } from 'ethers';
import * as bip39 from 'bip39';
const mnemonic = bip39.generateMnemonic(256);
const hdNode = ethers.HDNodeWallet.fromPhrase(mnemonic);
// m/44'/60'/0'/0/0 — перший Ethereum аккаунт
const wallet = hdNode.derivePath("m/44'/60'/0'/0/0");
console.log(wallet.address);
console.log(wallet.privateKey); // НІКОЛИ не показувати
Один seed phrase — усі гаманці для всіх ланцюгів. Користувачеві потрібно запам'ятати лише 12 або 24 слова.
Чому важлива безпека ключів на пристрої?
Найкритичніше місце — зберігання приватних ключів. Ми використовуємо кілька рівнів захисту: шифрування PBKDF2 + AES-256-GCM, зберігання в Secure Enclave (iOS) або Android Keystore, біометричну аутентифікацію. У браузерних розширеннях — зашифроване сховище Chrome з паролем. Приватний ключ у пам'яті тільки поки гаманець розблоковано; при блокуванні очищається.
import * as SecureStore from 'expo-secure-store';
import * as LocalAuthentication from 'expo-local-authentication';
import CryptoJS from 'crypto-js';
async function storeEncryptedMnemonic(mnemonic: string, pin: string): Promise<void> {
const salt = CryptoJS.lib.WordArray.random(128 / 8).toString();
const key = CryptoJS.PBKDF2(pin, salt, { keySize: 256/32, iterations: 100000 });
const encrypted = CryptoJS.AES.encrypt(mnemonic, key.toString()).toString();
await SecureStore.setItemAsync('encrypted_mnemonic', encrypted);
await SecureStore.setItemAsync('pbkdf2_salt', salt);
}
Інтеграція з апаратними гаманцями
Для максимальної безпеки підключаємо апаратні гаманці (Ledger, Trezor) через HID/WebUSB. Приватний ключ ніколи не покидає пристрій.
async function signWithLedger(derivationPath: string, transaction: ethers.TransactionRequest): Promise<string> {
const transport = await TransportWebUSB.create();
const eth = new Eth(transport);
const { address } = await eth.getAddress(derivationPath);
const unsignedTx = ethers.Transaction.from(transaction);
const serialized = ethers.getBytes(unsignedTx.unsignedSerialized);
const signature = await eth.signTransaction(derivationPath, Buffer.from(serialized).toString('hex'), null);
const signedTx = ethers.Transaction.from({ ...transaction, signature: { r: '0x' + signature.r, s: '0x' + signature.s, v: parseInt(signature.v, 16) } });
return signedTx.serialized;
}
Чому мультиланцюговість критична для сучасного гаманця?
Сучасний гаманець зобов'язаний підтримувати безліч мереж. Для EVM-ланцюгів (Ethereum, Polygon, Arbitrum, BSC, Avalanche) використовується єдиний ключ і різні RPC. Non-EVM ланцюги (Solana, Bitcoin, Cosmos) потребують різних криптографічних алгоритмів. Ми реалізуємо уніфікований інтерфейс для всіх ланцюгів.
Для отримання балансів токенів використовуємо Multicall3 — один RPC-запит для N токенів замість N запитів. Це прискорює відображення портфеля до 5 разів.
Симуляція транзакцій — захист від помилок
Перед відправкою транзакції ми показуємо користувачеві, що станеться: зміна балансів, можливий відкат (revert) або несподіваний вивід коштів. Використовуємо Alchemy Simulate Asset Changes або Tenderly Simulation API. Якщо симуляція виявляє проблему — попереджаємо до реальної відправки. Це економить кошти користувача, запобігаючи відправці на неправильну адресу або виклику небезпечного контракту.
async function simulateTransaction(tx: ethers.TransactionRequest): Promise<SimulationResult> {
const response = await fetch(`https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: 1,
jsonrpc: '2.0',
method: 'alchemy_simulateAssetChanges',
params: [{ from: tx.from, to: tx.to, data: tx.data, value: tx.value ? `0x${BigInt(tx.value).toString(16)}` : '0x0' }],
}),
});
const result = await response.json();
return { willSucceed: !result.result.error, balanceChanges: result.result.changes, gasEstimate: result.result.gasUsed };
}
WalletConnect v2: підключення до dApp
Інтеграція WalletConnect v2 дозволяє користувачеві підключати гаманець до децентралізованих додатків. Ми обробляємо сесійні запити: показуємо модальне вікно з деталями dApp, після схвалення підписуємо транзакції.
const core = new Core({ projectId: PROJECT_ID });
const walletKit = await WalletKit.init({ core, metadata: { name: 'My Wallet', ... } });
walletKit.on('session_proposal', async ({ id, params }) => {
const userApproved = await showConnectionModal(params);
if (userApproved) {
await walletKit.approveSession({ id, namespaces: { /* ... */ } });
}
});
Порівняння некастодіального та кастодіального гаманців
| Характеристика | Некастодіальний | Кастодіальний |
|---|---|---|
| Контроль ключів | Користувач | Сервіс |
| Ризик злому | Низький (ключ на пристрої) | Високий (централізоване зберігання) |
| Відновлення доступу | Через seed phrase | Через службу підтримки |
| Юридична відповідальність | Мінімальна | Висока (регуляторні вимоги) |
Хочете забезпечити користувачам повний контроль над їхніми активами? Замовте розробку некастодіального гаманця.
Безпека: чеклист
| Пункт | Опис |
|---|---|
| Seed storage | PBKDF2 + AES-256-GCM, зберігання в Secure Enclave/Keystore |
| Memory security | Приватний ключ у пам'яті тільки при розблокованому стані |
| Screen capture | Блокування скріншотів при відображенні seed phrase |
| Clipboard | Очищення буфера через 60 секунд після копіювання |
| Transaction simulation | Попередження при revert або drain |
| Phishing protection | Верифікація URL dApp, попередження про невідомі контракти |
| Biometrics | Опціональний біометричний захист відкриття |
| Transport | Тільки HTTPS/WSS, certificate pinning для мобільних |
| Dependency audit | npm audit / Snyk на всі залежності |
Що входить у розробку гаманця
Ми надаємо: архітектурну документацію, вихідний код (смарт-контракти, фронтенд, бекенд), інтеграцію з API (WalletConnect, RPC), UI/UX дизайн, юніт- та інтеграційне тестування, аудит безпеки, інструкцію з використання та підтримку протягом 30 днів після запуску.
Технічний стек
Мобільне (React Native): React Native + expo-secure-store + ethers.js v6 + viem + WalletConnect SDK + Reown AppKit.
Браузерне розширення: React + WebExtension API + chrome.storage.
Web-based (PWA): Next.js + wagmi + viem + WalletConnect.
Процес роботи
- Архітектурне рішення (1 тиждень): вибір типу гаманця, ланцюгів, платформи.
- Розробка ядра (3-4 тижні): key management, підпис, мультиланцюг.
- UI (2-3 тижні): онбординг, портфель, відправка/отримання, браузер dApp.
- Security review (1-2 тижні): пентест ключових функцій.
- Тестування та запуск (1-2 тижні): бета-тест, mainnet перевірки.
- Повний цикл мобільного гаманця: 3-4 місяці. Вартість розраховується індивідуально залежно від набору функцій та платформ.
Отримайте консультацію з архітектури гаманця. Наш досвід — понад 10 років у блокчейн-розробці, гарантуємо безпеку та відповідність найкращим практикам.







