Mobile Crypto Wallet Development (iOS)

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Mobile Crypto Wallet Development (iOS)
Complex
from 2 weeks to 3 months
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Mobile Crypto Wallet Development

Mobile wallet is not just "an app showing balance". It's a key management system, interface to blockchain networks, and security-critical product where error in key derivation or storage can cost user all their funds. Development requires clear understanding of cryptography (BIP-32, BIP-39, BIP-44), specifics of mobile Secure Enclave/Keystore, and WalletConnect/EIP protocols.

Complete picture from key hierarchy to signing flow, with emphasis on security-critical details.

Key Management: HD Wallet Architecture

BIP-39: Mnemonic Phrase

Starting point — 128-256 bits of randomness converted to 12-24 words from BIP-39 dictionary (2048 words). Words are human-readable key backup. Critical: entropy must be generated with cryptographically secure CSPRNG (iOS: SecRandomCopyBytes, Android: SecureRandom).

// iOS: generate 128 bits entropy
var entropy = [UInt8](repeating: 0, count: 16)
let result = SecRandomCopyBytes(kSecRandomDefault, entropy.count, &entropy)
guard result == errSecSuccess else { throw WalletError.entropyGenerationFailed }

// Convert to mnemonic via library (WalletKit, BitcoinKit, TrustWalletCore)
let mnemonic = try Mnemonic.generate(from: entropy)
// ["abandon", "ability", "able", "about", "above", ...]

BIP-32/BIP-44: Hierarchical Key Derivation

From seed (obtained from mnemonic via PBKDF2), key tree is built. BIP-44 defines standard path: m / purpose' / coin_type' / account' / change / address_index.

Example paths:

  • Ethereum: m/44'/60'/0'/0/0 — first ETH address
  • Bitcoin: m/44'/0'/0'/0/0 — first BTC address
  • 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);

// Derive first ETH account
const ethKey = root.derive("m/44'/60'/0'/0/0");
const privateKey = ethKey.privateKey!; // Uint8Array
const address = computeAddress(privateKey); // ethers.js or viem

Important: ' means hardened derivation — child keys cannot be computed from parent public key. Purpose, coin_type, account levels — always hardened. Change and index levels — not hardened (allows generating public keys without private key for watch-only function).

Secure Storage: Keys in Device Memory

Private keys and seed never stored in plaintext. Strategies by security level:

iOS Keychain + Secure Enclave. iOS Keychain is encrypted system storage. For maximum security: key created directly in Secure Enclave (separate processor, key never leaves chip). Signing operations happen inside Enclave — app gets only signature result, not private key.

Android Keystore. Analog of Keychain, keys in Hardware-backed keystore (TEE). Supports EC keys, including secp256k1 (Android 9+). KeyStore.getInstance("AndroidKeyStore").

Additional encryption layer. On top of OS keychain: seed encrypted via AES-256-GCM with key protected in Keychain. Double encryption adds protection if Keychain API compromised.

Transaction Signing Flow

Transaction Building

For EVM networks: nonce, to, value, data, gasLimit, maxFeePerGas, maxPriorityFeePerGas, chainId (EIP-1559 format). Building happens in app, signing — in secure context:

// viem: build and sign transaction
import { createWalletClient, http, parseEther } from 'viem';
import { mainnet } from 'viem/chains';

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

// Estimate gas
const gasEstimate = await publicClient.estimateGas(transaction);

// Get current fee data
const feeData = await publicClient.estimateFeesPerGas();

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

EIP-712 for Structured Data Signing

Most DeFi interactions — not just ETH transfers. approve, permit, signTypedData — all EIP-712 typed signatures. Wallet must:

  1. Parse EIP-712 structure from dApp request
  2. Display human-readable data to user (not raw hex)
  3. After confirmation — sign and return signature

Decoding and displaying EIP-712 — non-trivial task. ethers.js v6 and viem have built-in support. For correct UI display need recursively unfold typed structures.

WalletConnect v2 Integration

WalletConnect v2 — communication protocol between dApp and wallet via encrypted relay. Wallet scans QR-code or gets deep link → establishes encrypted channel → receives JSON-RPC requests from 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', ... } });

// Handle session proposal (user scans QR)
wallet.on('session_proposal', async (proposal) => {
  const { id, params } = proposal;
  
  // Show user what dApp requests
  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'],
        },
      },
    });
  }
});

// Handle signature requests
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 supports multi-chain: one session can manage addresses on Ethereum, Polygon, Arbitrum simultaneously.

Multi-chain Architecture

Chain Registry and RPC Management

Modern wallet supports 10-50+ networks. Pattern: chain registry with config for each:

interface ChainConfig {
  chainId: number;
  name: string;
  rpcUrls: string[];        // multiple for failover
  fallbackRpcUrls: string[]; // public RPC as fallback
  nativeCurrency: { symbol: string; decimals: number };
  blockExplorer: string;
  isTestnet: boolean;
}

// RPC with automatic 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 and Balance Fetching

Moralis API, Alchemy Token API, Ankr Advanced API — specialized endpoints for getting all tokens and NFTs of address without iterating all possible ERC-20 contracts. Much faster than separate balanceOf calls.

For production wallet: combination Alchemy/Moralis for main networks + own balance cache in SQLite (React Native with expo-sqlite or MMKV).

Security at App Level

Jailbreak/Root Detection

On compromised device (jailbreak/root), Keychain/Keystore don't guarantee protection — other apps with root access can read protected data. Detecting jailbreak:

iOS: check /Applications/Cydia.app, /private/var/lib/apt, ability to write /private/test-jailbreak. Android: check su binaries, Magisk/SuperSU apps, presence of test build keys.

Reaction: block some functions (seed backup), warn user, optionally — complete ban (debatable: some wallets allow with warning).

Screen Recording Protection

screens with seed phrase and private key must be unavailable for screenshots and recording:

// iOS: screenshot protection for specific view
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    // Add secure text field as overlay — system protection mechanism
    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 for activities with sensitive data.

Clipboard Security

Copying seed or private key to clipboard — risk: other apps can read it. Warn user, automatically clear clipboard after 60 seconds:

await Clipboard.setStringAsync(seedPhrase);
setTimeout(async () => {
  await Clipboard.setStringAsync(''); // clear after 60 seconds
}, 60_000);

Development Stack

React Native — cross-platform iOS + Android from one codebase. Expo simplifies native modules. But for crypto operations: native modules critical (React Native JavaScript bridge too slow for crypto, especially BIP-32 derivation).

TrustWallet Core — native library (C++), supports 60+ blockchains: HD Wallet, signing, address derivation. Bindings for Swift, Kotlin, TypeScript. Eliminates need to implement BIP-32/BIP-44 for each chain.

Component Technology Complexity
Key management TrustWallet Core + Keychain/Keystore High
EVM signing viem / ethers.js v6 Medium
WalletConnect v2 @walletconnect/web3wallet Medium
Multi-chain support Chain registry + RPC failover Medium
Token discovery Alchemy/Moralis API Low
Secure storage iOS Keychain / Android Keystore High
Biometric auth expo-local-authentication Low
NFT display Alchemy NFT API + expo-image Medium

Timeline. MVP with basic functions (create/import wallet, ETH/ERC-20 send/receive, WalletConnect) — 3-4 months. Full-featured wallet with multi-chain, NFT, DeFi integration, security hardening — 6-9 months.

Mandatory stages: security review before App Store/Google Play publication + penetration testing on real devices. Apple and Google check wallets stricter than regular apps — requirements for privacy policy, key management documentation, compliance with local financial regulations.

Cost calculated after detailed specification of target networks and functional scope.