ICONKit,Swift 的 ICON SDK
ICON 支持第三方或用户服务开发。您可以将 ICON SDK 集成到您的项目中并利用 ICON 的功能。
- ICONKit 现在提供 Swift 5
安装
CocoaPods
CocoaPods 是一个用于 Swift Cocoa 项目的依赖库管理器。
$ sudo gem install cocoapods
要将 ICONKit 集成到您的项目中,请在 Podfile
中指定它
target '<Your Target Name>' do
use_frameworks!
...
pod 'ICONKit', '~> 0.4.3'
...
end
现在安装 ICONKit
$ pod install
Swift 4.x 版本
0.3.2 是适用于 Swift 4.x 的最后一个 ICONKit 版本。
尝试
pod 'ICONKit', '0.3.2'
快速开始
按照高度查询块的简单方法如下。
// ICON Mainnet
let iconService = ICONService(provider: "https://ctz.solidwallet.io/api/v3", nid: "0x1")
// Gets a block matching the block height.
let request: Request<Response.Block> = iconService.getBlock(height: height)
let result = request.execute()
switch result {
case .success(let responseBlock):
...
case .failure(let error):
...
}
ICONService
通过 ICONService
调用的 API。
可以按以下方式初始化。
let iconService = ICONService(provider: "https://ctz.solidwallet.io/api/v3", nid: "0x1")
Queries
所有查询都由一个 Request<T>
发起。
同步
execute()
方法同步请求一个查询。
let response = iconService.getLastBlock().execute()
switch response {
case .success(let responseBlock):
print(responseBlock.blockHash)
...
case .failure(let error):
print(error.errorDescription)
...
}
异步
你可以使用下面的 async
表达式异步请求一个查询。
iconService.getLastBlock().async { (result) in
switch result {
case .success(let responseBlock):
print(responseBlock.blockHash)
...
case .failure(let error):
print(err.errorDescription)
...
}
}
查询 API
以下是查询 API。
- getLastBlock
- getBlock(height)
- getBlock(hash)
- call
- getBalance
- getScoreAPI
- getTotalSupply
- getTransaction
- getTransactionResult
- sendTransaction
getLastBlock
获取最后一块信息。
let request: Request<Response.Block> = iconService.getLastBlock()
按区块高度获取区块信息
通过区块高度获取区块信息。
let request: Request<Response.Block> = iconService.getBlock(height: height)
按区块哈希值获取区块信息
通过区块哈希值获取区块信息。
let request: Request<Response.Block> = iconService.getBlock(hash: "0x000...000")
调用SCORE API
调用SCORE API。使用你想调用的方法的输出返回类型进行泛型类型。例如,如果输出类型是《String》,就使用《String》。
let call = Call<String>(from: wallet.address, to: scoreAddress, method: "name", params: params)
let request: Request<String> = iconService.call(call)
let response: Result<String, ICError> = request.execute()
如果方法的输出类型是十六进制字符串(例如,“0x56bc75e2d63100000”),你也可以使用《String》和《BigUInt》!只需在泛型类型中输入《BigUInt》,然后ICONKit将输出值转换为BigUint。如果你想要使用十六进制字符串,就使用《String》。
// Using `BigUInt`
let call = Call<BigUInt>(from: wallet.address, to: scoreAddress, method: "balanceOf", params: params)
let request: Request<BigUInt> = iconService.call(call)
let response: Result<BigUInt, ICError> = request.execute() // return 100000000000000000000 or ICError
// Using `String`
let call = Call<String>(from: wallet.address, to: scoreAddress, method: "balanceOf", params: params)
let request: Request<String> = iconService.call(call)
let response: Result<String, ICError> = request.execute() // return "0x56bc75e2d63100000" or ICError
getBalance
获取指定账户的余额。
let request: Request<BigUInt> = iconService.getBalance(address: "hx000...1")
getScoreAPI
获取ScoreAPI列表。
let request: Request<Response.ScoreAPI> = iconService.getScoreAPI(scoreAddress: "cx000...1")
getTotalSupply
获取ICX的总供应量。
let request: Request<BigUInt> = iconService.getTotalSupply()
getTransaction
获取与指定事务哈希匹配的事务。
let request: Request<Response.TransactionByHashResult> = iconService.getTransaction(hash: "0x000...000")
getTransactionResult
获取由事务哈希请求的交易结果。
let request: Request<Response.TransactionResult> = iconService.getTransactionResult(hash: "0x000...000")
发送事务
调用SCORE API更改状态请求作为发送事务。
在发送事务之前,应签名事务。
加载钱包和存储密钥库
// Generates a wallet.
let wallet = Wallet(privateKey: nil)
// Load a wallet from the private key.
let privateKey = PrivateKey(hex: data)
let wallet = Wallet(privateKey: privateKey)
// Save wallet keystore.
let wallet = Wallet(privateKey: nil)
do {
try wallet.generateKeystore(password: "YOUR_WALLET_PASSWORD")
try wallet.save(filepath: "YOUR_STORAGE_PATH")
} catch {
// handle errors
}
// Load a wallet from the keystore.
do {
let jsonData: Data = try Data(contentsOf: "YOUR_KEYSTORE_PATH")
let decoder = JSONDecoder()
let keystore = try decoder.decoder(Keystore.self, from: jsonData)
let wallet = Wallet(keystore: keystore, password: "YOUR_WALLET_PASSWORD")
} catch {
// handle errors
}
创建事务
// Sending ICX
let coinTransfer = Transaction()
.from(wallet.address)
.to(to)
.value(BigUInt(15000000))
.stepLimit(BigUInt(1000000))
.nid(self.iconService.nid)
.nonce("0x1")
// SCORE function call
let call = CallTransaction()
.from(wallet.address)
.to(scoreAddress)
.stepLimit(BigUInt(1000000))
.nid(self.iconService.nid)
.nonce("0x1")
.method("transfer")
.params(["_to": to, "_value": "0x1234"])
// Message transfer
let transaction = MessageTransaction()
.from(wallet.address)
.to(to)
.value(BigUInt(15000000))
.stepLimit(BigUInt(1000000))
.nonce("0x1")
.nid(self.iconService.nid)
.message("Hello, ICON!")
发送请求
SignedTransaction
对象使用钱包签名字符串。
请求以类似查询请求的同步或异步方式执行。
同步请求
do {
let signed = try SignedTransaction(transaction: coinTransfer, privateKey: privateKey)
let request = iconService.sendTransaction(signedTransaction: signed)
let response = request.execute()
switch response {
case .success(let result):
print("SUCCESS: TXHash - \(result)")
...
case .failure(let error):
print("FAIL: \(error.errorDescription)")
...
}
} catch {
print(error)
...
}
异步请求
do {
let signed = try SignedTransaction(transaction: coinTransfer, privateKey: privateKey)
let request = iconService.sendTransaction(signedTransaction: signed)
request.async { (result) in
switch result {
case .success(let result):
print(result)
...
case .failure(let error):
print(error.errorDescription)
...
}
}
} catch {
print(error)
}
估算步骤
在交易中设置合适的stepLimit
值非常重要,以确保提交的交易能成功执行。
estimateStep
API提供了一种估算给定交易步数的估算方法。使用此方法,您可以在发送交易前获取步数的估算值,然后根据估算结果创建带有stepLimit
的SignedTransaction
。
// Make a raw transaction without the stepLimit
let message = MessageTransaction()
.from(fromAddress)
.to(toAddress)
.nid(self.iconService.nid)
.message("Hello, ICON!")
// Estimate step
let estimateStepResponse = iconService.estimateStep(transaction: message).execute()
if let estimatedStepCost = try? estimateStepResponse.get() {
// Add some margin to estimated step
let stepLimit = estimatedStepCost + 10000
message.stepLimit(estimatedStepCost)
}
// Send transaction
do {
let signed = try SignedTransaction(transaction: message, privateKey: yourPrivateKey)
let response = self.iconService.sendTransaction(signedTransaction: signed).execute()
switch response {
case .success(let result):
print("Message tx result - \(result)")
case .failure(let error):
print(error)
}
} catch {
print(error)
}
需要注意的是,估算值可能大于或小于交易实际使用的步数,因此建议在设置SignedTransaction
的stepLimit
时,为估算值添加一定的余量。
转换器
ICONKit支持转换函数。
// Convert ICX or gLoop to loop.
let balance: BigUInt = 100
let ICXToLoop: BigUInt = balance.convert() // 100000000000000000000
let gLoopToLoop: BigUInt = balance.convert(unit: .gLoop) // 100000000000
// Convert `BigUInt` value to HEX `String`.
let hexString: String = ICXToLoop.toHexString() // 0x56bc75e2d63100000
// Convert HEX `String` to `BigUInt`.
let hexBigUInt: BigUInt = hexString.hexToBigUInt()! // 100000000000000000000
// Convert HEX `String` to `Date`
let timestamp: String = "0x5850adcbaa178"
let confirmedDate: Date = timestamp.hexToDate()! // 2019-03-27 03:16:22 +0000
参考
版本
0.4.0
需求
- Xcode 10 或更高版本
- iOS 10 或更高版本
- Swift 5
- Cocoapods
许可
本项目遵循Apache 2.0许可。请参阅LICENSE获取详细信息。