Skip to main content

Contract Chain (C-Chain) API

info

Ethereum has its own notion of networkID and chainID. These have no relationship to Metal’s view of networkID and chainID and are purely internal to the C-Chain. On Mainnet, the C-Chain uses 1 and 381931 for these values. On the Tahoe Testnet, it uses 1 and 381932 for these values. networkID and chainID can also be obtained using the net_version and eth_chainId methods.

Ethereum APIs

Ethereum API Endpoints

JSON-RPC Endpoints

To interact with C-Chain via the JSON-RPC endpoint:

/ext/bc/C/rpc

To interact with other instances of the EVM via the JSON-RPC endpoint:

/ext/bc/blockchainID/rpc

where blockchainID is the ID of the blockchain running the EVM.

WebSocket Endpoints

info

On the public api node, it only supports C-Chain websocket API calls for API methods that don't exist on the C-Chain's HTTP API

To interact with C-Chain via the websocket endpoint:

/ext/bc/C/ws

For example, to interact with the C-Chain's Ethereum APIs via websocket on localhost you can use:

ws://127.0.0.1:9650/ext/bc/C/ws
tip

On localhost, use ws://. When using the Public API or another host that supports encryption, use wss://.

To interact with other instances of the EVM via the websocket endpoint:

/ext/bc/blockchainID/ws

where blockchainID is the ID of the blockchain running the EVM.

Methods

Standard Ethereum APIs

Metal offers an API interface identical to Geth's API except that it only supports the following services:

  • web3_
  • net_
  • eth_
  • personal_
  • txpool_
  • debug_ (note: this is turned off on the public api node.)

You can interact with these services the same exact way you’d interact with Geth. See the Ethereum Wiki’s JSON-RPC Documentation and Geth’s JSON-RPC Documentation for a full description of this API.

info

For batched requests on the public api node , the maximum number of items is 40. We are working on to support a larger batch size.

eth_getAssetBalance

In addition to the standard Ethereum APIs, Metal offers eth_getAssetBalance to retrieve the balance of first class Metal Native Tokens on the C-Chain (excluding METAL, which must be fetched with eth_getBalance).

Signature

eth_getAssetBalance({
address: string,
blk: BlkNrOrHash,
assetID: string,
}) -> {balance: int}
  • address owner of the asset
  • blk is the block number or hash at which to retrieve the balance
  • assetID id of the asset for which the balance is requested

Example Call

curl -X POST --data '{
"jsonrpc": "2.0",
"method": "eth_getAssetBalance",
"params": [
"0x8723e5773847A4Eb5FeEDabD9320802c5c812F46",
"latest",
"3RvKBAmQnfYionFXMfW5P8TDZgZiogKbHjM8cjpu16LKAgF5T"
],
"id": 1
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/rpc

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": "0x1388"
}

eth_baseFee

Get the base fee for the next block.

Signature

eth_baseFee() -> {}

result is the hex value of the base fee for the next block.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"eth_baseFee",
"params" :[]
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/rpc

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": "0x34630b8a00"
}

eth_maxPriorityFeePerGas

Get the priority fee needed to be included in a block.

Signature

eth_maxPriorityFeePerGas() -> {}

result is hex value of the priority fee needed to be included in a block.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"eth_maxPriorityFeePerGas",
"params" :[]
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/rpc

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": "0x2540be400"
}

Metal Specific APIs

Endpoints

To interact with the METAL specific RPC calls on the C-Chain:

/ext/bc/C/avax

To interact with other instances of the EVM METAL endpoints:

/ext/bc/blockchainID/avax

avax.getAtomicTx

Gets a transaction by its ID. Optional encoding parameter to specify the format for the returned transaction. Can only be hex when a value is provided.

Signature

avax.getAtomicTx({
txID: string,
encoding: string, //optional
}) -> {
tx: string,
encoding: string,
blockHeight: string
}

Request

  • txID is the transaction ID. It should be in cb58 format.
  • encoding is the encoding format to use. Can only be hex when a value is provided.

Response

  • tx is the transaction encoded to encoding.
  • encoding is the encoding.
  • blockHeight is the height of the block which the transaction was included in.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.getAtomicTx",
"params" :{
"txID":"2GD5SRYJQr2kw5jE73trBFiAgVQyrCaeg223TaTyJFYXf2kPty",
"encoding": "hex"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

Example Response

{
"jsonrpc": "2.0",
"result": {
"tx": "0x000000000000000030399d0775f450604bd2fbc49ce0c5c1c6dfeb2dc2acb8c92c26eeae6e6df4502b19d891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf000000018212d6807a0ec9c1b26321418fe7a548180b5be728ce53fe7e98ab5755ed316100000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005000003a352a382400000000100000000000000018db97c7cece249c2b98bdc0226cc4c2a57bf52fc000003a3529edd17dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db000000010000000900000001ead19377f015422fbb8731204fcf6d6879dd05146c2d5b5594e2fea2cb420b2f40bd457b71e279e547790b28fe5482f278c76cf39b2dce5c2e6c53352fe6827d002cc7d20d",
"encoding": "hex",
"blockHeight": "1"
},
"id": 1
}

avax.export

danger

Not recommended for use on Mainnet. See warning notice in Keystore API.

Export an asset from the C-Chain to X-Chain or P-Chain. After calling this method, you must call the X-Chain's avm.import or P-Chain's platform.import.

Signature

avax.export({
to: string,
amount: int,
assetID: string,
baseFee: int,
username: string,
password:string,
}) -> {txID: string}
  • to is the X-Chain or P-Chain address the asset is sent to.
  • amount is the amount of the asset to send.
  • assetID is the ID of the asset. To export METAL use "METAL" as the assetID.
  • baseFee is the base fee that should be used when creating the transaction. If omitted, a suggested fee will be used.
  • username is the user that controls the address that transaction will be sent from.
  • password is username‘s password.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.export",
"params" :{
"to":"X-Metal18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5",
"amount": 500,
"assetID": "2nzgmhZLuVq8jc7NNu2eahkKwoJcbFWXWJCxHBVWAJEZkhquoK",
"username":"myUsername",
"password":"myPassword"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

Example Response

{
"jsonrpc": "2.0",
"result": {
"txID": "2W5JuFENitZKTpJsy9igBpTcEeBKxBHHGAUkgsSUnkjVVGQ9i8"
},
"id": 1
}

avax.exportAVAX

danger

Not recommended for use on Mainnet. See warning notice in Keystore API.

DEPRECATED—instead use avax.export.

Send METAL from the C-Chain to X-Chain or P-Chain. After calling this method, you must call the X-Chain's avm.import or P-Chain's platform.import with assetID METAL on the X-Chain to complete the transfer.

Signature

avax.exportAVAX({
to: string,
amount: int,
baseFee: int,
username: string,
password:string,
}) -> {txID: string}

Request

  • to is X-Chain or P-Chain address the asset is sent to.
  • amount is the amount of the asset to send.
  • baseFee is the base fee that should be used when creating the transaction. If omitted, a suggested fee will be used.
  • username is the user that controls the address that transaction will be sent from.
  • password is username‘s password.

Response

  • txID is the txid of the completed ExportTx.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.exportAVAX",
"params" :{
"from": ["0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"],
"to":"X-Metal18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5",
"amount": 500,
"changeAddr": "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC",
"username":"myUsername",
"password":"myPassword"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

Example Response

{
"jsonrpc": "2.0",
"result": {
"txID": "2ffcxdkiKXXA4JdyRoS38dd7zoThkapNPeZuGPmmLBbiuBBHDa"
},
"id": 1
}

avax.exportKey

danger

Not recommended for use on Mainnet. See warning notice in Keystore API.

Get the private key that controls a given address. The returned private key can be added to a user with avax.importKey.

Signature

avax.exportKey({
username: string,
password:string,
address:string
}) -> {privateKey: string}

Request

  • username must control address.
  • address is the address for which you want to export the corresponding private key. It should be in hex format.

Response

  • privateKey is the CB58 endcoded string representation of the private key that controls address. It has a PrivateKey- prefix and can be used to import a key via avax.importKey.
  • privateKeyHex is the hex string representation of the private key that controls address. It can be used to import an account into Metamask.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.exportKey",
"params" :{
"username" :"myUsername",
"password":"myPassword",
"address": "0xc876DF0F099b3eb32cBB78820d39F5813f73E18C"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

Example Response

{
"jsonrpc": "2.0",
"result": {
"privateKey": "PrivateKey-2o2uPgTSf3aR5nW6yLHjBEAiatAFKEhApvYzsjvAJKRXVWCYkE",
"privateKeyHex": "0xec381fb8d32168be4cf7f8d4ce9d8ca892d77ba574264f3665ad5edb89710157"
},
"id": 1
}}

avax.getUTXOs

Gets the UTXOs that reference a given address.

Signature

avax.getUTXOs(
{
addresses: string,
limit: int, //optional
startIndex: { //optional
address: string,
utxo: string
},
sourceChain: string,
encoding: string, //optional
},
) ->
{
numFetched: int,
utxos: []string,
endIndex: {
address: string,
utxo: string
}
}
  • utxos is a list of UTXOs such that each UTXO references at least one address in addresses.
  • At most limit UTXOs are returned. If limit is omitted or greater than 1024, it is set to 1024.
  • This method supports pagination. endIndex denotes the last UTXO returned. To get the next set of UTXOs, use the value of endIndex as startIndex in the next call.
  • If startIndex is omitted, will fetch all UTXOs up to limit.
  • When using pagination (ie when startIndex is provided), UTXOs are not guaranteed to be unique across multiple calls. That is, a UTXO may appear in the result of the first call, and then again in the second call.
  • When using pagination, consistency is not guaranteed across multiple calls. That is, the UTXO set of the addresses may have changed between calls.
  • encoding sets the format for the returned UTXOs. Can only be hex when a value is provided.

Example

Suppose we want all UTXOs that reference at least one of C-Metal18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5.

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.getUTXOs",
"params" :{
"addresses":["C-Metal18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5"],
"sourceChain": "X",
"startIndex": {
"address": "C-Metal18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5",
"utxo": "22RXW7SWjBrrxu2vzDkd8uza7fuEmNpgbj58CxBob9UbP37HSB"
},
"encoding": "hex"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

This gives response:

{
"jsonrpc": "2.0",
"result": {
"numFetched": "3",
"utxos": [
"0x0000a799e7448acf74ca9223159a04f93b948f99cf28509f908839532b2f85baffc300000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000003a352a38240000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c22d23171",
"0x00006385c683d43bdbe754c224be36c5004ea7ce49c0849cadeaea6af93dae18cc7700000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000003a352a38240000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cb81cc877",
"0x000038137283c94582351b86c3e90808312636769e3f5c14fbf1152d6634f770695c00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007000003a352a38240000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c7412490e"
],
"endIndex": {
"address": "C-Metal18jma8ppw3nhx5r4ap8clazz0dps7rv5ukulre5",
"utxo": "0x9333ef8a05f26acf2d8766f94723f749870fa2ca80c19c33cc945d79013d7c50fd023beb"
},
"encoding": "hex"
},
"id": 1
}

avax.import

danger

Not recommended for use on Mainnet. See warning notice in Keystore API.

Finalize the transfer of a non-METAL or METAL from X-Chain or P-Chain to the C-Chain. Before this method is called, you must call the X-Chain’s avm.export or P-Chain’s platform.exportAVAX with assetID METAL to initiate the transfer.

Signature

avax.import({
to: string,
sourceChain: string,
baseFee: int, // optional
username: string,
password:string,
}) -> {txID: string}

Request

  • to is the address the asset is sent to. This must be the same as the to argument in the corresponding call to the X-Chain's or P-Chain's export.
  • sourceChain is the ID or alias of the chain the asset is being imported from. To import funds from the X-Chain, use "X"; for the P-Chain, use "P".
  • baseFee is the base fee that should be used when creating the transaction. If omitted, a suggested fee will be used.
  • username is the user that controls the address that transaction will be sent from.
  • password is username‘s password.

Response

  • txID is the ID of the completed ImportTx.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.import",
"params" :{
"to":"0x4b879aff6b3d24352Ac1985c1F45BA4c3493A398",
"sourceChain":"X",
"username":"myUsername",
"password":"myPassword"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

Example Response

{
"jsonrpc": "2.0",
"result": {
"txID": "6bJq9dbqhiQvoshT3uSUbg9oB24n7Ei6MLnxvrdmao78oHR9t"
},
"id": 1
}

avax.importAVAX

danger

Not recommended for use on Mainnet. See warning notice in Keystore API.

DEPRECATED—instead use avax.import

Finalize a transfer of METAL from the X-Chain or P-Chain to the C-Chain. Before this method is called, you must call the X-Chain’s avm.export or P-Chain’s platform.exportAVAX with assetID METAL to initiate the transfer.

Signature

avax.importAVAX({
to: string,
sourceChain: string,
baseFee: int, // optional
username: string,
password:string,
}) -> {txID: string}

Request

  • to is the address the METAL is sent to. It should be in hex format.
  • sourceChain is the ID or alias of the chain the METAL is being imported from. To import funds from the X-Chain, use "X"; for the P-Chain, use "P".
  • baseFee is the base fee that should be used when creating the transaction. If omitted, a suggested fee will be used.
  • username is the user that controls the address that transaction will be sent from.
  • password is username‘s password.

Response

  • txID is the ID of the completed ImportTx.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.importAVAX",
"params" :{
"to":"0x4b879aff6b3d24352Ac1985c1F45BA4c3493A398",
"sourceChain":"X",
"username":"myUsername",
"password":"myPassword"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

Example Response

{
"jsonrpc": "2.0",
"result": {
"txID": "LWTRsiKnEUJC58y8ezAk6hhzmSMUCtemLvm3LZFw8fxDQpns3"
},
"id": 1
}

avax.importKey

danger

Not recommended for use on Mainnet. See warning notice in Keystore API.

Give a user control over an address by providing the private key that controls the address.

Signature

avax.importKey({
username: string,
password:string,
privateKey:string
}) -> {address: string}

Request

  • Add privateKey to username's set of private keys.

Response

  • address is the address username now controls with the private key. It will be in hex format.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.importKey",
"params" :{
"username" :"myUsername",
"password":"myPassword",
"privateKey":"PrivateKey-2o2uPgTSf3aR5nW6yLHjBEAiatAFKEhApvYzsjvAJKRXVWCYkE"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

Example Response

{
"jsonrpc": "2.0",
"result": {
"address": "0xc876DF0F099b3eb32cBB78820d39F5813f73E18C"
},
"id": 1
}

avax.issueTx

Send a signed transaction to the network. encoding specifies the format of the signed transaction. Can only be hex when a value is provided.

Signature

avax.issueTx({
tx: string,
encoding: string, //optional
}) -> {
txID: string
}

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" : 1,
"method" :"avax.issueTx",
"params" :{
"tx":"0x00000009de31b4d8b22991d51aa6aa1fc733f23a851a8c9400000000000186a0000000005f041280000000005f9ca900000030390000000000000001fceda8f90fcb5d30614b99d79fc4baa29307762668f16eb0259a57c2d3b78c875c86ec2045792d4df2d926c40f829196e0bb97ee697af71f5b0a966dabff749634c8b729855e937715b0e44303fd1014daedc752006011b730",
"encoding": "hex"

}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"txID": "NUPLwbt2hsYxpQg4H2o451hmTWQ4JZx2zMzM4SinwtHgAdX1JLPHXvWSXEnpecStLj"
}
}

avax.getAtomicTxStatus

Get the status of an atomic transaction sent to the network.

Signature

avax.getAtomicTxStatus({txID: string}) -> {
status: string,
blockHeight: string // returned when status is Accepted
}

status is one of:

  • Accepted: The transaction is (or will be) accepted by every node. Check the blockHeight property
  • Processing: The transaction is being voted on by this node
  • Dropped: The transaction was dropped by this node because it thought the transaction invalid
  • Unknown: The transaction hasn’t been seen by this node

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.getAtomicTxStatus",
"params" :{
"txID":"2QouvFWUbjuySRxeX5xMbNCuAaKWfbk5FeEa2JmoF85RKLk2dD"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"status": "Accepted",
"blockHeight": "1"
}
}

Admin API

This API can be used for debugging. Note that the Admin API is disabled by default. To run a node with the Admin API enabled, use C-Chain config flag --coreth-admin-api-enabled:true .

Endpoint

/ext/bc/C/admin

Methods

admin.setLogLevel

Sets the log level of the C-Chain.

Signature

admin.setLogLevel({level:string}) -> {}
  • level is the log level to be set.

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"admin.setLogLevel",
"params": {
"level":"info"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/admin

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": {}
}

admin.startCPUProfiler

Starts a CPU profile.

Signature

admin.startCPUProfiler() -> {}

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"admin.startCPUProfiler",
"params": {}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/admin

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": {}
}

admin.stopCPUProfiler

Stops and writes a CPU profile.

Signature

admin.stopCPUProfiler() -> {}

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"admin.stopCPUProfiler",
"params": {}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/admin

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": {}
}

admin.memoryProfile

Runs and writes a memory profile.

Signature

admin.memoryProfile() -> {}

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"admin.memoryProfile",
"params": {}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/admin

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": {}
}

admin.lockProfile

Runs a mutex profile writing to the coreth_performance_c directory.

Signature

admin.lockProfile() -> {}

Example Call

curl -X POST --data '{
"jsonrpc":"2.0",
"id" :1,
"method" :"admin.lockProfile",
"params": {}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/admin

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": {}
}