Documentation Index
Fetch the complete documentation index at: https://docs.arqitech.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Our routing engine intelligently finds the most efficient path for your swaps, whether direct or through multiple hops. The system considers factors like liquidity, fees, slippage, and execution time to optimize your trades.
Route Types
Direct Routes
Single-hop swaps within one provider:
Characteristics:
- Single transaction
- Lower complexity
- Predictable fees
- Faster execution
Example:
{
"providers": ["THORCHAIN"],
"legs": [], // No intermediate legs for direct routes
"estimatedTime": {
"total": 600 // ~10 minutes
}
}
Multi-Leg Routes
Swaps requiring multiple steps within a provider:
Characteristics:
- Multiple swaps in one transaction
- Optimized routing through liquidity pools
- Higher gas costs on EVM chains
- Better rates for illiquid pairs
DEX Aggregation Routes
Cross-provider routes combining different protocols:
Characteristics:
- Multiple transactions across chains
- Combines strengths of different providers
- Enables otherwise impossible swaps
- Requires careful tracking
Route Discovery Process
1. Asset Analysis
The routing engine first analyzes the assets:
const analyzeAssets = (sellAsset, buyAsset) => {
return {
sellChain: sellAsset.split('.')[0],
buyChain: buyAsset.split('.')[0],
isCrossChain: sellChain !== buyChain,
isNativeToNative: !sellAsset.includes('-') && !buyAsset.includes('-'),
requiresWrapping: needsWrapping(sellAsset, buyAsset)
};
};
2. Provider Selection
Based on asset analysis, relevant providers are identified:
const selectProviders = (analysis) => {
const providers = [];
if (analysis.isCrossChain) {
// Cross-chain providers
providers.push('THORCHAIN', 'CHAINFLIP', 'MAYACHAIN');
}
if (analysis.sellChain === 'SOL') {
providers.push('JUPITER');
}
if (isEVMChain(analysis.sellChain)) {
providers.push('ONEINCH');
}
return providers;
};
3. Route Calculation
Each provider calculates possible routes:
- Liquidity depth at each hop
- Price impact based on swap size
- Fee structure (network, protocol, LP fees)
- Execution time estimates
4. Route Optimization
Routes are ranked by:
- Output amount (after all fees)
- Execution speed
- Route complexity
- Security considerations
Each route includes rich metadata for decision-making:
Price Impact
{
"meta": {
"priceImpact": 0.15, // 0.15% price impact
"tags": ["BEST", "LOW_IMPACT"]
}
}
Thresholds:
< 0.1% - Negligible impact
0.1% - 1% - Low impact
1% - 3% - Moderate impact
3% - 5% - High impact
> 5% - Very high impact
Routes are tagged for easy identification:
| Tag | Description |
|---|
FASTEST | Quickest execution time |
CHEAPEST | Lowest fees |
BEST | Best overall value |
RECOMMENDED | Platform recommendation |
Time Estimates
{
"estimatedTime": {
"inbound": 600, // Time for source chain confirmation
"swap": 10, // Time for swap execution
"outbound": 180, // Time for destination delivery
"total": 790 // Total seconds (~13 minutes)
}
}
Complex Routing Examples
Cross-Chain Token to Token
Swapping USDC on Ethereum to USDC on Solana:
Route Structure:
{
"providers": ["THORCHAIN", "JUPITER"],
"legs": [
{
"provider": "THORCHAIN",
"sellAsset": "ETH.USDC",
"buyAsset": "SOL.SOL"
},
{
"provider": "JUPITER",
"sellAsset": "SOL.SOL",
"buyAsset": "SOL.USDC"
}
]
}
Arbitrage Routes
Finding profitable paths between assets:
// Triangular arbitrage detection
const findArbitrageRoute = async (startAsset, amount) => {
// Path 1: Asset A → B → C → A
const path1 = await getQuote({
sellAsset: startAsset,
buyAsset: 'ETH.USDC',
sellAmount: amount
});
const path2 = await getQuote({
sellAsset: 'ETH.USDC',
buyAsset: 'ETH.WBTC',
sellAmount: path1.routes[0].expectedBuyAmount
});
const path3 = await getQuote({
sellAsset: 'ETH.WBTC',
buyAsset: startAsset,
sellAmount: path2.routes[0].expectedBuyAmount
});
const profit = BigInt(path3.routes[0].expectedBuyAmount) - BigInt(amount);
return {
profitable: profit > 0,
profitAmount: profit.toString(),
route: [path1, path2, path3]
};
};
Route Selection Strategies
Optimizing for Speed
const getFastestRoute = (routes) => {
return routes
.filter(r => r.estimatedTime)
.sort((a, b) => a.estimatedTime.total - b.estimatedTime.total)[0];
};
Optimizing for Output
const getBestOutput = (routes) => {
return routes
.sort((a, b) =>
BigInt(b.expectedBuyAmount) - BigInt(a.expectedBuyAmount)
)[0];
};
Balanced Optimization
const getBalancedRoute = (routes) => {
// Score each route
const scored = routes.map(route => {
const outputScore = calculateOutputScore(route);
const timeScore = calculateTimeScore(route);
const feeScore = calculateFeeScore(route);
return {
route,
score: outputScore * 0.5 + timeScore * 0.3 + feeScore * 0.2
};
});
return scored.sort((a, b) => b.score - a.score)[0].route;
};
Streaming Routes
For large swaps, THORChain automatically creates streaming routes:
{
"meta": {
"streamingInterval": 10, // Blocks between swaps
"maxStreamingQuantity": 100, // Number of sub-swaps
"tags": ["STREAMING", "LOW_IMPACT"]
}
}
Benefits:
- Reduced price impact
- Better execution price
- Protection against manipulation
Trade-offs:
- Longer execution time
- Multiple transactions
- Complex tracking
Route Warnings
Routes may include warnings about potential issues:
{
"warnings": [
{
"code": "HIGH_PRICE_IMPACT",
"display": "High price impact",
"tooltip": "This swap will move the market price by >3%"
},
{
"code": "LOW_LIQUIDITY",
"display": "Low liquidity",
"tooltip": "Limited liquidity may result in partial fills"
}
]
}
Common warning codes:
HIGH_PRICE_IMPACT - Significant market impact
LOW_LIQUIDITY - Shallow pools
LONG_EXECUTION - Extended completion time
REQUIRES_APPROVAL - Token approval needed
EXPERIMENTAL_ROUTE - New or untested path
Route Execution
Pre-execution Checks
const validateRoute = (route) => {
const checks = {
hasInboundAddress: !!route.inboundAddress || !!route.targetAddress,
hasValidMemo: route.memo && route.memo.length > 0,
withinExpiration: !route.expiration || Date.now() < route.expiration,
acceptableSlippage: route.totalSlippageBps < 500 // 5%
};
return Object.values(checks).every(check => check);
};
Transaction Building
Different routes require different transaction formats:
// Native cross-chain (THORChain)
const nativeTx = {
to: route.inboundAddress,
value: sellAmount,
memo: route.memo
};
// EVM contract interaction
const evmTx = {
to: route.tx.to,
from: userAddress,
value: route.tx.value,
data: route.tx.data,
gasLimit: estimateGas(route.tx)
};
// Solana transaction
const solanaTx = {
instructions: route.tx.instructions,
signers: [userWallet],
feePayer: userWallet.publicKey
};
Route Monitoring
Track multi-leg route progress:
const trackMultiLegRoute = async (quoteId, routeIndex) => {
let completed = false;
while (!completed) {
const status = await fetch('/track', {
body: JSON.stringify({
hash: currentTxHash,
chainId: currentChainId,
quoteId,
routeIndex
})
});
if (status.data.isDexAgg) {
const { currentLeg, totalLegs, legs } = status.data.dexAggProgress;
console.log(`Leg ${currentLeg}/${totalLegs}`);
// Check if we need to execute next leg
if (currentLeg < totalLegs && legs[currentLeg].status === 'waiting_user_action') {
// Execute next leg transaction
await executeNextLeg(legs[currentLeg]);
}
}
completed = status.data.trackingStatus === 'completed';
await sleep(5000);
}
};
Best Practices
- Always check route validity before execution
- Monitor expiration times for time-sensitive routes
- Implement fallback routes for critical swaps
- Cache route calculations for repeated queries
- Use appropriate slippage based on route complexity
- Track all legs of multi-hop routes
- Handle partial fills gracefully