Skip to main content

Solana Integration Guide

CreatorVault supports Solana users from Day 1 via the Base-Solana Bridge.

Overview

+-----------------------------------------------------------------------------+
| SOLANA -> BASE FLOW |
+-----------------------------------------------------------------------------+
| |
| SOLANA BRIDGE BASE |
| +---------+ +-------------+ +-----------------+ |
| | Phantom |--Lock---->| Validators |--Approve->| Mint SOL on | |
| | Wallet | SOL | (~300 blocks| | Twin Contract | |
| +---------+ +-------------+ +--------+--------+ |
| | |
| v |
| +------------------------+ |
| | Execute Call on Base | |
| | - CCA Bid | |
| | - Buy ■TOKEN | |
| | - Deposit to Vault | |
| +------------------------+ |
| |
+-----------------------------------------------------------------------------+

What Solana Users Can Do

1. Participate in CCA (Fair Launch)

Solana users can bid in Continuous Clearing Auctions to get ■TOKEN at fair prices:

// From Solana wallet
bridge SOL + call submitCCABidFromSolana(
solanaPubkey, // bytes32 (Solana public key)
ccaAuction,
maxPrice,
amount,
prevTickPrice
)

Flow:

  1. User locks SOL on Solana
  2. Validators approve the bridge message
  3. SOL minted on Base to user's Twin Contract
  4. Twin Contract submits bid to CCA
  5. User owns the bid (can claim tokens after graduation)

2. Enter Buy-To-Win Lottery

Every BUY of ■TOKEN is a lottery entry. Solana users can participate:

// From Solana wallet
bridge SOL + call buyAndEnterLottery(
solanaPubkey, // bytes32 (Solana public key)
creatorToken, // Creator Coin (Base ERC20)
tokenIn, // e.g., SOL_ON_BASE / WETH / USDC
amountIn,
amountOutMin,
recipient // Twin contract or any address
)

Flow:

  1. User locks SOL on Solana
  2. SOL minted on Base
  3. Adapter swaps SOL to ■TOKEN on Uniswap V4
  4. Tax hook captures 6.9% fee
  5. Lottery entry registered for the buyer
  6. User could win the jackpot

One-time Setup: Approve the Adapter

SolanaBridgeAdapter pulls ERC20s from the Twin via transferFrom, so the Twin must approve it once per input token (e.g., SOL_ON_BASE, USDC, WETH, and any Creator Coin you want to deposit).

You can do this as a separate Solana-to-Base call (no token transfer required) by having the Twin call:

ERC20(token).approve(SOLANA_BRIDGE_ADAPTER, MAX_UINT256)

After that, subsequent bridge+call actions can spend those tokens without additional approvals.

3. Deposit into Vaults

Solana users can deposit into CreatorVaults:

// From Solana wallet  
bridge SOL + call depositFromSolana(
solanaPubkey, // bytes32 (Solana public key)
creatorToken, // Creator Coin (vault asset)
amount,
recipient
)

Contract Addresses

Base Mainnet

ContractAddress
Bridge0x3eff766C76a1be2Ce1aCF2B69c78bCae257D5188
BridgeValidator0xAF24c1c24Ff3BF1e6D882518120fC25442d6794B
CrossChainERC20Factory0xDD56781d0509650f8C2981231B6C917f2d5d7dF2
SOL Token0x311935Cd80B76769bF2ecC9D8Ab7635b2139cf82
SolanaBridgeAdapter0x5D0e33a4DFAA4e1EB4BDf41B953baa03CA73eA92

Solana Mainnet

ProgramAddress
BridgeProgramHNCne2FkVaNghhjKXapxJzPaBvAKDG1Ge3gqhZyfVWLM
BaseRelayerProgramg1et5VenhfJHJwsdJsDbxWZuotD5H4iELNG61kS4fb9

Twin Contracts

Each Solana wallet has a deterministic Twin Contract on Base:

  • What is it? A smart contract on Base that represents your Solana wallet
  • Why? Enables Solana wallets to execute Base transactions
  • How? Bridge messages with attached calls execute FROM the Twin contract
Solana Wallet: 9aYkCA...
|
+---> Twin Contract: 0x1234... (on Base)
|
+---> msg.sender when executing calls

Twin Address Derivation

The adapter enforces Twin-only authorization by checking:

Bridge.getPredictedTwinAddress(bytes32 solanaPubkey)

Your client should compute:

solanaPubkey = pubkeyToBytes32(phantomPublicKey)
twin = await readContract(BRIDGE, "getPredictedTwinAddress", [solanaPubkey])

Use twin as the recipient for actions where appropriate.


Auto-Relay (Gasless for Solana Users)

With the BaseRelayerProgram, Solana users can:

  1. Pay gas fees in SOL on Solana
  2. Have their Base transaction executed automatically
  3. No need for ETH on Base
// Add PayForRelay instruction to your Solana tx
const ixs = [
getBridgeSolInstruction({ ... }),
await buildPayForRelayIx(RELAYER_PROGRAM_ID, outgoingMessage, payer)
];

Example: Solana User Enters Lottery

// 1. User connects Phantom wallet
const phantom = window.phantom?.solana;
const { publicKey } = await phantom.connect();

// 2. Build bridge + lottery call
const ixs = [
getBridgeSolInstruction({
payer: publicKey,
from: publicKey,
solVault: SOLANA_BRIDGE.solana.bridgeProgram,
bridge: bridgeAccountAddress,
outgoingMessage,
to: toBytes(SOLANA_BRIDGE_ADAPTER), // CreatorVault adapter
remoteToken: toBytes(SOLANA_BRIDGE.base.solToken),
amount: BigInt(0.1 * 10**9), // 0.1 SOL
}),
// Auto-relay for gasless
await buildPayForRelayIx(
RELAYER_PROGRAM_ID,
outgoingMessage,
publicKey
)
];

// 3. Attach call to buy ■TOKEN + enter lottery
const call = {
target: SOLANA_BRIDGE_ADAPTER,
data: encodeLotteryEntryCall({
solanaPubkey: pubkeyToBytes32(publicKey),
creatorToken: AKITA_CREATOR_COIN, // Base ERC20 (creator coin)
tokenIn: SOL_ON_BASE,
amountIn: BigInt(0.1 * 10**9),
amountOutMin: 0n,
recipient: getTwinAddress(publicKey)
}),
value: 0n
};

// 4. Send transaction
const signature = await buildAndSendTransaction(
SOLANA_RPC_URL,
ixs,
publicKey
);

// 5. Wait for bridge + execution (~5 minutes)
// User's Twin contract receives SOL, swaps for ■TOKEN
// Lottery entry automatically registered

Security Considerations

  1. Twin Contract Ownership: Only the corresponding Solana wallet can execute calls from its Twin
  2. Bridge Validation: All bridge messages require validator signatures
  3. Slippage Protection: Always set amountOutMin when swapping
  4. Time Sensitivity: CCA bids may expire; account for ~5 minute bridge time

Frontend Integration

import { SolanaConnect, SolanaBridgeCard } from '@/components'

function SolanaBridge() {
const [publicKey, setPublicKey] = useState<string | null>(null)

return (
<div>
<SolanaConnect onConnect={setPublicKey} />

<SolanaBridgeCard
publicKey={publicKey}
onBridge={(amount, action) => {
// Handle bridge transaction
}}
/>
</div>
)
}

Resources