English | 简体ä¸ć–‡
Native Swift SDK for integrating with CITA.
- HTTP provider for connecting to CITA networks.
- Implementation of CITA JSON-RPC API over HTTP.
- Signer for signing transaction.
Refer to docs.nervos.org/cita for a complete list of CITA JSON-RPC API.
To build CITA SDK, you'll need:
- Swift 5 and later
- Xcode 10.2 and later
- CocoaPods
To integrate CITA SDK into your Xcode project using CocoaPods, specify it in your Podfile
:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
target 'YourTargetName' do
use_frameworks!
pod 'CITA', git: 'https://github.com/cryptape/cita-sdk-swift'
end
Then, run the following command:
$ pod install
Fetch the source code:
git clone --recursive https://github.com/cryptape/cita-sdk-swift.git
pod install
cp Tests/Config.example.json Tests/Config.json
Then open CITA.xcworkspace
with Xcode and build.
Run tests from CITATests
target. Update rpcServer
value of Tests/Config.json
file if you want to test against another CITA node or chain of your choice. By default http://127.0.0.1:1337
is used.
Note: serveral tests depend on onchain data and would fail when running on your own chain. We're going to improve the tests and fix that in the near future.
CITA SDK was initially built upon matterinc/web3swift. Then we want to keep this a simple RPC client and transaction signer (this means no keystore management and other features) so web3swift dependency was removed, but some utils, foundation extensions and HTTP request implementations were taken and modified from it.
For test or development, you can follow the CITA document to run a local chain. We also provide a public testnet at http://121.196.200.225:1337 (or use https://node.cryptape.com).
This testnet supports CITA version v0.20.
HTTPProvider
connects to CITA testnet or any other network. To construct a provider:
import CITA
let testnetUrl = URL(string: "http://121.196.200.225:1337")! // Or use any other network
// let testnetUrl = URL(string: "https://node.cryptape.com")! // Also available
let provider = HTTPProvider(testnetUrl)
CITA
is the class that talks to CITA network through HTTPProvider
. Consume any JSON-RPC API with CITA
instance's rpc
property.
let cita = CITA(provider: provider)
let peerCount = cita.rpc.peerCount().value!
Before sending a raw transaction over JSON-RPC API, create a Transaction
object and sign it with private key using Signer
:
let privateKey = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
guard let metaData = try? cita.rpc.getMetaData(), let blockNumber = try? cita.rpc.blockNumber() else {
return
}
let metaData = try? cita.rpc.getMetaData()
let tx = Transaction(
to: Address("0x0000000000000000000000000000000000000000"),
nonce: UUID().uuidString, // Generate a random/unique nonce string
quota: 1_000_000, // Use 1,000,000 as default quota for sending a transaction
validUntilBlock: blockNumber + 88,
data: Data.fromHex("6060604...")!,
chainId: metaData.chainId,
version: metaData.version
)
guard let signed = try? Signer().sign(transaction: tx, with: privateKey) else {
print("Sign fail")
}
All JSON-RPC APIs would return result when the call is successful, or throw CITAError
exception when not.
JSON-RPC API functions are synchronous. But the underlying HTTP request might take some time to return, and in this project they're usually implemented in some promise
way. It's generally better to call API function in a background queue so it won't block the main thread.
A common flow to call an API and handle the result is as follows.
DispatchQueue.global().async {
do {
let peerCount = try cita.rpc.peerCount()
DispatchQueue.main.async {
print("CITA peer count: \(count)")
}
} catch let error {
DispatchQueue.main.async {
print(error.localizedDescription)
}
}
}
- peerCount
- blockNumber
- sendRawTransaction
- getBlockByHash
- getBlockByNumber
- getTransactionReceipt
- getLogs
- call
- getTransaction
- getTransactionCount
- getCode
- getAbi
- getBalance
- newFilter
- newBlockFilter
- uninstallFilter
- getFilterChanges
- getFilterLogs
- getTransactionProof
- getMetaData
- getBlockHeader
- getStateProof
/// Get the number of CITA peers currently connected to the client.
///
/// - Returns: Peer count.
func peerCount() throws -> BigUInt
/// Get the number of most recent block.
///
/// - Returns: Current block height.
func blockNumber() throws -> UInt64
/// Send signed transaction to CITA.
///
/// - Parameter signedTx: Signed transaction hex string.
///
/// - Returns: Transaction hash.
func sendRawTransaction(signedTx: String) throws -> String
/// Get a block by hash.
///
/// - Parameters:
/// - hash: The block hash hex string.
/// - fullTransactions: Whether to include transactions in the block object.
///
/// - Returns: The block object matching the hash.
func getBlockByHash(hash: String, fullTransactions: Bool = false) throws -> Block
/// Get a block by number.
///
/// - Parameters:
/// - number: The block number.
/// - fullTransactions: Whether to include transactions in the block object.
///
/// - Returns: The block object matching the number.
func getBlockByNumber(number: BigUInt, fullTransactions: Bool = false) throws -> Block
/// Get the receipt of a transaction by transaction hash.
///
/// - Parameter txhash: transaction hash hex string.
///
/// - Returns: The receipt of transaction matching the txhash.
func getTransactionReceipt(txhash: String) throws -> TransactionReceipt
/// Get all logs matching a given filter object.
///
/// - Parameter filter: The filter object.
///
/// - Returns: An array of all logs matching the filter.
func getLogs(filter: Filter) throws -> [EventLog]
/// Execute a new call immediately on a contract.
///
/// - Parameters:
/// - request: A call request.
/// - blockNumber: A block number
///
/// - Returns: The call result as hex string.
func call(request: CallRequest, blockNumber: String = "latest") throws -> String
/// Get a transaction for a given hash.
///
/// - Parameter txhash: The transaction hash hex string.
///
/// - Returns: A transaction details object.
func getTransaction(txhash: String) throws -> TransactionDetails
/// Get the number of transactions sent from an address.
///
/// - Parameters:
/// - address: An address to check for transaction count for.
/// - blockNumber: A block number.
///
/// - Returns: The number of transactions.
func getTransactionCount(address: String, blockNumber: String = "latest") throws -> BigUInt
/// Get code at a given address.
///
/// - Parameters:
/// - address: An address of the code.
/// - blockNumber: A block number.
///
/// - Returns: The code at the given address.
func getCode(address: String, blockNumber: String = "latest") throws -> String
/// Get ABI at a given address.
///
/// - Parameters:
/// - address: An address of the ABI.
/// - blockNumber: A block number.
///
/// - Returns: The ABI at the given address.
func getAbi(address: String, blockNumber: String = "latest") throws -> String
/// Get the balance of the account of given address.
///
/// - Parameters:
/// - address: An address.
/// - blockNumber: A block number.
///
/// - Returns: The balance of the account of the give address.
func getBalance(address: String, blockNumber: String = "latest") throws -> BigUInt
/// Create a new filter object.
///
/// - Parameter filter: The filter option object.
///
/// - Returns: ID of the new filter.
func newFilter(filter: Filter) throws -> BigUInt
/// Create a new block filter object.
///
/// - Parameter filter: The filter option object.
///
/// - Returns: ID of the new block filter.
func newBlockFilter() throws -> BigUInt
/// Uninstall a filter. Should always be called when watch is no longer needed.
/// Additonally Filters timeout when they aren't requested with getFilterChanges for a period of time.
///
/// - Parameter filterID: ID of the filter to uninstall.
///
/// - Returns: True if the filter was successfully uninstalled, otherwise false.
func uninstallFilter(filterID: BigUInt) throws -> Bool
/// Get an array of logs which occurred since last poll.
///
/// - Parameter filterID: ID of the filter to get changes from.
///
/// - Returns: An array of logs which occurred since last poll.
func getFilterChanges(filterID: BigUInt) throws -> [EventLog]
/// Get an array of all logs matching filter with given id.
///
/// - Parameter filterID: ID of the filter to get logs from.
///
/// - Returns: An array of logs matching the given filter id.
func getFilterLogs(filterID: BigUInt) throws -> [EventLog]
/// Get transaction proof by a given transaction hash.
///
/// - Parameter txhash: The transaction hash.
///
/// - Returns: A proof include transaction, receipt, receipt merkle tree proof, block header.
/// There will be a tool to verify the proof and extract some info.
func getTransactionProof(txhash: String) throws -> String
/// Get CITA metadata by a given block height.
///
/// - Parameter blockNumber: The block height, hex string integer or "latest".
///
/// - Returns: Metadata of given block height.
func getMetaData(blockNumber: String = "latest") throws -> MetaData
/// Get block header by a given block height.
///
/// - Parameter blockNumber: The block height, hex string integer or "latest".
///
/// - Returns: block header of the given block height.
func getBlockHeader(blockNumber: String = "latest") throws -> String
/// Get state proof of special value. Include address, account proof, key, value proof.
///
/// - Parameters:
/// - address: An address.
/// - key: A key, position of the variable.
/// - blockNumber: The block number, hex string integer, or the string "latest", "earliest".
///
/// - Returns: State proof of special value. Include address, account proof, key, value proof.
func getStateProof(address: String, key: String, blockNumber: String = "latest") throws -> String
CITA SDK is released under the MIT License.