KAI Integration for Exchanges

Related Documents:JSON API here ,JSON RPC APIs examples here,JavaScript SDK, Kardia_Golang_SDK.

Public Mainnet RPC endpoint: https://rpc.kardiachain.io

Initialize

Javascript:

KardiaChain JavaScript SDK is published at npm. The installation guide and examples are available there, we need the RPC endpoint of KardiaChain Mainnet to interact with these modules.

import KardiaClient from 'kardia-js-sdk';

const endpoint = "https://rpc.kardiachain.io";
const kardiaClient = new KardiaClient({ endpoint });

Golang:

Kardia Golang SDK provides the same set of interacting tools in Golang. We also need the RPC endpoint of KardiaChain mainnet to initialize the SDK.

func SetupKAIClient(rpcURL string) (*Node, context.Context, error) {
  ctx, _ := context.WithCancel(context.Background())
  cfg := zapdriver.NewProductionConfig()
  logger, err := cfg.Build()
  if err != nil {
    return nil, nil, fmt.Errorf("Failed to create logger: %v", err)
  }
  node, err := NewNode(rpcURL, lgr)
  if err != nil {
    logger.Warn("cannot connect to RPC url", rpcURL)
    return nil, nil, fmt.Errorf("Failed to dial to RPC URL: %v", err)
  }
  return node, ctx, nil
}

node, _, err := SetupKAIClient("https://rpc.kardiachain.io")

Blocks

Block Info API:

We can get blocks’ info including header and transactions/receipts using kai_getBlockByNumber and kai_getBlockByHash APIs.

REQUEST PARAMS

kai_getBlockByNumber: QUANTITY|TAG - integer of a block number, or the string "earliest", "latest" or "pending". kai_getBlockByHash: DATA, 32 Bytes - hash of a block.

RESPONSE

kai_getBlockByNumber POST body and response:

{
    "jsonrpc": "2.0",
    "method": "kai_getBlockByNumber",
    "params": [
        1427011
    ],
    "id": 1
}
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "hash": "0x30c1f5453e74cf076615f36b6b61427d8dc6e719ed2dcd50aa4a06a90c74b341",
        "height": 1427011,
        "lastBlock": "0x01c0e73f93a697e66ec4bd95bfbe6f0fa16a367eeef2fbe6f51a92c56efdcd14",
        "commitHash": "0x08ac8406b5d94aac6381036cd2c524e0aa3aeddd025bf2487926fc85a3e8d2d5",
        "time": "2021-03-23T11:12:16.81455482Z",
        "numTxs": 1,
        "gasLimit": 200000000,
        "gasUsed": 51859,
        "rewards": "14335139256888646354",
        "proposerAddress": "0x79B598b9AD8f0C1ed987014FE644Cc73C7b72035",
        "dataHash": "0x433f81b1480cdc3b19670ea4f5112f768f59e5027c3b52f5e1dbbd1bd5e18d5d",
        "receiptsRoot": "",
        "logsBloom": "",
        "validatorHash": "0x97dda26c0d13ececbd9f8ee53d2597c6047d8b8b4ab53ff131b57d4c25503f38",
        "nextValidatorHash": "0x97dda26c0d13ececbd9f8ee53d2597c6047d8b8b4ab53ff131b57d4c25503f38",
        "consensusHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "appHash": "0xf0879b3d44298dbdbf2a3dcfd4bc268e5332fbacbbd7a1e56a847a87033c3191",
        "evidenceHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "txs": [
            {
                "blockHash": "0x30c1f5453e74cf076615f36b6b61427d8dc6e719ed2dcd50aa4a06a90c74b341",
                "blockNumber": 1427011,
                "time": "2021-03-23T11:12:16.81455482Z",
                "from": "0x2D2C6517Dc89E8347eEAEcCe0f3a71B5c6b0a172",
                "gas": 3000000,
                "gasPrice": 1000000000,
                "hash": "0xbe49290b71ad5acbd75a471352df69e39d8c49fc7b209dbbb5cab5681fef3320",
                "input": "0xf0acd7d5",
                "nonce": 103,
                "to": "0xF512B1e8acc96Baf05b470182f1814Bfb14DF563",
                "transactionIndex": 0,
                "value": "0",
                "logsBloom": [...],
            }
        ],
        "receipts": [
            {
                "transactionHash": "0xbe49290b71ad5acbd75a471352df69e39d8c49fc7b209dbbb5cab5681fef3320",
                "gasUsed": 51859,
                "cumulativeGasUsed": 51859,
                "contractAddress": "0x",
                "logs": [
                    {
                        "address": "0xF512B1e8acc96Baf05b470182f1814Bfb14DF563",
                        "topics": [
                            "0x15490ebb4bc37fd11febf8b4a71b7bed47ac2d66d82fbdd5c83da3f202726eed"
                        ],
                        "data": "0000000000000000000000002d2c6517dc89e8347eeaecce0f3a71b5c6b0a1720000000000000000000000000000000000000000000000000000000000000000",
                        "blockHeight": 1427011,
                        "transactionHash": "0xbe49290b71ad5acbd75a471352df69e39d8c49fc7b209dbbb5cab5681fef3320",
                        "transactionIndex": 0,
                        "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
                        "logIndex": 1,
                        "removed": false
                    }
                ],
                "root": "0x",
                "status": 1
            }
        ]
    }
}

Notes: The status of a transaction in the txs array is reflected in the status field of the corresponding response in the receipts array. If the value of the status field is 1, this transaction is successfully applied, otherwise the transaction is failed to execute if the value of this field is 0 or if there is no receipt for this transaction hash.

kai_getBlockByHash parameters and response are similar to the above code.

Notes: The txs array contains transactions of a block, the receipts array contains corresponding receipts of the transactions in block, including status of them.

Javascript SDK

const BLOCK_NUMBER = "latest";
const block = await kardiaClient.kaiChain.getBlockByBlockNumber(
      BLOCK_NUMBER
);
const BLOCK_HASH = "0xd3fd9a6e3d7bc200b9fa9aacf768ebf1f30a7a656bba4a2d4af31996762f9308";
const block = await kardiaClient.kaiChain.getBlockByHash(
      BLOCK_HASH
);

Go KaiClient

blockNumber := "latest"
block, err := node.BlockByHeight(ctx, blockNumber)
if err != nil {
 return
}
blockHash := "0xd3fd9a6e3d7bc200b9fa9aacf768ebf1f30a7a656bba4a2d4af31996762f9308"
b, err := node.BlockByHash(ctx, blockHash)
if err != nil {
 return
}

Sending transactions

Sending Transaction

Response

tx_sendRawTransaction POST body and response:

{
    "jsonrpc": "2.0",  
    "method": "tx_sendRawTransaction",
    "params": [
"0xf85f800182714894990d94fef322b50c5014d88565851cd5cf0bc45373801ba0c9efea69ea237eefd5c8ee4da8f35faefa56ed8be371204d30049e5c06b27f17a03ebdf6f95633b86ceb064537bc765ff98367638ec71704bf6a8c8920ef14bed6"
    ],
    "id": 1
}
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": "0xc2f9e58228b1adbd3654c1cffdfc5aed0065b2bfaf1945bee64b55a0f876cdb7"
}

Javascript SDK

const ACCOUNT = {
  address: '0x9cD2CFa83e6d85625a64fe31779446944c024E36',
  privateKey:
    '0xc07bed6441a92d0c8b99da1c4a63a2ff1c6e233729e3bf9428eeee25b8b60996',
};

const nonce = await kardiaClient.account.getNonce(ACCOUNT.address);
const txData = {
  to: ACCOUNT.address,
  gas: 50000,
  nonce,
  gasPrice: 1,
  value: 22093,
  data: '',
};

const txHash = await kardiaClient.transaction.sendTransaction(
  txData,
  ACCOUNT.privateKey,
  true
);

Go KaiClient

import "github.com/kardiachain/go-kardia/types"

tx, err := types.SignTx(types.NewTransaction(
  nonce,
  toAddr,
  amount,
  DefaultGasLimit,
  defaultGasPrice,
  nil,
), senderKey)
if err != nil {
  panic(fmt.Sprintf("Fail to sign generated tx: %v", err))
}

Transactions and Receipts

Transaction and Receipt API:

We can get a transaction and the corresponding receipt using tx_getTransaction and tx_getTransactionReceipt APIs.

REQUEST PARAMS

tx_getTransaction: DATA, 32 Bytes - hash of a transaction.

tx_getTransactionReceipt: DATA, 32 Bytes - hash of a transaction.

RESPONSE

tx_getTransaction POST body and response:

{
    "jsonrpc": "2.0",  
    "method": "tx_getTransaction",
    "params": [
       "0x258105a566970c0665408073391ecf6112dd88422464de6c0b9fd5eae26f243d"
    ],
    "id": 1
}
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "blockHash": "0xef0c216eebf803647a057a32dbba19ca8ad4e650225facc689d025f3dcde6590",
        "blockNumber": 1426129,
        "time": "2021-03-23T09:52:02.923640411Z",
        "from": "0x81014E4C752037D6E01E7c1E07342F6645969F9A",
        "gas": 500000,
        "gasPrice": 2,
        "hash": "0x258105a566970c0665408073391ecf6112dd88422464de6c0b9fd5eae26f243d",
        "input": "0xc7b8981c",
        "nonce": 148,
        "to": "0x4dAe614b2eA2FaeeDDE7830A2e7fcEDdAE9f9161",
        "transactionIndex": 0,
        "value": "0",
        "logsBloom": [...]
    }
}

RESPONSE

tx_getTransactionReceipt POST body and response:

{
    "jsonrpc": "2.0",  
    "method": "tx_getTransactionReceipt",
    "params": [
       "0x258105a566970c0665408073391ecf6112dd88422464de6c0b9fd5eae26f243d"
    ],
    "id": 1
}
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "blockHash": "0xef0c216eebf803647a057a32dbba19ca8ad4e650225facc689d025f3dcde6590",
        "blockHeight": 1426129,
        "transactionHash": "0x258105a566970c0665408073391ecf6112dd88422464de6c0b9fd5eae26f243d",
        "transactionIndex": 0,
        "from": "0x81014E4C752037D6E01E7c1E07342F6645969F9A",
        "to": "0x4dAe614b2eA2FaeeDDE7830A2e7fcEDdAE9f9161",
        "gasUsed": 88667,
        "cumulativeGasUsed": 88667,
        "contractAddress": "0x",
        "logs": [],
        "logsBloom": [...],
        "root": "0x",
        "status": 1
    }
}

Notes: The status of a transaction is reflected in the status field of tx_getTransactionReceipt response. If the value of the status field is 1, this transaction is successfully applied, otherwise the transaction is failed to execute if the value of this field is 0.

Javascript SDK

const txHash = "0x258105a566970c0665408073391ecf6112dd88422464de6c0b9fd5eae26f243d";
const txDetail = await kardiaClient.transaction.getTransaction(txHash);
const receipt = await kardiaClient.transaction.getTransactionReceipt(txHash);

Go KaiClient

hash := "0x258105a566970c0665408073391ecf6112dd88422464de6c0b9fd5eae26f243d"
tx, err := node.GetTransaction(ctx, hash)
if err != nil {
 ...
}
receipt, err := node.GetTransactionReceipt(ctx, hash)
if err != nil {
 ...
}

Account Balances

Account Balances

RESPONSE

account_balance POST body and response:

{
    "jsonrpc": "2.0",
    "method": "account_balance",
    "params": [
        "0x14191195F9BB6e54465a341CeC6cce4491599ccC",
        "latest"
    ],
    "id": 1
}
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": "2852475404340986866629970957"
}

Notes: The balance string is balance of address in HYDRO, 1 KAI = 1018 HYDRO.

Javascript SDK

const ADDRESS = '0x14191195F9BB6e54465a341CeC6cce4491599ccC';
const balanceAtHeight = await kardiaClient.account.getBalance(ADDRESS, {blockHeight: 1});
const balanceAtHash = await kardiaClient.account.getBalance(ADDRESS, {blockHash: BLOCK_HASH});

Go KaiClient

address := "0x14191195F9BB6e54465a341CeC6cce4491599ccC";
balance, err := node.Balance(context.Background(), address)
if err != nil {
 ...
}

Last updated