Cross-Chain Token Standard - Registration & Administration (SVM)
When token administrators want to register their SPL token for Cross‐Chain Token (CCT) operations, they interact with both the Router program and Token Pool programs. This guide covers both token registration/administration (Router side) and token pool configuration (Pool side).
Token Registration & Administration (Router Side)
This section covers all operations performed through the Router program to manage token administrator roles and basic token configuration.
Router Access Control for Token Administration
Understanding who can call which Router instructions is critical for secure token administration. This table shows the authorization model for all token admin registry instructions:
Instruction | Mint Authority | Router Upgrade Authority | Current Token Admin | Pending Token Admin |
---|---|---|---|---|
owner_propose_administrator | ✅ | ❌ | ❌ | ❌ |
owner_override_pending_administrator | ✅ | ❌ | ❌ | ❌ |
ccip_admin_propose_administrator | ❌ | ✅ | ❌ | ❌ |
accept_admin_role_token_admin_registry | ❌ | ❌ | ❌ | ✅ |
transfer_admin_role_token_admin_registry | ❌ | ❌ | ✅ | ❌ |
set_pool | ❌ | ❌ | ✅ | ❌ |
set_pool_supports_auto_derivation | ❌ | ❌ | ✅ | ❌ |
Notes:
- Mint Authority: The SPL token's
mint_authority
holder - Router Upgrade Authority: The Router program's upgrade authority
- Current Token Admin: The active CCIP token administrator
- Pending Token Admin: Token administrator proposed but not yet accepted
Focus on Self-Service Registration: The following sections focus on the self-service registration flow where you control your token's mint authority. While the Router also supports ccip_admin_propose_administrator
for cases where mint authority is not accessible, we detail the self-service approach as it's the primary registration method for most token developers.
Self-Service Registration Flow
If your SPL token supports an automatic way to determine an admin using onchain verifiable data (e.g., you hold the mint authority), you can complete self-registration in a permissionless manner by calling the Router's owner_propose_administrator
instruction:
-
Admin Initiates Registration: The token admin calls the Router's
owner_propose_administrator
instruction, passing in the mint and the proposed administrator's public key. This instruction initializes aTokenAdminRegistry
PDA for this mint. -
Determine Administrator: The Router ensures that the caller is the SPL token's mint authority, confirming they have the right to set a CCIP admin.
-
Propose Administrator: The Router sets the proposed administrator as the pending administrator. The token admin is not fully recognized yet; they remain
pending
. TheTokenAdminRegistry
now stores this user aspending_administrator
. The next step is to accept the role.
Self-Service Registration Requirements:
- Caller Authorization: Only the SPL token's
mint_authority
can callowner_propose_administrator
- Registry State: TokenAdminRegistry PDA must not already exist for this mint
- Result: Creates new TokenAdminRegistry PDA with proposed administrator in pending state
Non-Self-Service Registration Flow
For token programs that do not have a standard way to identify an administrator using onchain verifiable data (e.g., no direct mint authority check), the token developer can manually initiate the registration by submitting a request above.
Administrator Role Management
Proposing the Administrator
The following sequence diagram illustrates the process of proposing the administrator.
Overriding Pending Administrator
If you need to change the pending administrator before they accept the role, you can use the owner_override_pending_administrator
instruction. This is useful when you initially proposed the wrong administrator or need to update the pending administrator for other reasons.
-
Override Pending Administrator: The mint authority calls the Router's
owner_override_pending_administrator
instruction, passing in the mint and the new proposed administrator's public key. -
Validate Authority: The Router ensures that the caller is the SPL token's mint authority and that no administrator has been accepted yet (the
administrator
field must be zero). -
Update Pending Administrator: The Router replaces the existing
pending_administrator
with the new proposed administrator. The previous pending administrator can no longer accept the role.
Override Requirements:
- Caller Authorization: Only the SPL token's
mint_authority
can callowner_override_pending_administrator
- Registry State: TokenAdminRegistry PDA must exist but have no accepted administrator yet (
administrator
field is zero) - Result: Updates the
pending_administrator
field with the new proposed administrator
Accepting the Administrator Role
Once the administrator has been proposed and is pending, they must accept the role to complete the registration process. This step finalizes the administrator's assignment.
-
Pending Administrator Calls
accept_admin_role_token_admin_registry
The pending admin invokes
accept_admin_role_token_admin_registry()
on the Router program, specifying the mint account in the transaction context. -
Finalize Registration
- The Router checks that the caller's public key matches the
pending_administrator
field in theTokenAdminRegistry
PDA. - If authorized, the Router sets
administrator = pending_administrator
and clearspending_administrator
. At this point, the role is fully active.
- The Router checks that the caller's public key matches the
Below is the sequence diagram illustrating how the pending administrator interacts with the Router program to complete registration.
Transfer Administrator Role
The transfer_admin_role_token_admin_registry
instruction allows the current token administrator to transfer their role to a new administrator. This transfer process is secure and involves two steps, requiring the new admin to accept it explicitly before finalization.
- Initiate Role Transfer
- The current admin calls
transfer_admin_role_token_admin_registry(new_admin)
on the Router, passing the new administrator's public key. - The Router checks that the caller is the token's existing administrator. If so, it sets
pending_administrator = new_admin
in theTokenAdminRegistry
(PDA).
- The current admin calls
- Pending Administrator
- The registry is now pending. The existing admin will still be active until the new admin accepts.
- Accept the Role
- The new administrator must call
accept_admin_role_token_admin_registry()
to finalize the transfer. - If
authority.key()
matchespending_administrator
, the Router updatesadministrator = pending_administrator
. Otherwise, it will fail. - Once accepted, the new administrator can set or modify the token pool.
- The new administrator must call
Below is a sequence diagram showing how the transfer is requested, followed by how the new admin must accept to complete the handover.
Setting the Token Pool
On SVM-based blockchains (e.g., Solana), the set_pool
instruction enables a token administrator to map a given mint to the pool lookup table that defines how that token is handled in cross-chain transfers. This instruction modifies the TokenAdminRegistry
PDA so the Route program knows which token pool accounts can lock or burn tokens on the source chain (and release or mint them on the destination).
- Set Token Pool: The current administrator calls the
set_pool
instruction on the Router program, passing in:- The token mint (for which we are configuring cross-chain transfers).
- The
pool_lookuptable
account (the Address Lookup Table containing the mandatory PDAs and program addresses for that token pool). - A list of "writable indexes" indicating which lookup table entries should be marked as writable during cross-chain transfers. These indexes specify positions in the ALT that require write permission for successful transaction execution.
- Reset Old Pool, Apply New Settings: Under the hood, the Router updates the
TokenAdminRegistry
PDA:- Overwrites any previously stored Address Lookup Table reference.
- Resets the old permission bits, then enables the specified "writable indexes."
- This ensures the new token pool has the correct set of PDAs with the correct writable permissions.
- Validate or Delist:
- If the new
pool_lookuptable
is not the zero address, the Router checks that this lookup table has at least the minimal set of addresses required for cross-chain transfers. This includes the token mint, pool program, token program, pool configuration PDA, and any other mandatory accounts specified by the pool implementation. If valid, the token becomes enabled for cross-chain transfers. - If the
pool_lookuptable
is the zero address, the token is effectively delisted from CCIP, meaning no new cross-chain transfers can occur.
- If the new
The sequence diagram below explains how the set_pool
instruction updates the TokenAdminRegistry
PDA and either enables or delists the token for cross-chain transfers.
Configuring Pool Auto-Derivation
The set_pool_supports_auto_derivation
instruction allows a token administrator to configure whether their token pool supports automatic account derivation for cross-chain transfers. This setting affects how the CCIP Router validates and handles account lists during token transfer operations.
Auto-Derivation Capability: When enabled (supports_auto_derivation = true
), the token pool can dynamically derive additional accounts and lookup tables required for cross-chain operations by implementing derive_accounts_lock_or_burn
and derive_accounts_release_or_mint
functions. This provides flexibility for pools that need message-dependent or dynamically calculated account sets.
Account Validation Impact:
- Auto-derivation enabled: The Router validates only the static accounts present in the Address Lookup Table, allowing the pool to handle validation of additional dynamically-derived accounts.
- Auto-derivation disabled: The Router validates all accounts against the static Address Lookup Table, expecting a complete and fixed account set.
Administrative Control: Only the current token administrator can modify this setting, ensuring that pool configuration changes are properly authorized. The function updates the supports_auto_derivation
flag in the TokenAdminRegistry
PDA and emits a PoolEdited
event for transparency.
Token Pool Configuration (Pool Side)
Once you have registered your token and set the token pool via the Router, you need to configure the specific pool parameters. These operations are performed directly on the Token Pool programs, not the Router.
Pool Initialization
Before any other configuration can occur, you must initialize your token pool:
-
Initialize Token Pool
- Instruction:
initialize
- Use Case: Create the pool state PDA for your specific mint. This is the first mandatory step that must be completed before any other pool configuration operations.
- Authorization: Program upgrade authority can always initialize pools. When self-serve is enabled (
self_served_allowed: true
), the token's mint authority can also initialize pools. - Requirements: Pool owner must create the Associated Token Account (ATA) for the Pool Signer PDA before pool operations can begin.
- Read the API reference to learn more.
- Instruction:
Remote Chain Configuration
Configure your token pool for specific destination blockchains:
-
Initialize a Remote Configuration
- Instruction:
init_chain_remote_config
- Use Case: Create a new onchain account (PDA derived from the chain selector and token pool program ID) holding configuration details for a specific remote blockchain (e.g., remote token address).
- Authorization: Pool Owner only
- Read the API reference to learn more.
- Instruction:
-
Edit an Existing Remote Configuration
- Instruction:
edit_chain_remote_config
- Use Case: Update the entire stored configuration for a remote chain (
RemoteConfig
), including the remote token address and decimals. - Authorization: Pool Owner only
- Read the API reference to learn more.
- Instruction:
-
Add Remote Pool Address
- Instruction:
append_remote_pool_addresses
- Use Case: Register one or more remote pool addresses for the same remote chain. This can happen when you deploy a new pool version on that blockchain but keep the old address functional until all in-flight messages are processed.
- Authorization: Pool Owner only
- Read the API reference to learn more.
- Instruction:
-
Remove Remote Pool Address
- Instruction:
edit_chain_remote_config
- Use Case: Remove one or more remote pool addresses from an existing remote chain configuration. Call this instruction with a new
RemoteConfig
that excludes the addresses you want to remove. - Authorization: Pool Owner only
- Read the API reference to learn more.
- Instruction:
-
Remove Chain Config
- Instruction:
delete_chain_config
- Use Case: Remove the remote blockchain configuration PDA to stop supporting it permanently.
- Authorization: Pool Owner only
- Read the API reference to learn more.
- Instruction:
Rate Limits and Security
Configure transfer limits and access controls for your token pool:
-
Configure Rate Limits
- Instruction:
set_chain_rate_limit
- Use Case: Apply or modify the remote blockchain's inbound/outbound rate-limit configuration. This uses a token bucket algorithm in which you can configure the capacity (maximum tokens) and rate (tokens per second refill rate) for both inbound and outbound transfers.
- Authorization: Pool Owner OR Rate Limit Admin
- Read the API reference to learn more.
- Instruction:
-
Optional Allowlist
- Instructions:
configure_allow_list
,remove_from_allow_list
- Use case: You can add or remove addresses if the pool has an allowlist. When the allowlist is enabled, only addresses that appear on it can initiate cross‐chain transfers. This provides an additional layer of access control for who can initiate cross-chain token transfers.
- Authorization: Pool Owner only
- Read the API reference to learn more.
- Instructions:
For detailed authorization requirements, see the access control tables for BurnMint pools and LockRelease pools.
Liquidity Management (Lock/Release Pools Only)
Configure liquidity providers and settings for Lock/Release token pools:
Liquidity Configuration
-
Set Rebalancer
- Instruction:
set_rebalancer
- Use Case: Configure which public key is authorized to add or withdraw liquidity from the pool.
- Authorization: Pool Owner only
- Read the API reference to learn more.
- Instruction:
-
Configure Liquidity Acceptance
- Instruction:
set_can_accept_liquidity
- Use Case: Enable or disable whether the pool can accept incoming liquidity via the
provide_liquidity
instruction. - Authorization: Pool Owner only
- Read the API reference to learn more.
- Instruction:
Liquidity Operations
-
Provide Liquidity
- Instruction:
provide_liquidity
- Use Case: Add tokens to the pool's reserves to enable cross-chain releases. The rebalancer transfers tokens from their account to the pool's Associated Token Account.
- Authorization: Rebalancer only
- Requirements: Pool must have
can_accept_liquidity
enabled - Read the API reference to learn more.
- Instruction:
-
Withdraw Liquidity
- Instruction:
withdraw_liquidity
- Use Case: Remove tokens from the pool's reserves. Can be used to transfer liquidity between pools by setting the destination as another pool's rebalancer.
- Authorization: Rebalancer only
- Requirements: Pool must have
can_accept_liquidity
enabled - Read the API reference to learn more.
- Instruction:
Note: Lock/Release token pools require active liquidity management to ensure sufficient tokens are available for releases. Insufficient liquidity will cause cross-chain transfer failures. For complete authorization details, see the LockRelease Access Control table.