EthereumKit-iOS is a native(Swift), secure, reactive and extensible Ethereum client toolkit for iOS platform. It can be used by ETH/Erc20 wallet or by dapp client for any kind of interactions with Ethereum blockchain.


  • Ethereum wallet support, including internal Ether transfer transactions
  • Support for ERC20 token standard
  • Uniswap DEX support
  • Reactive-functional API
  • Implementation of Ethereum's JSON-RPC client API over HTTP or WebSocket
  • Support for Infura
  • Support for Etherscan


  • Sync account state/balance
  • Sync/Send/Receive Ethereum transactions
  • Internal transactions retrieved from Etherscan
  • Reactive API for Smart Contracts (Erc20Kit.swift and UniswapKit.swift use EthereumKit.swift for interactions with the blockchain)
  • Reactive API for wallet
  • Restore with mnemonic phrase


  • Sync balance
  • Sync/Send/Receive Erc20 token transactions
  • Allowance management
  • Incoming Erc20 token transactions retrieved from Etherscan
  • Reactive API for wallet


Supports following settings:

  • Price Impact
  • Deadline
  • Recipient
  • Fee on Transfer



First you need to initialize an EthereumKit.Kit instance

import EthereumKit

let ethereumKit = try! Kit.instance(
        words: ["word1", ... , "word12"],
        syncMode: .api,
        networkType: .ropsten,
        rpcApi: .infuraWebSocket(id: "", secret: ""),
        etherscanApiKey: "",
        walletId: "walletId",
        minLogLevel: .error
syncMode parameter
  • .api: Uses RPC
  • .spv: Ethereum light client. Not supported currently
  • .geth: Geth client. Not supported currenly
networkfkType parameter
  • .mainNet
  • .ropsten
  • .kovan
rpcApi parameter
  • .infuraWebSocket(id: "", secret: ""): RPC over HTTP
  • .infura(id: "", secret: """): RPC over WebSocket
Additional parameters:
  • minLogLevel: Can be configured for debug purposes if required.

Starting and Stopping

EthereumKit.Kit instance requires to be started with start command


Getting wallet data

You can get account state, lastBlockHeight, syncState, transactionsSyncState and some others synchronously

guard let state = ethereumKit.accountState else {

state.balance    // 2937096768
state.nonce      // 10

ethereumKit.lastBlockHeight  // 10000000

You also can subscribe to Rx observables of those and some others

ethereumKit.accountStateObservable.subscribe(onNext: { state in print("balance: \(state.balance); nonce: \(state.nonce)") })
ethereumKit.lastBlockHeightObservable.subscribe(onNext: { height in print(height) })
ethereumKit.syncStateObservable.subscribe(onNext: { state in print(state) })
ethereumKit.transactionsSyncStateObservable.subscribe(onNext: { state in print(state) })

// Subscribe to all Ethereum transactions synced by the kit
ethereumKit.allTransactionsObservable.subscribe(onNext: { transactions in print(transactions.count) })

// Subscribe to Ether transactions
ethereumKit.etherTransactionsObservable.subscribe(onNext: { transactions in print(transactions.count) })

Send Transaction

let decimalAmount: Decimal = 0.1
let amount = BigUInt(decimalAmount.roundedString(decimal: decimal))!
let address = Address(hex: "0x73eb56f175916bd17b97379c1fdb5af1b6a82c84")!

        .sendSingle(address: address, value: amount, gasPrice: 50_000_000_000, gasLimit: 1_000_000_000_000)
        .subscribe(onSuccess: { transaction in 
            print(transaction.transaction.hash.hex)  // sendSingle returns FullTransaction object which contains transaction, receiptWithLogs and internalTransactions

Estimate Gas Limit

let decimalAmount: Decimal = 0.1
let amount = BigUInt(decimalAmount.roundedString(decimal: decimal))!
let address = Address(hex: "0x73eb56f175916bd17b97379c1fdb5af1b6a82c84")!

        .estimateGas(to: address, amount: amount, gasPrice: 50_000_000_000)
        .subscribe(onSuccess: { gasLimit in 

Send Erc20 Transaction

import EthereumKit
import Erc20Kit

let decimalAmount: Decimal = 0.1
let amount = BigUInt(decimalAmount.roundedString(decimal: decimal))!
let address = Address(hex: "0x73eb56f175916bd17b97379c1fdb5af1b6a82c84")!

let erc20Kit = Erc20Kit.Kit.instance(ethereumKit: ethereumKit, contractAddress: "contract address of token")
let transactionData = erc20Kit.transferTransactionData(to: address, value: amount)

        .sendSingle(transactionData: transactionData, gasPrice: 50_000_000_000, gasLimit: 1_000_000_000_000)
        .subscribe(onSuccess: { [weak self] _ in})

Send Uniswap swap transaction

import EthereumKit
import UniswapKit
import Erc20Kit

let uniswapKit = UniswapKit.Kit.instance(ethereumKit: ethereumKit)

let tokenIn = uniswapKit.etherToken
let tokenOut = uniswapKit.token(try! Address(hex: "0xad6d458402f60fd3bd25163575031acdce07538d"), decimal: 18)
let amount: Decimal = 0.1

        .swapDataSingle(tokenIn: tokenIn, tokenOut: tokenOut)
        .flatMap { swapData in
            let tradeData = try! uniswapKit.bestTradeExactIn(swapData: swapData, amountIn: amount)
            let transactionData = try! uniswapKit.transactionData(tradeData: tradeData)

            return ethereumKit.sendSingle(transactionData: transactionData, gasPrice: 50_000_000_000, gasLimit: 1_000_000_000_000)
        .subscribe(onSuccess: { [weak self] _ in})


Add transaction syncer

Some smart contracts store some information concerning your address, which you can't retrieve in a standard way over RPC. If you have an external API to get them from, you can create a custom syncer and add it to EthereumKit. It will sync all the transactions your syncer gives.

Erc20TransactionSyncer is a good example of this. It gets token transfer transactions from Etherscan and feeds EthereumKit syncer with them. It is added to EthereumKit as following:

let transactionSyncer = Erc20TransactionSyncer(...)
ethereumKit.add(syncer: transactionSyncer)

Smart contract call

In order to make a call to any smart contract, you can use ethereumKit.sendSingle(transactionData:,gasPrice:,gasLimit:) method. You need to create an instance of TransactionData object. Currently, we don't have an ABI or source code parser. Please, look in Erc20Kit.swift and UniswapKit.swift to see how TransactionData object is formed.


  • Xcode 10.0+
  • Swift 5+
  • iOS 11+



CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

CocoaPods 1.5.0+ is required to build EthereumKit.

To integrate EthereumKit into your Xcode project using CocoaPods, specify it in your Podfile:

source ''
platform :ios, '10.0'

target '<Your Target Name>' do
  pod 'EthereumKit.swift'
  pod 'Erc20.swift'
  pod 'UniswapKit.swift'

Then, run the following command:

$ pod install

Example Project

All features of the library are used in example project. It can be referred as a starting point for usage of the library.


  • HSHDWalletKit - HD Wallet related features, mnemonic phrase generation.
  • OpenSslKit.swift - Crypto functions required for working with blockchain.
  • Secp256k1Kit.swift - Crypto functions required for working with blockchain.
  • HsToolKit.swift - Helpers library from HorizontalSystems
  • RxSwift
  • BigInt
  • GRDB.swift
  • Starscream


The EthereumKit-iOS toolkit is open source and available under the terms of the MIT License.

Ethereum Kit IOS

Fully functional wallet implementation for Ethereum protocol. Using this toolkit you can built ethereum + ERC 20 token wallet in no time :)

Ethereum Kit IOS Info

⭐ Stars 90
🔗 Homepage
🔗 Source Code
🕒 Last Update 5 months ago
🕒 Created 4 years ago
🐞 Open Issues 12
➗ Star-Issue Ratio 8
😎 Author horizontalsystems