Latest 0.3.1
Homepage https://github.com/icon-project/ICONKit
License Apache-2.0
Platforms ios 10.0, osx 10.14
Dependencies Result, scrypt, secp256k1_ios, BigInt, CryptoSwift
Frameworks Security
Authors

ICONKit, ICON SDK for Swift

SwiftICONKit-license
CocoaPods


Platform

ICON supports SDK for 3rd party or user services development. You can integrate ICON SDK for your project and utilize ICON’s functionality.

Installation

CocoaPods

CocoaPods is a dependency manager for Swift Cocoa projects.

$ sudo gem install cocoapods

To integrate ICONKit into your project, specify it in your Podfile

target '<Your Target Name>' do
    use_frameworks!
    ...
    pod 'ICONKit', '~> 0.3.1'
    ...
end

Now install the ICONKit.

$ pod install

Result

ICONKit uses Result framework. All functions of ICONService returns Result<T, ICONResult>. T for successor, ICONResult for error.
Refer to Result for more detail.

Quick start

A simple query of the block by height is as follows.

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

APIs called through ICONService.

It can be initialized as follows.

let iconService = ICONService(provider: "https://ctz.solidwallet.io/api/v3", nid: "0x1")

Queries

All queries are requested by a Request<T>.

Synchronous

execute() requests a query synchronously.

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.

iconService.getLastBlock().async { (result) in
    switch result {
    case .success(let responseBlock):
      print(responseBlock.blockHash)
      ...
    case .failure(let error):
      print(err.errorDescription)
      ...
    }
}

The querying APIs are as follows.

// Gets the block
let request: Request<Response.Block> = iconService.getBlock(height: height)
let request: Request<Response.Block> = iconService.getBlock(hash: "0x000...000")
let request: Request<Response.Block> = iconService.getLastBlock()

// Gets the balance of an given account
let request: Request<BigUInt> = iconService.getBalance(address: "hx000...1")

// Gets a list of ScoreAPI
let request: Request<Response.ScoreAPI> = iconService.getScoreAPI(scoreAddress: "cx000...1")

// Gets the total supply of ICX
let request: Request<BigUInt> = iconService.getTotalSupply()

// Gets a transaction matching the given transaction hash
let request: Request<Response.TransactionByHashResult> = iconService.getTransaction(hash: "0x000...000")

// Gets the result of the transaction matching the given transaction hash
let request: Request<Response.TransactionResult> = iconService.getTransactionResult(hash: "0x000...000")

// Calls a SCORE API just for reading
let call = Call(from: wallet.address, to: scoreAddress, method: "balanceOf", params: params)
let request: Request<Response.IntValue> = service.call(call)

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

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

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


// Synchronous request
do {
    let signed = try SignedTransaction(transaction: coinTransfer, privateKey: privateKey)
    let request = iconService.sendTransaction(signedTransaction: signed)
    let response = request.execute()

    switch response {
    case .result(let result):
        print("SUCCESS: TXHash - (result)")
        ...
    case .error(let error):
        print("FAIL: (error.errorDescription)")
        ...
    }
} catch {
      print(error)
      ...
}

Asynchronous request

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

// Asynchronous request
do {
    let signed = try SignedTransaction(transaction: transaction, privateKey: privateKey)

    service.sendTransaction(signedTransaction: signed) { response in
        switch response {
        case .success(let result):
            print("tx result - (result)")

        case .failure(let error):
            // Error handling
            print("error")
        }
    }
} catch {
    // exception handling
}

Reference

Version

0.3.1 (Beta)

Requirement

  • Xcode 10 or higher
  • iOS 10 or higher
  • Swift 4
  • Cocoapods

License

This project follows the Apache 2.0 License. Please refer to LICENSE for details.

Latest podspec

{
    "name": "ICONKit",
    "version": "0.3.1",
    "summary": "ICON SDK for swift",
    "homepage": "https://github.com/icon-project/ICONKit",
    "license": {
        "type": "Apache-2.0",
        "file": "LICENSE"
    },
    "authors": {
        "a1ahn": "[email protected]"
    },
    "social_media_url": "https://twitter.com/helloicon",
    "module_name": "ICONKit",
    "platforms": {
        "ios": "10.0",
        "osx": "10.14"
    },
    "source": {
        "git": "https://github.com/icon-project/ICONKit.git",
        "tag": "0.3.1"
    },
    "source_files": "Source/*.swift",
    "frameworks": "Security",
    "dependencies": {
        "Result": [],
        "scrypt": [],
        "secp256k1_ios": [
            "~> 0.1.3"
        ],
        "BigInt": [],
        "CryptoSwift": [
            "~> 0.11.0"
        ]
    }
}

Pin It on Pinterest

Share This