Skip to content

How to Register Cross-Chain Assets

Introduction

For an asset to be transferred across chains via XCM, there needs to be an open channel between the two chains, and the asset needs to be registered on the destination chain. If a channel does not exist between the two chains, one will need to be opened. Please check out the XC Channel Registration guide for information on how to establish a channel between Moonbeam and another chain.

This guide will show you how to register external XC-20s on Moonbeam and provide the information you need to register Moonbeam assets, including Moonbeam native assets (GLMR, MOVR, and DEV) and local XC-20s (XCM-enabled ERC-20s), on another chain.

The examples in this guide use a CLI tool developed to ease the entire process, which you can find in the xcm-tools GitHub repository.

git clone https://github.com/Moonsong-Labs/xcm-tools && \
cd xcm-tools && \
yarn

Register External XC-20s on Moonbeam

Registering External XC-20s on Moonbeam is a multi-step process that, at a high level, involves proposing the asset registration on the Moonbeam Community Forum and creating an on-chain governance proposal.

If a channel between Moonbeam and the origin chain of the asset does not yet exist, one will need to be opened. You can batch the channel-related calls with the asset registration calls, so you only need to submit a single proposal. You must start by creating a couple of forum posts: an XCM Disclosure post and an XCM Proposal post.

After you've collected feedback from community members, you can create a proposal to open a channel and register any assets. Please refer to the Establishing an XC Integration with Moonbeam guide for more information on opening a channel.

Asset registration if XC channel doesn't exist

If a channel between the chains already exists, you'll need to create a forum post to register the asset, collect feedback, and then submit the proposal to register the asset.

Asset registration if XC channel exists

Create a Forum Post

To create a forum post on the Moonbeam Community Forum, you'll need to make sure that you're adding the post to the correct category and adding relevant content. For general guidelines and a template to follow, please refer to the Moonbeam Community Forum Templates for XCM Integrations page.

Calculate Relative Price

An asset's relativePrice refers to a u128 value that indicates how many units of said asset (in its smallest denomination) equate to one unit—i.e., 1 × 10^18 Wei—of the native token (GLMR or MOVR). This helps determine how much of your asset to use for fees initially quoted in the native token, particularly in cross-chain messaging (XCM).

You can use the following script (also available as part of xcm-tools ) to calculate the correct relativePrice value for your asset.

Calculate Relative Price
import axios from 'axios';

// CoinGecko IDs for the networks
const NETWORK_IDS = {
  GLMR: 'moonbeam',
  MOVR: 'moonriver',
};

async function calculateRelativePrice(
  assetPrice: number,
  assetDecimals: number,
  network: 'GLMR' | 'MOVR'
): Promise<bigint> {
  try {
    // Fetch the native token price from CoinGecko
    const response = await axios.get(
      `https://api.coingecko.com/api/v3/simple/price?ids=${NETWORK_IDS[network]}&vs_currencies=usd`
    );

    const nativeTokenPrice = response.data[NETWORK_IDS[network]].usd;

    // Calculate relative price with 18 decimal places
    // Formula: (assetPrice / nativeTokenPrice) * 10^18
    // This gives us how many units of the asset we need to equal 1 unit of native token
    const relativePrice = BigInt(
      0.175 *
        Math.pow(10, 18 - assetDecimals) *
        (assetPrice / nativeTokenPrice) *
        Math.pow(10, 18)
    );

    // Return as string to preserve precision
    return relativePrice;
  } catch (error) {
    if (error instanceof Error) {
      throw new Error(`Failed to calculate relative price: ${error.message}`);
    }
    throw error;
  }
}

function validateInput(
  price: string,
  decimals: string,
  network: string
): { assetPrice: number; assetDecimals: number; network: 'GLMR' | 'MOVR' } {
  // Validate price
  const assetPrice = parseFloat(price);
  if (isNaN(assetPrice) || assetPrice <= 0) {
    throw new Error('Price must be a positive number');
  }

  // Validate decimals
  const assetDecimals = parseFloat(decimals);
  if (isNaN(assetDecimals) || assetDecimals <= 0) {
    throw new Error('Decimals must be a positive number');
  }

  // Validate network
  const upperNetwork = network.toUpperCase() as 'GLMR' | 'MOVR';
  if (!['GLMR', 'MOVR'].includes(upperNetwork)) {
    throw new Error('Network must be either GLMR or MOVR');
  }

  return { assetPrice, assetDecimals, network: upperNetwork };
}

function printUsage() {
  console.log('\nUsage:');
  console.log(
    'npx ts-node calculate-relative-price.ts <price> <decimals> <network>'
  );
  console.log('\nExample:');
  console.log('npx ts-node calculate-relative-price.ts 0.25 12 GLMR');
  console.log('\nParameters:');
  console.log('price      - The price of your asset in USD');
  console.log('decimals   - The decimals of your asset');
  console.log('network    - Either GLMR or MOVR');
}

async function main() {
  try {
    // Get command line arguments
    const [, , price, decimals, network] = process.argv;

    // Check if help flag is passed
    if (price === '--help' || price === '-h') {
      printUsage();
      return;
    }

    // Check if required arguments are provided
    if (!price || !decimals || !network) {
      console.error('Error: Missing required arguments');
      printUsage();
      process.exit(1);
    }

    // Validate inputs
    const {
      assetPrice,
      assetDecimals,
      network: validNetwork,
    } = validateInput(price, decimals, network);

    console.log(
      `\nCalculating relative price for asset worth $${assetPrice} against ${validNetwork}...`
    );
    const relativePrice = await calculateRelativePrice(
      assetPrice,
      assetDecimals,
      validNetwork
    );
    const nativeTokenPrice = (
      await axios.get(
        `https://api.coingecko.com/api/v3/simple/price?ids=${NETWORK_IDS[validNetwork]}&vs_currencies=usd`
      )
    ).data[NETWORK_IDS[validNetwork]].usd;

    const decimalRatio = nativeTokenPrice / assetPrice;

    console.log(`\nResults:`);
    console.log(`Asset Price: $${assetPrice}`);
    console.log(`Network: ${validNetwork}`);
    console.log(`Native Token Price (from CoinGecko): $${nativeTokenPrice}`);
    console.log(`\nRelative Price Analysis:`);
    console.log(
      `1 ${validNetwork} is equal to approximately ${decimalRatio.toFixed(
        3
      )} of your specified token.`
    );
    console.log(
      `With 18 decimals, 1 ${validNetwork} or in WEI, 1000000000000000000 is equal to a relative price of ${relativePrice} units of your token`
    );
    console.log(`\nRelative Price: ${relativePrice}`);
    console.log(
      `\nThe relative price you should specify in asset registration steps is ${relativePrice}\n`
    );
  } catch (error) {
    console.error('\nError:', error instanceof Error ? error.message : error);
    process.exit(1);
  }
}

main();

Only three parameters are required to calculate the relative price of an asset:

  • Asset Price (USD) - a positive number representing how much 1 unit (in human-readable form) of your asset costs in USD
  • Asset Decimals - the number of decimal places your asset uses. For example, if your token has 12 decimals, specify 12
  • Network - either GLMR (Moonbeam) or MOVR (Moonriver). This should correspond to the network that you're registering the asset on, and this determines which native token’s USD price the script will fetch from CoinGecko

First, ensure that you've installed the required dependencies by running:

yarn

Execute the script, making sure to provide the USD price of the asset you're registering, the number of decimals it has, and the network you're registering the asset on (either GLMR or MOVR):

yarn calculate-relative-price INSERT_ASSET_PRICE INSERT_DECIMALS GLMR

For example, if the asset you're registering has a USD price of $0.25 and 12 decimals and you're registering the asset on the Moonbeam network, you would run:

yarn calculate-relative-price 0.25 12 GLMR

This instructs the script to calculate how many smallest units of an asset (priced at $0.25, with 12 decimals) correspond to 1 GLMR token.

yarn calculate-relative-price 0.04901 12 GLMR Calculating relative price for asset worth $0.04901 against GLMR... Results: Asset Price: $0.04901 Network: GLMR Native Token Price (from CoinGecko): $0.126009 Relative Price Analysis: 1 GLMR is equal to approximately 2.571 of your specified token. With 18 decimals, 1 GLMR (in WEI: 1000000000000000000) is equal to 68064582688538114392064 units of your token. Relative Price: 68064582688538114392064 The relative price you should specify in asset registration steps is 68064582688538114392064

Upon successful execution, the script prints the computed relativePrice as a BigInt. This value represents the scaled ratio between the asset’s USD price and the native token’s USD price, multiplied up to 18 decimals. You can then use this result in on-chain asset registration or fee calculation scenarios—especially where a u128 18-decimal format is required.

For additional info, usage details, or to see an example in action, you can invoke the help command by running:

yarn calculate-relative-price --help

Generate the Encoded Calldata for the Asset Registration

Submitting a governance proposal on Moonbeam requires two steps: first, submit a preimage that defines the actions to be executed, then use that preimage to submit the proposal. For more details, see the Governance on Moonbeam page. To submit a preimage for asset registration, you'll need the encoded calldata for both the evmForeignAssets.createForeignAsset and xcmWeightTrader.addAsset extrinsics. An existing asset's price can be updated with xcmWeightTrader.editAsset.

Proposals must be submitted via the Fast General Admin track. A channel must be established before an asset can be registered. To get the encoded calldata for the evmForeignAssets.createForeignAsset extrinsic, you will need to provide the following arguments:

  • assetId - unique identifier of the asset, generated from the calculate-external-asset-info.ts script
  • xcmLocation - the multilocation of the asset relative to Moonbeam
  • decimals - the number of decimals of the asset
  • symbol - the symbol of the asset. Remember that "xc" should be prepended to the symbol to indicate the asset is an XCM-enabled asset
  • name - the asset name

Using the above information, you can generate the encoded call data for the createForeignAsset call either via the Polkadot API or on Polkadot.js Apps.

You can generate this required calldata using the xcm-asset-registrator script as follows:

yarn register-asset --w wss://wss.api.moonbeam.network  \
--asset "INSERT_MULTILOCATION" \
--symbol "INSERT_ASSET_SYMBOL" \
--decimals INSERT_DECIMALS \
--name "INSERT_ASSET_NAME" \
--relative-price INSERT_RELATIVE_PRICE

Upon running the script with the relevant parameters, you'll see output like the following:

yarn register-asset --w wss://wss.api.moonbeam.network \ --asset '{ "parents": 1, "interior": {"X1": [{ "Parachain": 3370}]}}' \ --symbol "xcLAOS" \ --decimals 18 \ --name "LAOS" \ --relative-price 68064582688538114392064 yarn run v1.22.22 warning ../../../package.json: No license field $ ts-node 'scripts/xcm-asset-registrator.ts' --w wss://wss.api.moonbeam.network --asset '{ "parents": 1, "interior": {"X1": [{ "Parachain": 3370}]}}' --symbol xcLAOS --decimals 18 --name LAOS --relative-price 68064582688538114392064 XCM Version is V4 Encoded Call Data for registerAsset is 0x72008835e1b9f588de47ec5e4a828e4e70dd010100a934121878634c414f53104c414f53 Encoded Call Data for Set Relative Price is 0x7300010100a9340000805c9cf5d5c9690e000000000000 Encoded Call Data for batched is 0x1e000872008835e1b9f588de47ec5e4a828e4e70dd010100a934121878634c414f53104c414f537300010100a9340000805c9cf5d5c9690e000000000000 ✨ Done in 5.20s.

The script will provide the encoded call data for each of the following calls:

  • The registerAsset call
  • The setRelativePrice call
  • The batch call that combines each all of the above

Overview of the proposal process

Construct the Add Asset Call

If you've already used the xcm-asset-registrator script shown above, you can skip this section. This section dives into more detail about how the xcmWeightTrader.addAsset call is constructed. To get the encoded calldata for the xcmWeightTrader.addAsset extrinsic, you will need to provide the following arguments:

  • xcmLocation - the multilocation of the asset relative to Moonbeam
  • relativePrice - A numeric value (u128) representing the fraction of the native token’s price that your asset’s price constitutes, scaled to 18 decimals. This value calculates cross-chain fees by determining how many units of the non-native asset are required to cover XCM operation costs

Using the above information, you can generate the encoded call data for the addAsset call either via the Polkadot API or on Polkadot.js Apps.

To create a batch transaction that combines both the xcmWeightTrader.addAsset and the evmForeignAssets.createForeignAsset calls together, you can use the Polkadot API's batch method. As mentioned previously, the XCM asset registrator script can help you build and submit the required calls.

Submit the Preimage and Proposal for Asset Registration

Your next task is to submit the preimage of your batched call containing both the xcmWeightTrader.addAsset and the evmForeignAssets.createForeignAsset by following the guidelines in the Submit a Democracy Proposal Guide.

You do not need to go through governance for Moonbase Alpha, as Moonbase Alpha has sudo access. Instead, you can provide the output of the batch call data to the Moonbeam team, and they can submit the call with sudo. This will be a faster and easier process than going through governance. However, you may still wish to go through governance on Moonbase Alpha to prepare for Moonbeam's governance process.

After submitting the preimage, you can submit the proposal by following the guidelines in the Submitting a Proposal section.

If you prefer the script method and you're comfortable working with the scripts in the XCM tools repo, you can use the generic call proposer by passing in the requisite calls, including the acceptance and proposal of the XCM Channel, and the asset registration. The generic call proposer can help you assemble the multiple requisite calls as follows:

yarn generic-call-propose \
  --call INSERT_CALLDATA_INCOMING_XCM_CHANNEL \
  --call INSERT_CALLDATA_OUTGOING_XCM_CHANNEL \
  --call INSERT_CALLDATA_BATCH_ASSET_REGISTRATION \
  --ws-provider INSERT_WSS_PROVIDER

Test the Asset Registration on Moonbeam

After your asset is registered, the team will provide the asset ID and the XC-20 precompile address. Your XC-20 precompile address is calculated by converting the asset ID decimal number to hex and prepending it with F's until you get a 40-hex character (plus the “0x”) address. For more information on how it is calculated, please refer to the Calculate External XC-20 Precompile Addresses section of the External XC-20 guide. After the asset is successfully registered, you can transfer tokens from your parachain to the Moonbeam-based network you are integrating with.

Note

Remember that Moonbeam-based networks use AccountKey20 (Ethereum-style addresses).

For testing, please also provide your parachain WSS endpoint so that the Moonbeam dApp can connect to it. Lastly, please fund the corresponding account:

AccountId: 5E6kHM4zFdH5KEJE3YEzX5QuqoETVKUQadeY8LVmeh2HyHGt
Hex:       0x5a071f642798f89d68b050384132eea7b65db483b00dbb05548d3ce472cfef48
AccountId: 5E6kHM4zFdH5KEJE3YEzX5QuqoETVKUQadeY8LVmeh2HyHGt
Hex:       0x5a071f642798f89d68b050384132eea7b65db483b00dbb05548d3ce472cfef48
AccountId: 5GWpSdqkkKGZmdKQ9nkSF7TmHp6JWt28BMGQNuG4MXtSvq3e
Hex:       0xc4db7bcb733e117c0b34ac96354b10d47e84a006b9e7e66a229d174e8ff2a063

Note

For Moonbeam and Moonriver testing, please send $50 worth of tokens to the aforementioned account. In addition, provide an Ethereum-style account to send $50 worth of GLMR/MOVR for testing purposes.

XC-20s are Substrate-based assets with an ERC-20 interface. This means they can be added to MetaMask and composed with any EVM DApp that exists in the ecosystem. The team can connect you with any DApp you find relevant for an XC-20 integration.

If you need DEV tokens (the native token for Moonbase Alpha) to use your XC-20 asset, you can get some from the Moonbase Alpha Faucet, which dispenses 1.1 DEV tokens every 24 hours. If you need more, feel free to reach out to the team on Telegram or Discord.

Set XC-20 Precompile Bytecode

Once your XC-20 has been registered on Moonbeam, you can set the XC-20's precompile bytecode. This is necessary because precompiles are implemented inside the Moonbeam runtime and, by default, do not have bytecode. In Solidity, when a contract is called, there are checks that require the contract bytecode to be non-empty. So, setting the bytecode as a placeholder bypasses these checks and allows the precompile to be called.

You can use the Precompile Registry, which is a Solidity interface, to update the XC-20 precompile's bytecode to avoid any issues and ensure that the precompile is callable from Solidity. To do so, you'll use the Precompile Registry's updateAccountCode function.

To get started, you'll need to calculate your XC-20's precompile address and have the Precompile Registry's ABI.

Precompile Registry ABI
[
    {
        "inputs": [
            {
                "internalType": "address",
                "name": "a",
                "type": "address"
            }
        ],
        "name": "isActivePrecompile",
        "outputs": [
            {
                "internalType": "bool",
                "name": "",
                "type": "bool"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [
            {
                "internalType": "address",
                "name": "a",
                "type": "address"
            }
        ],
        "name": "isPrecompile",
        "outputs": [
            {
                "internalType": "bool",
                "name": "",
                "type": "bool"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [
            {
                "internalType": "address",
                "name": "a",
                "type": "address"
            }
        ],
        "name": "updateAccountCode",
        "outputs": [],
        "stateMutability": "nonpayable",
        "type": "function"
    }
]

Then, you can use the following scripts to set the dummy code for your XC-20's precompile.

Remember

The following snippets are for demo purposes only. Never store your private keys in a JavaScript or Python file.

import { ethers } from 'ethers'; // Import Ethers library

const privateKey = 'INSERT_PRIVATE_KEY';
const abi = 'INSERT_PRECOMPILE_REGISTRY_ABI';
const xc20Address = 'INSERT_XC_20_PRECOMPILE_ADDRESS';
const registryAddress = '0x0000000000000000000000000000000000000815';

// Create Ethers provider and signer
const provider = new ethers.JsonRpcProvider(
  'https://rpc.api.moonbase.moonbeam.network'
);
const signer = new ethers.Wallet(privateKey, provider);

// Create interface for the Precompile Registry
const precompileRegistry = new ethers.Contract(registryAddress, abi, signer);

const updateAccountCode = async () => {
  // Update the precompile bytecode
  await precompileRegistry.updateAccountCode(xc20Address);

  // Check the precompile bytecode
  const bytecode = await provider.getCode(xc20Address);
  console.log(`The XC-20 precompile's bytecode is: ${bytecode}`);
};

updateAccountCode();
import { Web3 } from 'web3';

const privateKey = 'INSERT_PRIVATE_KEY';
const abi = 'INSERT_PRECOMPILE_REGISTRY_ABI';
const xc20Address = 'INSERT_XC_20_PRECOMPILE_ADDRESS';
const registryAddress = '0x0000000000000000000000000000000000000815';

// Create provider
const web3 = new Web3('https://rpc.api.moonbase.moonbeam.network');

// Create interface for the Precompile Registry
const precompileRegistry = new web3.eth.Contract(abi, registryAddress, {
  from: web3.eth.accounts.privateKeyToAccount(privateKey).address,
});

const updateAccountCode = async () => {
  // Update the precompile bytecode
  await precompileRegistry.methods.updateAccountCode(xc20Address).call();

  // Check the precompile bytecode
  const bytecode = await web3.eth.getCode(xc20Address);
  console.log(`The XC-20 precompile's bytecode is: ${bytecode}`);
};

updateAccountCode();
from web3 import Web3

private_key = "INSERT_PRIVATE_KEY"
abi = "INSERT_PRECOMPILE_REGISTRY_ABI"  # Paste or import the Precompile Registry ABI
xc20_address = "INSERT_XC_20_PRECOMPILE_ADDRESS"
registry_address = "0x0000000000000000000000000000000000000815"

# Create provider
web3 = Web3(Web3.HTTPProvider("https://rpc.api.moonbase.moonbeam.network"))

# Create interface for the Precompile Registry
precompile_registry = web3.eth.contract(address=registry_address, abi=abi)


def update_account_code():
    # Update the precompile bytecode
    precompile_registry.functions.updateAccountCode(xc20_address).call()

    # Check the precompile bytecode
    bytecode = web3.eth.get_code(xc20_address)
    print("The XC-20 precompile's bytecode is: ", web3.to_hex(bytecode))


update_account_code()

After running the script to set the bytecode, you should see The XC-20 precompile's bytecode is: 0x60006000fd printed to your terminal.

Register Moonbeam Assets on Another Chain

To enable cross-chain transfers of Moonbeam assets, including Moonbeam native assets (GLMR, MOVR, DEV) and local XC-20s (XCM-enabled ERC-20s) deployed on Moonbeam, between Moonbeam and another chain, you'll need to register the assets on the other chain. Since each chain stores cross-chain assets differently, the exact steps to register Moonbeam assets on another chain will vary depending on the chain. At the very least, you'll need to know the metadata and the multilocation of the assets on Moonbeam.

There are additional steps aside from asset registration that will need to be taken to enable cross-chain integration with Moonbeam. For more information, please refer to the Establishing an XC Integration with Moonbeam guide.

Register Moonbeam Native Assets on Another Chain

The metadata for each network is as follows:

Variable Value
Name Glimmer
Symbol GLMR
Decimals 18
Existential deposit 1 (1 * 10^-18 GLMR)
Variable Value
Name Moonriver
Symbol MOVR
Decimals 18
Existential deposit 1 (1 * 10^-18 MOVR)
Variable Value
Name DEV
Symbol DEV
Decimals 18
Existential deposit 1 (1 * 10^-18 DEV)

The multilocation of Moonbeam native assets includes the parachain ID of the Moonbeam network and the pallet instance where Moonbeam assets live, which corresponds to the index of the Balances Pallet. The multilocation for each network is as follows:

{
  V4: {
    parents: 1,
    interior: {
      X2: [
        { 
          Parachain: 2004
        },
        {
          PalletInstance: 10
        }
      ]
    }
  }
}
{
  V4: {
    parents: 1,
    interior: {
      X2: [
        { 
          Parachain: 2023
        },
        {
          PalletInstance: 10
        }
      ]
    }
  }
}
{
  V4: {
    parents: 1,
    interior: {
      X2: [
        { 
          Parachain: 1000
        },
        {
          PalletInstance: 3
        }
      ]
    }
  }
}

Register Local XC-20s on Another Chain

The multilocation for local XC-20s include the parachain ID of Moonbeam, the pallet instance, and the address of the ERC-20. The pallet instance corresponds to the index of the ERC-20 XCM Bridge Pallet, as this is the pallet that enables any ERC-20 to be transferred via XCM.

To be registered on other chains, local XC-20s must strictly comply with the standard ERC-20 interface as described in EIP-20. In particular, the transfer function must be as described in EIP-20:

function transfer(address _to, uint256 _value) public returns (bool success)

If the function selector of the transfer function deviates from the standard, the cross-chain transfer will fail.

You can use the following multilocation to register a local XC-20:

{
  parents: 1,
  interior: {
    X3: [
      { 
        Parachain: 2004
      },
      {
        PalletInstance: 110
      },
      {
        AccountKey20: {
          key: 'INSERT_ERC20_ADDRESS'
        }
      }
    ]
  }
}
{
  parents: 1,
  interior: {
    X3: [
      { 
        Parachain: 2023
      },
      {
        PalletInstance: 110
      },
      {
        AccountKey20: {
          key: 'INSERT_ERC20_ADDRESS'
        }
      }
    ]
  }
}
{
  parents: 1,
  interior: {
    X3: [
      { 
        Parachain: 1000
      },
      {
        PalletInstance: 48
      },
      {
        AccountKey20: {
          key: 'INSERT_ERC20_ADDRESS'
        }
      }
    ]
  }
}

Since local XC-20s are ERC-20s on Moonbeam, there are no deposits required to create an ERC-20 on Moonbeam. However, deposits may be required to register the asset on another parachain. Please consult with the parachain team you wish to register the asset with for more information.

Managing XC Assets

After completing the registration process for an XC asset, you may need to periodically update asset details, such as the XCM multilocation details or asset price. This section will cover these topics.

Updating Foreign Asset XCM Location

You can update the multilocation of an asset with the evmForeignAssets.changeXcmLocation call, which takes as parameters the assetId and the new multilocation. You'll need to raise a governance proposal and submit the update under the General Admin track. If you're testing in Moonbase Alpha, you can ask the Moonbeam Team to submit the extrinsic using Sudo to speed up the process. You can also submit the requisite governance proposal on Moonbase Alpha.

Freezing a Foreign Asset

You can freeze a foreign asset by calling evmForeignAssets.freezeForeignAsset, which takes as parameters the assetId and an allowXcmDeposit boolean. If set to true, XCM deposits from remote chains will still be allowed and mint tokens. If set to false, XCM deposits from remote chains will fail as no minting will be permitted.

Paying XCM Fees with Foreign Assets

After you've registered the foreign asset via the evmForeignAssets and the xcmWeightTrader pallet, your asset will now be among the supported assets for paying XCM fees. To verify, you can query the xcmWeightTrader pallet and the supportedAssets chain state query. Toggle the Include Option slider off to see the complete list, or you can filter the list by the multilocation of your asset.

Last update: February 11, 2025
| Created: July 27, 2023