Comprehensive EVM SDK (Ethereum, Binance Smart Chain, Avalanche, Arbitrum, Optimism, Polygon) for iOS devices, implemented on Swift. Create wallets, watch wallets (read-only), sync transactions, filter transactions by type (erc20, bep20, swap transactions etc.), swap using native DEX protocols, connect to DeFi smart contracts using WalletConnect. Easily extendable to work with custom smart contracts. Full support for EIP1159.
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.
Supports following settings:
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 currently
networkfkType
parameter.mainNet
.ropsten
.kovan
rpcApi
parameter.infuraWebSocket(id: "", secret: "")
: RPC over HTTP.infura(id: "", secret: """)
: RPC over WebSocketminLogLevel
: Can be configured for debug purposes if required.EthereumKit.Kit instance requires to be started with start
command
ethereumKit.start()
ethereumKit.stop()
You can get account state, lastBlockHeight, syncState, transactionsSyncState and some others synchronously
guard let state = ethereumKit.accountState else {
return
}
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) })
let decimalAmount: Decimal = 0.1
let amount = BigUInt(decimalAmount.roundedString(decimal: decimal))!
let address = Address(hex: "0x73eb56f175916bd17b97379c1fdb5af1b6a82c84")!
ethereumKit
.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
})
let decimalAmount: Decimal = 0.1
let amount = BigUInt(decimalAmount.roundedString(decimal: decimal))!
let address = Address(hex: "0x73eb56f175916bd17b97379c1fdb5af1b6a82c84")!
ethereumKit
.estimateGas(to: address, amount: amount, gasPrice: 50_000_000_000)
.subscribe(onSuccess: { gasLimit in
print(gasLimit)
})
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)
ethereumKit
.sendSingle(transactionData: transactionData, gasPrice: 50_000_000_000, gasLimit: 1_000_000_000_000)
.subscribe(onSuccess: { [weak self] _ in})
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
uniswapKit
.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})
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)
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.
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 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!
target '<Your Target Name>' do
pod 'EthereumKit.swift'
pod 'Erc20.swift'
pod 'UniswapKit.swift'
end
Then, run the following command:
$ pod install
All features of the library are used in example project. It can be referred as a starting point for usage of the library.
The EthereumKit-iOS
toolkit is open source and available under the terms of the MIT License.