Разработка мобильного криптокошелька (iOS)

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка мобильного криптокошелька (iOS)
Сложная
от 2 недель до 3 месяцев
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1258
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1170
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    873
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1092
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    830

Разработка мобильного криптокошелька

Мобильный кошелёк — это не просто «приложение, которое показывает баланс». Это система управления ключами, интерфейс к блокчейн-сетям и security-critical продукт, где ошибка в key derivation или storage может стоить пользователю всех средств. Разработка требует чёткого понимания криптографии (BIP-32, BIP-39, BIP-44), особенностей мобильных Secure Enclave/Keystore, и WalletConnect/EIP протоколов.

Здесь — полная картина от ключевой иерархии до signing flow, с акцентом на security-критичные детали.

Управление ключами: HD Wallet архитектура

BIP-39: мнемоническая фраза

Отправная точка всего — 128-256 бит случайности, преобразованной в 12-24 слова из BIP-39 словаря (2048 слов). Слова — человекочитаемый бэкап ключей. Критично: энтропия должна быть сгенерирована криптографически безопасным CSPRNG (iOS: SecRandomCopyBytes, Android: SecureRandom).

// iOS: генерация 128 бит энтропии
var entropy = [UInt8](repeating: 0, count: 16)
let result = SecRandomCopyBytes(kSecRandomDefault, entropy.count, &entropy)
guard result == errSecSuccess else { throw WalletError.entropyGenerationFailed }

// Преобразование в мнемонику через библиотеку (WalletKit, BitcoinKit, TrustWalletCore)
let mnemonic = try Mnemonic.generate(from: entropy)
// ["abandon", "ability", "able", "about", "above", ...]

BIP-32/BIP-44: иерархическая деривация ключей

Из seed (полученного из мнемоники через PBKDF2) строится дерево ключей. BIP-44 задаёт стандартный путь: m / purpose' / coin_type' / account' / change / address_index.

Примеры путей:

  • Ethereum: m/44'/60'/0'/0/0 — первый ETH адрес
  • Bitcoin: m/44'/0'/0'/0/0 — первый BTC адрес
  • Solana: m/44'/501'/0'/0'
import { HDKey } from '@scure/bip32';
import { mnemonicToSeedSync } from '@scure/bip39';

const seed = mnemonicToSeedSync(mnemonic);
const root = HDKey.fromMasterSeed(seed);

// Деривация первого ETH аккаунта
const ethKey = root.derive("m/44'/60'/0'/0/0");
const privateKey = ethKey.privateKey!; // Uint8Array
const address = computeAddress(privateKey); // ethers.js или viem

Важно: ' означает hardened derivation — child keys не могут быть вычислены из parent public key. Уровни purpose, coin_type, account — всегда hardened. Уровни change и index — не hardened (что позволяет генерировать public keys без private key для watch-only функции).

Secure Storage: ключи в памяти устройства

Приватные ключи и seed никогда не хранятся в plaintext. Стратегии по уровню безопасности:

iOS Keychain + Secure Enclave. iOS Keychain — зашифрованное хранилище системы. Для наивысшей безопасности: ключ создаётся прямо в Secure Enclave (отдельный процессор, ключ никогда не покидает чип). Операции подписи происходят внутри Enclave — приложение получает только результат подписи, но не private key.

// Создание ключа в Secure Enclave
let access = SecAccessControlCreateWithFlags(
    nil,
    kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
    [.privateKeyUsage, .biometryCurrentSet], // требует биометрию
    nil
)

let attributes: [String: Any] = [
    kSecAttrKeyType as String: kSecAttrKeyTypeECSECPrimeRandom,
    kSecAttrKeySizeInBits as String: 256,
    kSecAttrTokenID as String: kSecAttrTokenIDSecureEnclave,
    kSecPrivateKeyAttrs as String: [
        kSecAttrIsPermanent as String: true,
        kSecAttrApplicationLabel as String: "com.wallet.signing-key",
        kSecAttrAccessControl as String: access!
    ]
]

var error: Unmanaged<CFError>?
guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
    throw error!.takeRetainedValue()
}

Ограничение Secure Enclave: только P-256 (secp256r1), не secp256k1 (Ethereum/Bitcoin стандарт). Для Ethereum-подписей нельзя использовать Enclave напрямую. Компромисс: seed хранится в Keychain с защитой .biometryCurrentSet, подписание через software secp256k1 с ключом, извлекаемым только при биометрической аутентификации.

Android Keystore. Аналог Keychain, ключи в Hardware-backed keystore (TEE). Поддерживает EC keys, включая secp256k1 (Android 9+). KeyStore.getInstance("AndroidKeyStore").

Дополнительный слой шифрования. Поверх OS keychain: seed шифруется через AES-256-GCM ключом, который в свою очередь защищён в Keychain. Double encryption добавляет защиту при гипотетическом компрометировании Keychain API.

Transaction Signing Flow

Построение транзакции

Для EVM сетей транзакция включает: nonce, to, value, data, gasLimit, maxFeePerGas, maxPriorityFeePerGas, chainId (EIP-1559 формат). Формирование происходит в приложении, подписание — в secure контексте:

// viem: построение и подпись транзакции
import { createWalletClient, http, parseEther } from 'viem';
import { mainnet } from 'viem/chains';

const transaction = {
  to: recipientAddress,
  value: parseEther('0.1'),
  chainId: 1,
};

// Оценка gas
const gasEstimate = await publicClient.estimateGas(transaction);

// Получение текущих fee данных
const feeData = await publicClient.estimateFeesPerGas();

const signedTx = await walletClient.signTransaction({
  ...transaction,
  gas: gasEstimate,
  maxFeePerGas: feeData.maxFeePerGas,
  maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
});

EIP-712 для structured data signing

Большинство DeFi взаимодействий — не просто ETH переводы. approve, permit, signTypedData — всё это EIP-712 типизированные подписи. Кошелёк должен:

  1. Парсить EIP-712 структуру из dApp запроса
  2. Отображать человекочитаемые данные пользователю (не raw hex)
  3. После подтверждения — подписать и вернуть signature

Декодирование и отображение EIP-712 — нетривиальная задача. Библиотека ethers.js v6 и viem имеют встроенную поддержку. Для корректного отображения в UI нужно рекурсивно разворачивать типизированные структуры.

WalletConnect v2 интеграция

WalletConnect v2 — протокол коммуникации между dApp и кошельком через зашифрованный relay. Кошелёк сканирует QR-код или получает deep link → устанавливает зашифрованный канал → получает JSON-RPC запросы от dApp.

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', ... } });

// Обработка session proposal (пользователь сканирует QR)
wallet.on('session_proposal', async (proposal) => {
  const { id, params } = proposal;
  
  // Показать пользователю что dApp запрашивает
  const approved = await showApprovalUI(params.proposer.metadata, params.requiredNamespaces);
  
  if (approved) {
    await wallet.approveSession({
      id,
      namespaces: {
        eip155: {
          accounts: [`eip155:1:${userAddress}`, `eip155:137:${userAddress}`],
          methods: ['eth_sendTransaction', 'personal_sign', 'eth_signTypedData_v4'],
          events: ['accountsChanged', 'chainChanged'],
        },
      },
    });
  }
});

// Обработка запросов подписи
wallet.on('session_request', async (request) => {
  const { topic, params } = request;
  const { method, params: callParams } = params.request;
  
  if (method === 'eth_sendTransaction') {
    const tx = callParams[0];
    const approved = await showTransactionUI(tx);
    
    if (approved) {
      const signedTx = await signTransaction(tx);
      const txHash = await broadcastTransaction(signedTx);
      await wallet.respondSessionRequest({ topic, response: { id: request.id, result: txHash } });
    }
  }
});

WalletConnect v2 поддерживает multi-chain: один session может управлять адресами на Ethereum, Polygon, Arbitrum одновременно.

Multi-chain архитектура

Chain Registry и RPC management

Современный кошелёк поддерживает 10-50+ сетей. Паттерн: chain registry с конфигурацией каждой сети:

interface ChainConfig {
  chainId: number;
  name: string;
  rpcUrls: string[];        // несколько для failover
  fallbackRpcUrls: string[]; // публичные RPC как fallback
  nativeCurrency: { symbol: string; decimals: number };
  blockExplorer: string;
  isTestnet: boolean;
}

// RPC с автоматическим failover
class RobustProvider {
  private providers: JsonRpcProvider[];
  private currentIndex = 0;
  
  async call(method: string, params: any[]) {
    for (let i = 0; i < this.providers.length; i++) {
      try {
        return await this.providers[this.currentIndex].send(method, params);
      } catch (err) {
        this.currentIndex = (this.currentIndex + 1) % this.providers.length;
      }
    }
    throw new Error('All RPC endpoints failed');
  }
}

Token discovery и balance fetching

Moralis API, Alchemy Token API, Ankr Advanced API — специализированные endpoint-ы для получения всех токенов и NFT адреса без итерации по всем возможным ERC-20 контрактам. Значительно быстрее, чем вызовы отдельных balanceOf.

Для production кошелька: комбинация Alchemy/Moralis для основных сетей + собственный кэш балансов в SQLite (React Native с expo-sqlite или MMKV).

Безопасность на уровне приложения

Jailbreak/Root detection

На взломанном устройстве (jailbreak/root) Keychain/Keystore не гарантируют защиту — другие приложения с root доступом могут читать защищённые данные. Определение jailbreak:

iOS: проверка наличия /Applications/Cydia.app, /private/var/lib/apt, возможности писать в /private/test-jailbreak. Android: проверка su бинарников, Magisk/SuperSU приложений, наличия тестовых ключей сборки.

Реакция на обнаружение: блокировка некоторых функций (seed backup), предупреждение пользователю, опционально — полный запрет (спорно: некоторые кошельки разрешают использование с предупреждением).

Screen recording protection

Экраны с seed фразой и private key должны быть недоступны для скриншотов и записи экрана:

// iOS: защита от скриншотов для конкретного view
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    // Добавить secure text field как overlay — системный механизм защиты
    let field = UITextField()
    field.isSecureTextEntry = true
    self.view.addSubview(field)
    field.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    field.sendActions(for: .editingDidBegin)
}

Android: WindowManager.LayoutParams.FLAG_SECURE для активити с чувствительными данными.

Clipboard security

Копирование seed или private key в clipboard — риск: другие приложения могут читать clipboard. Предупреждать пользователя, автоматически очищать clipboard через 60 секунд:

await Clipboard.setStringAsync(seedPhrase);
setTimeout(async () => {
  await Clipboard.setStringAsync(''); // очистить через 60 секунд
}, 60_000);

Стек разработки

React Native — кроссплатформенная разработка iOS + Android из одного кодабейза. Expo для упрощения нативных модулей. Однако для крипто-операций: нативные модули критичны (React Native JavaScript bridge слишком медленный для криптографических операций, особенно на BIP-32 деривации).

TrustWallet Core — нативная библиотека (C++), поддерживает 60+ блокчейнов: HD Wallet, signing, address derivation. Bindings для Swift, Kotlin, TypeScript. Избавляет от необходимости самостоятельно реализовывать BIP-32/BIP-44 для каждой цепи.

Компонент Технология Сложность
Key management TrustWallet Core + Keychain/Keystore Высокая
EVM signing viem / ethers.js v6 Средняя
WalletConnect v2 @walletconnect/web3wallet Средняя
Multi-chain support Chain registry + RPC failover Средняя
Token discovery Alchemy/Moralis API Низкая
Secure storage iOS Keychain / Android Keystore Высокая
Biometric auth expo-local-authentication Низкая
NFT display Alchemy NFT API + expo-image Средняя

Сроки. MVP с базовыми функциями (создание/импорт кошелька, ETH/ERC-20 отправка/получение, WalletConnect) — 3-4 месяца. Полноценный кошелёк с multi-chain, NFT, DeFi интеграцией, security hardening — 6-9 месяцев.

Обязательные этапы: security review перед publication в App Store/Google Play + penetration testing на реальных устройствах. Apple и Google проверяют кошельки строже обычных приложений — требования к privacy policy, key management документации, и соответствию местным финансовым регуляциям.

Стоимость рассчитывается после детальной спецификации целевых сетей и функционального scope.