JSON-RPC API
dApps can get account status, send transactions, and call other functions via zkLink API.
The zkLink API follows the JSON-RPC standard and is accessed via POST.
Networks
Block
Account
Transaction
- getBlockOnChainNumber: get the transaction information in a block that is executed on L1 blockchains.
- getAccountSnapshot: get the account states of a certain block height, including the basic info, balance info, and order slot info.
- getAccountTransactionHistory: get account history in descending order of the transaction id in the database.
Get the configuration of all supported chains.
Request
Response
Parameters
None
{
"id": 1,
"jsonrpc": "2.0",
"method": "getSupportChains",
"params": []
}
Returns
ChainResp
{
"jsonrpc": "2.0",
"result": [
{
"chainId":1,
"chainType": 0,
"layerOneChainId":1001,
"mainContract":"0x03855e8120691526f82085453AEefac3f6A484F1",
"layerZeroContract": "0xcb45b54BA16fBdc7092E56938225a11799eb1124",
"web3Url": "https://rpc-mumbai.maticvigil.com",
"feeCap": 1000000000000000000,
"gasTokenId": 33,
"validator": "0x526212fbd41080b455ae81014b5b6bf859c30094"
}
],
"id": 1
}
ChainResp
Field | Type | Description |
---|---|---|
chainId | uint32 | Defined by zkLink |
chainType | uint8 | Defined by zkLink {0:"EVM", 1:"STARKNET"} |
layerOneChainId | uint32 | The chain ID of L1 blockchains |
mainContract | address(EVM|StarkNet) | The address of zkLink main contract that interacts with the rest module contracts |
layerZeroContract | address(EVM|StarkNet) | The address of layerZero bridge that syncs L1 states |
web3Url | string | The url of L1 RPC |
feeCap | unit | The max transaction fee when L1 RPC send the transaction |
gasTokenId | uint32 | The id of the gas token, defined by zkLink |
validator | address(EVM|StarkNet) | Validator address |
Get the data of all tokens with on-chain contract addresses.
Request
Response
Parameters
None
{
"id": 1,
"jsonrpc": "2.0",
"method": "getSupportTokens",
"params": []
}
Returns
HashMap<TokenId,TokenResp>
{
"jsonrpc": "2.0",
"result": {
"1": {
"id": 1,
"symbol": "ZKL",
"usdPrice": "12.1",
"chains": {
"1": {
"chainId": 1,
"address": "0x1aef2b4c06b83cdb2783d3458cdbf3886a6ae7d4",
"decimals": 18,
"fastWithdraw": false
},
"2": {
"chainId": 2,
"address": "0xa684f63605ccdedbce7e2e7e3fa06441758da6d1",
"decimals": 10,
"fastWithdraw": true
}
}
}
},
"id": 1
}
It returns a
HashMap<TokenId,TokenResp>
, which has a unique token id and is used for all token-related queries in the RPC service. Symbols are used only for display on the UI and do not promise uniqueness.Field | Description |
---|---|
id | Token id |
symbol | Token symbol |
usdPrice | Token price |
chains | HashMap<ChainId,ChainTokenResp> that includes the contract addresses on each chain |
Field | Description |
---|---|
chainId | Defined by zkLink |
address | The on-chain contract address of the token |
decimals | The decimals of the token on L1 |
fastWithdraw | Whether the token supports fast withdraw |
The decimal is the accuracy of the token on L1, which is not always 18 (6 for USDC and 18 for ZKL), and varies on different chains for the same token (6 for USDC on Ethereum and 18 for USDC on BSC).
When a user deposits to zkLink from connected networks, the front-end needs to calculate the amount required for calling the contract according to the accuracy:
var amount_of_user_input = 1.0 // input from the user
var amount_to_call_contract = amount_of_user_input * 10 ** token.decimals // the parameter during calling the contract
// Example
// A user deposits 2 USDC, the parameter is 2 * 10^6
// A user deposits 5 ZKL, the parameter is 5 * 10^18
Get the latest block height info.
Request
Response
Parameters
None
{
"id": 1,
"jsonrpc": "2.0",
"method": "getLatestBlockNumber",
"params": []
}
Returns
BlockNumberResp
{
"jsonrpc": "2.0",
"result": {
"lastBlockNumber": 2,
"timestamp": 1663488014,
"committed": 1,
"verified": 0
},
"id": 1
}
Field | Description |
---|---|
lastBlockNumber | The block height of the latest batch |
timestamp | The timestamp of the last block |
committed | The block height of the latest block committed to L1 |
verified | The block height of the latest block executed on L1 |
Get the block info by block height.
Request
Response
Parameters
blockNumber
: the block height, and returns the latest block height if nullincludeTx
: whether contains transaction details: returns transaction hash if false. only successful transactions will be included in a block. callgetTransactionByHash
to query the failed transactions.includeUpdate
: whether contains the state change by transactions; valid only whenincludeTx
is true.
{
"id": 1,
"jsonrpc": "2.0",
"method": "getBlockByNumber",
"params": [
123,
true,
true
]
}
Returns
BlockResp
{
"jsonrpc": "2.0",
"result": {
"number": 14127,
"commitment": "0x052fdba72bbb6fcc10940fc22dc76e459dda32604a17a920b8f2d2d0f0caff8f",
"rootHash": "0x2a5bb557a7b39afc2480b84c56f230ac2be6148fc367edf5f9447e3521a0da56",
"feeAccountId": 0,
"blockSize": 20,
"opsCompositionNumber": 401,
"createdAt": "2023-02-04T04:41:35Z",
"transactions": [
{
"txHash": "0x7c85b50664efb9672613b2b3ceafd6e1f9f47938053690b885f0a8071fac1ffa",
"tx": {
"type": "Deposit",
"fromChainId": 2,
"from": "0x3d809e414ba4893709c85f242ba3617481bc4126",
"subAccountId": 0,
"l1SourceToken": 18,
"l2TargetToken": 18,
"amount": "10000000000000000000",
"to": "0xb92a8ba62ff1d141798c7133cccefb33d9073323",
"serialId": 22,
"ethHash": "0x6ac27ec5de06c51dc9f167aa13424d08026953c9706d39c72d64cabe59ad7266"
},
"executedTimestamp":1689731233,
"updates": [
{
"type": "AccountCreate",
"updateId": 15,
"accountId": 4,
"address": "0xb92a8ba62ff1d141798c7133cccefb33d9073323"
},
{
"type": "BalanceUpdate",
"updateId": 16,
"accountId": 4,
"subAccountId": 0,
"coinId": 18,
"oldBalance": "0",
"newBalance": "10000000000000000000",
"oldNonce": 0,
"newNonce": 0
},
{
"type": "BalanceUpdate",
"updateId": 17,
"accountId": 1,
"subAccountId": 2,
"coinId": 18,
"oldBalance": "3030000000000000000000",
"newBalance": "3040000000000000000000",
"oldNonce": 0,
"newNonce": 0
}
]
},
{
"txHash": "0x7aaf7535c5edecf19805b6395e92865c544f387c71d8f75648d0353100a821f6",
"tx": {
"type": "FullExit",
"toChainId": 1,
"accountId": 28,
"subAccountId": 1,
"exitAddress": "0xae08c2e27765faef5cb05908dbac12242caf91af",
"l2SourceToken": 44,
"l1TargetToken": 44,
"serialId": 28,
"ethHash": "0x57b1fda1f7dd3aac85af60dc69300e0209c0a6abadc047a8f88e0a894220ba82"
},
"executedTimestamp":1689731234,
"updates": [
{
"type": "BalanceUpdate",
"updateId": 0,
"accountId": 28,
"subAccountId": 1,
"coinId": 44,
"oldBalance": "1080000000000000000",
"newBalance": "0",
"oldNonce": 0,
"newNonce": 0
},
{
"type": "BalanceUpdate",
"updateId": 1,
"accountId": 1,
"subAccountId": 1,
"coinId": 44,
"oldBalance": "1497300000000000000000",
"newBalance": "1496220000000000000000",
"oldNonce": 0,
"newNonce": 0
}
]
},
{
"txHash": "0x7c2dab9dadc2f3471b71c5531bfa70d0a67d16df62cfd6ed43b5970b3dccf7ad",
"tx": {
"type": "ChangePubKey",
"chainId": 2,
"accountId": 2,
"subAccountId": 0,
"newPkHash": "0x870b67b523f93dad7a313f6b64b9608dedab3874",
"feeToken": 18,
"fee": "1000000000000000000",
"nonce": 0,
"signature": {
"pubKey": "5f07954b65b5407a37ec0a2c54fb4647e2014475936057bb2f52a6faab938b02",
"signature": "4ad95ddd573830c2e85065ee201e503b24fb56faeedc1790e8a35668805d7b00691cb8c78ce124fbe0c15ed903c72975750eb12f74a5c711b870fba3496f0402"
},
"ethAuthData": {
"type": "EthECDSA",
"ethSignature": "0xf8aa40b44c89e3be8a07fc25e90b9c069fde2f3fb01125f9a8683fba054b5b4961ccbc6e957fda303c64868d9f6bc3b0f8c55a38137195633f330573a813a5d31b"
},
"ts": 1677821209
},
"executedTimestamp":1689731235,
"updates": [
{
"type": "AccountChangePubkeyUpdate",
"updateId": 8,
"accountId": 2,
"oldPubkeyHash": "0x0000000000000000000000000000000000000000",
"newPubkeyHash": "0x870b67b523f93dad7a313f6b64b9608dedab3874",
"oldNonce": 0,
"newNonce": 1
},
{
"type": "BalanceUpdate",
"updateId": 9,
"accountId": 2,
"subAccountId": 0,
"coinId": 18,
"oldBalance": "10000000000000000000",
"newBalance": "9000000000000000000",
"oldNonce": 1,
"newNonce": 1
},
{
"type": "BalanceUpdate",
"updateId": 10,
"accountId": 0,
"subAccountId": 0,
"coinId": 18,
"oldBalance": "0",
"newBalance": "1000000000000000000",
"oldNonce": 0,
"newNonce": 0
}
]
},
{
"txHash": "0xa2fa942af20e3ea1764158470a9f1f5609280dcd73cad5497ecf5ec20e8cad83",
"tx": {
"type": "Transfer",
"accountId": 2,
"fromSubAccountId": 0,
"toSubAccountId": 1,
"to": "0xdc9c9863167ee865edd5216964b8b99d43ee7a81",
"token": 18,
"amount": "1000000000000",
"fee": "209000000000000",
"nonce": 115,
"signature": {
"pubKey": "5f07954b65b5407a37ec0a2c54fb4647e2014475936057bb2f52a6faab938b02",
"signature": "d6501c14f1ed8e3feeb4c3242697067dd60da0c56af544c8faeb2d055a21d3059c78c320008028f37fedc4d9578553782b2fd204610da670d1326a277dac2004"
},
"ts": 1677821506
},
"executedTimestamp":1689731236,
"updates": [
{
"type": "BalanceUpdate",
"updateId": 12,
"accountId": 2,
"subAccountId": 0,
"coinId": 18,
"oldBalance": "3018976060000000000000",
"newBalance": "3018975850000000000000",
"oldNonce": 115,
"newNonce": 116
},
{
"type": "BalanceUpdate",
"updateId": 13,
"accountId": 2,
"subAccountId": 1,
"coinId": 18,
"oldBalance": "114000000000000",
"newBalance": "115000000000000",
"oldNonce": 115,
"newNonce": 116
},
{
"type": "BalanceUpdate",
"updateId": 14,
"accountId": 0,
"subAccountId": 0,
"coinId": 18,
"oldBalance": "1023826000000000000",
"newBalance": "1024035000000000000",
"oldNonce": 0,
"newNonce": 0
}
]
},
{
"txHash": "0x3b285c94d89ae17f7c288b10036a3dacff3460384601005afb440b1620bb538a",
"tx": {
"type": "Withdraw",
"toChainId": 1,
"accountId": 3,
"subAccountId": 0,
"to": "0x3d809e414ba4893709c85f242ba3617481bc4126",
"l2SourceToken": 44,
"l1TargetToken": 44,
"amount": "1300000000000000000",
"fee": "1531000000000000",
"nonce": 81,
"signature": {
"pubKey": "b720c6110e673b55b5725dd0ff5778a8668ef4c7324718f78fa11def63081e85",
"signature": "ec2c25aded9d1bbc85106178917a9da55a711449b4a49d0dbc01485290959225739ef0b3155498e96ba79cfbcb4a79a5f3ea4a179c6c210baca86820e8020b05"
},
"fastWithdraw": 1,
"withdrawFeeRatio": 2000,
"ts": 1677830493
},
"executedTimestamp":1689731237,
"updates": [
{
"type": "BalanceUpdate",
"updateId": 3,
"accountId": 3,
"subAccountId": 0,
"coinId": 44,
"oldBalance": "2993839561700000000000",
"newBalance": "2992538030700000000000",
"oldNonce": 81,
"newNonce": 82
},
{
"type": "BalanceUpdate",
"updateId": 4,
"accountId": 1,
"subAccountId": 1,
"coinId": 44,
"oldBalance": "1500000000000000000000",
"newBalance": "1498700000000000000000",
"oldNonce": 0,
"newNonce": 0
},
{
"type": "BalanceUpdate",
"updateId": 5,
"accountId": 0,
"subAccountId": 0,
"coinId": 44,
"oldBalance": "438300000000000",
"newBalance": "1969300000000000",
"oldNonce": 0,
"newNonce": 0
}
]
},
{
"txHash": "0x8ada34680c8ba0e5cdbc14011e51c9989cab9339e0a7e679d14c14e7a587149d",
"tx": {
"type": "ForcedExit",
"toChainId": 2,
"initiatorAccountId": 3,
"initiatorSubAccountId": 0,
"target": "0x086cacda48e8a77680ba1e79177d1655f7130c95",
"targetSubAccountId": 1,
"l2SourceToken": 40,
"l1TargetToken": 40,
"fee": "19030000000000000",
"feeToken": 18,
"nonce": 178,
"signature": {
"pubKey": "b720c6110e673b55b5725dd0ff5778a8668ef4c7324718f78fa11def63081e85",
"signature": "b119bd5971397b6abc499f6a2c09358b8c39d937be5bc96e3f186b4fc5026c80a933eea1b8f9c71cab8bb10ae554a2765008b937a724d026512f97cbeeacef05"
},
"ts": 1677836553
},
"executedTimestamp":1689731238,
"updates": [
{
"type": "BalanceUpdate",
"updateId": 20,
"accountId": 3,
"subAccountId": 0,
"coinId": 18,
"oldBalance": "2790050120799999999999",
"newBalance": "2790031090799999999999",
"oldNonce": 178,
"newNonce": 179
},
{
"type": "BalanceUpdate",
"updateId": 21,
"accountId": 15,
"subAccountId": 1,
"coinId": 40,
"oldBalance": "2100000000000000000",
"newBalance": "0",
"oldNonce": 0,
"newNonce": 0
},
{
"type": "BalanceUpdate",
"updateId": 22,
"accountId": 1,
"subAccountId": 2,
"coinId": 40,
"oldBalance": "4000001486590000000000000000",
"newBalance": "4000001484490000000000000000",
"oldNonce": 0,
"newNonce": 0
},
{
"type": "BalanceUpdate",
"updateId": 23,
"accountId": 0,
"subAccountId": 0,
"coinId": 18,
"oldBalance": "7272586000000000000",
"newBalance": "7291616000000000000",
"oldNonce": 0,
"newNonce": 0
}
]
},
{
"txHash": "0x640f38c6b09744d627b16e03339064d6edd39187cde8c4329fa19a2a60db8664",
"tx": {
"type": "OrderMatching",
"accountId": 6,
"subAccountId": 1,
"taker": {
"accountId": 13,
"subAccountId": 1,
"slotId": 163,
"nonce": 0,
"baseTokenId": 41,
"quoteTokenId": 1,
"amount": "1886200000000000000",
"price": "1568210000000000000000",
"isSell": 1,
"feeRatio1": 5,
"feeRatio2": 10,
"signature": {
"pubKey": "1aedae58e43fe6661db7f834ae438930443908d108fdf621bfd4741fedfcd82f",
"signature": "57b7a0f06eb5d5dffbc8e8a6626ef7f9c472a8ac7761db36f8a0a2df2049988a9b43e8b3292a969b9b6cc5f689a5eecb8b05981ef1e3ca6e0de0da64ae6d6e01"
}
},
"maker": {
"accountId": 13,
"subAccountId": 1,
"slotId": 898,
"nonce": 1,
"baseTokenId": 41,
"quoteTokenId": 1,
"amount": "684900000000000000",
"price": "1569150000000000000000",
"isSell": 0,
"feeRatio1": 5,
"feeRatio2": 10,
"signature": {
"pubKey": "1aedae58e43fe6661db7f834ae438930443908d108fdf621bfd4741fedfcd82f",
"signature": "b0aebe2bdd7a98a78d564d11c5f138cf428382628af55e85c250446b03dc0005f734e952819278d0b96fa970c6ab0018e33bb5bda7c55d69658551d2e606b904"
}
},
"fee": "391000000000000",
"feeToken": 1,
"expectBaseAmount": "54800000000000000",
"expectQuoteAmount": "85989420000000000000",
"signature": {
"pubKey": "84bf4edbe1f7056f079ba4c38359427f43d529fbab2e94e6d6b7a18efbf2fb87",
"signature": "34e768dce60268f702b9a9ca68cb19d6785d2d1da8d7c799a29aa45e8c8bd9096c20cbf518c95fce2b2b58329492c35896162fe9cb1ff13f6e3a946b15bb2202"
}
},
"executedTimestamp":1689731239,
"updates": [
{
"type": "OrderUpdate",
"updateId": 0,
"accountId": 13,
"subAccountId": 1,
"slotId": 898,
"oldTidyOrder": {
"nonce": 1,
"residue": "54800000000000000"
},
"newTidyOrder": {
"nonce": 2,
"residue": "0"
}
},
{
"type": "BalanceUpdate",
"updateId": 1,
"accountId": 13,
"subAccountId": 1,
"coinId": 1,
"oldBalance": "200304228482442156994500000",
"newBalance": "200304142493022156994500000",
"oldNonce": 1,
"newNonce": 1
},
{
"type": "BalanceUpdate",
"updateId": 2,
"accountId": 13,
"subAccountId": 1,
"coinId": 41,
"oldBalance": "199999971788889400000000000",
"newBalance": "199999971843662000000000000",
"oldNonce": 1,
"newNonce": 1
},
{
"type": "OrderUpdate",
"updateId": 3,
"accountId": 13,
"subAccountId": 1,
"slotId": 163,
"oldTidyOrder": {
"nonce": 0,
"residue": "1467400000000000000"
},
"newTidyOrder": {
"nonce": 0,
"residue": "1412600000000000000"
}
},
{
"type": "BalanceUpdate",
"updateId": 4,
"accountId": 13,
"subAccountId": 1,
"coinId": 41,
"oldBalance": "199999971843662000000000000",
"newBalance": "199999971788862000000000000",
"oldNonce": 1,
"newNonce": 1
},
{
"type": "BalanceUpdate",
"updateId": 5,
"accountId": 13,
"subAccountId": 1,
"coinId": 1,
"oldBalance": "200304142493022156994500000",
"newBalance": "200304228396452736994500000",
"oldNonce": 1,
"newNonce": 1
},
{
"type": "BalanceUpdate",
"updateId": 6,
"accountId": 6,
"subAccountId": 1,
"coinId": 1,
"oldBalance": "9999680162000000000000",
"newBalance": "9999679771000000000000",
"oldNonce": 224,
"newNonce": 224
},
{
"type": "BalanceUpdate",
"updateId": 7,
"accountId": 6,
"subAccountId": 0,
"coinId": 1,
"oldBalance": "3529001244641983488661500000",
"newBalance": "3529001244727972908661500000",
"oldNonce": 224,
"newNonce": 224
},
{
"type": "BalanceUpdate",
"updateId": 8,
"accountId": 6,
"subAccountId": 0,
"coinId": 41,
"oldBalance": "1594000000063937300000000000",
"newBalance": "1594000000063964700000000000",
"oldNonce": 224,
"newNonce": 224
},
{
"type": "BalanceUpdate",
"updateId": 9,
"accountId": 0,
"subAccountId": 0,
"coinId": 1,
"oldBalance": "483683000000000000",
"newBalance": "484074000000000000",
"oldNonce": 0,
"newNonce": 0
}
]
}
]
},
"id": 1
}
Field | Description |
---|---|
number | The block height |
commitment | The commitment of the block, similar to the block hash of Ethereum |
rootHash | The root hash of the state tree |
feeAccountId | The id of the fee account |
blockSize | The maximum chunk number that a block can contain |
opsCompositionNumber | The vk of generating ZKPs |
timestamp | The block timestamp |
transactions | Returns [BlockTxResp] when includeTx is false, TxResp when true; ordered by transaction execution: the ones executed first come first in the array |
Field | Description |
---|---|
txHash | The transaction hash |
tx | ZkLinkTx |
executedTimestamp | The unix timestamp of transaction execution |
updates | [StateUpdateResp] , ordered by updateId : the ones executed first come first in the array |
The success of transaction execution will lead to the change of the state tree:
- AccountCreate: create a new account in the state tree
- AccountChangePubkeyUpdate: change in pubkey and nonce
- BalanceUpdate: change in account balance and nonce
- OrderUpdate: change in account slot
AccountCreate
Field | Description |
---|---|
type | AccountCreate |
updateId | The position of the update in the block |
accountId | The id of the new account |
address | The account address |
Example:
{
"type": "AccountCreate",
"updateId": 40,
"accountId": 42,
"address": "0xe4efc3d7b69a19d3ae574cbc2915ddf598efe43f"
}
Transactions that may generate
AccountCreate
include:- Deposit
- Transfer
AccountChangePubkeyUpdate