If you're building an application on the Avalanche network, you may want to do the transfer programmatically as part of some broader functionality. You can do that by calling the appropriate APIs on an AvalancheGo node. The rest of the tutorial assumes you have access to an AvalancheGo node, AVAX tokens on the P-Chain, and user credentials created and stored in the node's keystore.

All the example API calls below assume the node is running locally (that is, listening on 127.0.0.1). The node can be connected to the main network, a test network or a local network. In each case, the API calls and responses should be the same, except for the address formats. The node need not be local; you can make calls to a node hosted elsewhere.

As you may have noticed while transferring AVAX using the Avalanche Wallet, a cross-chain transfer is a two-transaction operation:

  • Export AVAX from the P-Chain (source)

  • Import AVAX to the C-chain (destination)

Before we can do the transfer, we need to set up the address on the C-Chain, along with the controlling key.

Set Up the Address and Key on the C-Chain

The P-Chain and X-Chain use Bech32 addresses and the C-Chain uses hex Ethereum Virtual Machine (EVM) addresses. There is no way to convert the address from one format to the other since they are both derived from a private key using a one-way cryptographic function.

In order to get around this, you can export a private key from the X-Chain and then import it to the C-Chain. This way, you can use the X-Chain address and change the X- prefix to a C- prefix in order to get the correct Bech32 address to use for the C-Chain.

First, export a private key from the X-Chain:

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

Response:

{
"jsonrpc":"2.0",
"id" :1,
"result" :{
"privateKey":"PrivateKey-2w4XiXxPfQK4TypYqnohRL8DRNTz9cGiGmwQ1zmgEqD9c9KWLq"
}
}

Now, import the same private key to the C-Chain:

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

The response contains a hex-encoded EVM address:

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

Now we have everything we need to transfer the tokens.

Transfer from the P-Chain to C-Chain

Use the address corresponding to the private key you exported and switch to using the C- prefix in the platform.exportAVAX call:

curl -X POST --data '{ 
"jsonrpc":"2.0",
"id" :1,
"method" :"platform.exportAVAX",
"params" :{
"assetID": "AVAX",
"to": "C-avax1fw57u4tp7xzx0k6ufn7tj9caua59mt9gqcvy7m"
"amount": 5000000,
"username":"myUsername",
"password":"myPassword"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P

Since your keystore user owns the corresponding private key on the C-Chain, you can now import the AVAX to the address of your choice. It’s not necessary to import it to the same address that it was exported to; you can import the AVAX to an address that you own in MetaMask or another third-party service.

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

where to is a hex-encoded EVM address of your choice.

The response looks like this:

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

Note: there is no transaction fee for import transactions to the C Chain.

Once your AVAX has been transferred to the C-Chain, you can use it to deploy and interact with smart contracts.

Transfer from the C-Chain to P-Chain

Now, you can move AVAX back from the C-Chain to the P-Chain. First, we need to export:

curl -X POST --data '{ 
"jsonrpc":"2.0",
"id" :1,
"method" :"avax.exportAVAX",
"params" :{
"to":"P-avax1fw57u4tp7xzx0k6ufn7tj9caua59mt9gqcvy7m",
"assetID": "AVAX",
"amount": 5000000,
"username":"myUsername",
"password":"myPassword"
}
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/C/avax

where to is the bech32 encoded address of an P-Chain address you hold. Make sure that the amount you export exceeds the transaction fee because both the export and import transactions will charge a transaction fee.

The response should look like this:

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

To finish the transfer, call P-Chain’s platform.importAVAX

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

where to is the bech32 encoded address the P-Chain address to which you sent the funds in the previous step.

The response should look like this:

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

Wrapping Up

That’s it! Now, you can swap AVAX back and forth between the P-Chain and C-Chain, both by using the Avalanche Wallet, and by calling the appropriate API calls on an Avalanche node.


For any additional questions, please visit our knowledge base or contact a support team member via the chat button at support.avax.network.

Chat with Ava Labs | Use Apps on Avalanche | Validate on Avalanche

Build on Avalanche

Did this answer your question?