# Bridging from Solana to Chiliz Chain

To bridge an existing token from Solana to Chiliz Chain, you need to write and deploy two separate smart contracts: an OFT Adapter on the chain where the token already exists (Solana), and a Native OFT on the destination chain (Chiliz Chain).

*Note that LayerZero provide their own QuickStart for OFT contracts:*

{% embed url="<https://docs.layerzero.network/v2/developers/evm/oft/quickstart>" %}

## Prerequisites

{% hint style="info" %}
Bridging from Solana (Non-EVM) to Chiliz Chain (EVM) requires dual-stack development.\
You will need environments and wallets set up for both ecosystems.

You will therefore need the following environments:

* For Solana interactions: [Rustup](https://rustup.rs/) (Solana smart contracts use the Rust programming language), [Solana CLI and Anchor framework](https://solana.com/docs/intro/installation), and [LayerZero's Solana SDK](https://docs.layerzero.network/v2/tools/sdks/solana-sdk).
* For Chiliz Chain interactions: Node/npx and Hardhat.
  {% endhint %}

This guide requires the following:

* The mint address of the existing SPL Token you wish to bridge to Chiliz Chain.
* A Web3 wallet for each chain:
  * For Solana: [Solflare](https://www.solflare.com/) wallet with [Solana Mainnet configuration](https://solana.com/docs/references/clusters). Here is [their set-up guide](https://www.solflare.com/guides/how-to-set-up-your-first-crypto-wallet-with-solflare-step-by-step/).
  * For Chiliz Chain: MetaMask wallet with [the Chiliz Chain RPC configuration](/develop/basics/connect-to-chiliz-chain/connect-using-rpc.md).
* Enough gas tokens on each chain to pay for the contract deployments as well as the gas fees for sending messages.
  * On Solana: SOL tokens.
  * On Chiliz Chain: CHZ tokens.

## Step 1: Contract Development

{% hint style="info" %}
**The "Shared Decimals" Challenge**

Because the Ethereum Virtual Machine (EVM) handles token mathematics differently than Solana, we must align their decimal precision before tokens cross the bridge:

* Solana (Source): Native SPL Tokens typically have 9 decimals of precision.
* Chiliz Chain (Destination): Standard ERC-20 tokens (and your new destination OFT) typically use 18 decimals.

If you sent a 9-decimal payload from Solana directly to Chiliz without conversion, the EVM contract would misinterpret the amount, resulting in a microscopic fraction of a token being minted on the destination chain.

To normalize the math, LayerZero uses a `sharedDecimals` configuration. By default, the LayerZero V2 OFT standard sets `sharedDecimals` to 6.

* When a user bridges 1.00 SPL token from Solana, the Solana Adapter scales the number down to 6 decimals (treating the lowest 3 decimals of the SPL token as "dust" and leaving them safely in the user's wallet).
* The 6-decimal message payload is sent across the bridge.
* The Chiliz Chain Native OFT receives the 6-decimal number and scales it *up* to its local 18 decimals before minting the ERC-20 token into the user's EVM wallet.

[Learn more here](https://docs.layerzero.network/v2/faq#what-is-shareddecimals-can-i-override-default-shareddecimals-in-an-oft-contract).
{% endhint %}

### Solana Program Development

Because your token already exists on Solana, you do not need to create a new token contract. Instead, you will deploy a Solana OFT Adapter Program written in Rust. This program will act as a decentralized lockbox, securely holding your SPL tokens when users bridge them to Chiliz Chain, and releasing them when users bridge back.

LayerZero provides an Anchor workspace with pre-built, audited contracts so you do not have to write the Rust logic from scratch.

#### **1. Cloning the LayerZero Solana SDK**

Start by cloning the official LayerZero developer tools repository, which contains the Solana OFT Adapter example.

Open your terminal and run:

{% code overflow="wrap" %}

```bash
git clone https://github.com/LayerZero-Labs/devtools.git
cd devtools/examples/oft-solana
npm install
```

{% endcode %}

#### **2. Building the Solana Adapter Program**

This directory is an Anchor workspace containing both Native OFT and OFT Adapter implementations. You need to build the Rust program to generate your unique Solana Program ID.

{% code overflow="wrap" %}

```bash
anchor build
```

{% endcode %}

After the build completes, retrieve your new Program ID by running:

{% code overflow="wrap" %}

```bash
anchor keys list
```

{% endcode %}

{% hint style="warning" %}
You must update the `Anchor.toml` file and the `declare_id!` macro inside the `programs/oft-adapter/src/lib.rs` file with your new Program ID before deploying.
{% endhint %}

#### **3. Deploying to Solana Mainnet**

Ensure your Solana CLI is configured for Mainnet and that your local wallet has enough $SOL to cover the deployment size and storage rent.

{% code overflow="wrap" %}

```bash
solana config set --url mainnet-beta
anchor deploy
```

{% endcode %}

#### **4. Initializing the OFT Adapter**

Unlike the Native OFT (which requires creating a new Mint), initializing the Adapter simply links your newly deployed Program ID to your existing SPL Token Mint Address.

The LayerZero SDK provides Hardhat tasks to handle this initialization from the command line. Ensure your Solana LayerZero Endpoint (`30168`) is configured, then run:

{% code overflow="wrap" lineNumbers="true" %}

```bash
npx hardhat lz:oft-adapter-solana:init --program-id <YOUR_NEW_PROGRAM_ID> --mint <YOUR_EXISTING_SPL_MINT_ADDRESS_BASE58> --shared-decimals 6
```

{% endcode %}

There are crucial parameters here:

* `--mint`: This must be the exact Base58 Mint Address of the SPL token you want to bridge. The Adapter will create an escrow account specifically for this token.
* `--shared-decimals 6`: This dictates how the Adapter scales the payload before sending it to the EVM. If your Solana token has 9 decimals, leaving 6 shared decimals here ensures it translates safely across the bridge without overflow issues.

Once this initialization transaction is confirmed on Solana, your Adapter is live and ready to securely lock your SPL tokens!

### Chiliz Contract Development

Because your Solana SPL token does not yet exist on the Chiliz Chain, you must deploy a standard Native `OFT` contract. This contract will act as the minter. When it receives a verified message from your Solana Adapter, it will mint the corresponding ERC-20 tokens; when a user bridges back to Solana, it will burn them.

{% hint style="info" %}
As we discussed in "The Shared Decimals Challenge", your Solana Adapter scales the payload down to 6 decimals before sending it.

LayerZero's EVM implementation is such that you do not need to write custom scaling logic. By default, the `OFT.sol` contract uses 18 local decimals and 6 shared decimals. It will automatically detect the 6-decimal payload arriving from Solana and scale it up to the standard 18-decimal format ($$ $1 \times 10^{18}$ $$) before minting the ERC-20 token to the user's wallet.
{% endhint %}

#### Deploying the OFT on Chiliz Chain

Create a new file named `ChilizNativeOFT.sol` in your Hardhat project's `contracts/` folder:

{% code lineNumbers="true" %}

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

import { OFT } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oft/OFT.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";

contract ChilizNativeOFT is OFT {
    constructor(
        string memory _name,    // The name of the token (Should match your Solana SPL Token)
        string memory _symbol,  // The symbol of the token (Should match your Solana SPL Token)
        address _lzEndpoint,    // The LayerZero V2 Endpoint address on Chiliz
        address _delegate       // The address capable of making configuration changes
    ) OFT(_name, _symbol, _lzEndpoint, _delegate) Ownable(_delegate) {}
}
```

{% endcode %}

Do not deploy yet! But keep this in mind:

* Make sure that the `_name` and `_symbol` parameters match your original Solana SPL token exactly to provide a unified experience for your users.
* When deploying to Chiliz Mainnet, you will pass the Chiliz Endpoint V2 address (`0x6F475642a6e85809B1c36Fa62763669b1b48DD5B`) as the `_lzEndpoint`.

## Step 2: LayerZero Configuration

Now that you have your Solana Adapter initialized and your Chiliz Native OFT ready for deployment, you must configure the connection between them.

The main challenge here is address formatting. LayerZero’s cross-chain messaging requires all peer addresses to be formatted as `bytes32`. The LayerZero V2 Hardhat toolbox handles this automatically by decoding your Base58 Solana Adapter Program ID and padding it to the standard EVM format.

The [Simple Config Generator](https://docs.layerzero.network/v2/tools/simple-config) is the recommended way to generate wiring configuration, as it automates bidirectional wiring and applies recommended security configurations under the hood.

Create or update your `layerzero.config.ts` file in the root of your Hardhat project:

{% code lineNumbers="true" %}

```typescript
import { ExecutorOptionType } from '@layerzerolabs/lz-v2-utilities';
import { OAppEnforcedOption, OmniPointHardhat } from '@layerzerolabs/toolbox-hardhat';
import { EndpointId } from '@layerzerolabs/lz-definitions';
import { generateConnectionsConfig } from '@layerzerolabs/metadata-tools';

// Define the Contracts
const solanaContract: OmniPointHardhat = {
    eid: EndpointId.SOLANA_V2_MAINNET,
    address: 'YourSolanaAdapterProgramIdHereInBase58', 
    // NOTE: Non-EVMs use 'address' instead of 'contractName'
};

const chilizContract: OmniPointHardhat = {
    eid: EndpointId.CHILIZ_V2_MAINNET,
    contractName: 'ChilizNativeOFT', // Your Hardhat deployment name on EVM
};

// Define Execution Options for Chiliz (EVM Gas)
const EVM_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
    {
        msgType: 1, 
        optionType: ExecutorOptionType.LZ_RECEIVE,
        gas: 200000, // Standard EVM gas units to mint tokens on Chiliz
        value: 0,
    },
];

// Define Execution Options for the return trip to Solana (Compute Units & Lamports)
const SOLANA_ENFORCED_OPTIONS: OAppEnforcedOption[] = [
    {
        msgType: 1, 
        optionType: ExecutorOptionType.LZ_RECEIVE,
        gas: 200000,    // Solana Compute Units to execute the unlock
        value: 2500000, // Lamports to cover the ATA creation rent fee
    },
];

// Export the Generated Configuration
export default async function () {
    return {
        contracts: [
            { contract: solanaContract },
            { contract: chilizContract },
        ],
        connections: await generateConnectionsConfig([
            [
                solanaContract, 
                chilizContract,
                [['LayerZero Labs'], []], 
                [1, 1], 
                [EVM_ENFORCED_OPTIONS, SOLANA_ENFORCED_OPTIONS], // Options [To Chiliz EVM, To Solana SVM]
            ],
        ]),
    };
}
```

{% endcode %}

The generator handles the automatic conversion of your Solana Base58 address into the EVM `bytes32` padding required by the Chiliz smart contract.

## Step 3: Deployment Workflow

At this stage, your Solana Adapter is already compiled, deployed, and initialized (as covered in Step 1). Now, you need to deploy the EVM side of the bridge—the Native OFT—to the Chiliz Chain.

You will use Hardhat to push this contract to the Chiliz Mainnet.

### **1. The Chiliz Native OFT Deployment Script**

In your Hardhat project, create a deployment script in your `deploy/` directory named `01_deploy_chiliz_native_oft.ts`. This script will initialize the new ERC-20 token on Chiliz.

{% code lineNumbers="true" %}

```typescript
import { DeployFunction } from 'hardhat-deploy/types';

const deployOFT: DeployFunction = async ({ getNamedAccounts, deployments }) => {
    const { deploy } = deployments;
    const { deployer } = await getNamedAccounts();

    // Token Details (Must strictly match your existing Solana SPL Token)
    const TOKEN_NAME = "My Solana Token";
    const TOKEN_SYMBOL = "SOLTKN";

    // The Chiliz Mainnet Endpoint V2 Address
    const CHILIZ_ENDPOINT_V2 = "0x6F475642a6e85809B1c36Fa62763669b1b48DD5B";

    console.log("Deploying Native OFT to Chiliz Mainnet...");

    await deploy('ChilizNativeOFT', {
        from: deployer,
        args: [
            TOKEN_NAME,         // _name
            TOKEN_SYMBOL,       // _symbol
            CHILIZ_ENDPOINT_V2, // _lzEndpoint
            deployer            // _delegate (Owner)
        ],
        log: true,
        waitConfirmations: 2,
    });
};

export default deployOFT;
deployOFT.tags = ['ChilizNativeOFT'];
```

{% endcode %}

### **2. The Solana Program Deployment**

As a quick reminder, your Solana Adapter does not use Hardhat for its initial deployment. You should have already:

1. Run `anchor build` and `anchor deploy` to push the Rust program to Solana Mainnet.
2. Executed the `lz:oft-adapter-solana:init` task to link your Adapter to your existing SPL Token Mint.
3. Copied the resulting Base58 Program ID into your `layerzero.config.ts` file.

### **3. Executing the Chiliz Deployment**

Ensure your `hardhat.config.ts` file has the RPC URL and private key properly configured for the `chiliz` network.

Run the following command in your terminal to deploy the Native OFT:

{% code lineNumbers="true" %}

```bash
npx hardhat deploy --network chiliz --tags ChilizNativeOFT
```

{% endcode %}

Once the deployment finishes, Hardhat will save the newly minted Chiliz contract address in the `deployments/` folder. You now have live contracts on both Solana (SVM) and Chiliz Chain (EVM), but they are not yet authorized to speak to one another.

## Step 4: Wiring & Peering

At this point, you have a Rust Adapter Program on Solana and a Native EVM OFT on Chiliz Chain. To allow them to communicate securely, you must "wire" them together as trusted peers.

Just like bridging in the opposite direction, we are dealing with two completely different Virtual Machines (SVM and EVM). Because of this, configuring the Enforced Options (Gas Limits) correctly is critical to ensuring your transactions don't stall on the destination chain.

### **The "Enforced Options" for Chiliz (EVM)**

When a user bridges their SPL token from Solana to Chiliz, the LayerZero Executor needs EVM gas to call the `lzReceive` function on your Chiliz contract to mint the ERC-20 tokens.

Conversely, for the return trip (Chiliz back to Solana), the Executor will need Solana Compute Units and Lamports to unlock the SPL tokens and potentially pay the rent for an Associated Token Account (ATA).

### **Updating the Configuration**

To guarantee the Executor has enough gas for both directions, you must define these limits in your `layerzero.config.ts` file before wiring.

Update the `connections` array in your config file to include the following `enforcedOptions`:

{% code lineNumbers="true" %}

```typescript
import { EndpointId } from '@layerzerolabs/lz-definitions';
import { ExecutorOptionType } from '@layerzerolabs/lz-v2-utilities';

// ... (contracts array from Step 3)

    connections: [
        // Pathway 1: Solana -> Chiliz (The primary route)
        {
            from: 'YourSolanaAdapterProgramIdHereInBase58',
            to: 'ChilizNativeOFT',
            config: {
                enforcedOptions: [
                    {
                        msgType: 1, // Standard OFT Transfer
                        optionType: ExecutorOptionType.LZ_RECEIVE,
                        gas: 200000, // Standard EVM Gas to mint tokens on Chiliz
                        value: 0,    // No native drop needed on Chiliz EVM
                    }
                ]
            },
        },
        // Pathway 2: Chiliz -> Solana (The return trip)
        {
            from: 'ChilizNativeOFT',
            to: 'YourSolanaAdapterProgramIdHereInBase58',
            config: {
                enforcedOptions: [
                    {
                        msgType: 1, 
                        optionType: ExecutorOptionType.LZ_RECEIVE,
                        gas: 200000,    // Solana Compute Units for the unlock
                        value: 2500000, // Lamports (covers the ATA rent fee if needed)
                    }
                ]
            },
        },
    ],
// ...
```

{% endcode %}

### **Executing the Wire Task**

Once your configuration is saved, the LayerZero V2 toolbox automates the peering process. It decodes your Base58 Solana address, pads it to the required `bytes32` EVM format, and submits the configuration transactions to both the Solana Mainnet and the Chiliz Mainnet.

Run the following command in your terminal:

{% code lineNumbers="true" %}

```bash
npx hardhat lz:oapp:wire --oapp-config layerzero.config.ts
```

{% endcode %}

{% hint style="info" %}
The CLI will prompt you to confirm the transactions. It will use your configured Solana wallet to submit the source transaction (costing $SOL) and Hardhat to submit the Chiliz destination transaction (costing $CHZ).
{% endhint %}

On the Chiliz side, the LayerZero Hardhat toolbox will automatically generate and execute 6 required configuration transactions:

1. `setSendLibrary`: Assigns the V2 MessageLib for sending messages.
2. `setReceiveLibrary`: Assigns the MessageLib for receiving messages.
3. `setConfig` (Send Library): Configures the DVNs and Executor.
4. `setConfig` (Receive Library): Configures the DVNs for inbound verification.
5. `setEnforcedOptions`: Ensures consistent execution parameters (specifically ensuring enough Solana Compute Units are paid for the return trip).
6. `setPeer`: Cryptographically links the Chiliz EID to your Solana Adapter's Base58 Program ID (converted to `bytes32`).

The Solana SDK handles the equivalent programmatic instructions for the SVM side under the hood.

Once both transactions confirm, your Solana-to-Chiliz bridge is officially live and securely permissioned!

## Step 5: Operation & Testing

With your Solana Adapter deployed, your Chiliz Native OFT initialized, and the two properly wired together, your SPL Token is officially ready to cross the SVM/EVM divide. The final step is to execute and track a test transfer from Solana to Chiliz Chain.

### **1) Preparing Your Solana Wallet**

Unlike the EVM where you must execute a separate, prior `approve()` transaction to grant an Adapter an allowance, Solana handles token approvals and transfers within the same transaction instructions.

However, you must ensure that your local Solana wallet (the one configured in your project) actually holds a balance of the SPL tokens you intend to bridge, as well as enough $SOL to pay for the source transaction fee and the LayerZero cross-chain message fee.

**2) Sending the Cross-Chain Message to Chiliz**

The LayerZero V2 toolbox includes a Hardhat task for sending OFT transfers directly from the command line, even when the source chain is Solana.

Unlike Solana-to-Solana transfers, your destination here is a standard EVM hexadecimal wallet address (e.g., `0x123...`). The LayerZero CLI handles the padding and byte conversion for the payload automatically.

Run the following command in your terminal:

{% code lineNumbers="true" %}

```bash
npx hardhat lz:oft:send \
  --oapp-config layerzero.config.ts \
  --from-eid 30168 \
  --to-eid 30409 \
  --to <YOUR_CHILIZ_EVM_WALLET_ADDRESS> \
  --amount 10
```

{% endcode %}

{% hint style="info" %}
What happens here?

1. The script quotes the cross-chain fee in `$SOL`.
2. It constructs a transaction that transfers 10 SPL tokens from your wallet into the Solana Adapter's escrow account.
3. The Adapter scales the 9-decimal SPL token amount down to the 6 shared decimals.
4. The LayerZero Endpoint emits the packet toward the Chiliz Mainnet.
   {% endhint %}

### **3) Tracking the Packet on LayerZero Scan**

Because bridging from Solana involves translating between two entirely different consensus mechanisms and finalizing the transaction on the SVM before executing on the EVM, an asynchronous delay is normal.

To track this journey in real-time, click the LayerZero Scan link that appears in the CLI output.

Learn more about this tool here:

{% embed url="<https://docs.layerzero.network/v2/developers/evm/tooling/layerzeroscan>" %}

{% hint style="info" %}
The Chiliz Native OFT will have automatically scaled the 6-decimal payload back up to the EVM-standard 18 decimals, so you receive exactly 10 full tokens
{% endhint %}

### **4) Troubleshooting Stuck Messages**

If your transaction is marked as confirmed on Solana but fails to execute on Chiliz, the most common culprit is an EVM Out-of-Gas error.

* If the `gas` parameter in your `enforcedOptions` (configured in Step 5) was set too low for the Chiliz network to process the `lzReceive` minting function, the LayerZero Executor will fail to deliver the message.
* Fix: You do not lose your tokens. You can manually push a stuck message through via the LayerZero Scan UI. Simply connect your EVM wallet to Chiliz Chain, click the "Force Resume" or "Execute" button on the block explorer, and pay the Chiliz gas fee yourself to finalize the minting.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.chiliz.com/develop/advanced/use-omnichain-tokens/bridging-from-solana-to-chiliz-chain.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
