Integrate Embedded Wallets with the Bitkub Blockchain in iOS/Swift Applications
While using the Embedded Wallets iOS SDK, you get the private key within the user scope after successful authorization. This private key can be used to retrieve the user's address, and interact with Bitkub to make any blockchain calls..
Chain details for Bitkub
- Mainnet
- Testnet
- Chain ID: 0x60
- Public RPC URL:
https://rpc.bitkubchain.io - Display Name: Bitkub Chain Mainnet
- Block Explorer Link:
https://www.bkcscan.com - Ticker: KUB
- Ticker Name: Bitkub Coin
- Chain ID: 0x6545
- Public RPC URL:
https://rpc-testnet.bitkubchain.io - Display Name: Bitkub Chain Testnet
- Block Explorer Link:
https://testnet.bkcscan.com - Ticker: tKUB
- Ticker Name: Test Bitkub Coin
Prerequisites
- Project is set up in the MetaMask Developer Dashboard
- Web3Auth is integrated in your iOS app
Installation
To interact with the Ethereum compatible blockchains in Swift, you can use any
EIP1193 compatible package. Here, we're using
web3swift to demonstrate how to make blockchain calls
using it with Web3Auth.
To install the web3swift package, you have two options. You can either use Swift Package Manager
or CocoaPods.
- Swift Package Manager
- CocoaPods
-
In Xcode, with your app project open, navigate to File > Add Packages.
-
When prompted, add the single-factor-auth-swift iOS SDK repository:
https://github.com/argentlabs/web3.swift -
When finished, Xcode will automatically begin resolving and downloading your dependencies in the background.
To install the Web3Auth SingleFactorAuth SDK using Cocoapods, follow the below steps:
-
Open the Podfile, and add the SingleFactorAuth pod:
pod 'web3.swift' -
Once added, use
pod installcommand to download the dependency.
Initialize
Initialize the EthereumHttpClient with the RPC URL and chain id
of the network you want to connect to, to interact with the blockchain. To get the public RPC URL, and other details as chain id, see ChainList.
import web3
let client = EthereumHttpClient(
// Please avoid using public RPC URL in production, use services
// like Infura.
url: URL.init(string: rpcUrl)!,
// Replace with the chain id of the network you want to connect to
network: .custom(chainId)
)
Get account
Use the EthereumAccount class to retrieve the user's Ethereum address. This account can
also be used to sign transactions and messages.
The package doesn't provides any direct way to consume the the private key and create an account.
Hence, we'll create an extension for the Web3AuthState extending the
EthereumSingleKeyStorageProtocol to retrieve the private key and create an account.
import web3
import Web3Auth
extension Web3AuthState: EthereumSingleKeyStorageProtocol {
public func storePrivateKey(key: Data) throws {
}
public func loadPrivateKey() throws -> Data {
guard let data = self.privKey?.web3.hexData else {
throw PlaygroundError.decodingError
}
return data
}
}
Once we have created the extension, we can use the Web3AuthState to create an EthereumAccount.
Please note, that this assumes that the user has already logged in and the state is available.
import web3
// Use your existing Web3Auth instance
let web3authState = web3Auth.state!
let account = try EthereumAccount(keyStorage: web3authState)
let address = account.address
Get balance
Use the EthereumClient.eth_getBalance method to retrieve the balance of an Ethereum address.
The result we get from Web3Client is in wei, the smallest unit of ether. To convert wei to ether, divide by 10^18, where 18 denotes the decimals for wei.
import web3
let etherInWei = pow(Double(10), 18)
/// Convert Wei(BInt) unit to Ether(Decimal) unit
public func toEther(wei: Wei) -> Ether {
guard let decimalWei = Double(wei.description) else {
return 0
}
return decimalWei / etherInWei
}
let balanceResponse = try await client.eth_getBalance(
// Use the address from previous step
address: address,
block: .Latest
)
let balance = toEther(wei: balanceResponse)
Sign a message
To sign the message, you can use the EthereumAccount.sign method. The sign method takes in the
data of the message, and returns the signature.
import web3
let message = "Hello World"
// Use the account from previous step
guard let data = message.data(using: .ascii) else {
// throw error
}
let signature = try ethereumAccount.signMessage(message: data)