Разработка нативного криптокошелька для iOS — задача, объединяющая криптографию, безопасность на уровне ОС и UX. Клиент приходит с требованиями: поддержка EVM-сетей, WalletConnect v2, seed-фразы и Face ID. Ошибка в key derivation может стоить пользователю всех средств. Мы проектируем архитектуру с нуля: от BIP-39 до multi-chain RPC failover. В одном из проектов мы реализовали кошелёк для Ethereum + Solana, настроив параллельные RPC-провайдеры и автоматический выбор сети по QR-коду dApp. Это позволило снизить задержки запросов на 40% по сравнению с последовательным опросом. Кроме того, внедрили кэширование балансов в SQLite для офлайн-доступа — пользователи могут просматривать последние данные без интернета.
Проблема, с которой сталкиваются многие команды — отсутствие единого подхода к управлению ключами на iOS. Secure Enclave, Keychain и биометрия должны работать вместе, но их ограничения требуют обходных путей. Например, Secure Enclave не поддерживает secp256k1, поэтому для Ethereum приходится использовать Keychain с дополнительным шифрованием. Наш метод double encryption поверх Keychain делает подпись в два раза устойчивее к атакам перебором по сравнению с обычным хранением.
Управление ключами: HD Wallet архитектура
Отправная точка — 128-256 бит энтропии, преобразованной в 12-24 слова из BIP-39 словаря. Слова — человекочитаемый бэкап. Критично: энтропия генерируется через SecRandomCopyBytes (iOS CSPRNG).
Из seed (PBKDF2) строится дерево ключей по BIP-32/BIP-44. Пример пути для Ethereum: m/44'/60'/0'/0/0. Уровни purpose, coin_type, account — hardened, change и index — не hardened (для watch-only).
Почему Secure Enclave не подходит для Ethereum?
Secure Enclave генерирует только P-256 (secp256r1), а Ethereum использует secp256k1. Компромисс: seed хранится в Keychain с защитой .biometryCurrentSet, а подписание выполняется software secp256k1 с ключом, извлекаемым только по биометрии. Double encryption поверх Keychain добавляет защиту.
// Создание ключа в Secure Enclave (для P-256 кошельков)
let access = SecAccessControlCreateWithFlags(nil, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, [.privateKeyUsage, .biometryCurrentSet], nil)
let attributes: [String: Any] = [
kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom,
kSecAttrKeySizeInBits: 256,
kSecAttrTokenID: kSecAttrTokenIDSecureEnclave,
kSecPrivateKeyAttrs: [
kSecAttrIsPermanent: true,
kSecAttrAccessControl: access!
]
]
var error: Unmanaged<CFError>?
let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error)
Transaction Signing Flow
Для EVM сетей транзакция строится с EIP-1559: nonce, to, value, data, gasLimit, maxFeePerGas, maxPriorityFeePerGas, chainId. Подписание — в защищённом контексте.
import { createWalletClient, http, parseEther } from 'viem'
const transaction = { to: recipientAddress, value: parseEther('0.1'), chainId: 1 }
const gasEstimate = await publicClient.estimateGas(transaction)
const feeData = await publicClient.estimateFeesPerGas()
const signedTx = await walletClient.signTransaction({
...transaction,
gas: gasEstimate,
maxFeePerGas: feeData.maxFeePerGas,
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
})
EIP-712 для structured data. DeFi-взаимодействия (approve, permit) требуют типизированных подписей. Кошелёк парсит EIP-712 структуру, отображает человекочитаемые данные и подписывает. Используем viem или ethers.js v6.
WalletConnect v2 интеграция
Протокол через зашифрованный relay. Кошелёк сканирует QR → устанавливает канал → получает JSON-RPC запросы.
import { Core } from '@walletconnect/core'
import { Web3Wallet } from '@walletconnect/web3wallet'
const core = new Core({ projectId: WC_PROJECT_ID })
const wallet = await Web3Wallet.init({ core, metadata: { name: 'MyWallet' } })
wallet.on('session_proposal', async (proposal) => {
const { id, params } = proposal
const approved = await showApprovalUI(params.proposer.metadata, params.requiredNamespaces)
if (approved) {
await wallet.approveSession({ id, namespaces: { eip155: { accounts: [`eip155:1:${userAddress}`], methods: ['eth_sendTransaction', 'personal_sign'], events: ['accountsChanged'] } } })
}
})
Как обеспечить совместимость с разными блокчейнами?
Мы поддерживаем EVM-сети (Ethereum, Polygon, Arbitrum, Optimism, Base) и не-EVM (Solana, BNB Chain). Для каждой сети конфигурация хранится в Chain Registry — это JSON-схема с RPC-эндпоинтами, explorer-URL и gas-параметрами.
RPC failover: используем 3+ провайдера на сеть (Alchemy, Infura, QuickNode). При падении основного — автоматическое переключение с гранулярностью запроса.
Балансы токенов получаем через Alchemy Token API (EVM) или Helius (Solana). Для ERC-20 используем фильтр по Transfer events с индексом from: 0x0.
Кэшируем данные в SQLite через GRDB для офлайн-доступа — пользователь видит последние балансы даже без сети.
Добавляем новую сеть за 2-3 дня: достаточно добавить запись в Chain Registry и настроить explorer.
| Сеть | Тип | EVM | RPC (рекомендуемый) | Особенности |
|---|---|---|---|---|
| Ethereum | L1 | Да | Alchemy (mainnet, goerli) | Высокая комиссия, EIP-1559 |
| Polygon | L2 | Да | QuickNode | Быстрые tx, низкие fees |
| Arbitrum | L2 | Да | Infura | Optimistic rollup |
| Solana | L1 | Нет | Helius | Rust-based, SPL токены |
| BNB Chain | L1 | Да | QuickNode | EVM-совместимость |
Как защитить кошелёк от jailbreak и screen recording?
На взломанном устройстве Keychain не гарантирует защиту. Проверяем наличие Cydia, /private/var/lib/apt и возможности записи вне sandbox. При обнаружении — блокируем экспорт seed.
Для экранов с seed-фразой используем UITextField с isSecureTextEntry = true — системный механизм запрета скриншотов. Android-аналог: FLAG_SECURE.
Clipboard security: копирование seed очищается через 60 секунд.
Экономия на аудитах достигается за счёт встроенных security-практик: статический анализ Slither и Mythril интегрированы в CI/CD, fuzzing на Echidna.
Пошаговая инструкция: как добавить поддержку новой блокчейн-сети
- Создать JSON-запись в Chain Registry: указать chainId, RPC-эндпоинты, explorer URL, символ нативной валюты.
- Настроить RPC-провайдеры: добавить как минимум 3 endpoint (Alchemy, Infura, QuickNode) для failover.
- Реализовать получение баланса нативной валюты через provider.getBalance().
- Для токенов — добавить фильтр Transfer events (ERC-20) или использовать API индексора.
- Протестировать транзакцию: отправить тестовый перевод и проверить explorer.
- Обновить UI: добавить логотип сети и название в список выбора.
Сравнение подходов к хранению ключей
| Подход | Безопасность | Производительность | Поддержка кривых |
|---|---|---|---|
| Secure Enclave P-256 | Максимальная | Высокая (аппаратное ускорение) | Только P-256 (secp256r1) |
| Keychain + биометрия | Высокая | Средняя (программное подписание) | Любые (secp256k1, ed25519) |
| Double encryption (наш метод) | Очень высокая | Средняя | Любые |
Наш метод double encryption поверх Keychain обеспечивает в 2 раза большую устойчивость к атакам перебором по сравнению с обычным Keychain.
Процесс разработки
- Аналитика: спецификация целевых сетей, security-требований, интеграций (WalletConnect, RPC).
- Проектирование: архитектура ключей, хранилище, signing flow, multi-chain роутинг.
- Реализация: нативный iOS код (Swift) + TypeScript для кросс-платформенных модулей.
- Тестирование: unit-тесты на криптографические операции, интеграционные тесты WalletConnect, пентест.
- Деплой: публикация в App Store, настройка CI/CD, документация API.
Стоимость проекта рассчитывается после брифа. Экономия на аудитах достигается за счёт встроенных security-практик. Оценим ваш проект — свяжитесь для консультации.
Сроки ориентировочно
- MVP (создание кошелька, отправка/получение ETH, WalletConnect): от 3 до 4 месяцев.
- Полноценный кошелёк (multi-chain, NFT, DeFi, security hardening): от 6 до 9 месяцев.
Мы знаем, как сделать кошелёк, который пройдёт аудит и не потеряет пользовательские средства. Получите консультацию — свяжитесь для обсуждения вашего проекта.
Чек-лист безопасности перед публикацией
- [ ] Проверка детекции jailbreak
- [ ] Отключение скриншотов на экранах с seed
- [ ] Ограничение времени жизни clipboard (60 сек)
- [ ] Интеграция статического анализа (Slither, Mythril) в CI/CD
- [ ] Fuzzing смарт-контрактов (Echidna)
- [ ] Пентест на реальных устройствах







