Documentation Index Fetch the complete documentation index at: https://mintlify.com/1inch/cross-chain-sdk/llms.txt
Use this file to discover all available pages before exploring further.
This guide demonstrates how to create atomic swaps from Solana to EVM-compatible chains. Solana swaps require both relayer announcement and on-chain order publishing.
Overview
Solana to EVM swaps differ from EVM-to-EVM swaps:
Orders must be announced to the relayer using announceOrder()
Orders must be published on-chain using Solana transactions
Address formats use SolanaAddress for Solana and EvmAddress for EVM chains
Native Solana tokens use SolanaAddress.NATIVE
Prerequisites
Solana wallet with sufficient SOL for transaction fees
Sufficient token balance for the swap
Dev Portal API key from portal.1inch.dev
Complete Example
This example swaps 10 USDT from Solana to USDT on Ethereum.
Setup Dependencies
Import required modules and initialize the SDK. import {
NetworkEnum ,
SDK ,
SolanaAddress ,
HashLock ,
EvmAddress ,
SvmSrcEscrowFactory ,
OrderStatus
} from '@1inch/cross-chain-sdk'
import { utils , web3 } from '@coral-xyz/anchor'
import { randomBytes } from 'node:crypto'
import { setTimeout } from 'node:timers/promises'
import assert from 'node:assert'
const authKey = process . env . DEV_PORTAL_API_TOKEN
assert ( authKey , 'Please provide DEV_PORTAL_API_TOKEN' )
const signerPrivateKey = process . env . SOLANA_PRIVATE_KEY
assert ( signerPrivateKey , 'Please provide SOLANA_PRIVATE_KEY' )
const makerSigner = web3 . Keypair . fromSecretKey (
utils . bytes . bs58 . decode ( signerPrivateKey )
)
Initialize SDK and Addresses
Configure the SDK and set up token addresses. const SOLANA_RPC = 'https://api.mainnet-beta.solana.com'
const sdk = new SDK ({
url: 'https://api.1inch.com/fusion-plus' ,
authKey
})
// Token addresses
const USDT_SOL = 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'
const USDT_ETHEREUM = '0xdac17f958d2ee523a2206206994597c13d831ec7'
const maker = makerSigner . publicKey . toBase58 ()
const receiver = '0x962a836519109e162754161000D65d9Dc027Fa0F'
const srcToken = SolanaAddress . fromString ( USDT_SOL )
const dstToken = EvmAddress . fromString ( USDT_ETHEREUM )
const amount = 10_000_000 n // 10 USDT
const srcChainId = NetworkEnum . SOLANA
const dstChainId = NetworkEnum . ETHEREUM
For native SOL, use EvmAddress.NATIVE as the token address.
Get Quote
Request a quote for the Solana to EVM swap. console . log (
`Creating order from wallet ${ maker } for [ ${ srcChainId } ] ${ amount } ${ srcToken } -> ${ dstToken } [ ${ dstChainId } ]`
)
const quote = await sdk . getQuote ({
amount: amount . toString (),
srcChainId ,
dstChainId ,
srcTokenAddress: srcToken . toString (),
dstTokenAddress: dstToken . toString (),
enableEstimate: true ,
walletAddress: maker
})
console . log ( 'Got quote' , quote )
const preset = quote . getPreset ( quote . recommendedPreset )
assert ( quote . quoteId )
Generate Secrets and Create Order
Generate secrets and create the Solana order. function getSecret () : string {
return '0x' + randomBytes ( 32 ). toString ( 'hex' )
}
const secrets = Array . from ({ length: preset . secretsCount }). map ( getSecret )
const secretHashes = secrets . map ( HashLock . hashSecret )
const leaves = HashLock . getMerkleLeaves ( secrets )
const hashLock = secrets . length > 1
? HashLock . forMultipleFills ( leaves )
: HashLock . forSingleFill ( secrets [ 0 ])
// Create Solana-specific order
const order = quote . createSolanaOrder ({
hashLock ,
receiver: EvmAddress . fromString ( receiver ),
preset: quote . recommendedPreset
})
Announce Order to Relayer
First, announce the order to the 1inch relayer network. const orderHash = await sdk . announceOrder ( order , quote . quoteId , secretHashes )
console . log ( 'Announced order to relayer' , orderHash )
This registers your order with the relayer before publishing on-chain.
Publish Order On-Chain
Create and submit the Solana transaction to publish the order on-chain. // Create instruction for order creation
const ix = SvmSrcEscrowFactory . DEFAULT . createOrder ( order , {
srcTokenProgramId: SolanaAddress . TOKEN_PROGRAM_ID
})
// Build transaction
const tx = new web3 . Transaction (). add ({
data: ix . data ,
programId: new web3 . PublicKey ( ix . programId . toBuffer ()),
keys: ix . accounts . map (( a ) => ({
isSigner: a . isSigner ,
isWritable: a . isWritable ,
pubkey: new web3 . PublicKey ( a . pubkey . toBuffer ())
}))
})
// Send transaction
const connection = new web3 . Connection ( SOLANA_RPC )
const result = await connection . sendTransaction ( tx , [ makerSigner ])
console . log ( 'Submitted order' , result )
await setTimeout ( 5000 ) // Wait for transaction confirmation
Wait for transaction confirmation before proceeding to secret sharing.
Monitor and Share Secrets
Monitor escrow deployments and share secrets when ready. const alreadyShared = new Set < number >()
while ( true ) {
const readyToAcceptSecrets = await sdk . getReadyToAcceptSecretFills ( orderHash )
const idxes = readyToAcceptSecrets . fills . map (( f ) => f . idx )
for ( const idx of idxes ) {
if ( ! alreadyShared . has ( idx )) {
// Verify escrow addresses before sharing secrets
await sdk . submitSecret ( orderHash , secrets [ idx ])
alreadyShared . add ( idx )
console . log ( 'Submitted secret' , secrets [ idx ])
}
}
// Check if order finished
const { status } = await sdk . getOrderStatus ( orderHash )
if (
status === OrderStatus . Executed ||
status === OrderStatus . Expired ||
status === OrderStatus . Refunded
) {
break
}
await setTimeout ( 5000 )
}
const statusResponse = await sdk . getOrderStatus ( orderHash )
console . log ( statusResponse )
Key Differences from EVM
Solana orders require calling sdk.announceOrder() instead of sdk.submitOrder(). This registers the order with the relayer before on-chain publication. // Solana
const orderHash = await sdk . announceOrder ( order , quote . quoteId , secretHashes )
// vs EVM
const { orderHash } = await sdk . submitOrder ( srcChainId , order , quoteId , secretHashes )
After announcement, Solana orders must be published on-chain using SvmSrcEscrowFactory: const ix = SvmSrcEscrowFactory . DEFAULT . createOrder ( order , {
srcTokenProgramId: SolanaAddress . TOKEN_PROGRAM_ID
})
EVM orders are automatically published when submitted to the relayer.
Use proper address types for each chain: // Solana addresses
const srcToken = SolanaAddress . fromString ( USDT_SOL )
const maker = makerSigner . publicKey . toBase58 ()
// EVM addresses
const dstToken = EvmAddress . fromString ( USDT_ETHEREUM )
const receiver = EvmAddress . fromString ( '0x...' )
Solana requires building and sending transactions manually: const connection = new web3 . Connection ( SOLANA_RPC )
const result = await connection . sendTransaction ( tx , [ makerSigner ])
await connection . waitForTransaction ( result )
Error Handling
try {
const result = await connection . sendTransaction ( tx , [ makerSigner ])
await setTimeout ( 5000 )
} catch ( error ) {
if ( error . message . includes ( 'insufficient funds' )) {
console . error ( 'Insufficient SOL for transaction fees' )
} else if ( error . message . includes ( 'TokenAccountNotFound' )) {
console . error ( 'Token account does not exist' )
} else {
console . error ( 'Transaction failed:' , error )
}
throw error
}
Best Practices
Wait for Confirmation Always wait for Solana transaction confirmation before sharing secrets.
Check Token Accounts Verify token accounts exist before attempting swaps.
Use Recommended Preset Use quote.recommendedPreset for optimal execution.
Track Shared Secrets Maintain a set of shared secret indices to avoid duplicates.
Next Steps
EVM to Solana Learn about swaps from EVM to Solana
Order Lifecycle Understand order states and transitions