GithubHelp home page GithubHelp logo

horizontalsystems / ethereum-kit-ios Goto Github PK

View Code? Open in Web Editor NEW
173.0 13.0 41.0 10.21 MB

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.

Home Page: https://unstoppable.money

License: MIT License

Swift 84.73% Ruby 0.62% Objective-C 0.54% C 13.66% C++ 0.45%
ethereum ethereum-wallet erc20 ethereum-sdk ethereum-library binance-smart-chain bep20 web3 eip1159 arbitrum

ethereum-kit-ios's Introduction

EthereumKit-iOS

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.

Features

  • 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

EthereumKit.swift

  • 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

Erc20Kit.swift

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

UniswapKit.swift

Supports following settings:

  • Price Impact
  • Deadline
  • Recipient
  • Fee on Transfer

Usage

Initialization

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 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

ethereumKit.start()
ethereumKit.stop()

Getting wallet data

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) })

Send Transaction

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
        })

Estimate Gas Limit

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)
        })

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)

ethereumKit
        .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

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})

Extending

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.

Prerequisites

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

Installation

CocoaPods

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

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.

Dependencies

  • 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

License

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

ethereum-kit-ios's People

Contributors

ant013 avatar ealymbaev avatar esen avatar esengulov avatar mnizhurin avatar rex4539 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ethereum-kit-ios's Issues

Handle "Announce" messages

When "Announce" message is received,

  • New block(s) must be downloaded from the peer
  • New state must be requested and validated
  • Peer's bestBlockHeight must be updated
  • The following delegate methods should be called

IBlockchainDelegate#onUpdate(lastBlockHeight: Int)
IBlockchainDelegate#onUpdate(balance: String)
IBlockchainDelegate#onUpdate(syncState: SyncState)

ERC-20 in SPV

  • Check blocks header's bloom bits and if it matches token events, request state proof and validate it
  • Call following delegate methods if needed:

IBlockchainDelegate#onUpdateErc20(balance: String, contractAddress: String)
IBlockchainDelegate#onUpdateErc20(syncState: SyncState, contractAddress: String)

Some ERC20 Tokens incorrectly display the amount in transactions

Some ERC20 charge fee in tokens

Ex.: Stasis EURS for every transfer the contract collects arbitrary variable and fixed fee in EURS that will be deducted from your token balance in addition to the transferred amount.

At the moment: when i send this token, from my token balance deduct transferred Amount+ fixed fee in EURS, but in my transactions list I see only the amount of fee. It will be more correct to display 2 transactions: Transferred Amount and Fee in token

Update:

It should be taken into account that there is no standard for fee on ERC20 level. In other words, each ERC20 token may potentially have their own customized version of the fee on an ERC20 contract level. Therefore, whatever fix we apply it should be universal and work correctly for all such contracts.

Hello

Hi everyone!
I am Ryo and am an author of EthereumKit. I found this repo today. I looked though the codebase and it looks like this repo shares a same codebase with my framework. Now im wondering if you guys could buy my framework off from me in some way because I am not much working on it anymore but you guys look like you are. Let me know if you are interested. My email is on my profile.

Thank you

PeerGroup refactoring

  • reimplement PeerGroup using TDD
  • handle outgoing and incoming data correctly
  • handle forks and block header sync (and validation)

Separate connection layers

The following layers should be introduced:

  • Connection
  • FrameConnection
  • DevP2PConnection
  • DevP2PPeer
  • LESPeer

EthereumKit api refactoring

  • EthereumKit#transactions should accept fromHash and limit parameters and return Observable<[TransactionInfo]>
  • EthereumKit#balance and EthereumKit#lastBlockHeight must return cached values

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.