Platform Chain (P-Chain) API
This API allows clients to interact with the P-Chain, which maintains Avalanche’s validator set and handles blockchain creation.

Endpoint

1
/ext/P
Copied!

Format

This API uses the json 2.0 RPC format.

Methods

platform.addDelegator

Add a delegator to the Primary Network.
A delegator stakes AVAX and specifies a validator (the delegatee) to validate on their behalf. The delegatee has an increased probability of being sampled by other validators (weight) in proportion to the stake delegated to them.
The delegatee charges a fee to the delegator; the former receives a percentage of the delegator’s validation reward (if any.) A transaction that delegates stake has no fee.
The delegation period must be a subset of the period that the delegatee validates the Primary Network.
Note that once you issue the transaction to add a node as a delegator, there is no way to change the parameters. You can’t remove a stake early or change the stake amount, node ID, or reward address. Please make sure you’re using the correct values. If you’re not sure, check out our Developer FAQ or ask for help on Discord.

Signature

1
platform.addDelegator(
2
{
3
nodeID: string,
4
startTime: int,
5
endTime: int,
6
stakeAmount: int,
7
rewardAddress: string,
8
from: []string, //optional
9
changeAddr: string, //optional
10
username: string,
11
password: string
12
}
13
) ->
14
{
15
txID: string,
16
changeAddr: string
17
}
Copied!
    nodeID is the ID of the node to delegate to.
    startTime is the Unix time when the delegator starts delegating.
    endTime is the Unix time when the delegator stops delegating (and staked AVAX is returned).
    stakeAmount is the amount of nAVAX the delegator is staking.
    rewardAddress is the address the validator reward goes to, if there is one.
    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.
    password is username‘s password.
    txID is the transaction ID

Example Call

1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "platform.addDelegator",
4
"params": {
5
"nodeID":"NodeID-MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ",
6
"rewardAddress":"P-avax1gss39m5sx6jn7wlyzeqzm086yfq2l02xkvmecy",
7
"startTime":1594102400,
8
"endTime":1604102400,
9
"stakeAmount":100000,
10
"from": ["P-avax1gss39m5sx6jn7wlyzeqzm086yfq2l02xkvmecy"],
11
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u",
12
"username":"myUsername",
13
"password":"myPassword"
14
},
15
"id": 1
16
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/P
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"txID": "6pB3MtHUNogeHapZqMUBmx6N38ii3LzytVDrXuMovwKQFTZLs",
5
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u"
6
},
7
"id": 1
8
}
Copied!

platform.addValidator

Add a validator to the Primary Network. You must stake AVAX to do this. If the node is sufficiently correct and responsive while validating, you receive a reward when end of staking period is reached. The validator’s probability of being sampled by other validators during consensus is in proportion to the amount of AVAX staked.
The validator charges a fee to delegators; the former receives a percentage of the delegator’s validation reward (if any.) The minimum delegation fee is 2%. A transaction that adds a validator has no fee.
The validation period must be between 2 weeks and 1 year.
There is a maximum total weight imposed on validators. This means that no validator will ever have more AVAX staked and delegated to it than this value. This value will initially be set to min(5 * amount staked, 3M AVAX). The total value on a validator is 3 million AVAX.
Note that once you issue the transaction to add a node as a validator, there is no way to change the parameters. You can’t remove stake early or change the stake amount, node ID, or reward address. Please make sure you’re using the correct values. If you’re not sure, check out our Developer FAQ or ask for help on Discord.

Signature

1
platform.addValidator(
2
{
3
nodeID: string,
4
startTime: int,
5
endTime: int,
6
stakeAmount: int,
7
rewardAddress: string,
8
delegationFeeRate: float,
9
from: []string, //optional
10
changeAddr: string, //optional
11
username: string,
12
password: string
13
}
14
) ->
15
{
16
txID: string,
17
changeAddr: string
18
}
Copied!
    nodeID is the node ID of the validator being added.
    startTime is the Unix time when the validator starts validating the Primary Network.
    endTime is the Unix time when the validator stops validating the Primary Network (and staked AVAX is returned).
    stakeAmount is the amount of nAVAX the validator is staking.
    rewardAddress is the address the validator reward will go to, if there is one.
    delegationFeeRate is the percent fee this validator charges when others delegate stake to them. Up to 4 decimal places allowed; additional decimal places are ignored. Must be between 0 and 100, inclusive. For example, if delegationFeeRate is 1.2345 and someone delegates to this validator, then when the delegation period is over, 1.2345% of the reward goes to the validator and the rest goes to the delegator.
    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.
    password is username‘s password.
    txID is the transaction ID

Example Call

In this example, we use shell command date to compute Unix times 10 minutes and 2 days in the future. (Note: If you’re on a Mac, replace $(date with $(gdate. If you don’t have gdate installed, do brew install coreutils.)
1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "platform.addValidator",
4
"params": {
5
"nodeID":"NodeID-ARCLrphAHZ28xZEBfUL7SVAmzkTZNe1LK",
6
"rewardAddress":"P-avax1gss39m5sx6jn7wlyzeqzm086yfq2l02xkvmecy",
7
"from": ["P-avax1gss39m5sx6jn7wlyzeqzm086yfq2l02xkvmecy"],
8
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u",
9
"startTime":'$(date --date="10 minutes" +%s)',
10
"endTime":'$(date --date="2 days" +%s)',
11
"stakeAmount":1000000,
12
"delegationFeeRate":10,
13
"username":"myUsername",
14
"password":"myPassword"
15
},
16
"id": 1
17
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/P
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"txID": "6pb3mthunogehapzqmubmx6n38ii3lzytvdrxumovwkqftzls",
5
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u"
6
},
7
"id": 1
8
}
Copied!

platform.addSubnetValidator

Add a validator to a subnet other than the Primary Network. The Validator must validate the Primary Network for the entire duration they validate this subnet.

Signature

1
platform.addSubnetValidator(
2
{
3
nodeID: string,
4
subnetID: string,
5
startTime: int,
6
endTime: int,
7
weight: int,
8
from: []string, //optional
9
changeAddr: string, //optional
10
username: string,
11
password: string
12
}
13
) ->
14
{
15
txID: string,
16
changeAddr: string,
17
}
Copied!
    nodeID is the node ID of the validator.
    subnetID is the subnet they will validate.
    startTime is the unix time when the validator starts validating the subnet.
    endTime is the unix time when the validator stops validating the subnet.
    weight is the validator’s weight used for sampling.
    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.
    password is username‘s password.
    txID is the transaction ID.

Example call

1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "platform.addSubnetvalidator",
4
"params": {
5
"nodeID":"NodeID-7xhw2mdxuds44j42tcb6u5579esbst3lg",
6
"subnetID":"zbfoww1ffkpvrfywpj1cvqrfnyesepdfc61hmu2n9jnghduel",
7
"startTime":1583524047,
8
"endTime":1604102399,
9
"weight":1,
10
"from": ["P-avax1gss39m5sx6jn7wlyzeqzm086yfq2l02xkvmecy"],
11
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u",
12
"username":"myUsername",
13
"password":"myPassword"
14
},
15
"id": 1
16
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/P
Copied!

Example response

1
{
2
"jsonrpc":"2.0",
3
"id" :1,
4
"result" :{
5
"txID": "2exafyvRNSE5ehwjhafBVt6CTntot7DFjsZNcZ54GSxBbVLcCm",
6
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u"
7
}
8
}
Copied!

platform.createAddress

Create a new address controlled by the given user.

Signature

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

Example Call

1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "platform.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/P
Copied!

Example Response

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

platform.createBlockchain

Create a new blockchain. Currently only supports the creation of new instances of the AVM and the Timestamp VM.

Signature

1
platform.createBlockchain(
2
{
3
subnetID: string,
4
vmID: string,
5
name: string,
6
genesisData: string,
7
encoding: string, //optional
8
from: []string, //optional
9
changeAddr: string, //optional
10
username: string,
11
password: string
12
}
13
) ->
14
{
15
txID: string,
16
changeAddr: string
17
}
Copied!
    subnetID is the ID of the Subnet that validates the new blockchain. The Subnet must exist and can’t be the Primary Network.
    vmID is the ID of the Virtual Machine the blockchain runs. Can also be an alias of the Virtual Machine.
    name is a human-readable name for the new blockchain. Not necessarily unique.
    genesisData is the byte representation of the genesis state of the new blockchain encoded in the format specified by the encoding parameter.
    encoding specifies the format to use for genesisData. Can be either "cb58" or "hex". Defaults to "cb58". Virtual Machines should have a static API method named buildGenesis that can be used to generate genesisData
    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. This user must have a sufficient number of the subnet’s control keys.
    password is username‘s password.
    txID is the transaction ID.

Example Call

In this example we’re creating a new instance of the Timestamp Virtual Machine. genesisData came from calling timestamp.buildGenesis.
1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "platform.createBlockchain",
4
"params" : {
5
"vmID":"timestamp",
6
"subnetID":"2bRCr6B4MiEfSjidDwxDpdCyviwnfUVqB2HGwhm947w9YYqb7r",
7
"name":"My new timestamp",
8
"genesisData": "45oj4CqFViNHUtBxJ55TZfqaVAXFwMRMj2XkHVqUYjJYoTaEM",
9
"encoding": "cb58",
10
"from": ["P-avax1gss39m5sx6jn7wlyzeqzm086yfq2l02xkvmecy"],
11
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u",
12
"username":"myUsername",
13
"password":"myPassword"
14
},
15
"id": 1
16
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/P
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"txID": "2TBnyFmST7TirNm6Y6z4863zusRVpWi5Cj1sKS9bXTUmu8GfeU",
5
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u"
6
},
7
"id": 1
8
}
Copied!

platform.createSubnet

Create a new subnet.
The subnet’s ID is the same as this transaction’s ID.

Signature

1
platform.createSubnet(
2
{
3
controlKeys: []string,
4
threshold: int,
5
from: []string, //optional
6
changeAddr: string, //optional
7
username: string,
8
password: string
9
}
10
) ->
11
{
12
txID: string,
13
changeAddr: string
14
}
Copied!
    In order to add a validator to this subnet, threshold signatures are required from the addresses in controlKeys
    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.
    password is username‘s password.

Example Call

1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "platform.createSubnet",
4
"params": {
5
"controlKeys":[
6
"P-avax13xqjvp8r2entvw5m29jxxjhmp3hh6lz8laep9m",
7
"P-avax165mp4efnel8rkdeqe5ztggspmw4v40j7pfjlhu"
8
],
9
"threshold":2,
10
"from": ["P-avax1gss39m5sx6jn7wlyzeqzm086yfq2l02xkvmecy"],
11
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u",
12
"username":"myUsername",
13
"password":"myPassword"
14
},
15
"id": 1
16
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/P
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"txID": "hJfC5xGhtjhCGBh1JWn3vZ51KJP696TZrsbadPHNbQG2Ve5yd"
5
},
6
"id": 1
7
}
Copied!

platform.exportAVAX

Send AVAX from an address on the P-Chain to an address on the X-Chain. After issuing this transaction, you must call the X-Chain’s avm.importAVAX method to complete the transfer.

Signature

1
platform.exportAVAX(
2
{
3
amount: int,
4
from: []string, //optional
5
to: string,
6
changeAddr: string, //optional
7
username: string,
8
password: string
9
}
10
) ->
11
{
12
txID: string,
13
changeAddr: string
14
}
Copied!
    amount is the amount of nAVAX to send.
    to is the address on the X-Chain to send the AVAX 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 sending the AVAX and paying the transaction fee.
    password is username‘s password.
    txID is the ID of this transaction.

Example Call

1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "platform.exportAVAX",
4
"params": {
5
"to":"X-avax1yv8cwj9kq3527feemtmh5gkvezna5xys08mxet",
6
"amount":1,
7
"from": ["P-avax1gss39m5sx6jn7wlyzeqzm086yfq2l02xkvmecy"],
8
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u",
9
"username":"myUsername",
10
"password":"myPassword"
11
},
12
"id": 1
13
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/P
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"txID": "2Kz69TNBSeABuaVjKa6ZJCTLobbe5xo9c5eU8QwdUSvPo2dBk3",
5
"changeAddr": "P-avax103y30cxeulkjfe3kwfnpt432ylmnxux8r73r8u"
6
},
7
"id": 1
8
}
Copied!

platform.exportKey

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

Signature

1
platform.exportKey({
2
username: string,
3
password: string,
4
address: string
5
}) -> {privateKey: string}
Copied!
    username is the user that controls address.
    password is username‘s password.
    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" :"platform.exportKey",
5
"params" :{
6
"username" :"myUsername",
7
"password": "myPassword",
8
"address": "P-avax1zwp96clwehpwm57r9ftzdm7rnuslrunj68ua3r"
9
}
10
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/P
Copied!

Example Response

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

platform.getBalance

Get the balance of AVAX controlled by a given address.

Signature

1
platform.getBalance({
2
address:string
3
}) -> {
4
balance: string,
5
unlocked: string,
6
lockedStakeable: string,
7
lockedNotStakeable: string,
8
utxoIDs: []{
9
txID: string,
10
outputIndex: int
11
}
12
}
Copied!
    address is the address to get the balance of.
    balance is the total balance, in nAVAX.
    unlocked is the unlocked balance, in nAVAX.
    lockedStakeable is the locked stakeable balance, in nAVAX.
    lockedNotStakeable is the locked and not stakeable balance, in nAVAX.
    utxoIDs are the IDs of the UTXOs that reference address.

Example Call

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

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"balance": "20000000000000000",
5
"unlocked": "10000000000000000",
6
"lockedStakeable": "10000000000000000",
7
"lockedNotStakeable": "0",
8
"utxoIDs": [
9
{
10
"txID": "11111111111111111111111111111111LpoYY",
11
"outputIndex": 1
12
},
13
{
14
"txID": "11111111111111111111111111111111LpoYY",
15
"outputIndex": 0
16
}
17
]
18
},
19
"id": 1
20
}
Copied!

platform.getBlockchains

Get all the blockchains that exist (excluding the P-Chain).

Signature

1
platform.getBlockchains() ->
2
{
3
blockchains: []{
4
id: string,
5
name:string,
6
subnetID: string,
7
vmID: string
8
}
9
}
Copied!
    blockchains is all of the blockchains that exists on the Avalanche network.
    name is the human-readable name of this blockchain.
    id is the blockchain’s ID.
    subnetID is the ID of the Subnet that validates this blockchain.
    vmID is the ID of the Virtual Machine the blockchain runs.

Example Call

1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "platform.getBlockchains",
4
"params": {},
5
"id": 1
6
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/P
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"blockchains": [
5
{
6
"id": "2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM",
7
"name": "X-Chain",
8
"subnetID": "11111111111111111111111111111111LpoYY",
9
"vmID": "jvYyfQTxGMJLuGWa55kdP2p2zSUYsQ5Raupu4TW34ZAUBAbtq"
10
},
11
{
12
"id": "2q9e4r6Mu3U68nU1fYjgbR6JvwrRx36CohpAX5UQxse55x1Q5",
13
"name": "C-Chain",
14
"subnetID": "11111111111111111111111111111111LpoYY",
15
"vmID": "mgj786NP7uDwBCcq6YwThhaN8FLyybkCa4zBWTQbNgmK6k9A6"
16
},
17
{
18
"id": "CqhF97NNugqYLiGaQJ2xckfmkEr8uNeGG5TQbyGcgnZ5ahQwa",
19
"name": "Simple DAG Payments",
20
"subnetID": "11111111111111111111111111111111LpoYY",
21
"vmID": "sqjdyTKUSrQs1YmKDTUbdUhdstSdtRTGRbUn8sqK8B6pkZkz1"
22
},
23
{
24
"id": "VcqKNBJsYanhVFxGyQE5CyNVYxL3ZFD7cnKptKWeVikJKQkjv",
25
"name": "Simple Chain Payments",
26
"subnetID": "11111111111111111111111111111111LpoYY",
27
"vmID": "sqjchUjzDqDfBPGjfQq2tXW1UCwZTyvzAWHsNzF2cb1eVHt6w"
28
},
29
{
30
"id": "2SMYrx4Dj6QqCEA3WjnUTYEFSnpqVTwyV3GPNgQqQZbBbFgoJX",
31
"name": "Simple Timestamp Server",
32
"subnetID": "11111111111111111111111111111111LpoYY",
33
"vmID": "tGas3T58KzdjLHhBDMnH2TvrddhqTji5iZAMZ3RXs2NLpSnhH"
34
},
35
{
36
"id": "KDYHHKjM4yTJTT8H8qPs5KXzE6gQH5TZrmP1qVr1P6qECj3XN",
37
"name": "My new timestamp",
38
"subnetID": "2bRCr6B4MiEfSjidDwxDpdCyviwnfUVqB2HGwhm947w9YYqb7r",
39
"vmID": "tGas3T58KzdjLHhBDMnH2TvrddhqTji5iZAMZ3RXs2NLpSnhH"
40
},
41
{
42
"id": "2TtHFqEAAJ6b33dromYMqfgavGPF3iCpdG3hwNMiart2aB5QHi",
43
"name": "My new AVM",
44
"subnetID": "2bRCr6B4MiEfSjidDwxDpdCyviwnfUVqB2HGwhm947w9YYqb7r",
45
"vmID": "jvYyfQTxGMJLuGWa55kdP2p2zSUYsQ5Raupu4TW34ZAUBAbtq"
46
}
47
]
48
},
49
"id": 1
50
}
Copied!

platform.getBlockchainStatus

Get the status of a blockchain.

Signature

1
platform.getBlockchainStatus(
2
{
3
blockchainID: string
4
}
5
) -> {status: string}
Copied!
status is one of:
    Validating: The blockchain is being validated by this node.
    Created: The blockchain exists but isn’t being validated by this node.
    Preferred: The blockchain was proposed to be created and is likely to be created but the transaction isn’t yet accepted.
    Unknown: The blockchain either wasn’t proposed or the proposal to create it isn’t preferred. The proposal may be resubmitted.

Example Call

1
curl -X POST --data '{
2
"jsonrpc": "2.0",
3
"method": "platform.getBlockchainStatus",
4
"params":{
5
"blockchainID":"2NbS4dwGaf2p1MaXb65PrkZdXRwmSX4ZzGnUu7jm3aykgThuZE"
6
},
7
"id": 1
8
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/P
Copied!

Example Response

1
{
2
"jsonrpc": "2.0",
3
"result": {
4
"status": "Created"
5
},
6
"id": 1
7
}
Copied!

platform.getCurrentSupply

Returns an upper bound on the number of AVAX that exist. This is an upper bound because it does not account for burnt tokens, including transaction fees.

Signature

1
platform.