Integrate Web3Auth with the Ethereum Blockchain in iOS/Swift Applications
While using the Web3Auth iOS SDK, you get the private key within the user scope. This private key
can interact with Ethereum to make any blockchain calls, like getting
user's account
, fetch balance
, sign transaction
, send transaction
, read
from and write
to the smart contract, etc. We have highlighted a few here for getting you started quickly on that.
Installation
To interact with the Ethereum blockchain in iOS Swift environment, we will be using the web3swift package.
CocoaPods
Add web3.swift to your Podfile
:
pod 'web3.swift'
Then run the following command:
$ pod install
- Import the package and shims into your codebase:
import web3
Here are a few sample apps which you can checkout to get started with the integration.
Chain Details for Ethereum
- Mainnet
- Testnet
- Chain ID: 0x1
- Public RPC URL: https://rpc.ankr.com/eth (Avoid using public rpcTarget in production, use services like Infura, Quicknode etc)
- Display Name: Ethereum Mainnet
- Block Explorer Link: https://etherscan.io
- Ticker: ETH
- Ticker Name: Ethereum
- Chain ID: 0xaa36a7
- Public RPC URL: https://rpc.ankr.com/eth_sepolia (Avoid using public rpcTarget in production, use services like Infura, Quicknode etc)
- Display Name: Ethereum Sepolia Testnet
- Block Explorer Link: https://sepolia.etherscan.io
- Ticker: ETH
- Ticker Name: Sepolia
Initialize
import web3
import Web3Auth
var user: Web3AuthState
var client: EthereumClientProtocol
var address: EthereumAddress
var account: EthereumAccount
var latestBlock = 0
var chainID = 1 // EVM Chain ID
var providerUrl = "" // EVM chain RPC URL
Get User Info
You get the user information after a successful login returned from the login
method. The userInfo
object contains the user information, whereas
the privKey
object contains the private key that can be used to make blockchain calls.
let result = try await Web3Auth(.init(
clientId: clientId,
network: network)).login(
W3ALoginParams(loginProvider: provider)
)
await MainActor.run(body: {
user = result
loggedIn = true
})
let userInfo = user.userInfo
let privKey = user.privKey
Get Account
account = try EthereumAccount(keyStorage: user )
address = account.address
Get Balance
client = EthereumClient(url: URL(string: RPC_URL)!)
latestBlock = client.eth_blockNumber
let balance = try client.eth_getBalance(address: address, block:latestBlock)
Send Transaction
We have used some util functions to convert the values to the required format.
let gasPrice = try await client.eth_gasPrice()
let maxTipInGwie = BigUInt(TorusWeb3Utils.toEther(Gwie: BigUInt(amount)))
let totalGas = gasPrice + maxTipInGwie
let amtInGwie = TorusWeb3Utils.toWei(ether: amount)
let nonce = try await client.eth_getTransactionCount(address: address, block: .Latest)
let transaction = EthereumTransaction(from: address, to: EthereumAddress(sendTo), value: amtInGwie, data: Data(), nonce: nonce + 1, gasPrice: totalGas, gasLimit: gasLimit, chainId: chainID)
let signed = try account.sign(transaction: transaction)
let val = try await client.eth_sendRawTransaction(signed.transaction, withAccount: account)
The util functions are as follows
import BigInt
import Foundation
import web3
public typealias Ether = Double
public typealias Wei = BigUInt
public final class TorusWeb3Utils {
public static func timeMinToSec(val: Double) -> Double {
return val * 60
}
// NOTE: calculate wei by 10^18
private static let etherInWei = pow(Double(10), 18)
private static let etherInGwei = pow(Double(10), 9)
/// Convert Wei(BInt) unit to Ether(Decimal) unit
public static func toEther(wei: Wei) -> Ether {
guard let decimalWei = Double(wei.description) else {
return 0
}
return decimalWei / etherInWei
}
public static func toEther(Gwie: BigUInt) -> Ether {
guard let decimalWei = Double(Gwie.description) else {
return 0
}
return decimalWei / etherInGwei
}
/// Convert Ether(Decimal) unit to Wei(BInt) unit
public static func toWei(ether: Ether) -> Wei {
let wei = Wei(ether * etherInWei)
return wei
}
/// Convert Ether(String) unit to Wei(BInt) unit
public static func toWei(ether: String) -> Wei {
guard let decimalEther = Double(ether) else {
return 0
}
return toWei(ether: decimalEther)
}
// Only used for calcurating gas price and gas limit.
public static func toWei(GWei: Double) -> Wei {
return Wei(GWei * 1000000000)
}
}
Sign a message
account = try EthereumAccount(keyStorage: user )
let val = try account.sign(message: "Hello World")
let signedMessage = val.web3.hexString