Exchange Chain (X-Chain) API
The X-Chain is an instance of the Avalanche Virtual Machine (AVM)
The X-Chain, Avalanche’s native platform for creating and trading assets, is an instance of the Avalanche Virtual Machine (AVM). This API allows clients to create and trade assets on the X-Chain and other instances of the AVM.

Format

This API uses the json 2.0 RPC format. For more information on making JSON RPC calls, see here.

Endpoints

/ext/bc/X to interact with the X-Chain.
/ext/bc/blockchainID to interact with other AVM instances, where blockchainID is the ID of a blockchain running the AVM.

Methods

avm.buildGenesis

Given a JSON representation of this Virtual Machine’s genesis state, create the byte representation of that state.

Endpoint

This call is made to the AVM’s static API endpoint:
/ext/vm/avm
Note: addresses should not include a chain prefix (ie. X-) in calls to the static API endpoint because these prefixes refer to a specific chain.

Signature

1
avm.buildGenesis({
2
networkID: int,
3
genesisData: JSON,
4
encoding: string, //optional
5
}) -> {
6
bytes: string,
7
encoding: string,
8
}
Copied!
Encoding specifies the encoding format to use for arbitrary bytes ie. the genesis bytes that are returned. Can be either "cb58" or "hex". Defaults to "cb58".
genesisData has this form:
1
{
2
"genesisData" :
3
{
4
"assetAlias1": { // Each object defines an asset
5
"name": "human readable name",
6
"symbol":"AVAL", // Symbol is between 0 and 4 characters
7
"initialState": {
8
"fixedCap" : [ // Choose the asset type.
9
{ // Can be "fixedCap", "variableCap", "limitedTransfer", "nonFungible"
10
"amount":1000, // At genesis, address A has
11
"address":"A" // 1000 units of asset
12
},
13
{
14
"amount":5000, // At genesis, address B has
15
"address":"B" // 1000 units of asset
16
},
17
... // Can have many initial holders
18
]
19
}
20
},
21
"assetAliasCanBeAnythingUnique": { // Asset alias can be used in place of assetID in calls
22
"name": "human readable name", // names need not be unique
23
"symbol": "AVAL", // symbols need not be unique
24
"initialState": {
25
"variableCap" : [ // No units of the asset exist at genesis
26
{
27
"minters": [ // The signature of A or B can mint more of
28
"A", // the asset.
29
"B"
30
],
31
"threshold":1
32
},
33
{
34
"minters": [ // The signatures of 2 of A, B and C can mint
35
"A", // more of the asset
36
"B",
37
"C"
38
],
39
"threshold":2
40
},
41
... // Can have many minter sets
42
]
43
}
44
},
45
... // Can list more assets
46
}
47
}
Copied!

Example Call

1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"id" : 1,
4
"method" : "avm.buildGenesis",
5
"params" : {
6
"networkId": 16,
7
"genesisData": {
8
"asset1": {
9
"name": "myFixedCapAsset",
10
"symbol":"MFCA",
11
"initialState": {
12
"fixedCap" : [
13
{
14
"amount":100000,
15
"address": "avax13ery2kvdrkd2nkquvs892gl8hg7mq4a6ufnrn6"
16
},
17
{
18
"amount":100000,
19
"address": "avax1rvks3vpe4cm9yc0rrk8d5855nd6yxxutfc2h2r"
20
},
21
{
22
"amount":50000,
23
"address": "avax1ntj922dj4crc4pre4e0xt3dyj0t5rsw9uw0tus"
24
},
25
{
26
"amount":50000,
27
"address": "avax1yk0xzmqyyaxn26sqceuky2tc2fh2q327vcwvda"
28
}
29
]
30
}
31
},
32
"asset2": {
33
"name": "myVarCapAsset",
34
"symbol":"MVCA",
35
"initialState": {
36
"variableCap" : [
37
{
38
"minters": [
39
"avax1kcfg6avc94ct3qh2mtdg47thsk8nrflnrgwjqr",
40
"avax14e2s22wxvf3c7309txxpqs0qe9tjwwtk0dme8e"
41
],
42
"threshold":1
43
},
44
{
45
"minters": [
46
"avax1y8pveyn82gjyqr7kqzp72pqym6xlch9gt5grck",
47
"avax1c5cmm0gem70rd8dcnpel63apzfnfxye9kd4wwe",
48
"avax12euam2lwtwa8apvfdl700ckhg86euag2hlhmyw"
49
],
50
"threshold":2
51
}
52
]
53
}
54
}
55
},
56
"encoding": "hex"
57
}
58
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/vm/avm
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"bytes": "0x0000000000010006617373657431000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6d794669786564436170417373657400044d464341000000000100000000000000010000000700000000000186a10000000000000000000000010000000152b219bc1b9ab0a9f2e3f9216e4460bd5db8d153bfa57c3c",
5
"encoding": "hex"
6
},
7
"id": 1
8
}
Copied!

avm.createAddress

Create a new address controlled by the given user.

Signature

1
avm.createAddress({
2
username: string,
3
password: string
4
}) -> {address: string}
Copied!

Example Call

1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "avm.createAddress",
4
"params": {
5
"username": "myUsername",
6
"password": "myPassword"
7
},
8
"id": 1
9
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/X
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"address": "X-avax12c6n252g5v3w6a6v69f0mnnzwr77jxzr3q3u7d"
5
},
6
"id": 1
7
}
Copied!

avm.createFixedCapAsset

Create a new fixed-cap, fungible asset. A quantity of it is created at initialization and then no more is ever created. The asset can be sent with avm.send.

Signature

1
avm.createFixedCapAsset({
2
name: string,
3
symbol: string,
4
denomination: int, //optional
5
initialHolders: []{
6
address: string,
7
amount: int
8
},
9
from: []string, //optional
10
changeAddr: string, //optional
11
username: string,
12
password: string
13
}) ->
14
{
15
assetID: string,
16
changeAddr: string
17
}
Copied!
    name is a human-readable name for the asset. Not necessarily unique.
    symbol is a shorthand symbol for the asset. Between 0 and 4 characters. Not necessarily unique. May be omitted.
    denomination determines how balances of this asset are displayed by user interfaces. If denomination is 0, 100 units of this asset are displayed as 100. If denomination is 1, 100 units of this asset are displayed as 10.0. If denomination is 2, 100 units of this asset are displayed as 1.00, etc. Defaults to 0.
    from are the addresses that you want to use for this operation. If omitted, uses any of your addresses as needed.
    changeAddr is the address any change will be sent to. If omitted, change is sent to one of the addresses controlled by the user.
    username and password denote the user paying the transaction fee.
    Each element in initialHolders specifies that address holds amount units of the asset at genesis.
    assetID is the ID of the new asset.

Example Call

1
curl -X POST --data '{
2
"jsonrpc":"2.0",
3
"id" : 1,
4
"method" :"avm.createFixedCapAsset",
5
"params" :{
6
"name": "myFixedCapAsset",
7
"symbol":"MFCA",
8
"initialHolders": [
9
{
10
"address": "X-avax1s65kep4smpr9cnf6uh9cuuud4ndm2z4jguj3gp",
11
"amount": 10000
12
},
13
{
14
"address":"X-avax1y0h66sjk0rlnh9kppnfskwpw2tpcluzxh9png8",
15
"amount":50000
16
}
17
],
18
"from":["X-avax1s65kep4smpr9cnf6uh9cuuud4ndm2z4jguj3gp"],
19
"changeAddr":"X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8",
20
"username":"myUsername",
21
"password":"myPassword"
22
}
23
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/X
Copied!

Example Response

1
{
2
"jsonrpc":"2.0",
3
"id" :1,
4
"result" :{
5
"assetID":"ZiKfqRXCZgHLgZ4rxGU9Qbycdzuq5DRY4tdSNS9ku8kcNxNLD",
6
"changeAddr":"X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8"
7
}
8
}
Copied!

avm.mint

Mint units of a variable-cap asset created with avm.createVariableCapAsset.

Signature

1
avm.mint({
2
amount: int,
3
assetID: string,
4
to: string,
5
from: []string, //optional
6
changeAddr: string, //optional
7
username: string,
8
password: string
9
}) ->
10
{
11
txID: string,
12
changeAddr: string,
13
}
Copied!
    amount units of assetID will be created and controlled by address to.
    from are the addresses that you want to use for this operation. If omitted, uses any of your addresses as needed.
    changeAddr is the address any change will be sent to. If omitted, change is sent to one of the addresses controlled by the user.
    username is the user that pays the transaction fee. username must hold keys giving it permission to mint more of this asset. That is, it must control at least threshold keys for one of the minter sets.
    txID is this transaction’s ID.
    changeAddr in the result is the address where any change was sent.

Example Call

1
curl -X POST --data '{
2
"jsonrpc":"2.0",
3
"id" : 1,
4
"method" :"avm.mint",
5
"params" :{
6
"amount":10000000,
7
"assetID":"i1EqsthjiFTxunrj8WD2xFSrQ5p2siEKQacmCCB5qBFVqfSL2",
8
"to":"X-avax1ap39w4a7fk0au083rrmnhc2pqk20yjt6s3gzkx",
9
"from":["X-avax1s65kep4smpr9cnf6uh9cuuud4ndm2z4jguj3gp"],
10
"changeAddr":"X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8",
11
"username":"myUsername",
12
"password":"myPassword"
13
}
14
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/X
Copied!

Example Response

1
{
2
"jsonrpc":"2.0",
3
"id" :1,
4
"result" :{
5
"txID":"2oGdPdfw2qcNUHeqjw8sU2hPVrFyNUTgn6A8HenDra7oLCDtja",
6
"changeAddr": "X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8"
7
}
8
}
Copied!

avm.createVariableCapAsset

Create a new variable-cap, fungible asset. No units of the asset exist at initialization. Minters can mint units of this asset using avm.mint.

Signature

1
avm.createVariableCapAsset({
2
name: string,
3
symbol: string,
4
denomination: int, //optional
5
minterSets: []{
6
minters: []string,
7
threshold: int
8
},
9
from: []string, //optional
10
changeAddr: string, //optional
11
username: string,
12
password: string
13
}) ->
14
{
15
assetID: string,
16
changeAddr: string,
17
}
Copied!
    name is a human-readable name for the asset. Not necessarily unique.
    symbol is a shorthand symbol for the asset. Between 0 and 4 characters. Not necessarily unique. May be omitted.
    denomination determines how balances of this asset are displayed by user interfaces. If denomination is 0, 100 units of this asset are displayed as 100. If denomination is 1, 100 units of this asset are displayed as 10.0. If denomination is 2, 100 units of this asset are displays as .100, etc.
    minterSets is a list where each element specifies that threshold of the addresses in minters may together mint more of the asset by signing a minting transaction.
    from are the addresses that you want to use for this operation. If omitted, uses any of your addresses as needed.
    changeAddr is the address any change will be sent to. If omitted, change is sent to one of the addresses controlled by the user.
    username pays the transaction fee.
    assetID is the ID of the new asset.
    changeAddr in the result is the address where any change was sent.

Example Call

1
curl -X POST --data '{
2
"jsonrpc":"2.0",
3
"id" : 1,
4
"method" :"avm.createVariableCapAsset",
5
"params" :{
6
"name":"myVariableCapAsset",
7
"symbol":"MFCA",
8
"minterSets":[
9
{
10
"minters":[
11
"X-avax14q0p6y4yzweuugz9p080kapajwvac3ur755n7d"
12
],
13
"threshold": 1
14
},
15
{
16
"minters": [
17
"X-avax1fzyldr3mwn6lj7y46edhua6vr5ayx0ruuhezpv",
18
"X-avax1x5mrgxj0emysnnzyszamqxhq95t2kwcp9n3fy3",
19
"X-avax13zmrjvj75h3578rn3sfth8p64t2ll4gm4tv2rp"
20
],
21
"threshold": 2
22
}
23
],
24
"from":["X-avax1s65kep4smpr9cnf6uh9cuuud4ndm2z4jguj3gp"],
25
"changeAddr":"X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8",
26
"username":"myUsername",
27
"password":"myPassword"
28
}
29
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/X
Copied!

Example Response

1
{
2
"jsonrpc":"2.0",
3
"id" :1,
4
"result" :{
5
"assetID":"2QbZFE7J4MAny9iXHUwq8Pz8SpFhWk3maCw4SkinVPv6wPmAbK",
6
"changeAddr":"X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8"
7
}
8
}
Copied!

avm.createNFTAsset

Create a new non-fungible asset. No units of the asset exist at initialization. Minters can mint units of this asset using avm.mintNFT.

Signature

1
avm.createNFTAsset({
2
name: string,
3
symbol: string,
4
minterSets: []{
5
minters: []string,
6
threshold: int
7
},
8
from: []string, //optional
9
changeAddr: string, //optional
10
username: string,
11
password: string
12
}) ->
13
{
14
assetID: string,
15
changeAddr: string,
16
}
Copied!
    name is a human-readable name for the asset. Not necessarily unique.
    symbol is a shorthand symbol for the asset. Between 0 and 4 characters. Not necessarily unique. May be omitted.
    minterSets is a list where each element specifies that threshold of the addresses in minters may together mint more of the asset by signing a minting transaction.
    from are the addresses that you want to use for this operation. If omitted, uses any of your addresses as needed.
    changeAddr is the address any change will be sent to. If omitted, change is sent to one of the addresses controlled by the user.
    username pays the transaction fee.
    assetID is the ID of the new asset.
    changeAddr in the result is the address where any change was sent.

Example Call

1
curl -X POST --data '{
2
"jsonrpc":"2.0",
3
"id" : 1,
4
"method" :"avm.createNFTAsset",
5
"params" :{
6
"name":"Coincert",
7
"symbol":"TIXX",
8
"minterSets":[
9
{
10
"minters":[
11
"X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8"
12
],
13
"threshold": 1
14
}
15
],
16
"from": ["X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8"],
17
"changeAddr": "X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8",
18
"username":"myUsername",
19
"password":"myPassword"
20
}
21
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/X
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"assetID": "2KGdt2HpFKpTH5CtGZjYt5XPWs6Pv9DLoRBhiFfntbezdRvZWP",
5
"changeAddr": "X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8"
6
},
7
"id": 1
8
}
Copied!

avm.mintNFT

Mint non-fungible tokens which were created with avm.createNFTAsset.

Signature

1
avm.mintNFT({
2
assetID: string,
3
payload: string,
4
to: string,
5
encoding: string, //optional
6
from: []string, //optional
7
changeAddr: string, //optional
8
username: string,
9
password: string
10
}) ->
11
{
12
txID: string,
13
changeAddr: string,
14
}
Copied!
    assetID is the assetID of the newly created NFT asset.
    payload is an arbitrary payload of up to 1024 bytes. Its encoding format is specified by the encoding argument.
    from are the addresses that you want to use for this operation. If omitted, uses any of your addresses as needed.
    changeAddr is the address any change will be sent to. If omitted, change is sent to one of the addresses controlled by the user.
    username is the user that pays the transaction fee. username must hold keys giving it permission to mint more of this asset. That is, it must control at least threshold keys for one of the minter sets.
    txID is this transaction’s ID.
    changeAddr in the result is the address where any change was sent.
    encoding is the encoding format to use for the payload argument. Can be either "cb58" or "hex". Defaults to "cb58".

Example Call

1
curl -X POST --data '{
2
"jsonrpc":"2.0",
3
"id" : 1,
4
"method" :"avm.mintNFT",
5
"params" :{
6
"assetID":"2KGdt2HpFKpTH5CtGZjYt5XPWs6Pv9DLoRBhiFfntbezdRvZWP",
7
"payload":"2EWh72jYQvEJF9NLk",
8
"to":"X-avax1ap39w4a7fk0au083rrmnhc2pqk20yjt6s3gzkx",
9
"from":["X-avax1s65kep4smpr9cnf6uh9cuuud4ndm2z4jguj3gp"],
10
"changeAddr":"X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8",
11
"username":"myUsername",
12
"password":"myPassword"
13
}
14
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/X
Copied!

Example Response

1
{
2
"jsonrpc":"2.0",
3
"id" :1,
4
"result" :{
5
"txID":"2oGdPdfw2qcNUHeqjw8sU2hPVrFyNUTgn6A8HenDra7oLCDtja",
6
"changeAddr": "X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8"
7
}
8
}
Copied!

avm.export

Send a non-AVAX from the X-Chain to the P-Chain or C-Chain. After calling this method, you must call avax.import on the C-Chain to complete the transfer.

Signature

1
avm.export({
2
to: string,
3
amount: int,
4
assetID: string,
5
from: []string, //optional
6
changeAddr: string, //optional
7
username: string,
8
password: string,
9
}) ->
10
{
11
txID: string,
12
changeAddr: string,
13
}
Copied!
    to is the P-Chain or C-Chain address the asset is sent to.
    amount is the amount of the asset to send.
    assetID is the asset id of the asset which is sent.
    from are the addresses that you want to use for this operation. If omitted, uses any of your addresses as needed.
    changeAddr is the address any change will be sent to. If omitted, change is sent to one of the addresses controlled by the user.
    The asset is sent from addresses controlled by username
    txID is this transaction’s ID.
    changeAddr in the result is the address where any change was sent.

Example Call

1
curl -X POST --data '{
2
"jsonrpc":"2.0",
3
"id" :1,
4
"method" :"avm.export",
5
"params" :{
6
"to":"C-avax1q9c6ltuxpsqz7ul8j0h0d0ha439qt70sr3x2m0",
7
"amount": 500,
8
"assetID": "2YmsQfMaCczE4mLG1DPYUnRURNGfhjj4qrqnLRR3LmZ3GxDWPt",
9
"from":["X-avax1s65kep4smpr9cnf6uh9cuuud4ndm2z4jguj3gp"],
10
"changeAddr":"X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8",
11
"username":"myUsername",
12
"password":"myPassword"
13
}
14
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/X
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"txID": "2Eu16yNaepP57XrrJgjKGpiEDandpiGWW8xbUm6wcTYny3fejj",
5
"changeAddr": "X-avax1turszjwn05lflpewurw96rfrd3h6x8flgs5uf8"
6
},
7
"id": 1
8
}
Copied!

avm.exportKey

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

Signature

1
avm.exportKey({
2
username: string,
3
password: string,
4
address: string
5
}) -> {privateKey: string}
Copied!
    username must control address.
    privateKey is the string representation of the private key that controls address.

Example Call

1
curl -X POST --data '{
2
"jsonrpc":"2.0",
3
"id" :1,
4
"method" :"avm.exportKey",
5
"params" :{
6
"username":"myUsername",
7
"password":"myPassword",
8
"address":"X-avax1jggdngzc9l87rgurmfu0z0n0v4mxlqta0h3k6e"
9
}
10
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/X
Copied!

Example Response

1
{
2
"jsonrpc":"2.0",
3
"id" :1,
4
"result" :{
5
"privateKey":"PrivateKey-2w4XiXxPfQK4TypYqnohRL8DRNTz9cGiGmwQ1zmgEqD9c9KWLq"
6
}
7
}
Copied!

avm.getAllBalances

Get the balances of all assets controlled by a given address.

Signature

1
avm.getAllBalances({address:string}) -> {
2
balances: []{
3
asset: string,
4
balance: int
5
}
6
}
Copied!

Example Call

1
curl -X POST --data '{
2
"jsonrpc":"2.0",
3
"id" : 1,
4
"method" :"avm.getAllBalances",
5
"params" :{
6
"address":"X-avax1c79e0dd0susp7dc8udq34jgk2yvve7hapvdyht"
7
}
8
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/X
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"balances": [
5
{
6
"asset": "AVAX",
7
"balance": "102"
8
},
9
{
10
"asset": "2sdnziCz37Jov3QSNMXcFRGFJ1tgauaj6L7qfk7yUcRPfQMC79",
11
"balance": "10000"
12
}
13
]
14
},
15
"id": 1
16
}
Copied!

avm.getAssetDescription

Get information about an asset.

Signature

1
avm.getAssetDescription({assetID: string}) -> {
2
assetId: string,
3
name: string,
4
symbol: string,
5
denomination: int
6
}
Copied!
    assetID is the id of the asset for which the information is requested.
    name is the asset’s human-readable, not necessarily unique name.
    symbol is the asset’s symbol.
    denomination determines how balances of this asset are displayed by user interfaces. If denomination is 0, 100 units of this asset are displayed as 100. If denomination is 1, 100 units of this asset are displayed as 10.0. If denomination is 2, 100 units of this asset are displays as .100, etc.

Example Call

1
curl -<