- Transfer tokens between Base and Solana
- Send arbitrary cross-chain messages
- Combine both flows (transfer with arbitrary calls)
- Deploy wrapped tokens on either chain
How it works
On Base
The Base bridge contract locks or burns tokens when sending tokens to Solana, and mints or unlocks tokens when receiving tokens from Solana. The Bridge contract itself builds Merkle trees from outgoing messages. Validators verify the Merkle root every ~300 finalized blocks and relay it to Solana. You then prove your message exists in the tree to complete the transfer on Solana.Tokens that are native to Base are locked and tokens that are native to Solana are burned when bridging to Solana.
Tokens that are native to Solana are minted and tokens that are native to Base are unlocked when bridging to Base.
- Bridge Contract: Handles outgoing transfers
- CrossChainERC20: Mintable/burnable tokens for cross-chain transfers
- BridgeValidator: Validates messages with oracle signatures
- Twin Contract: Your personal smart contract on Base for executing calls from Solana
On Solana
The Solana bridge program handles token transfers by locking or burning tokens and emitting events. For messaging, validators relay these events to Base where they are executed through your Twin contract. Key Programs (Solana Mainnet-Beta):- Bridge Program: Handles outgoing transfers and message commitments.
- Base Relayer Program: Optional relayer that can prepay gas on Base.
The relayer program is not part of the core bridge. It is an optional convenience layer that can pay
Base gas fees on behalf of the Solana user in the Solana → Base direction.The user would still need to pay the gas fee by adding
PayForRelay to the Solana transaction.
If the user does not add PayForRelay, the relayer program will not pay the gas fee.Bridging Flows
Solana → Base
Push-based with optional relayer for instant execution on Base
Base → Solana
Proof-based burn and unlock with full custody
Terminally Onchain
Production terminal UI for bridging + contract calls
Solana to Base
Flow: Lock SOL/SPL → (Optional) Pay for relay → Validators approve → Mint + execute on Base The Solana to Base bridge uses a pull-based model that requires 3 steps:- Initiate the bridge on Solana - Lock your SOL or native SPL token in a Solana vault
- Wait for validators to pre-approve the message - Validators verify and approve your bridge message
- Execute the message on Base - The approved message is executed on Base to mint SOL and execute any additional arbitrary calls
When bridging from Solana to Base, native SOL/SPL are locked and ERC20 SOL is minted on Base.
scripts/ directory of the official repository:
Auto-Relay Example
This is a sample script that shows how to bridge SOL with auto-relaysolToBaseWithAutoRelay/index.ts
Wrap Custom SPL Tokens
The example above shows how to bridge native SOL to Base. To bridge custom SPL tokens, you need to create wrapped ERC20 representations on Base using the CrossChainERC20Factory.wrapSolTokenOnBase/index.ts
Base to Solana
Flow: Burn ERC20 SOL on Base → Wait for finalization → Generate Merkle proof → Execute on Solana Burn wrapped tokens on Base, wait for the message to become provable, then execute the proof on Solana to unlock the native asset. This path offers full custody and requires a prover.bridgeSolFromBaseToSolana/index.ts
Utilities
The repository includes utilities for converting between Solana and Base address formats, getting your Solana CLI keypair for signing transactions, and building and sending Solana transactions.Address Conversion
Convert Solana pubkey to bytes32 for Base contracts:example.ts
Keypair Management
Get your Solana CLI keypair for signing transactions:example.ts
Transaction Building
Build and send Solana transactions:example.ts
Terminally Onchain Example
Terminally Onchain is a production Next.js app that exposes the bridge via a command terminal UI. Users connect a Solana wallet, type commands such as to bridge and call a contract on Base:- Parse command: The terminal parser resolves the asset, destination, and optional Base call (selector + args + value).
- Stage bridge:
queueBridgevalidates SPL overrides, ABI-encodes the Base call viaencodeFunctionData, and stages relay overrides. - Execute:
solanaBridge.bridge()resolves the destination (ENS/Basename), ensures balances, and callsrealBridgeImplementationto sign and send the Solana transaction. - Relay + Call: If relay gas is prepaid, the Base Relayer executes the attached call from the user’s Twin contract immediately after ERC20 SOL is minted.
src/lib/bridge.ts: Asset resolution (supports mint addresses), environment-aware RPC connections, and call attachment support.src/lib/realBridgeImplementation.ts: Builds Solana transactions withPayForRelay+bridge_sol/bridge_splinstructions, using per-environment PDAs and gas-fee receivers.src/components/MainContent.tsx: Terminal UI with command staging, log viewer, and ABI encoding for arbitrary Base calls.src/components/WalletConnection.tsx: Fetches the deterministic Twin address on Base Mainnet/Sepolia for the connected Solana wallet.
Running the Terminal
Terminal