Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/icon-project/ICONKit
ICONKit, ICON SDK for iOS
https://github.com/icon-project/ICONKit
Last synced: 14 days ago
JSON representation
ICONKit, ICON SDK for iOS
- Host: GitHub
- URL: https://github.com/icon-project/ICONKit
- Owner: icon-project
- License: apache-2.0
- Archived: true
- Created: 2018-08-24T03:25:37.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2022-03-04T02:07:32.000Z (over 2 years ago)
- Last Synced: 2024-09-19T23:02:07.830Z (about 2 months ago)
- Language: Swift
- Homepage:
- Size: 274 KB
- Stars: 8
- Watchers: 8
- Forks: 7
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-icon - ICONKit - ICON SDK for iOS (RPC API)
README
# ICONKit, ICON SDK for Swift
ICON supports SDK for 3rd party or user services development. You can integrate ICON SDK for your project and utilize ICON’s functionality.
* ICONKit now provide Swift 5## Installation
### CocoaPods
[CocoaPods](https://cocoapods.org/) is a dependency manager for Swift Cocoa projects.
```
$ sudo gem install cocoapods
```To integrate ICONKit into your project, specify it in your `Podfile`
```
target '' do
use_frameworks!
...
pod 'ICONKit', '~> 0.4.3'
...
end
```Now install the ICONKit.
```
$ pod install
```#### Swift 4.x version
[0.3.2](https://github.com/icon-project/ICONKit/releases/tag/0.3.2) is a last version of ICONKit for Swift 4.x.
try
```
pod 'ICONKit', '0.3.2'
```## Quick start
A simple query of the block by height is as follows.
```Swift
// ICON Mainnet
let iconService = ICONService(provider: "https://ctz.solidwallet.io/api/v3", nid: "0x1")// Gets a block matching the block height.
let request: Request = iconService.getBlock(height: height)
let result = request.execute()switch result {
case .success(let responseBlock):
...
case .failure(let error):
...
}
```## ICONService
APIs called through `ICONService`.
It can be initialized as follows.
```Swift
let iconService = ICONService(provider: "https://ctz.solidwallet.io/api/v3", nid: "0x1")
```# Queries
All queries are requested by a `Request`.
#### Synchronous
`execute()` requests a query synchronously.```Swift
let response = iconService.getLastBlock().execute()switch response {
case .success(let responseBlock):
print(responseBlock.blockHash)
...
case .failure(let error):
print(error.errorDescription)
...
}
```#### Asynchronous
You can request a query asynchronously using a `async` closure as below.
```swift
iconService.getLastBlock().async { (result) in
switch result {
case .success(let responseBlock):
print(responseBlock.blockHash)
...
case .failure(let error):
print(err.errorDescription)
...
}
}
```## Querying API
The querying APIs are as follows.
* [getLastBlock](#getLastBlock)
* [getBlock(height)](#getblock(height))
* [getBlock(hash)](#getBlock(hash))
* [call](#call)
* [getBalance](#getBalance)
* [getScoreAPI](#getScoreAPI)
* [getTotalSupply](#getTotalSupply)
* [getTransaction](#getTransaction)
* [getTransactionResult](#getTransactionResult)
* [sendTransaction](#Sending-transactions)### getLastBlock
Gets the last block information.
```swift
let request: Request = iconService.getLastBlock()
```### getBlock(height)
Gets block information by block height.
```swift
let request: Request = iconService.getBlock(height: height)
```### getBlock(hash)
Gets block information by block hash.
```swift
let request: Request = iconService.getBlock(hash: "0x000...000")
```### call
Calls a SCORE API.
Use the return type of method's outputs you want to call in generic type.
For example, the type of output that is `String` use `String`.```swift
let call = Call(from: wallet.address, to: scoreAddress, method: "name", params: params)
let request: Request = iconService.call(call)
let response: Result = request.execute()
```If the output type of method is hex String (ex. `"0x56bc75e2d63100000"`), you can use `String` and `BigUInt` too!
Just input `BigUInt` at generic type, then ICONKit convert the output value to BigUInt.
If you want to use hex `String`, use `String`.```swift
// Using `BigUInt`
let call = Call(from: wallet.address, to: scoreAddress, method: "balanceOf", params: params)
let request: Request = iconService.call(call)
let response: Result = request.execute() // return 100000000000000000000 or ICError// Using `String`
let call = Call(from: wallet.address, to: scoreAddress, method: "balanceOf", params: params)
let request: Request = iconService.call(call)
let response: Result = request.execute() // return "0x56bc75e2d63100000" or ICError
```### getBalance
Gets the balance of an given account.
```swift
let request: Request = iconService.getBalance(address: "hx000...1")
```### getScoreAPI
Gets a list of ScoreAPI.
```swift
let request: Request = iconService.getScoreAPI(scoreAddress: "cx000...1")
```### getTotalSupply
Gets the total supply of ICX.
```swift
let request: Request = iconService.getTotalSupply()
```### getTransaction
Gets a transaction matching the given transaction hash.
```Swift
let request: Request = iconService.getTransaction(hash: "0x000...000")
```### getTransactionResult
Gets the transaction result requested by transaction hash.
```swift
let request: Request = iconService.getTransactionResult(hash: "0x000...000")
```### Sending transactions
Calling SCORE APIs to change states is requested as sending a transaction.
Before sending a transaction, the transaction should be signed.
#### Loading wallets and storing the Keystore
```Swift
// 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
}
```#### Creating transactions
```Swift
// 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!")
```#### Sending Requests
`SignedTransaction` object signs a transaction using the wallet.
And a request is executed as **Synchronized** or **Asynchronized** like a querying request.
**Synchronous request**
```Swift
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)
...
}
```**Asynchronous request**
```swift
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)
}
```#### Estimate step
It is important to set a proper `stepLimit` value in your transaction to make the submitted transaction executed successfully.
`estimateStep` API provides a way to **estimate** the Step usage of a given transaction. Using the method, you can get an estimated Step usage before sending your transaction then make a `SignedTransaction` with the `stepLimit` based on the estimation.
```swift
// 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)
}
```Note that the estimation can be smaller or larger than the actual amount of step to be used by the transaction, so it is recommended to add some margin to the estimation when you set the `stepLimit` of the `SignedTransaction`.
### Converter
ICONKit supports converter functions.
```swift
// 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
```## Reference
- [ICON JSON-RPC API v3](https://github.com/icon-project/icon-rpc-server/blob/master/docs/icon-json-rpc-v3.md)
- [ICON Network](https://github.com/icon-project/icon-project.github.io/blob/master/docs/icon_network.md)## Version
0.4.0
## Requirement
- Xcode 10 or higher
- iOS 10 or higher
- Swift 5
- [Cocoapods](https://cocoapods.org)## License
This project follows the Apache 2.0 License. Please refer to [LICENSE](https://www.apache.org/licenses/LICENSE-2.0) for details.