Swap
Execute token swaps on Ferra pools.
Quick Start
// Simple swap: 1 SUI -> USDC
const swapParams = {
pool_id: '0x...',
coinTypeA: '0x2::sui::SUI',
coinTypeB: '0x...::usdc::USDC',
a2b: true, // SUI -> USDC
by_amount_in: true, // Fix input amount
amount: '1000000000', // 1 SUI
amount_limit: '990000', // Min 990 USDC (1% slippage)
}
const tx = await sdk.Swap.createSwapTransactionPayload(swapParams)
const result = await sdk.fullClient.signAndExecuteTransaction({
transaction: tx,
signer: keypair
})
Swap Parameters
Parameter
Type
Description
pool_id
string
Pool object ID
coinTypeA
string
First token type
coinTypeB
string
Second token type
a2b
boolean
Direction (true: A→B, false: B→A)
by_amount_in
boolean
Fix input (true) or output (false)
amount
string
Fixed amount
amount_limit
string
Slippage limit
swap_partner
string
Optional partner for fees
Swap Directions
Swap A to B
const params = {
pool_id: poolId,
coinTypeA: '0x2::sui::SUI',
coinTypeB: '0x...::usdc::USDC',
a2b: true, // SUI -> USDC
by_amount_in: true,
amount: '1000000000', // Input: 1 SUI
amount_limit: '990000' // Min output: 990 USDC
}
Swap B to A
const params = {
pool_id: poolId,
coinTypeA: '0x2::sui::SUI',
coinTypeB: '0x...::usdc::USDC',
a2b: false, // USDC -> SUI
by_amount_in: true,
amount: '1000000', // Input: 1000 USDC
amount_limit: '990000000' // Min output: 0.99 SUI
}
Fix Output Amount
Get exactly the amount you want:
const params = {
pool_id: poolId,
coinTypeA: '0x2::sui::SUI',
coinTypeB: '0x...::usdc::USDC',
a2b: true,
by_amount_in: false, // Fix output amount
amount: '1000000', // Want exactly 1000 USDC
amount_limit: '1010000000' // Max input: 1.01 SUI
}
Calculate Slippage
// 1. PreSwap to get expected amounts
const preSwap = await sdk.Swap.preswap({
pool,
coinTypeA: pool.coinTypeA,
coinTypeB: pool.coinTypeB,
decimalsA: 9,
decimalsB: 6,
a2b: true,
byAmountIn: true,
amount: '1000000000',
currentSqrtPrice: pool.current_sqrt_price
})
// 2. Apply slippage (1%)
const slippage = 0.01
const expectedOut = Number(preSwap.estimatedAmountOut)
const minOutput = Math.floor(expectedOut * (1 - slippage))
// 3. Create swap transaction
const swapParams = {
pool_id: pool.poolAddress,
coinTypeA: pool.coinTypeA,
coinTypeB: pool.coinTypeB,
a2b: true,
by_amount_in: true,
amount: '1000000000',
amount_limit: minOutput.toString()
}
const tx = await sdk.Swap.createSwapTransactionPayload(swapParams)
Gas Optimization (SUI)
Optimize gas when swapping SUI:
const gasConfig = {
byAmountIn: true,
slippage: new Percentage(1, 100), // 1%
decimalsA: 9,
decimalsB: 6,
swapTicks: ticks,
currentPool: pool
}
const tx = await sdk.Swap.createSwapTransactionPayload(
swapParams,
gasConfig
)
Partner Swaps
Route fees to partners:
const params = {
...swapParams,
swap_partner: '0xpartner...' // Partner object ID
}
const tx = await sdk.Swap.createSwapTransactionPayload(params)
Advanced Usage
Manual Coin Management
// Get swap transaction without auto-transfer
const { tx, coinABs } = await sdk.Swap.createSwapTransactionWithoutTransferCoinsPayload(swapParams)
// coinABs[0] = coin A after swap
// coinABs[1] = coin B after swap
// Custom handling
tx.transferObjects([coinABs[1]], recipient)
const result = await sdk.fullClient.signAndExecuteTransaction({
transaction: tx,
signer: keypair
})
Batch Swaps
const tx = new Transaction()
// First swap: SUI -> USDC
await sdk.Swap.createSwapTransactionPayload(swap1Params, undefined, tx)
// Second swap: USDC -> USDT
await sdk.Swap.createSwapTransactionPayload(swap2Params, undefined, tx)
// Execute both
const result = await sdk.fullClient.signAndExecuteTransaction({
transaction: tx,
signer: keypair
})
Complete Example
async function swapTokens() {
// 1. Get pool
const pool = await sdk.Pool.getPool(poolId)
// 2. Check current price
const price = TickMath.sqrtPriceX64ToPrice(
pool.current_sqrt_price,
9, // SUI decimals
6 // USDC decimals
)
console.log('Current price:', price.toString())
// 3. PreSwap simulation
const preSwap = await sdk.Swap.preswap({
pool,
coinTypeA: pool.coinTypeA,
coinTypeB: pool.coinTypeB,
decimalsA: 9,
decimalsB: 6,
a2b: true,
byAmountIn: true,
amount: '1000000000',
currentSqrtPrice: pool.current_sqrt_price
})
// 4. Check if swap is viable
if (preSwap.isExceed) {
throw new Error('Insufficient liquidity')
}
// 5. Create swap with 0.5% slippage
const minOutput = Math.floor(Number(preSwap.estimatedAmountOut) * 0.995)
const swapParams = {
pool_id: pool.poolAddress,
coinTypeA: pool.coinTypeA,
coinTypeB: pool.coinTypeB,
a2b: true,
by_amount_in: true,
amount: '1000000000',
amount_limit: minOutput.toString()
}
// 6. Execute swap
const tx = await sdk.Swap.createSwapTransactionPayload(swapParams)
const result = await sdk.fullClient.signAndExecuteTransaction({
transaction: tx,
signer: keypair
})
console.log('Swap completed:', result.digest)
}
Error Handling
try {
const tx = await sdk.Swap.createSwapTransactionPayload(swapParams)
} catch (error) {
if (error.code === 'InvalidSendAddress') {
sdk.senderAddress = '0x...'
}
if (error.message.includes('Insufficient balance')) {
console.log('Not enough tokens')
}
if (error.message.includes('Slippage exceeded')) {
console.log('Price moved, increase slippage')
}
}
Important Notes
Always use
amount_limit
for slippage protectionSDK automatically handles coin selection
Excess coins are returned to sender
Partner swaps share fees with partners
Gas optimization available for SUI swaps
Last updated