Split trading
Split trading allows the SDK to split your trade across multiple DEXs to achieve better rates. This is particularly useful for large trades where a single DEX might not have sufficient liquidity.
Basic Split Trade
Enable split trading for potentially better rates.
const { MoroBestRate } = require('@moromoro/moro-sdk')
const { ethers } = require('ethers')
async function splitTradeExample() {
const provider = new ethers.providers.JsonRpcProvider(
'https://rpc.hyperliquid.xyz/evm'
)
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider)
const moroClient = new MoroBestRate(provider, 'hyperevm')
const HYPE = '0x5555555555555555555555555555555555555555'
const USDT = '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb'
const amountIn = ethers.utils.parseUnits('100', 18) // Large amount
const gasPrice = ethers.BigNumber.from('5000000000')
// Get quote with split enabled
const quote = await moroClient.getQuote(
HYPE,
USDT,
amountIn,
gasPrice,
{ enableSplit: true } // Enable split trading
)
console.log('Quote type:', quote.type)
if (quote.type === 'split') {
console.log('Trade will be split across', quote.paths.length, 'paths')
console.log('Volume distribution:', quote.volumns)
// Display each path
quote.paths.forEach((path, i) => {
console.log(`\nPath ${i + 1}:`)
console.log('- Volume:', quote.volumns[i] + '%')
console.log('- Routes:', path.routes.map(r => r.name).join(' -> '))
console.log('- Tokens:', path.tokens.length)
})
}
// Execute split trade
const minOut = ethers.BigNumber.from(quote.amountOut).mul(99).div(100)
const tx = await moroClient.swap(
signer,
HYPE,
USDT,
amountIn,
minOut,
quote
)
await tx.wait()
console.log('✓ Split trade completed')
}
splitTradeExample()Comparing Single vs Split Trade
Compare rates between single path and split trading.
const { MoroBestRate } = require('@moromoro/moro-sdk')
const { ethers } = require('ethers')
async function compareSingleVsSplit() {
const provider = new ethers.providers.JsonRpcProvider(
'https://rpc.hyperliquid.xyz/evm'
)
const moroClient = new MoroBestRate(provider, 'hyperevm')
const HYPE = '0x5555555555555555555555555555555555555555'
const USDT = '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb'
const amountIn = ethers.utils.parseUnits('100', 18)
const gasPrice = ethers.BigNumber.from('5000000000')
// Get single path quote
console.log('Getting single path quote...')
const singleQuote = await moroClient.getQuote(
HYPE,
USDT,
amountIn,
gasPrice,
{ enableSplit: false }
)
console.log('Single path:')
console.log('- Amount out:', ethers.utils.formatUnits(singleQuote.amountOut, 6), 'USDT')
console.log('- Type:', singleQuote.type)
// Get split quote
console.log('\nGetting split quote...')
const splitQuote = await moroClient.getQuote(
HYPE,
USDT,
amountIn,
gasPrice,
{ enableSplit: true }
)
console.log('Split trade:')
console.log('- Amount out:', ethers.utils.formatUnits(splitQuote.amountOut, 6), 'USDT')
console.log('- Type:', splitQuote.type)
if (splitQuote.type === 'split') {
console.log('- Number of paths:', splitQuote.paths.length)
}
// Calculate improvement
const singleAmount = parseFloat(ethers.utils.formatUnits(singleQuote.amountOut, 6))
const splitAmount = parseFloat(ethers.utils.formatUnits(splitQuote.amountOut, 6))
const improvement = ((splitAmount - singleAmount) / singleAmount * 100).toFixed(2)
console.log('\nComparison:')
console.log('- Improvement:', improvement + '%')
console.log('- Better option:', splitAmount > singleAmount ? 'Split' : 'Single')
}
compareSingleVsSplit()Inspecting Split Paths
Detailed inspection of split trade paths.
const { MoroBestRate } = require('@moromoro/moro-sdk')
const { ethers } = require('ethers')
async function inspectSplitPaths() {
const provider = new ethers.providers.JsonRpcProvider(
'https://rpc.hyperliquid.xyz/evm'
)
const moroClient = new MoroBestRate(provider, 'hyperevm')
const HYPE = '0x5555555555555555555555555555555555555555'
const USDT = '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb'
const amountIn = ethers.utils.parseUnits('100', 18)
const gasPrice = ethers.BigNumber.from('5000000000')
const quote = await moroClient.getQuote(
HYPE,
USDT,
amountIn,
gasPrice,
{ enableSplit: true }
)
if (quote.type !== 'split') {
console.log('Trade is not split')
return
}
console.log('=== Split Trade Analysis ===\n')
console.log('Total paths:', quote.paths.length)
console.log('Total output:', ethers.utils.formatUnits(quote.amountOut, 6), 'USDT')
console.log('Block number:', quote.blockNumber)
quote.paths.forEach((path, index) => {
console.log(`\n--- Path ${index + 1} ---`)
console.log('Volume allocation:', quote.volumns[index] + '%')
console.log('Deposit address:', quote.depositAddresses[index])
console.log('Number of hops:', path.routes.length)
console.log('\nRoute details:')
path.routes.forEach((route, i) => {
console.log(` Hop ${i + 1}:`)
console.log(` - DEX: ${route.name}`)
console.log(` - Address: ${route.address}`)
console.log(` - Model: ${route.model}`)
console.log(` - Gas: ${route.gas}`)
})
console.log('\nToken path:')
path.tokens.forEach((token, i) => {
console.log(` ${i}: ${token}`)
})
})
console.log('\n=== Gas Fees ===')
console.log(JSON.stringify(quote.gasFees, null, 2))
}
inspectSplitPaths()Large Trade with Split
Example of a large trade benefiting from split trading.
const { MoroBestRate } = require('@moromoro/moro-sdk')
const { ethers } = require('ethers')
async function largeTrade() {
const provider = new ethers.providers.JsonRpcProvider(
'https://rpc.hyperliquid.xyz/evm'
)
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider)
const moroClient = new MoroBestRate(provider, 'hyperevm')
const HYPE = '0x5555555555555555555555555555555555555555'
const USDT = '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb'
// Large trade amount
const amountIn = ethers.utils.parseUnits('1000', 18) // 1000 HYPE
const gasPrice = ethers.BigNumber.from('5000000000')
console.log('Executing large trade of', ethers.utils.formatEther(amountIn), 'HYPE')
// Always use split for large trades
const quote = await moroClient.getQuote(
HYPE,
USDT,
amountIn,
gasPrice,
{ enableSplit: true }
)
console.log('\nQuote details:')
console.log('- Expected output:', ethers.utils.formatUnits(quote.amountOut, 6), 'USDT')
if (quote.type === 'split') {
console.log('- Split across', quote.paths.length, 'paths')
console.log('- Distribution:', quote.volumns.map(v => v + '%').join(', '))
// Calculate effective price
const inputAmount = parseFloat(ethers.utils.formatEther(amountIn))
const outputAmount = parseFloat(ethers.utils.formatUnits(quote.amountOut, 6))
const pricePerHYPE = outputAmount / inputAmount
console.log('- Effective price:', pricePerHYPE.toFixed(4), 'USDT per HYPE')
}
// Use tighter slippage for large trades (0.5%)
const minOut = ethers.BigNumber.from(quote.amountOut).mul(995).div(1000)
console.log('- Minimum output (0.5% slippage):', ethers.utils.formatUnits(minOut, 6), 'USDT')
// Execute
const tx = await moroClient.swap(
signer,
HYPE,
USDT,
amountIn,
minOut,
quote
)
console.log('\nTransaction:', tx.hash)
const receipt = await tx.wait()
console.log('✓ Large trade completed in block', receipt.blockNumber)
}
largeTrade()Optimal Split Configuration
Customize split trading parameters for better performance.
const { MoroBestRate } = require('@moromoro/moro-sdk')
const { ethers } = require('ethers')
async function optimizedSplitTrading() {
const provider = new ethers.providers.JsonRpcProvider(
'https://rpc.hyperliquid.xyz/evm'
)
// Configure with custom split parameters
const moroClient = new MoroBestRate(provider, 'hyperevm', {
maxCandidatePathsCount: 30, // Increase for more path options
maxCallsPerFetch: 100 // Batch size for RPC calls
})
const HYPE = '0x5555555555555555555555555555555555555555'
const USDT = '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb'
const amountIn = ethers.utils.parseUnits('500', 18)
const gasPrice = ethers.BigNumber.from('5000000000')
console.log('Getting optimized split quote...')
const startTime = Date.now()
const quote = await moroClient.getQuote(
HYPE,
USDT,
amountIn,
gasPrice,
{ enableSplit: true }
)
const endTime = Date.now()
console.log('Quote generated in', endTime - startTime, 'ms')
console.log('Amount out:', ethers.utils.formatUnits(quote.amountOut, 6), 'USDT')
if (quote.type === 'split') {
console.log('Optimized across', quote.paths.length, 'paths')
}
}
optimizedSplitTrading()Handling Split Trade Failures
Error handling specific to split trades.
const { MoroBestRate } = require('@moromoro/moro-sdk')
const { ethers } = require('ethers')
async function robustSplitTrade() {
const provider = new ethers.providers.JsonRpcProvider(
'https://rpc.hyperliquid.xyz/evm'
)
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider)
const moroClient = new MoroBestRate(provider, 'hyperevm')
const HYPE = '0x5555555555555555555555555555555555555555'
const USDT = '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb'
const amountIn = ethers.utils.parseUnits('100', 18)
const gasPrice = ethers.BigNumber.from('5000000000')
try {
// Try split trade first
console.log('Attempting split trade...')
const splitQuote = await moroClient.getQuote(
HYPE,
USDT,
amountIn,
gasPrice,
{ enableSplit: true }
)
const minOut = ethers.BigNumber.from(splitQuote.amountOut).mul(99).div(100)
const tx = await moroClient.swap(
signer,
HYPE,
USDT,
amountIn,
minOut,
splitQuote
)
await tx.wait()
console.log('✓ Split trade successful')
} catch (error) {
console.log('Split trade failed:', error.message)
console.log('Falling back to single path trade...')
try {
// Fallback to single path
const singleQuote = await moroClient.getQuote(
HYPE,
USDT,
amountIn,
gasPrice,
{ enableSplit: false }
)
const minOut = ethers.BigNumber.from(singleQuote.amountOut)
.mul(98)
.div(100) // More slippage for fallback
const tx = await moroClient.swap(
signer,
HYPE,
USDT,
amountIn,
minOut,
singleQuote
)
await tx.wait()
console.log('✓ Fallback single trade successful')
} catch (fallbackError) {
console.error('Both split and single trades failed')
throw fallbackError
}
}
}
robustSplitTrade()Analyzing Split Efficiency
Analyze whether split trading provides value.
async function analyzeSplitEfficiency(amountIn) {
const provider = new ethers.providers.JsonRpcProvider(
'https://rpc.hyperliquid.xyz/evm'
)
const moroClient = new MoroBestRate(provider, 'hyperevm')
const HYPE = '0x5555555555555555555555555555555555555555'
const USDT = '0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb'
const gasPrice = ethers.BigNumber.from('5000000000')
// Get both quotes
const [singleQuote, splitQuote] = await Promise.all([
moroClient.getQuote(HYPE, USDT, amountIn, gasPrice, { enableSplit: false }),
moroClient.getQuote(HYPE, USDT, amountIn, gasPrice, { enableSplit: true })
])
const singleOut = parseFloat(ethers.utils.formatUnits(singleQuote.amountOut, 6))
const splitOut = parseFloat(ethers.utils.formatUnits(splitQuote.amountOut, 6))
const improvement = ((splitOut - singleOut) / singleOut * 100).toFixed(4)
console.log({
amountIn: ethers.utils.formatEther(amountIn),
singlePathOutput: singleOut,
splitPathOutput: splitOut,
improvement: improvement + '%',
worthSplitting: parseFloat(improvement) > 0.1 // 0.1% threshold
})
return parseFloat(improvement)
}
// Test different amounts
async function testDifferentAmounts() {
const amounts = [
ethers.utils.parseUnits('10', 18),
ethers.utils.parseUnits('50', 18),
ethers.utils.parseUnits('100', 18),
ethers.utils.parseUnits('500', 18),
ethers.utils.parseUnits('1000', 18)
]
for (const amount of amounts) {
console.log('\n=== Testing amount:', ethers.utils.formatEther(amount), 'HYPE ===')
await analyzeSplitEfficiency(amount)
}
}
testDifferentAmounts()When to Use Split Trading
General guidelines:
function shouldUseSplit(amountInUSD) {
// Rule of thumb for when to enable split trading
if (amountInUSD < 100) {
return false // Small trades: gas cost may outweigh benefits
} else if (amountInUSD < 1000) {
return true // Medium trades: likely beneficial
} else {
return true // Large trades: almost always beneficial
}
}
// Usage
const amountIn = ethers.utils.parseUnits('100', 18)
const hypePrice = 2.50 // USD
const tradeValueUSD = parseFloat(ethers.utils.formatEther(amountIn)) * hypePrice
const enableSplit = shouldUseSplit(tradeValueUSD)
console.log('Trade value:', tradeValueUSD, 'USD')
console.log('Use split trading:', enableSplit)
const quote = await moroClient.getQuote(
HYPE,
USDT,
amountIn,
gasPrice,
{ enableSplit }
)See Also
Simple Swap Examples
Multi-Chain Examples