Skip to main content
For a rollup to be supported by the the core Initia apps such as Initia Wallet, Initia Scan, and Initia App, it must be registered on the Initia Registry. This is a public GitHub repository that contains the metadata for all rollups that are currently live on the various Initia networks.

Adding a Rollup to the Registry

To add a rollup to the registry, follow these steps:

Fork the Initia Registry Repository

To make changes to the registry, you will need to fork the Initia Registry repository. This will create a copy of the repository in your own GitHub account.

Add the Rollup to the Registry

Once you have forked the repository, you can add the rollup to the registry by following these steps:
  1. Add a new folder with your rollup’s name in the testnets or mainnets folder, depending on whether your rollup is currently live on the testnet or mainnet.
  2. Add a chain.json file to the folder. This file will contain the metadata for your rollup to be used by the apps.
{
  "$schema": "../../chain.schema.json",
  "chain_name": "move",
  "pretty_name": "Move",
  "chain_id": "move-1",
  "bech32_prefix": "init",
  "network_type": "testnet",
  "codebase": {
    "git_repo": "https://github.com/initia-labs/minimove",
    "recommended_version": "v1.0.7",
    "binaries": {
      "linux/amd64": "https://github.com/initia-labs/minimove/releases/download/v1.0.7/minimove_v1.0.7_Linux_x86_64.tar.gz",
      "linux/arm64": "https://github.com/initia-labs/minimove/releases/download/v1.0.7/minimove_v1.0.7_Linux_aarch64.tar.gz",
      "darwin/amd64": "https://github.com/initia-labs/minimove/releases/download/v1.0.7/minimove_v1.0.7_Darwin_x86_64.tar.gz",
      "darwin/arm64": "https://github.com/initia-labs/minimove/releases/download/v1.0.7/minimove_v1.0.7_Darwin_aarch64.tar.gz"
    },
    "genesis": {
      "genesis_url": "https://rpc-move-1.anvil.asia-southeast.initia.xyz/genesis"
    }
  },
  "apis": {
    "rpc": [
      {
        "address": "https://rpc-move-1.anvil.asia-southeast.initia.xyz"
      }
    ],
    "rest": [
      {
        "address": "https://rest-move-1.anvil.asia-southeast.initia.xyz"
      }
    ],
    "grpc": [
      {
        "address": "grpc-move-1.anvil.asia-southeast.initia.xyz:443"
      }
    ],
    "indexer": [
      {
        "address": "https://rollytics-api-move-1.anvil.asia-southeast.initia.xyz"
      }
    ]
  },
  "explorers": [
    {
      "kind": "initia scan",
      "url": "https://scan.testnet.initia.xyz/move-1",
      "tx_page": "https://scan.testnet.initia.xyz/move-1/txs/${txHash}",
      "account_page": "https://scan.testnet.initia.xyz/move-1/accounts/${accountAddress}"
    }
  ],
  "key_algos": ["secp256k1"],
  "slip44": 118,
  "fees": {
    "fee_tokens": [
      {
        "denom": "l2/07b129ceb9c4b0bdef7db171ce1e22f90d34bc930058b23e21adf8cc938d8145",
        "fixed_min_gas_price": 0.015
      }
    ]
  },
  "images": [
    {
      "png": "https://raw.githubusercontent.com/initia-labs/initia-registry/main/images/minimove.png"
    }
  ],
  "logo_URIs": {
    "png": "https://raw.githubusercontent.com/initia-labs/initia-registry/main/images/minimove.png"
  },
  "metadata": {
    "op_bridge_id": "1458",
    "op_denoms": ["uinit"],
    "executor_uri": "https://opinit-api-move-1.anvil.asia-southeast.initia.xyz",
    "ibc_channels": [
      {
        "chain_id": "initiation-2",
        "port_id": "nft-transfer",
        "channel_id": "channel-1",
        "version": "ics721-1"
      },
      {
        "chain_id": "initiation-2",
        "port_id": "transfer",
        "channel_id": "channel-0",
        "version": "ics20-1"
      }
    ],
    "assetlist": "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/move/assetlist.json",
    "minitia": {
      "type": "minimove",
      "version": "v1.0.7"
    }
  }
}

Description

General Information
FieldDescriptionOptional
$schemaThe schema definition file. (should always be ../../chain.schema.json)No
chain_nameThe name of the rollup.No
chain_idThe chain ID of the rollup.No
websiteThe website of the rollup.No
pretty_nameA human-readable name for your rollup.No
statusThe current status of the rollup (e.g., live).No
network_typeThe type of network (one of mainnet, testnet, devnet).No
bech32_prefixThe Bech32 prefix used for addresses on the blockchain.No
daemon_nameThe name of the daemon process for the blockchain (e.g., minitiad).No
node_homeThe default home directory for the blockchain node.No
key_algosThe cryptographic algorithms supported for keys.No
slip44The SLIP-0044 identifier for the blockchain.No
descriptionA brief description of the rollup.No
Fees
FieldDescriptionOptional
feesDetails about the fee and fee tokens on the rollup.No
fee_tokensTokens used for fees, including their denominations and gas prices.No
StakingThese fields should be empty for all rollups.
FieldDescriptionOptional
stakingInformation about staking on the rollup.No
staking_tokensTokens used for staking.No
Codebase
FieldDescriptionOptional
codebaseInformation about the blockchain’s codebase.No
git_repoThe URL of the Git repository for the rollup.No
recommended_versionThe recommended version of the rollup software. This should in most cases be the latest version of the software.No
compatible_versionsVersions of the rollup software that are compatible.No
binariesURLs for downloading binary files for different platforms.No
genesisInformation about the genesis block of the rollup.No
genesis_urlThe URL to download the rollup genesis file.No
versionsList of versions of the rollup software.No
Peers
FieldDescriptionOptional
peersInformation about network peers.No
seedsThe list of seed nodes for the rollup.No
persistent_peersThe list of persistent peers for the rollup.No
APIs
FieldDescriptionOptional
apisInformation about the different endpoints for the rollup.No
rpcRPC endpoints and their providers.No
restREST endpoints and their providers.No
grpcgRPC endpoints and their providers.No
Explorers
FieldDescriptionOptional
explorersBlockchain explorers available for the network.No
kindThe type of explorer.No
urlThe URL of the explorer.No
tx_pageThe URL template for transaction pages.No
account_pageThe URL template for account pages.No
Images
FieldDescriptionOptional
imagesURLs for images related to the blockchain.No
pngURL for the PNG image.No
svgURL for the SVG image.No
logo_URIsURLs for the blockchain logo.No
Metadata
FieldDescriptionOptional
metadataAdditional metadata about the blockchain.No
op_bridge_idThe bridge ID for operations.Yes
op_denomsDenominations used in by the OP Bridge.Yes
executor_uriThe URI for the executor service.Yes
ibc_channelsInformation about IBC channels.Yes
chain_idThe chain ID for the IBC channel.No
port_idThe port ID for the IBC channel.No
channel_idThe channel ID for the IBC channel.No
versionThe version of the IBC protocol used.No
assetlistURL for the asset list JSON file.Yes
minitiaSpecific metadata for the rollup.No
typeThe type of chain (one of minimove, minievm, or miniwasm).No
versionThe version of the rollup.No
  1. Create an assetlist.json file in the folder. This file will contain the metadata for the assets on your rollup to be used by the apps.
{
  "$schema": "../../assetlist.schema.json",
  "chain_name": "move",
  "assets": [
    {
      "description": "The native token of Initia",
      "denom_units": [
        {
          "denom": "l2/07b129ceb9c4b0bdef7db171ce1e22f90d34bc930058b23e21adf8cc938d8145",
          "exponent": 0
        },
        {
          "denom": "INIT",
          "exponent": 6
        }
      ],
      "base": "l2/07b129ceb9c4b0bdef7db171ce1e22f90d34bc930058b23e21adf8cc938d8145",
      "display": "INIT",
      "traces": [
        {
          "type": "op",
          "counterparty": {
            "base_denom": "uinit",
            "chain_name": "initia"
          },
          "chain": {
            "bridge_id": "1"
          }
        }
      ],
      "name": "Initia Native Token",
      "symbol": "INIT",
      "coingecko_id": "",
      "images": [
        {
          "png": "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/minimove/images/INIT.png",
          "svg": "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/minimove/images/INIT.svg"
        }
      ],
      "logo_URIs": {
        "png": "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/minimove/images/INIT.png",
        "svg": "https://raw.githubusercontent.com/initia-labs/initia-registry/main/testnets/minimove/images/INIT.svg"
      }
    },
  ]
}
General Information
FieldDescriptionOptional
nameThe name of the tokenNo
symbolThe symbol of the tokenNo
descriptionThe description of the tokenNo
coingecko_idThe CoinGecko ID of the tokenYes
Denomination Units
FieldDescriptionOptional
denom_unitsList of denomination unitsNo
denom_units.denomThe denomination identifier (e.g. “uinit”, “INIT”)No
denom_units.exponentThe exponent of the denomination (e.g. 0, 6)No
Base and Display
FieldDescriptionOptional
baseThe base denomination of the token (e.g. uinit, l2/…)No
displayThe display denomination identifier (e.g. INIT)No
Traces
FieldDescriptionOptional
tracesList of trace information for the tokenNo
traces.typeThe type of trace (e.g., “op”, “ibc”)No
traces.counterpartyInformation about the counterparty chainNo
traces.counterparty.base_denomThe base denomination on the counterparty chainNo
traces.counterparty.chain_nameThe name of the counterparty chainNo
traces.counterparty.channel_idThe channel ID on the counterparty chainYes
traces.chainInformation about the current chainNo
traces.chain.bridge_idThe bridge ID on the current chainYes
traces.chain.channel_idThe channel ID on the current chainYes
traces.chain.pathThe path on the current chainYes
Images
FieldDescriptionOptional
imagesList of image URIs for the tokenNo
images.pngThe PNG image URI for the tokenNo
images.svgThe SVG image URI for the tokenNo
Logo URIs
FieldDescriptionOptional
logo_URIsObject containing logo URIs for the tokenNo
logo_URIs.pngThe PNG logo URI for the tokenNo
logo_URIs.svgThe SVG logo URI for the tokenNo
For tokens bridged from L1, the denom can vary depending on the type of bridge used. In order for token bridging to work correctly, you must add the appropriate denom to your assetlist.We have two scenarios for calculating the denom:
  • OP Denom: The denom used in the OP Bridge
  • IBC Denom: The denom used in the IBC Bridge
OP Denom
denom.ts
import { RESTClient } from '@initia/initia.js'

/**
 *
 * Queries the Initia REST API to find the L2 (Layer 2) denomination
 * corresponding to a given L1 (Layer 1) denomination, for a specific bridge ID.
 *
 * @param {string} uri - The REST endpoint for the Initia network (e.g., "https://rest.testnet.initia.xyz").
 * @param {number} bridge_id - The bridge ID (e.g., 1).
 * @param {string} l1_denom - The L1 denomination (e.g., "uinit").
 * @returns {Promise<string>} - The corresponding L2 denomination (e.g., "l2/...").
 */
export async function opDenomByL1Denom(
  uri: string,
  bridge_id: number,
  l1_denom: string
): Promise<string> {
  const restClient = new RESTClient(uri)
  const tokenPair = await restClient.ophost.tokenPairByL1Denom(bridge_id, l1_denom)
  return tokenPair.l2_denom
}

/**
 *
 * Queries the Initia REST API to find the L1 (Layer 1) denomination
 * corresponding to a given L2 (Layer 2) denomination, for a specific bridge ID.
 *
 * @param {string} uri - The REST endpoint for the Initia network (e.g., "https://rest.testnet.initia.xyz").
 * @param {number} bridge_id - The bridge ID (e.g., 1).
 * @param {string} l2_denom - The L2 denomination (e.g., "l2/xyz...").
 * @returns {Promise<string>} - The corresponding L1 denomination (e.g., "uinit").
 */
export async function opDenomByL2Denom(
  uri: string,
  bridge_id: number,
  l2_denom: string
): Promise<string> {
  const restClient = new RESTClient(uri)
  const tokenPair = await restClient.ophost.tokenPairByL2Denom(bridge_id, l2_denom)
  return tokenPair.l1_denom
}

async function main() {
  // Example usage of opDenomByL1Denom and opDenomByL2Denom
  const uri = 'https://rest.testnet.initia.xyz'
  const bridge_id = 1

  const l1_denom = 'uinit'
  const l2_denom = 'l2/07b129ceb9c4b0bdef7db171ce1e22f90d34bc930058b23e21adf8cc938d8145'

  const l2_denom_for_l1_denom = await opDenomByL1Denom(uri, bridge_id, l1_denom)
  console.log(`L2 denom for L1 denom "${l1_denom}":`, l2_denom_for_l1_denom)

  const l1_denom_for_l2_denom = await opDenomByL2Denom(uri, bridge_id, l2_denom)
  console.log(`L1 denom for L2 denom "${l2_denom}":`, l1_denom_for_l2_denom)
}

main().catch((error) => {
  console.error('Error in main:', error)
})
IBC Denom
denom.ts
import { RESTClient, sha256 } from '@initia/initia.js'

interface DenomTrace {
  denom_trace: {
    path: string
    base_denom: string
  }
}

/**
 *
 * Takes a full trace string (e.g., "transfer/channel-0/uinit"), computes its SHA-256 hash,
 * and returns it in uppercase as "ibc/<HASH>".
 *
 * @param {string} fullTrace - For example, "transfer/channel-0/uinit".
 * @returns {string} - For example, "ibc/2A3B4C...".
 */
function makeIBCHash(fullTrace: string): string {
  const shaSum = sha256(Buffer.from(fullTrace))
  const hash = Buffer.from(shaSum).toString('hex').toUpperCase()
  return `ibc/${hash}`
}

/**
 *
 * Retrieves the original "transfer/..." full trace (e.g., "transfer/channel-0/uinit")
 * from an IBC denom that starts with "ibc/...". It queries the IBC module's
 * `denom_traces` endpoint to get the path and base denom.
 *
 * @param {RESTClient} restClient - The RESTClient instance for the chain.
 * @param {string} denom - The IBC denom (must start with "ibc/").
 * @returns {Promise<string>} - The combined path and base denom (e.g., "transfer/channel-0/uinit").
 */
async function getFullTrace(restClient: RESTClient, denom: string): Promise<string> {
  if (!denom.startsWith('ibc/')) {
    throw Error('Not an IBC denom')
  }

  const trace = await restClient.apiRequester.get<DenomTrace>(
    `/ibc/apps/transfer/v1/denom_traces/${denom}`
  )
  return `${trace.denom_trace.path}/${trace.denom_trace.base_denom}`
}

/**
 *
 * Takes a denom from chain A (e.g., "uinit" or "ibc/...") and determines how it is
 * represented on chain B. This may result in a hashed IBC denom ("ibc/...") or
 * a "transfer/..." full trace string.
 *
 * 1. If the input denom starts with "ibc/", retrieve the original full trace using `getFullTrace`.
 * 2. If the resulting full trace starts with "transfer/{chainAChannel}/...", it indicates
 *    the token originally came from chain B (unwind logic).
 * 3. Otherwise, prepend "transfer/{chainBChannel}/..." (wind logic).
 * 4. Finally, if the resulting string begins with "transfer/", convert it to an IBC hash
 *    using `makeIBCHash`. Otherwise, return it as is.
 *
 * @param {RESTClient} restClient - The RESTClient for chain A.
 * @param {string} denom - The denom used on chain A (e.g., "uinit" or "ibc/...").
 * @param {string} chainAChannel - The channel ID on chain A (e.g., "channel-1").
 * @param {string} chainBChannel - The channel ID on chain B (e.g., "channel-2").
 * @returns {Promise<string>} - The resulting IBC denom (e.g., "ibc/...") or a "transfer/..." full trace.
 */
export async function ibcDenom(
  restClient: RESTClient,
  denom: string,
  chainAChannel: string,
  chainBChannel: string
): Promise<string> {
  let wind = true
  let fullTrace = denom

  // If denom starts with "ibc/", retrieve the original trace
  if (denom.startsWith('ibc/')) {
    fullTrace = await getFullTrace(restClient, denom)

    // If the token's trace starts with "transfer/chainAChannel/", token originated from chain B
    if (fullTrace.startsWith(`transfer/${chainAChannel}/`)) {
      wind = false
    }
  }

  // Depending on wind/unwind, construct the trace for chain B
  let fullTraceOnChainB: string
  if (wind) {
    // Wind: prepend "transfer/{chainBChannel}/"
    fullTraceOnChainB = `transfer/${chainBChannel}/${fullTrace}`
  } else {
    // Unwind: remove "transfer/{chainAChannel}/"
    fullTraceOnChainB = fullTrace.slice(`transfer/${chainAChannel}/`.length)
  }

  // If it starts with "transfer/", convert to an IBC hash; otherwise, return as is
  const denomInChainB = fullTraceOnChainB.startsWith('transfer/')
    ? makeIBCHash(fullTraceOnChainB)
    : fullTraceOnChainB

  return denomInChainB
}

async function main() {
  // Example usage of ibcDenom
  const denom = 'uinit' // or "ibc/..."
  const restClientChainA = new RESTClient('https://rest.testnet.initia.xyz')
  const channelA = 'channel-132' // Example channel ID for chain A
  const channelB = 'channel-0'   // Example channel ID for chain B

  const ibcDenomStr = await ibcDenom(restClientChainA, denom, channelA, channelB)
  console.log('Calculated IBC Denom:', ibcDenomStr)
}

main().catch((error) => {
  console.error('Error in main:', error)
})
  1. (Optional) create an images folder to store the images for your rollup logo and token logos to link to in the two JSON files above.

Submit a Pull Request

Once you have completed the above steps, you can submit a pull request to the Registry repository to add your rollup to the registry. Once your pull request is reviewed & merged by a member of the Initia team, your rollup will be supported by the core Initia apps shortly after.