# Cross-Chain Token Setup: BurnMint with Production Multisig Governance
Source: https://docs.chain.link/ccip/tutorials/svm/cross-chain-tokens/production-multisig-tutorial
Last Updated: 2026-06-15

> For the complete documentation index, see [llms.txt](/llms.txt).

This tutorial implements **production-grade cross-chain tokens** using Chainlink CCIP with **dual-layer multisig governance** between Solana Devnet and Ethereum Sepolia. You'll build a **production-ready governance architecture** following **Path A** from the [CCIP Cross-Chain Token Integration Guide](/ccip/concepts/cross-chain-token/svm/integration-guide#path-a-full-self-service-mint-authority-controlled).

## What You Will Build

This tutorial implements the **production multisig governance** variant of **Path A** from the [CCIP Cross-Chain Token Integration Guide](/ccip/concepts/cross-chain-token/svm/integration-guide). This approach is designed for **production environments** with enterprise-grade dual-layer governance.

### Cross-Chain Token Architecture

This tutorial implements the **[Burn and Mint](/ccip/concepts/cross-chain-token/overview#burn-and-mint)** token handling mechanism between Solana Devnet and Ethereum Sepolia with **dual-layer multisig governance**. You'll deploy **two BurnMint pools** (one on each chain) that work together to maintain consistent token supply across chains while providing enterprise-grade security controls.

**How Burn and Mint Works:**

1. **Source Chain**: Burns tokens from sender's account
2. **CCIP Protocol**: Transmits message cross-chain
3. **Destination Chain**: Mints equivalent tokens to the receiver

For complete details on token handling mechanisms, see [Token Handling Mechanisms](/ccip/concepts/cross-chain-token/overview#token-handling-mechanisms).

### Component Overview

| Component                | Implementation                       | Authority Model           |
| ------------------------ | ------------------------------------ | ------------------------- |
| **Ethereum Sepolia**     | ERC20 token with CCIP BurnMint pool  | EOA-controlled (tutorial) |
| **Solana Devnet**        | SPL token with dual-layer governance | Squads + SPL multisig     |
| **Cross-Chain Transfer** | Bidirectional token transfers        | Autonomous operations     |

### Dual-Layer Governance Architecture

This tutorial implements **dual-layer multisig governance** that separates concerns:

- **Layer 1 (Squads)**: Controls CCIP administration, pool ownership, protocol configuration
- **Layer 2 (SPL Multisig)**: Controls mint authority with Pool Signer PDA for autonomous operations

**Production Benefits:**

- **Comprehensive Security**: Two independent governance layers
- **Operational Autonomy**: Pool Signer PDA enables autonomous cross-chain transfers
- **Administrative Control**: Squads provides enterprise-grade governance

> **CAUTION: SPL Token Multisig Limitations**
>
> **Critical Understanding**: The SPL token multisig demonstrated in this tutorial can **ONLY execute SPL token
> instructions** (mint, burn, transfer, etc.). It **cannot execute arbitrary transactions** or general governance
> operations like transferring CCIP admin roles or pool ownership. This is why we implement dual-layer governance:
> Squads handles arbitrary governance operations while SPL multisig handles only token-specific operations.

## Prerequisites

This tutorial uses a **two-terminal workflow** with **Squads multisig governance** on Solana. Install the system tools below, create your Squad on devnet, clone both repositories, then complete environment setup before starting Phase 1.

### System Requirements

- **Node.js v22 or higher**: Required for all tools. Verify with `node -v`
- **pnpm**: Required for the BS58 generator (`npm install -g pnpm`)
- **npm**: Required for the Hardhat project (bundled with Node.js)
- **Solana CLI**: [Installation guide](https://docs.solana.com/cli/install-solana-cli-tools) (includes `spl-token`)
- **Git**: For cloning repositories
- **CCIP CLI**: For cross-chain transfer testing in the final phase

**Wallets:**

- **Solana**: [Phantom](https://phantom.app/) or [Backpack](https://backpack.app/) for Devnet and Squads operations
- **Ethereum**: [MetaMask](https://metamask.io/) for Sepolia testnet operations

Install the [CCIP CLI](https://github.com/smartcontractkit/ccip-tools-ts) globally:

```bash
npm install -g @chainlink/ccip-cli
ccip-cli --help
```

See the [CCIP CLI documentation](https://docs.chain.link/ccip/tools/cli/) for RPC and wallet configuration.

### Repository Setup

**Terminal 1: CCIP Solana BS58 Generator** (skip `git clone` if you already have the repo)

```bash
git clone https://github.com/smartcontractkit/ccip-solana-bs58-generator.git
cd ccip-solana-bs58-generator
pnpm install
```

**Terminal 2: Smart Contract Examples (Hardhat)** (skip `git clone` if you already have the repo)

```bash
git clone https://github.com/smartcontractkit/smart-contract-examples.git
cd smart-contract-examples/ccip/cct/hardhat
npm install
npm run compile
```

### Environment Configuration

#### Solana (Terminal 1)

First, check whether your environment is already set up:

```bash
solana config get
solana address
solana balance
```

If the RPC URL is already `https://api.devnet.solana.com`, your keypair path is correct, and you have sufficient SOL, skip to [Ethereum Sepolia setup](#ethereum-sepolia-terminal-2) below.

Otherwise, run only the steps you need:

```bash
# Set devnet (skip if config get already shows devnet)
solana config set --url https://api.devnet.solana.com

# Point to your keypair (skip if config get already shows the path you want)
solana config set --keypair ~/.config/solana/id.json

# Create a keypair only if the file does not exist yet
solana-keygen new --outfile ~/.config/solana/id.json

# Fund your wallet if balance is low
solana airdrop 3
solana balance
```

#### Ethereum Sepolia (Terminal 2)

```bash
# Required at the start of each session
npx env-enc set-pw

# Verify existing variables (skip npx env-enc set if all required vars are already configured)
npx env-enc view

# Add or update variables only if missing
npx env-enc set
```

Required variables:

- `ETHEREUM_SEPOLIA_RPC_URL`: RPC endpoint ([Alchemy](https://www.alchemy.com/) or [Infura](https://www.infura.io/))
- `PRIVATE_KEY`: Testnet wallet private key
- `ETHERSCAN_API_KEY`: API key from [Etherscan](https://etherscan.io/apis)

**Testnet tokens:**

- **Solana Devnet**: `solana airdrop 3` for SOL
- **Ethereum Sepolia**: ETH for gas and CCIP fees ([Chainlink faucet](https://faucets.chain.link/) or [Google Cloud Faucet](https://cloud.google.com/application/web3/faucet/ethereum/sepolia)). LINK is optional for `--fee-token LINK` on EVM sends.

> **NOTE: When to Use --execute**
>
> **Governance steps** generate base58-encoded transactions in Terminal 1 **without** `--execute`. Import the output
> into Squads and sign there. **Pre-transfer steps** (token delegation, pool ATA creation) use your local Solana wallet
> with `--execute` on `pnpm bs58` commands. **Read-only** commands (`get-state`, `get-chain-config`) omit `--execute`.
> See the [CCIP Solana BS58 Generator
> README](https://github.com/smartcontractkit/ccip-solana-bs58-generator/blob/main/README.md).

### Squads Multisig Setup

> **CAUTION: Required: Create Squads Multisig**
>
> **Before starting this tutorial**, create a Squads multisig on Solana Devnet. It serves as your governance mechanism
> for CCIP administrative operations.

**Step 1: Prepare signers**

```bash
# Create additional signers using Solana CLI
solana-keygen new --outfile ~/.config/solana/signer2.json
solana-keygen new --outfile ~/.config/solana/signer3.json

# Get signer addresses
solana address --keypair ~/.config/solana/id.json
solana address --keypair ~/.config/solana/signer2.json
solana address --keypair ~/.config/solana/signer3.json

# Fund signers (minimum 0.1 SOL each for transaction fees)
solana transfer <SIGNER2_ADDRESS> 0.1 --allow-unfunded-recipient
solana transfer <SIGNER3_ADDRESS> 0.1 --allow-unfunded-recipient
```

Alternatively, create signers in Phantom and fund them:

```bash
solana transfer <PHANTOM_SIGNER_ADDRESS> 0.5 --allow-unfunded-recipient
```

**Step 2: Create your Squad**

1. Visit [devnet.squads.so](https://devnet.squads.so)
2. Connect your Solana wallet (Phantom or Backpack)
3. Click **Create New Squad**
4. Configure members and threshold (recommended: 2/3 or 3/5)

> **NOTE: Threshold Best Practices**
>
> - **Avoid 1/n thresholds** (single point of failure)

- **Avoid maximum thresholds** (e.g., 3/3 prevents recovery if one key is lost)

**Step 3: Record the vault address**

After Squad creation, open the Settings tab and copy the **vault address** (not the multisig address).

**In Terminal 1:**

```bash
# CRITICAL: Use the VAULT address, NOT the multisig address
export SOL_SQUAD_VAULT_MULTISIG="YOUR_VAULT_ADDRESS_HERE"
echo "Squads Vault Address: $SOL_SQUAD_VAULT_MULTISIG"
```

> **CAUTION: Vault vs Multisig Address**
>
> Use the **vault address** for authorities and receiving funds. The **multisig address** is for CLI detection only —
> sending assets to it causes **irreversible loss**.

**Step 4: Test your Squad**

1. Send a small amount of SOL to your Squad vault
2. Create a test transaction in Squads UI (e.g., SOL transfer to your wallet)
3. Confirm signers can approve and execute

See [Squads Documentation](https://docs.squads.so/) for detailed setup guidance.

### Token Creation Option

> **NOTE: Existing Token Requirements**
>
> You can skip token creation only if you have an existing SPL token where **mint authority is already controlled by your
> Squad vault**.

**Two scenarios:**

1. **Mint authority = Squad vault**: Skip to pool initialization and export your existing mint address
2. **Mint authority ≠ Squad vault**: Transfer mint authority to your Squad vault first, or create a fresh token in the tutorial

**For a fresh start**: Proceed with token creation so the Squad vault is mint authority from the beginning.

## Tutorial Approach

| Terminal       | Repository                                                                                                                  | Purpose                                    | Commands        |
| -------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | --------------- |
| **Terminal 1** | [CCIP Solana BS58 Generator](https://github.com/smartcontractkit/ccip-solana-bs58-generator)                                | Governance txs and pre-transfer setup      | `pnpm bs58`     |
| **Terminal 2** | [Smart Contract Examples (Hardhat)](https://github.com/smartcontractkit/smart-contract-examples/tree/main/ccip/cct/hardhat) | Deploy and configure EVM components        | `npx hardhat`   |
| **Either**     | Global `@chainlink/ccip-cli`                                                                                                | Cross-chain transfer testing (final phase) | `ccip-cli send` |

The [CCIP Solana BS58 Generator README](https://github.com/smartcontractkit/ccip-solana-bs58-generator/blob/main/README.md) contains command syntax, simulation behavior, and troubleshooting.

### Key Implementation Notes

- **Terminal 1** generates base58 transactions for Squads governance (no `--execute`). Pre-transfer delegation steps use `--execute` with your local wallet.
- **Terminal 2** uses an EOA for tutorial simplicity; production EVM deployments should use multisig wallets (e.g., Safe).
- **Cross-chain transfers** use [`@chainlink/ccip-cli`](https://github.com/smartcontractkit/ccip-tools-ts): Terminal 1 for Solana → EVM, Terminal 2 for EVM → Solana. For EVM sends, prefer `--wallet hardhat:<name>` ([Hardhat keystore](https://hardhat.org/docs/plugins/hardhat-keystore)) from the Hardhat directory; alternatively export `PRIVATE_KEY` manually after `npx env-enc view` (Hardhat tasks load env-enc automatically, but `ccip-cli` does not). Provide RPCs via `--rpc`/`--rpcs`, `RPC_*` environment variables, or a `.env` file — see [CCIP CLI configuration](https://docs.chain.link/ccip/tools/cli/configuration).

### base58 Transaction Execution Workflow

**Transaction generation:**

1. **CLI simulation**: Each base58 transaction is simulated during generation
2. **Error handling**: If simulation fails, do not upload the transaction to Squads
3. **Success**: Terminal shows a transaction preview and base58 output

**Squads execution:**

1. **Propose**: Import base58 output in Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx** → **Initiate Transaction**
2. **Approve**: Required threshold of signers approves
3. **Simulate** (recommended): Preview onchain effects in Squads before execution
4. **Execute**: Any approved signer executes after threshold is met

> **NOTE: Security Best Practice**
>
> Always simulate in Squads before execution. This validates complex governance operations before commitment.

### Environment Variables

Variables use prefixes to prevent confusion across repositories:

| Prefix       | Usage                   | Examples                                                                  |
| ------------ | ----------------------- | ------------------------------------------------------------------------- |
| `ETH_*`      | Ethereum addresses      | `ETH_TOKEN_ADDRESS`, `ETH_POOL_ADDRESS`                                   |
| `SOL_*`      | Solana addresses        | `SOL_TOKEN_MINT`, `SOL_POOL_ADDRESS`                                      |
| `SOL_CCIP_*` | Solana CCIP program IDs | `SOL_CCIP_POOL_PROGRAM`, `SOL_CCIP_ROUTER`, `SOL_CCIP_FEE_QUOTER_PROGRAM` |

## Phase 1: EVM Chain Setup (Ethereum Sepolia)

In this phase, you will deploy ERC20 tokens and configure CCIP BurnMint pools on Ethereum Sepolia. This setup is identical across all Path A variants and provides the foundation for cross-chain operations.

> **NOTE: Terminal Context Check**
>
> **Current Focus: Terminal 2 (EVM Hardhat)** You'll be working exclusively in the Hardhat repository for this phase.
> Other terminals remain idle. Note: This tutorial uses EOA for simplicity; production deployments should use multisig
> wallets.

### Step 1: Prepare EVM Environment

First, set up your terminal and verify your environment:

### Step 2: Deploy ERC20 Token

Deploy your cross-chain token on Ethereum Sepolia:

Set the token address variable:

### Step 3: Deploy and Configure CCIP BurnMint Pool

Deploy the BurnMint token pool:

Set the pool address and configure:

### Step 4: Mint Initial Token Supply

Mint tokens for testing:

### Step 5: Claim CCIP Admin Role

In this step, you will use the `claimAdmin` task to register your EOA as the administrator for the deployed token on Ethereum Sepolia. This process involves calling the `RegistryModuleOwnerCustom` contract, which will fetch the CCIP admin of the token and set it up as the admin in the registry.

### Step 6: Accept CCIP Admin Role

In this step, you will use the `acceptAdminRole` task to accept the admin role for the deployed token on Ethereum Sepolia. Once you have claimed the role, accepting the role finalizes your control over the token administration.

### Step 7: Register Pool with Token

In this step, you will use the `setPool` task to register the BurnMint token pool with the token in Ethereum's TokenAdminRegistry contract. This function sets the pool contract address for the token, enabling it for CCIP cross-chain transfers. Only the token administrator can call this function.

**Phase 1 Complete**: Save your variables:

> **NOTE: Phase 1 Complete**
>
> **EVM Setup Complete**: You have successfully deployed and configured the EVM side. Next, you'll implement the
> production-grade Solana side with dual-layer multisig governance.

## Phase 2: Solana Setup with Production Dual Multisig Governance

In this phase, you will implement the **production-grade dual-layer multisig governance** architecture on Solana Devnet.

> **NOTE: Terminal Context Check**
>
> **Current Focus: Terminal 1 (base58 Generator)** Switch to the base58 generator repository for transaction generation.
> This tool creates Base58-encoded transactions that will be executed through Squads UI.

### Step 1: Prepare base58 Environment

Set up CCIP constants on Solana Devnet (DO NOT CHANGE THESE)

### Step 2: Create SPL Token (Layer 2 Foundation)

This command generates a transaction that creates a new SPL token mint with the following features:

- **Mint Authority**: Set to your Squad vault multisig for governance control
- **Metaplex Metadata**: Includes token name, symbol, and URI for cross-platform compatibility
- **Initial Supply**: Automatically mints 5,000 tokens (5,000,000,000,000 smallest units) to your wallet
- **Deterministic Address**: Uses a seed-based approach for predictable mint addresses

> **TIP: Customize Your Token**
>
> **Recommended**: Create your own token metadata! Upload your token's JSON metadata to IPFS (using services like Pinata, NFT.Storage, or Arweave), then update the command parameters:

- `--name "Your Token Name"` (max 32 characters)
- `--symbol "YOUR-SYMBOL"` (max 10 characters)
- `--uri "https://your-ipfs-gateway/ipfs/your-hash"`
- `--initial-supply "your-amount"` (in smallest units)

This ensures your token has unique branding and proper metadata for cross-platform compatibility.

Generate the SPL token creation transaction (customize parameters or reuse the example):

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**

- **Review**: Verify transaction details, check authority and mint

- **Simulate**: Simulate the transaction to ensure it will succeed

- **Approve**: Obtain required threshold signatures

- **Execute**: Complete the transaction execution

After execution, set the token mint:

### Step 3: Initialize BurnMint Token Pool (Before Multisig Setup)

> **CAUTION: Why Initialize Pool Before Mint Authority Transfer**
>
> **Critical**: Since your Squad multisig currently holds the mint authority, you can follow [**PATH A**
> (self-service)](/ccip/concepts/cross-chain-token/svm/integration-guide#path-a-full-self-service-mint-authority-controlled)
> and initialize the pool without Chainlink Labs intervention. However, once you transfer mint authority to an SPL token
> multisig, you would lose this capability - SPL token multisigs can only execute SPL token instructions, not CCIP pool
> initialization instructions. Initialize the pool now while you still have direct control.

**Alternative Options**: If you have an existing token where the mint authority is held by a wallet or another multisig under your control, you can transfer the mint authority to your Squad vault first to follow the self-service path. Otherwise, if you cannot control the mint authority, you can submit a [registration request](https://chain.link/ccip-contact?v=Tokens:%20Token%20admin%20registration) to have Chainlink Labs initialize the pool for you.

This command creates only one new account and establishes references to existing infrastructure:

**What Gets Created:**

- **Pool State PDA**: Creates the onchain Pool State account that stores your token's CCIP configuration

**What Gets Referenced (Not Created):**

- **Authority Assignment**: Sets your Squad vault as the pool owner with full configuration control
- **Router Integration**: References the existing global CCIP router and RMN (Risk Management Network)
- **Pool Signer PDA**: The Pool Signer PDA is mathematically derived but not created - it will be used on-demand during cross-chain operations

The `initialize-pool` instruction creates only the Pool State account for your SPL token mint, establishing you as the pool owner while referencing existing global infrastructure.

Generate the pool initialization transaction:

**Account Breakdown from the Transaction (Example):**

| Account | Address                                        | Purpose                                                     |
| ------- | ---------------------------------------------- | ----------------------------------------------------------- |
| **#1**  | `2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu` | **Pool State PDA** - Your main pool configuration           |
| **#2**  | `hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub`  | Token Mint (your token)                                     |
| **#3**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | Authority (your Squad vault)                                |
| **#4**  | `11111111111111111111111111111111`             | System Program                                              |
| **#5**  | `41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB` | CCIP Pool Program                                           |
| **#6**  | `4sVSCJqG9ZKEvnpN38qTzb7Kc8QdHakBgB87HN3FYRaz` | Program Data PDA                                            |
| **#7**  | `E4Bsi43kX3iwXAFia2ebm1mS5Xkmmdv3minZDnfo7Zzf` | **Global Config PDA** - Program-wide configuration settings |

**Key Addresses You Need:**

- **Account #1** → `SOL_POOL_ADDRESS` (writable account = pool state)
- **Pool Signer PDA** → Must be derived separately (NOT in transaction accounts)

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**

- **Review**: Verify pool initialization parameters

- **Simulate**: Simulate the transaction to ensure it will succeed

- **Approve**: Obtain required threshold signatures

- **Execute**: Complete the transaction execution

After execution, set the pool state address from the transaction:

### Step 4: Derive Pool Signer PDA

The Pool Signer PDA is the critical address that will serve as the autonomous signing authority for cross-chain mint and burn operations.

Set the Pool Signer PDA address for use in subsequent steps:

### Step 5: Register CCIP Administrator

This two-step process establishes your Squad vault as the CCIP token administrator, enabling you to enable your token in CCIP. Since your Squad vault currently holds the mint authority, you can complete this registration using the [self-service registration flow](/ccip/concepts/cross-chain-token/svm/registration-administration#self-service-registration-flow) without external assistance.

**Why This Works**: The Router's [owner\_propose\_administrator](/ccip/concepts/cross-chain-token/svm/registration-administration#self-service-registration-flow) instruction verifies onchain that the caller matches the token's `mint_authority` field. Your Squad vault has this authority, enabling [PATH A self-service registration](/ccip/concepts/cross-chain-token/svm/integration-guide#path-a-full-self-service-mint-authority-controlled).

#### Sub-step 5a: Propose Administrator

The [owner\_propose\_administrator](/ccip/concepts/cross-chain-token/svm/registration-administration#self-service-registration-flow) instruction creates a TokenAdminRegistry PDA for your token and sets your Squad vault as the [pending administrator](/ccip/concepts/cross-chain-token/svm/registration-administration#self-service-registration-flow):

**Account Breakdown from the Transaction (Example):**

| Account | Address                                        | Description                                                           |
| ------- | ---------------------------------------------- | --------------------------------------------------------------------- |
| **#1**  | `3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3` | Router Config PDA (read-only)                                         |
| **#2**  | `6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3` | **🎯 Token Admin Registry PDA** - Gets created/updated for your token |
| **#3**  | `hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub`  | Token Mint (your token)                                               |
| **#4**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | Authority/Payer (your Squad vault)                                    |
| **#5**  | `11111111111111111111111111111111`             | System Program                                                        |

**What This Transaction Does:**
This transaction proposes your Squad vault as the administrator for your token in the Router's Token Admin Registry. **Account #2** is the Token Admin Registry PDA that stores who has administrative control over your token's cross-chain operations.

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**

- **Review**: Verify transaction details and parameters

- **Simulate**: Simulate the transaction to ensure it will succeed

- **Approve**: Obtain required threshold signatures

- **Execute**: Complete the transaction execution

#### Sub-step 5b: Accept Administrator Role

The [accept\_admin\_role](/ccip/concepts/cross-chain-token/svm/registration-administration#self-service-registration-flow) instruction completes the [registration process](/ccip/concepts/cross-chain-token/svm/registration-administration#self-service-registration-flow) by having the pending administrator (your Squad vault) explicitly accept the CCIP token administrator role:

**Account Breakdown from the Transaction (Example):**

| Account | Address                                        | Description                                                  |
| ------- | ---------------------------------------------- | ------------------------------------------------------------ |
| **#1**  | `3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3` | Router Config PDA (read-only)                                |
| **#2**  | `6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3` | **🎯 Token Admin Registry PDA** - Updates status to "active" |
| **#3**  | `hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub`  | Token Mint (your token)                                      |
| **#4**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | Authority (your Squad vault - must be pending admin)         |

**What This Transaction Does:**
This is the **acceptance step** of the two-phase administrator registration. It updates the Token Admin Registry PDA (Account #2) from "pending administrator" to "active administrator" status. Your Squad vault explicitly accepts the administrator role, completing the secure registration process.

**Key Difference**: Only 4 accounts (vs. 5 in the propose step) because we're updating an existing registry entry, not creating a new one.

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**

- **Review**: Verify transaction details and parameters

- **Simulate**: Simulate the transaction to ensure it will succeed

- **Approve**: Obtain required threshold signatures

- **Execute**: Complete the transaction execution

After both transactions are executed, your Squad vault will be the CCIP token administrator. See [Registration & Administration](/ccip/concepts/cross-chain-token/svm/registration-administration) for more details.

### Step 6: Create SPL Token Multisig (Layer 2 Mint Authority)

This command creates the second layer of your dual-multisig architecture by establishing an SPL token multisig that will control mint authority. The `create-multisig` instruction creates a deterministic multisig account that includes both your Pool Signer PDA and Squad vault as authorized signers.

**What This Accomplishes**:

- **SPL Token Multisig Creation**: Establishes a new multisig account
- **Dual Authority Setup**: Includes both Pool Signer PDA (for autonomous CCIP operations) and Squad vault (for governance control)
- **Threshold Configuration**: Sets threshold to 1, allowing either signer to authorize mint operations
- **Layer 2 Foundation**: Creates the mint authority that will be transferred from your Squad vault in the next step

**Token Program Detection**: The CLI automatically detects whether your mint uses SPL Token v1 or Token-2022 and creates the appropriate multisig type.

**Account Breakdown from the Transaction (Example):**

| Account | Address                                        | Description                               |
| ------- | ---------------------------------------------- | ----------------------------------------- |
| **#1**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | **Payer/Authority** (your Squad vault)    |
| **#2**  | `3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX` | **🎯 SPL Token Multisig** (newly created) |

**What This Transaction Does:**
This creates an **SPL Token Multisig** account that will control your token's mint authority. The CLI automatically detected SPL Token v1 and created the appropriate multisig type.

**Key Details:**

- **Generated Multisig Address**: `3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX`
- **Multisig Signers**: Pool Signer PDA + Squad vault
- **Threshold**: 1 (either signer can authorize mint operations)
- **Hybrid Control**: Enables both automated CCIP operations and human governance

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**
- **Review**: Verify transaction details and parameters
- **Simulate**: Simulate the transaction to ensure it will succeed
- **Approve**: Obtain required threshold signatures
- **Execute**: Complete the transaction execution

**After execution, set the variable for the next step:**

### Step 7: Transfer Mint Authority (Layer 2 Mint Authority)

Transfer mint authority from your Squad vault to the SPL Token Multisig, completing the dual-layer governance architecture. This enables both automated CCIP operations and human governance control.

**What This Command Does:**

- **Authority Transfer**: Moves mint control from Squad vault to SPL Token Multisig
- **SPL Token Operation**: Uses the native `SetAuthority` instruction for mint authority
- **Governance Architecture**: Establishes the final production-ready control structure
- **Dual Control Setup**: Enables both Pool Signer PDA (autonomous) and Squad vault (governance) control
- **Irreversible Change**: Once executed, only the SPL Token Multisig can mint tokens

**Account Breakdown from the Transaction (Example):**

| Account | Address                                        | Description                                   |
| ------- | ---------------------------------------------- | --------------------------------------------- |
| **#1**  | `hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub`  | **Token Mint** (writable - authority updated) |
| **#2**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | **Current Authority** (signer - Squad vault)  |

**Key Details:**

- **Current Authority**: `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` (Squad vault)
- **New Authority**: `3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX` (SPL Token Multisig)
- **Token Mint**: `hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub` (authority field updated)

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**

- **Review**: Verify transaction details and parameters

- **Simulate**: Simulate the transaction to ensure it will succeed

- **Approve**: Obtain required threshold signatures

- **Execute**: Complete the transaction execution

### Step 8: Test Token Minting (Verify Dual-Layer Control)

Verify that your Squad vault can still mint tokens after the authority transfer. This proves the dual-layer governance is working correctly: Squad vault → SPL Token Multisig → Token minting.

**Purpose of This Test:**

- **Verify Authority Transfer**: Confirm the SPL Token Multisig now controls mint authority
- **Prove Squad Control**: Demonstrate that Squad vault can still mint through the multisig
- **Validate Architecture**: Test the dual-layer governance model works as designed

> **NOTE: Multisig Minting Process**
>
> **Important**: Since mint authority now belongs to the SPL Token Multisig, you must use multisig mode. The Squad vault
> acts as one of the multisig signers, proving it retains operational control through the new governance structure.

**Account Breakdown from the Transaction (Example):**

| Account | Address                                        | Description                                         |
| ------- | ---------------------------------------------- | --------------------------------------------------- |
| **#1**  | `hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub`  | **Token Mint** (writable - supply updated)          |
| **#2**  | `gKhGBvVGw62EdjfdNQFvVvvbg8CqdepTrdmSdVsEDBS`  | **Recipient's ATA** (writable - receives tokens)    |
| **#3**  | `3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX` | **SPL Token Multisig** (read-only - mint authority) |
| **#4**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | **Squad Vault** (signer - multisig member)          |

**What This Transaction Does:**
This is an **SPL Token Multisig Mint** operation that proves your dual-layer governance is working correctly. The Squad vault acts as a signer for the SPL Token Multisig that now controls mint authority.

**Key Details:**

- **Amount**: 1,000,000,000 smallest units = 1 token (with 9 decimals)
- **Recipient**: Your wallet address (`GY3V5RAtSxoJf2dZGqAbzaSxDyXWb8RPMWQdv1mC5PXN`)
- **Mint Authority**: SPL Token Multisig (`3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX`)
- **Multisig Signer**: Squad vault (`AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB`)
- **Token Program**: SPL Token v1 (`TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`)

**Transaction Flow:**

1. **Authority Verification**: SPL Token program verifies the multisig has mint authority
2. **Signature Validation**: Program confirms Squad vault is an authorized multisig signer
3. **Token Creation**: 1 token is minted and added to total supply
4. **Token Transfer**: New tokens are deposited into your wallet's ATA

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**
- **Review**: Verify transaction details and parameters
- **Simulate**: Simulate the transaction to ensure it will succeed
- **Approve**: Obtain required threshold signatures
- **Execute**: Complete the transaction execution

**Phase 2 Complete**: Save your variables:

> **NOTE: Dual-Layer Architecture Established**
>
> **Production Governance Complete**: You have successfully established dual-layer multisig governance:

- **Layer 1**: Squads multisig controls CCIP administration
- **Layer 2**: SPL token multisig (Pool Signer PDA + Squads Vault) controls mint authority This provides comprehensive governance while maintaining autonomous CCIP operations.

## Phase 3: Solana Cross-Chain Setup

In this phase, you will configure the cross-chain connection and complete the CCIP setup.

> **NOTE: Terminal Context Check**
>
> **Current Focus: Terminal 1 (base58 Generator)** Continue using the base58 generator repository for cross-chain
> configuration.

### Step 1: Load Phase 1 Variables

Load Phase 1 variables and set the Ethereum Sepolia chain selector for cross-chain configuration.

**What This Step Does:**

- **Terminal Verification**: Confirms you're in the correct base58 generator repository
- **Variable Loading**: Imports EVM token and pool addresses from Phase 1
- **Chain Selector Setup**: Establishes Ethereum Sepolia chain selector for cross-chain configuration

### Step 2: Configure Cross-Chain Pool Settings

Configure your token pool for cross-chain transfers to Ethereum Sepolia. This process involves two sequential operations:

1. **Initialize Chain Remote Config**: Create the basic cross-chain configuration using [init\_chain\_remote\_config](/ccip/api-reference/svm/v1.6.0/burn-mint-token-pool#init_chain_remote_config)
2. **Edit Chain Remote Config**: Add the remote pool address using [edit\_chain\_remote\_config](/ccip/api-reference/svm/v1.6.0/burn-mint-token-pool#edit_chain_remote_config)

#### Step 2A: Initialize Chain Remote Config

Initialize the basic remote chain configuration for Ethereum Sepolia. Pool addresses must be empty at initialization and rate limits are not configured at this stage.

**Account Breakdown from the Transaction (Example):**

| Account | Address                                        | Description                                         |
| ------- | ---------------------------------------------- | --------------------------------------------------- |
| **#1**  | `2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu` | **Pool State PDA** (read-only - validation)         |
| **#2**  | `A3TEVLHYCbBzncbmVtiZAsK9R281n9oe4DZwMZyKy5p2` | **Chain Remote Config PDA** (writable - created)    |
| **#3**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | **Squad Vault** (signer, writable - pool authority) |
| **#4**  | `11111111111111111111111111111111`             | **System Program** (read-only - account creation)   |

**What This Command Does:**
This initializes the **cross-chain configuration** for your Solana token to enable CCIP bridging to Ethereum Sepolia. This creates the foundational connection without rate limits or pool addresses.

**Key Details:**

- **Remote Chain**: Ethereum Sepolia (chain selector: `16015286601757825753`)
- **Token Mapping**: Links to ERC20 token `0x8b7ce78b89f05eaec2e803e638ff5b0f6f009184`
- **Decimal Precision**: 18 decimals (standard EVM token format)
- **Basic Setup**: No rate limits or pool addresses configured at this stage
- **Account Creation**: Creates a new Chain Remote Config PDA for this cross-chain relationship

**Transaction Flow:**

1. **Authority Verification**: Confirms Squad vault owns the pool state
2. **PDA Derivation**: Calculates Chain Remote Config PDA using pool state + chain selector
3. **Account Creation**: Creates new account with rent-exempt balance
4. **Basic Configuration**: Stores minimal cross-chain parameters (no rate limits, no pool addresses)

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**
- **Review**: Verify transaction details and parameters
- **Simulate**: Simulate the transaction to ensure it will succeed
- **Approve**: Obtain required threshold signatures
- **Execute**: Complete the transaction execution

#### Step 2B: Edit Chain Remote Config (Add Remote Pool Address)

After initializing the chain remote config, add the remote pool address to enable bidirectional cross-chain transfers. This uses [`edit_chain_remote_config`](/ccip/api-reference/svm/v1.6.0/burn-mint-token-pool#edit_chain_remote_config) to specify the Ethereum pool address.

**Account Breakdown from the Transaction:**

| Account | Address                                        | Description                                                    |
| ------- | ---------------------------------------------- | -------------------------------------------------------------- |
| **#1**  | `2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu` | **Pool State PDA** (read-only - authority validation)          |
| **#2**  | `A3TEVLHYCbBzncbmVtiZAsK9R281n9oe4DZwMZyKy5p2` | **Chain Remote Config PDA** (writable - configuration updated) |
| **#3**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | **Squad Vault Authority** (signer, writable - fee payer)       |
| **#4**  | `11111111111111111111111111111111`             | **System Program** (read-only - account operations)            |

**Transaction Flow:**

1. **Authority Verification**: Confirms Squad vault owns the pool state
2. **PDA Access**: Updates the existing Chain Remote Config PDA
3. **Pool Address Addition**: Adds the remote pool to the the remote pool list for Ethereum Sepolia

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**
- **Review**: Verify transaction details and parameters
- **Simulate**: Simulate the transaction to ensure it will succeed
- **Approve**: Obtain required threshold signatures
- **Execute**: Complete the transaction execution

### Step 3: Configure Rate Limits (Optional)

This command configures inbound and outbound rate limiting for token transfers between your Solana token and Ethereum Sepolia. Rate limits act as "token buckets" that control the flow of tokens across chains.

> **NOTE: CCIP Rate Limit Best Practices**
>
> **Recommendations for rate limits:**

- **Outbound = 90% of Inbound**: Prevents in-flight congestion during high-volume periods
- **Conservative Values**: The example uses 20 tokens inbound capacity with 0.1 tokens/second refill rate
- **9-Decimal Tokens**: All values are in smallest token units (Solana uses 9 decimals)

**Configuration Controls:**

- **Pause lane**: Set `capacity=1`, `rate=1` for both directions
- **Remove limits**: Set `enabled=false`, `capacity=0`, `rate=0` for both directions

**Value Calculations:**

- 20 tokens = `20000000000` (20 × 10^9)
- 18 tokens = `18000000000` (18 × 10^9)
- 0.1 tokens/sec = `100000000` (0.1 × 10^9)

**Transaction Accounts (3 total):**

| Account | Address                                        | Type                 | Purpose                                                           |
| ------- | ---------------------------------------------- | -------------------- | ----------------------------------------------------------------- |
| **#1**  | `2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu` | **Read-only**        | **Pool State PDA** - Main pool configuration account              |
| **#2**  | `A3TEVLHYCbBzncbmVtiZAsK9R281n9oe4DZwMZyKy5p2` | **Writable**         | **Chain Config PDA** - Chain-specific config (stores rate limits) |
| **#3**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | **Signer, Writable** | **Authority** - Your Squad vault that can modify rate limits      |

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**
- **Review**: Verify transaction details and parameters
- **Simulate**: Simulate the transaction to ensure it will succeed
- **Approve**: Obtain required threshold signatures
- **Execute**: Complete the transaction execution

### Step 4: Create Address Lookup Table

Create an Address Lookup Table (ALT) containing all accounts needed for CCIP router operations.

**What This Command Does:**

This command creates an **Address Lookup Table (ALT)** that stores frequently used accounts for CCIP operations. ALTs are a Solana optimization that reduces transaction size and costs by replacing full 32-byte addresses with small 1-byte indices.

**Account Breakdown from the Transaction:**

| Account | Address                                        | Description                                               |
| ------- | ---------------------------------------------- | --------------------------------------------------------- |
| **#1**  | `DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv` | **ALT Account** (writable - being created)                |
| **#2**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | **ALT Authority** (signer - will own the table)           |
| **#3**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | **Fee Payer** (signer, writable - pays creation costs)    |
| **#4**  | `11111111111111111111111111111111`             | **System Program** (read-only - handles account creation) |

**What This Command Does:**

This command creates the ALT infrastructure needed for efficient CCIP operations by storing frequently used account addresses in a lookup table.

**Transaction Flow:**

1. **ALT Creation**: Creates lookup table account `DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv` with Squad Vault as authority
2. **Core Address Addition**: Adds essential CCIP accounts (programs, PDAs) to the table
3. **SPL Multisig Addition**: Adds your SPL multisig `$SOL_SPL_MULTISIG` via `--additional-addresses`
4. **Index Assignment**: Each address gets a unique 1-byte index for future reference

**ALT Contents (What Gets Stored):**
The created lookup table will contain indices for these accounts in this exact order:

> **NOTE: Example-Specific Values**
>
> The addresses shown below are from our specific tutorial example. Your actual addresses will be different based on
> your token mint, multisig addresses, and derived PDAs.

| Index  | Account Address                                | Purpose                                               |
| ------ | ---------------------------------------------- | ----------------------------------------------------- |
| **0**  | `DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv` | **ALT Address (Self-Reference)**                      |
| **1**  | `6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3` | **Token Admin Registry PDA**                          |
| **2**  | `41FGToCmdaWa1dgZLKFAjvmx6e6AjVTX7SVRibvsMGVB` | **Pool Program ID**                                   |
| **3**  | `2wEj5e6gpdsEu6DxMQyGbvgRvTe8ZsQmfPbJWV8HUNEu` | **Pool State PDA**                                    |
| **4**  | `2Lzp4uRF6N2x65aMpKqFrajFukAbTCtQcG8thVgqcsEh` | **Pool Signer's Associated Token Account**            |
| **5**  | `62So4PhmWWzMpVXKzsCXdNUfrrB4jGXTVda9BzS6HTeo` | **Pool Signer PDA**                                   |
| **6**  | `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`  | **Token Program ID (SPL Token v1)**                   |
| **7**  | `hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub`  | **Token Mint**                                        |
| **8**  | `GTz54AfhMRkKzFVse8jX8rjAx21fA86ZmVBF1v5VUC3u` | **Fee Quoter Token Config PDA**                       |
| **9**  | `H6ZviaabTYZqUPgiSoMDbeVthcNW9ULcAuUu3zRLFqDR` | **Router External Token Pools Signer PDA**            |
| **10** | `3cKsjnEtGtH47n5wzzA2GKGTTTFWby6n4nWSQDEJU1MX` | **SPL Token Multisig** ← **Your Additional Address!** |

**Transaction Efficiency Impact:**

- **Before ALT**: Each account = 32 bytes (10 accounts = 320 bytes)
- **After ALT**: Each account = 1 byte index (10 accounts = 10 bytes)
- **Savings**: \~310 bytes per future CCIP transaction!

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**
- **Review**: Verify transaction details and parameters
- **Simulate**: Simulate the transaction to ensure it will succeed
- **Approve**: Obtain required threshold signatures
- **Execute**: Complete the transaction execution

**Set Variables:**

Copy the ALT address from the transaction output and set the environment variable:

### Step 5: Register Pool with Router

Register your token pool with the CCIP Router using [set\_pool](/ccip/api-reference/svm/v1.6.0/router#set_pool). This enables the router to route cross-chain transfers through your token pool.

**What This Command Does:**

- **Pool Registration**: Connects your token pool to the CCIP Router for cross-chain operations
- **Lookup Table Integration**: Uses the ALT created in the previous step for efficient account management
- **Router Configuration**: Enables the router to call your pool's token operations

**Account Breakdown from the Transaction:**

| Account | Address                                        | Description                                                 |
| ------- | ---------------------------------------------- | ----------------------------------------------------------- |
| **#1**  | `3Yrg9E4ySAeRezgQY99NNarAmFLtixapga9MZb6y2dt3` | **Router Config PDA** (read-only - configuration reference) |
| **#2**  | `6jWPxptvZKTiLFNdLT39uG1HHa1DXnUqFpi6VttNGrH3` | **Token Admin Registry PDA** (writable - pool registration) |
| **#3**  | `hdTyFD4Pv5vLRvGVAQqs1ZSedNvTM1iu5Y5Rwur5gub`  | **Token Mint** (read-only - token identification)           |
| **#4**  | `DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv` | **Address Lookup Table** (read-only - ALT registration)     |
| **#5**  | `AgPSS5TVRimXPx2bv7Cs2CnuD6pVGPZkrPxjnZ8tLtgB` | **Squad Vault Authority** (signer, writable - admin & fees) |

**What This Command Does:**

This command **registers your token pool** with the CCIP Router. It configures the router to use your Address Lookup Table and specifies which accounts need write access during CCIP operations.

**Key Configuration:**

- **ALT Integration**: Uses the lookup table `DtbZ7Py3pmH5azq4HTqc4axfKwj8zLApkFzueouKg9Zv` you just created
- **Writable Indexes**: `[3,4,7]` - Specific accounts from the ALTthat need write access during CCIP operations

**Transaction Flow:**

1. **Authority Verification**: Confirms Squad Vault has CCIP token admin permissions
2. **Pool Registration**: Updates Token Admin Registry with pool configuration
3. **ALT Association**: Links your token with the specific lookup table
4. **Permission Setup**: Defines which accounts can be modified during cross-chain operations

**Writable Indexes Analysis: `[3,4,7]`**

Based on the ALT order established earlier:

| **Index** | **ALT Account** | **Why Writable**                                 |
| --------- | --------------- | ------------------------------------------------ |
| **3**     | Pool State PDA  | Gets updated during cross-chain operations       |
| **4**     | Pool Token ATA  | Tokens get minted/burned during transfers        |
| **7**     | Token Mint      | Supply gets modified during mint/burn operations |

> **NOTE: Squads Execution Required**
>
> **Execute this base58 transaction in Squads UI:**

- **Import**: Copy the base58 output → Squads UI → **Developers** (left sidebar) → **TX Builder** → **Import base58 encoded tx**
- **Review**: Verify transaction details and parameters
- **Simulate**: Simulate the transaction to ensure it will succeed
- **Approve**: Obtain required threshold signatures
- **Execute**: Complete the transaction execution

**Phase 3 Complete**: Save all variables:

## Phase 4: EVM Cross-Chain Setup

Configure the Ethereum pool to recognize the Solana chain and set production rate limits.

> **NOTE: Terminal Context Check**
>
> **Current Focus: Terminal 2 (EVM Hardhat)** - Ensure you're in the Hardhat repository for EVM configuration.

### Step 1: Load Phase 3 Variables

Ensure you're in Terminal 2 (Hardhat) and load all the variables from Phase 3.

### Step 2: Configure Cross-Chain Settings

Configure the Ethereum pool to recognize the Solana chain and set production rate limits using [`applyChainUpdates`](/ccip/api-reference/evm/v1.6.1/token-pool#applychainupdates).

> **TIP: CCIP Rate Limit Best Practices**
>
> **Recommendations for rate limits**:

- **Outbound = 90% of Inbound**: Prevents in-flight congestion during high-volume periods
- **Conservative Values**: The example uses 20 tokens inbound capacity with 0.1 tokens/second refill rate
- **18-Decimal Tokens**: All values are in wei (smallest token unit)
- **Configuration Controls**:
  - **Pause lane**: Set capacity=1, rate=1 for both directions
  - **Remove limits**: Set enabled=false, capacity=0, rate=0 for both directions
- **Value Calculations**:
  - 20 tokens = `20000000000000000000` wei (20 × 10^18)
  - 18 tokens = `18000000000000000000` wei (18 × 10^18)
  - 0.1 tokens/sec = `100000000000000000` wei (0.1 × 10^18)

## Phase 5: Pre-Transfer Setup, Validation, and Testing

> **NOTE: Terminal Context Check**
>
> **Current Focus: Terminal 1 (CCIP Solana BS58 Generator)** Complete pre-transfer setup and validate your
> configuration. Governance steps use Squads; delegation and verification use your local wallet with `--execute`.

> **NOTE: Cross-Chain Transfers with CCIP CLI**
>
> Use [`@chainlink/ccip-cli`](https://github.com/smartcontractkit/ccip-tools-ts) for bidirectional token transfers. Run Solana → EVM sends from Terminal 1 and EVM → Solana sends from Terminal 2. See the [CCIP CLI documentation](https://docs.chain.link/ccip/tools/cli/) for full options.

### Step 1: Load Configuration

### Step 2: Pre-Transfer Setup

Before cross-chain transfers (when available), complete token delegation so CCIP can move tokens from your wallet.

#### Check Token Balance

#### Create Pool Associated Token Account

If not created during pool setup, create the pool's ATA:

#### Delegate Token Authority

Approve the fee-billing signer to transfer tokens from your ATA:

#### Verify Delegation

Check that your token account is delegated to the fee-billing signer:

Display token account and delegation status:

### Step 3: Verify Solana Pool and Chain Config

### Step 4: Verify Ethereum Pool (Terminal 2)

**Switch to Terminal 2** (Smart Contract Examples - Hardhat):

```bash
npx hardhat getPoolConfig \
  --pooladdress $ETH_POOL_ADDRESS \
  --network ethereumSepolia
```

Confirm the Ethereum pool recognizes Solana Devnet with your `$SOL_POOL_ADDRESS` and `$SOL_TOKEN_MINT`.

### Configure CCIP CLI

Export these RPC URLs once before your first transfer:

```bash
export SOLANA_DEVNET_RPC="https://api.devnet.solana.com"
export ETHEREUM_SEPOLIA_RPC_URL="<YOUR_ETHEREUM_SEPOLIA_RPC_URL>"

export ETH_CCIP_ROUTER="0x0BF3dE8c5D3e8A2B34D2BEeB17ABfCeBaf363A59"
```

Use the same `ETHEREUM_SEPOLIA_RPC_URL` from your env-enc setup in Terminal 2 (`npx env-enc view`). On `ccip-cli send`, the source chain RPC quotes fees and submits the transaction; for token-only transfers in this tutorial, that is the only RPC strictly required to send. Pass both RPCs on cross-chain commands anyway: the destination RPC is required for `ccip-cli show --wait` and for optional send features such as `--estimate-gas-limit` or `send --wait`.

> **NOTE: RPC and wallet configuration**
>
> Repeat `--rpc` for multiple networks, or use `--rpcs` with comma-separated URLs. Alternatively, set `RPC_*` environment variables or a `.env` file — see [CCIP CLI configuration](https://docs.chain.link/ccip/tools/cli/configuration). Solana sends use `--wallet ~/.config/solana/id.json`. EVM sends: prefer `--wallet hardhat:<name>` from the Hardhat project directory ([Hardhat keystore](https://hardhat.org/docs/plugins/hardhat-keystore)); alternatively export `PRIVATE_KEY` manually after `npx env-enc view` (Hardhat tasks load env-enc automatically, but `ccip-cli` does not). See [CCIP CLI wallet configuration](https://docs.chain.link/ccip/tools/cli/configuration#wallet-configuration).

### Transfer Solana → Ethereum

**Terminal 1** (CCIP Solana BS58 Generator):

The `-t` flag uses human-readable amounts (0.001 tokens with 9 decimals = 1,000,000 smallest units).

### Transfer Ethereum → Solana

**Switch to Terminal 2** (Smart Contract Examples - Hardhat):

`ccip-cli` does not load Hardhat env-enc automatically. Run these commands from the Hardhat project directory. Prefer [Hardhat keystore](https://hardhat.org/docs/plugins/hardhat-keystore) over exporting a private key in plain text.

For token-only transfers to Solana, `--to` is the destination wallet that receives minted tokens. CCIP fees are paid in native Sepolia ETH by default — ensure your wallet has sufficient ETH for gas and fees.

> **NOTE: Pay fees in LINK (optional)**
>
> Add `--fee-token LINK` to pay CCIP fees in LINK instead of ETH (Sepolia LINK:
> `0x779877A7B0D9E8603169DdbD7836e478b4624789`).

### Optional: Test Rate Limit Enforcement

If you configured rate limits in Phase 3, attempt a transfer that exceeds capacity (25 tokens vs 20-token limit):

### Optional: Verify Rate Limit Configuration

If you configured rate limits in Phase 3, confirm they appear in your chain configuration:

```bash
# Terminal 1 — inspect Solana outbound/inbound rate limits
pnpm bs58 --env devnet burnmint-token-pool \
  --instruction get-chain-config \
  --program-id $SOL_CCIP_POOL_PROGRAM \
  --mint $SOL_TOKEN_MINT \
  --remote-chain-selector $ETHEREUM_SEPOLIA_CHAIN_SELECTOR
```

```bash
# Terminal 2 — inspect EVM rate limit settings
npx hardhat getPoolConfig \
  --pooladdress $ETH_POOL_ADDRESS \
  --network ethereumSepolia
```

**Congratulations!** Your production cross-chain token infrastructure with Squads governance is fully configured on both chains.