For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
Contact SupportDiscordGo to dashboard
HomeDocsAPI ReferenceLiquidity IntegrationChangelog
HomeDocsAPI ReferenceLiquidity IntegrationChangelog
  • Introduction
    • Welcome
    • Supported Chains and Providers
    • Demo Apps
    • FAQ
    • API Issues & Error Codes
    • Need Help?
  • Swap API
    • Introduction
    • FAQ
  • Gasless API
    • Introduction
    • Gasless FAQ
  • Solana Swap API
    • Introduction
      • Add Solana to EVM Projects
      • Troubleshooting
      • Rate Limits
    • Gasless FAQ
  • Cross-Chain API
    • Introduction
    • Learn More
  • Trade Analytics API
    • Introduction
    • Transaction Data
    • Trade Analytics FAQ
  • Core Concepts
    • Introduction to 0x
    • 0x Cheat Sheet
    • Contracts
    • Order Types
    • Glossary
    • White Paper
    • Transaction Data
  • Developer Resources
    • Bounties
    • Rate Limits
    • System Status
  • Upgrading
    • Overview
    • Upgrading to Swap v2
    • Upgrading to Gasless v2
  • Need Help?
    • FAQ
    • API Issues & Error Codes
    • Contact Support
    • Contact Sales
LogoLogo
Contact SupportDiscordGo to dashboard
On this page
  • SVM + EVM Integration Checklist
  • 1. Abstract Core Concepts
  • 2. Wallet Connection UX
  • Option 1: Single Wallet at a Time
  • Option 2: Multiple Wallets Connected
  • 3. Normalize Transaction Flow
  • 4. Solana-Specific Considerations
  • 4.1 RPC Provider Selection
  • 4.2 Program-Specific Accounts
  • 4.3 SPL Tokens
  • 4.4 What is an ATA
  • 4.5 Token Account Model: Solana vs Ethereum
  • 4.6 Limitations of Shared Token Accounts
Solana Swap APIReference

Best Practices to Add Solana to EVM Projects

||View as Markdown|
Was this page helpful?
Edit this page
Previous

Integrator Byte Costs

Next

Troubleshooting

Built with

The 0x Solana Swap API is available via priority access. Apply now to start building.

This guide outlines design patterns, integration tips, and architectural considerations for teams adding Solana (SVM) support to an existing EVM-based application. It is geared toward engineers familiar with Ethereum who want to offer a unified cross-chain experience.

SVM + EVM Integration Checklist

  • Abstract tokens, wallets, and transaction logic across chains
  • Normalize the transaction UX flow
  • Detect and create ATAs as needed
  • Select production-ready RPC providers
  • Decide on a wallet connection UX (single vs. multi-wallet)
  • Account for Solana-specific token account behavior

1. Abstract Core Concepts

Avoid hardcoding chain-specific assumptions in your app. Design your architecture around abstract interfaces to encapsulate EVM and SVM differences:

  • Token abstraction: Define a generic token model that hides differences like hexadecimal (EVM) vs base58 (Solana) addresses.
  • Wallet abstraction: Represent wallets as objects that can return addresses, sign messages, and send transactions across chains.
  • Chain awareness: Add utility methods to check if a wallet or token belongs to EVM or SVM to help enforce compatibility or limit unsupported operations.

2. Wallet Connection UX

Decide how your application should handle multi-chain wallet connections.

Option 1: Single Wallet at a Time

  • Simpler to implement
  • Reuses more of your current EVM app architecture
  • Less user flexibility

Option 2: Multiple Wallets Connected

  • Supports simultaneous connections (e.g., one EVM wallet and one Solana wallet)
  • Enables richer cross-chain interactions
  • Requires additional UI logic and app-wide refactoring

Choose your wallet provider carefully. The abstractions they expose can significantly affect your architecture. For example, 0x uses Privy for multi-chain key management.


3. Normalize Transaction Flow

While EVM and SVM transactions are different at the protocol level, you can normalize the user experience:

UX BehaviorEVMSolana
Fetch priceAPI callAPI call
Build transactionConstruct calldataBuild instructions
Approve allowanceERC-20 approve()Typically unnecessary
Submit transactionSend signed transactionSend versioned transaction
Track statuseth_getTransactionReceiptgetSignatureStatus

One option is to create an internal type (e.g. AbstractTransaction) that abstract sthe transaction type with shared fields (e.g. fees, tips, status), while allowing chain-specific logic to compute them differently.


4. Solana-Specific Considerations

Solana has different design assumptions from EVM-based chains, which must be accounted for.


4.1 RPC Provider Selection

You’ll need to address Solana-specific infrastructure concerns, such as choosing a high-quality RPC provider (e.g., Helius or Triton) to improve transaction reliability during peak activity. For additional protection against MEV, consider integrating with Jito.


4.2 Program-Specific Accounts

  • Users must have Associated Token Accounts (ATAs) to receive SPL tokens.
  • Order book DEXes like OpenBook may also require program-specific Open Orders Accounts.

Be prepared to handle creation of these accounts per swap, especially for new tokens or protocols requiring dedicated accounts.

4.3 SPL Tokens

SPL (Solana Program Library) tokens are analogous to ERC-20 tokens.

Each SPL token has an on-chain mint account owned by the SPL Token Program.

The address So11111111111111111111111111111111111111112 is the WSOL mint address, but native SOL is not an SPL token mint account.

A simple, effective way to verify if a token address is an SPL token it to check if the account is owned by the SPL Token Program.

To verify whether a token address on Solana is a valid SPL token mint:

1import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
2import { Connection, PublicKey } from "@solana/web3.js";
3
4/**
5 * Checks whether a list of token addresses are SPL tokens.
6 * @param addresses - An array of base58 token account addresses or mint addresses.
7 * @param connection - A Solana RPC connection object.
8 */
9export async function classifyTokenAccounts(
10 addresses: string[],
11 connection: Connection,
12): Promise<void> {
13 for (const address of addresses) {
14 try {
15 const pubkey = new PublicKey(address);
16 const accountInfo = await connection.getAccountInfo(pubkey);
17
18 if (!accountInfo) {
19 console.log(`${address} does not exist on-chain`);
20 continue;
21 }
22
23 const owner = accountInfo.owner.toBase58();
24 const isSPL = owner === TOKEN_PROGRAM_ID.toBase58();
25
26 console.log(
27 `${address} is ${isSPL ? "an SPL token" : "NOT an SPL token"}`,
28 );
29 } catch (err) {
30 console.error(`Error checking ${address}:`, err);
31 }
32 }
33}
34
35// Example usage
36if (require.main === module) {
37 const tokenAddresses = [
38 "So11111111111111111111111111111111111111112", // not a mint
39 "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
40 "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", // USDT
41 // ... other tokens
42 ];
43
44 const connection = new Connection(
45 "https://api.mainnet-beta.solana.com",
46 "confirmed",
47 );
48
49 classifyTokenAccounts(tokenAddresses, connection);
50}

4.4 What is an ATA

An Associated Token Account (ATA) is a deterministic, standard token account that holds SPL tokens for a specific wallet.

  • Each wallet has one ATA per token mint
  • The ATA must be created before it can receive tokens
  • ATAs are rent-exempt and owned by the wallet

To compute an ATA:

1import { getAssociatedTokenAddress } from "@solana/spl-token";
2
3const ata = await getAssociatedTokenAddress(
4 mintPublicKey, // Token mint address
5 userPublicKey, // Wallet address
6);

4.5 Token Account Model: Solana vs Ethereum

FeatureEthereum (ERC-20)Solana (SPL Token)
Token balancesStored in token contractStored in separate on-chain token account
Receiving tokensSend directly to walletMust create ATA before receiving
Token account creationNot requiredRequired per (wallet, token) pair
Ownership modelWallet owns balance via mappingWallet owns a dedicated account

Solana’s model is more explicit and composable, but requires additional account management logic.


4.6 Limitations of Shared Token Accounts

Shared or global token accounts are not universal.

  • Created and managed by specific aggregators to reduce account bloat
  • Not guaranteed to be accepted by all DEXes or routing paths
  • Best used for efficiency, with fallbacks to user-owned accounts when needed

These accounts are infrastructure shortcuts managed at the protocol level—not core features of the SPL Token Program.