Quote System
The IXFI Protocol's quote system provides real-time, accurate pricing information across all supported DEXes and chains. It aggregates quotes from multiple sources, accounts for gas costs, and provides execution guarantees.
Overview
The quote system serves as the pricing engine for the IXFI Protocol, offering:
Multi-source aggregation from 35+ DEXes across 8+ chains
Real-time price discovery with sub-second latency
Gas-adjusted quotes including transaction costs
Execution guarantees with slippage protection
Quote comparison across different routes and DEXes
Architecture
Core Components
class IXFIQuoteSystem {
constructor() {
this.quoteSources = new Map(); // dexName -> QuoteSource
this.priceCache = new PriceCache();
this.gasOracle = new GasOracle();
this.slippageCalculator = new SlippageCalculator();
this.routeOptimizer = new RouteOptimizer();
}
async getQuote(request) {
const {
fromToken,
toToken,
amountIn,
fromChain,
toChain,
slippageTolerance = 0.005, // 0.5% default
gasPrice,
includeGasCosts = true,
preferredDEXes = [],
maxHops = 3
} = request;
// Validate input parameters
this.validateQuoteRequest(request);
// Get quotes from all relevant sources
const quotes = await this.aggregateQuotes(request);
// Filter and rank quotes
const rankedQuotes = await this.rankQuotes(quotes, request);
// Return best quotes with detailed breakdown
return {
bestQuote: rankedQuotes[0],
alternativeQuotes: rankedQuotes.slice(1, 5),
marketAnalysis: await this.getMarketAnalysis(request),
timestamp: Date.now(),
validUntil: Date.now() + 30000 // 30 seconds
};
}
async aggregateQuotes(request) {
const { fromToken, toToken, fromChain, toChain } = request;
const quotePromises = [];
// Same chain quotes - direct DEX swaps
if (fromChain === toChain) {
const chainDEXes = this.getChainDEXes(fromChain);
for (const dex of chainDEXes) {
if (await this.supportsPair(dex, fromToken, toToken)) {
quotePromises.push(
this.getDirectQuote(dex, request)
);
}
}
// Multi-hop quotes on same chain
if (request.maxHops > 1) {
quotePromises.push(
this.getMultiHopQuotes(request)
);
}
} else {
// Cross-chain quotes
quotePromises.push(
this.getCrossChainQuotes(request)
);
}
// Execute all quote requests in parallel
const results = await Promise.allSettled(quotePromises);
return results
.filter(result => result.status === 'fulfilled')
.map(result => result.value)
.flat()
.filter(quote => quote && quote.outputAmount > 0);
}
async getDirectQuote(dex, request) {
try {
const source = this.quoteSources.get(dex.name);
if (!source) {
throw new Error(`No quote source for DEX: ${dex.name}`);
}
const rawQuote = await source.getQuote(
request.fromToken,
request.toToken,
request.amountIn,
request.fromChain
);
return this.enrichQuote(rawQuote, dex, request);
} catch (error) {
console.warn(`Failed to get quote from ${dex.name}:`, error.message);
return null;
}
}
async enrichQuote(rawQuote, dex, request) {
const enrichedQuote = {
...rawQuote,
dexName: dex.name,
dexType: dex.type,
chainId: request.fromChain,
route: 'DIRECT',
timestamp: Date.now()
};
// Add gas cost estimation
if (request.includeGasCosts) {
const gasEstimate = await this.estimateGasCost(dex, request);
enrichedQuote.gasCost = gasEstimate;
enrichedQuote.netOutputAmount = enrichedQuote.outputAmount - gasEstimate.usdValue;
}
// Add slippage analysis
enrichedQuote.slippageAnalysis = await this.analyzeSlippage(dex, request);
// Add execution probability
enrichedQuote.executionProbability = await this.calculateExecutionProbability(dex, request);
// Add route breakdown
enrichedQuote.routeBreakdown = [{
step: 1,
dex: dex.name,
fromToken: request.fromToken,
toToken: request.toToken,
inputAmount: request.amountIn,
outputAmount: enrichedQuote.outputAmount,
fee: enrichedQuote.fee,
priceImpact: enrichedQuote.priceImpact
}];
return enrichedQuote;
}
async getMultiHopQuotes(request) {
const intermediateTokens = await this.getIntermediateTokens(request.fromChain);
const multiHopQuotes = [];
for (const intermediateToken of intermediateTokens) {
try {
// First hop: fromToken -> intermediateToken
const firstHopQuotes = await this.getHopQuotes(
request.fromToken,
intermediateToken,
request.amountIn,
request.fromChain
);
for (const firstHop of firstHopQuotes) {
// Second hop: intermediateToken -> toToken
const secondHopQuotes = await this.getHopQuotes(
intermediateToken,
request.toToken,
firstHop.outputAmount,
request.fromChain
);
for (const secondHop of secondHopQuotes) {
// Skip if using same DEX twice (unless it's beneficial)
if (firstHop.dexName === secondHop.dexName &&
!this.isBeneficialSameDEX(firstHop, secondHop)) {
continue;
}
const multiHopQuote = this.combineHops([firstHop, secondHop], request);
if (multiHopQuote.outputAmount > 0) {
multiHopQuotes.push(multiHopQuote);
}
}
}
} catch (error) {
console.warn(`Multi-hop quote failed for ${intermediateToken}:`, error.message);
}
}
return multiHopQuotes;
}
async getCrossChainQuotes(request) {
const crossChainQuotes = [];
const bridges = await this.getAvailableBridges(request.fromChain, request.toChain);
for (const bridge of bridges) {
try {
// Option 1: Swap then bridge
const swapThenBridge = await this.getSwapThenBridgeQuote(bridge, request);
if (swapThenBridge) {
crossChainQuotes.push(swapThenBridge);
}
// Option 2: Bridge then swap
const bridgeThenSwap = await this.getBridgeThenSwapQuote(bridge, request);
if (bridgeThenSwap) {
crossChainQuotes.push(bridgeThenSwap);
}
// Option 3: Bridge native asset (if applicable)
if (this.isNativeAsset(request.fromToken) || this.isNativeAsset(request.toToken)) {
const nativeBridge = await this.getNativeBridgeQuote(bridge, request);
if (nativeBridge) {
crossChainQuotes.push(nativeBridge);
}
}
} catch (error) {
console.warn(`Cross-chain quote failed for bridge ${bridge.name}:`, error.message);
}
}
return crossChainQuotes;
}
async getSwapThenBridgeQuote(bridge, request) {
// Step 1: Swap fromToken to bridgeable token on source chain
const bridgeableTokens = bridge.getSupportedTokens(request.fromChain);
let bestQuote = null;
for (const bridgeToken of bridgeableTokens) {
if (bridgeToken === request.fromToken) continue;
try {
// Get swap quote on source chain
const swapQuote = await this.getBestDirectQuote(
request.fromToken,
bridgeToken,
request.amountIn,
request.fromChain
);
if (!swapQuote) continue;
// Get bridge quote
const bridgeQuote = await bridge.getQuote(
bridgeToken,
swapQuote.outputAmount,
request.fromChain,
request.toChain
);
if (!bridgeQuote) continue;
// Get final swap quote on destination chain (if needed)
let finalQuote = null;
if (bridgeToken !== request.toToken) {
finalQuote = await this.getBestDirectQuote(
bridgeToken,
request.toToken,
bridgeQuote.outputAmount,
request.toChain
);
}
const finalOutputAmount = finalQuote
? finalQuote.outputAmount
: bridgeQuote.outputAmount;
const combinedQuote = {
outputAmount: finalOutputAmount,
route: 'SWAP_BRIDGE_SWAP',
steps: [
{ type: 'SWAP', ...swapQuote },
{ type: 'BRIDGE', ...bridgeQuote },
...(finalQuote ? [{ type: 'SWAP', ...finalQuote }] : [])
],
totalGasCost: this.calculateTotalGasCost([swapQuote, bridgeQuote, finalQuote].filter(Boolean)),
estimatedTime: swapQuote.estimatedTime + bridgeQuote.estimatedTime + (finalQuote?.estimatedTime || 0),
bridgeUsed: bridge.name,
reliability: Math.min(
swapQuote.reliability || 0.99,
bridgeQuote.reliability || 0.99,
finalQuote?.reliability || 0.99
)
};
if (!bestQuote || combinedQuote.outputAmount > bestQuote.outputAmount) {
bestQuote = combinedQuote;
}
} catch (error) {
console.warn(`Swap-then-bridge quote failed for ${bridgeToken}:`, error.message);
}
}
return bestQuote;
}
async rankQuotes(quotes, request) {
const rankedQuotes = [];
for (const quote of quotes) {
const score = await this.scoreQuote(quote, request);
rankedQuotes.push({ ...quote, score });
}
// Sort by score (higher is better)
rankedQuotes.sort((a, b) => b.score - a.score);
return rankedQuotes;
}
async scoreQuote(quote, request) {
const weights = request.weights || {
outputAmount: 0.4, // 40% - amount received
gasCost: 0.25, // 25% - gas efficiency
reliability: 0.15, // 15% - execution probability
speed: 0.1, // 10% - execution time
priceImpact: 0.1 // 10% - slippage
};
// Normalize metrics to 0-1 scale
const normalizedMetrics = {
outputAmount: this.normalizeOutputAmount(quote.outputAmount, request.amountIn),
gasCost: this.normalizeGasCost(quote.gasCost, quote.outputAmount),
reliability: quote.reliability || 0.99,
speed: this.normalizeSpeed(quote.estimatedTime),
priceImpact: 1 - Math.min(quote.priceImpact || 0, 0.1) / 0.1
};
// Calculate weighted score
let score = 0;
for (const [metric, weight] of Object.entries(weights)) {
score += normalizedMetrics[metric] * weight;
}
return score;
}
normalizeOutputAmount(outputAmount, inputAmount) {
// Higher output ratio is better (capped at 1.0 for safety)
return Math.min(outputAmount / inputAmount, 1.0);
}
normalizeGasCost(gasCost, outputAmount) {
if (!gasCost || !gasCost.usdValue) return 1.0;
// Lower gas cost ratio is better
const gasCostRatio = gasCost.usdValue / outputAmount;
return Math.max(0, 1 - Math.min(gasCostRatio * 10, 1));
}
normalizeSpeed(estimatedTime) {
// Faster is better (normalize against 1 hour max)
const maxTime = 3600; // 1 hour in seconds
return Math.max(0, 1 - Math.min(estimatedTime / maxTime, 1));
}
}
Quote Sources
DEX Integration
Each DEX has a specialized quote source that handles its unique characteristics:
class UniswapV2QuoteSource {
constructor(chainId, routerAddress) {
this.chainId = chainId;
this.routerAddress = routerAddress;
this.provider = this.getProvider(chainId);
this.routerContract = this.getRouterContract();
}
async getQuote(tokenA, tokenB, amountIn) {
try {
// Get reserves for the pair
const pair = await this.getPairAddress(tokenA, tokenB);
const reserves = await this.getReserves(pair);
// Calculate output using x*y=k formula
const outputAmount = this.calculateOutputAmount(
amountIn,
reserves.reserve0,
reserves.reserve1,
tokenA,
tokenB
);
// Calculate price impact
const priceImpact = this.calculatePriceImpact(
amountIn,
outputAmount,
reserves.reserve0,
reserves.reserve1
);
return {
outputAmount,
priceImpact,
fee: 0.003, // 0.3% for Uniswap V2
estimatedGas: 150000,
estimatedTime: 60, // 1 minute
reliability: 0.99,
dexType: 'UNISWAP_V2',
liquiditySource: pair
};
} catch (error) {
throw new Error(`Uniswap V2 quote failed: ${error.message}`);
}
}
calculateOutputAmount(amountIn, reserveIn, reserveOut, tokenA, tokenB) {
const amountInWithFee = amountIn * 997; // 0.3% fee
const numerator = amountInWithFee * reserveOut;
const denominator = (reserveIn * 1000) + amountInWithFee;
return numerator / denominator;
}
calculatePriceImpact(amountIn, amountOut, reserveIn, reserveOut) {
const priceBeforeTrade = reserveOut / reserveIn;
const priceAfterTrade = (reserveOut - amountOut) / (reserveIn + amountIn);
return Math.abs((priceAfterTrade - priceBeforeTrade) / priceBeforeTrade);
}
}
class UniswapV3QuoteSource {
constructor(chainId, quoterAddress) {
this.chainId = chainId;
this.quoterAddress = quoterAddress;
this.quoterContract = this.getQuoterContract();
}
async getQuote(tokenA, tokenB, amountIn, fee = 3000) {
try {
// Try different fee tiers
const feeTiers = [500, 3000, 10000];
let bestQuote = null;
for (const feeLevel of feeTiers) {
try {
const quote = await this.quoterContract.callStatic.quoteExactInputSingle(
tokenA,
tokenB,
feeLevel,
amountIn,
0 // sqrtPriceLimitX96
);
if (!bestQuote || quote.amountOut > bestQuote.outputAmount) {
bestQuote = {
outputAmount: quote.amountOut,
fee: feeLevel / 1000000, // Convert to decimal
priceImpact: await this.calculateV3PriceImpact(tokenA, tokenB, amountIn, quote.amountOut, feeLevel),
estimatedGas: 180000,
estimatedTime: 60,
reliability: 0.99,
dexType: 'UNISWAP_V3',
feeLevel: feeLevel
};
}
} catch (error) {
// Fee tier might not exist, continue with others
continue;
}
}
if (!bestQuote) {
throw new Error('No valid Uniswap V3 pools found');
}
return bestQuote;
} catch (error) {
throw new Error(`Uniswap V3 quote failed: ${error.message}`);
}
}
async calculateV3PriceImpact(tokenA, tokenB, amountIn, amountOut, fee) {
// Implementation would query pool state and calculate price impact
// This is simplified for demonstration
const poolContract = await this.getPoolContract(tokenA, tokenB, fee);
const slot0 = await poolContract.slot0();
// Calculate price impact based on current price and trade size
// Complex calculation involving tick math - simplified here
return amountIn / (amountIn + 1000000) * 0.01; // Simplified estimate
}
}
class CurveQuoteSource {
constructor(chainId) {
this.chainId = chainId;
this.provider = this.getProvider(chainId);
this.pools = this.getCurvePools();
}
async getQuote(tokenA, tokenB, amountIn) {
try {
// Find pool containing both tokens
const pool = await this.findPool(tokenA, tokenB);
if (!pool) {
throw new Error('No Curve pool found for token pair');
}
const poolContract = this.getPoolContract(pool.address);
const tokenAIndex = pool.tokens.indexOf(tokenA);
const tokenBIndex = pool.tokens.indexOf(tokenB);
// Get quote from Curve pool
const outputAmount = await poolContract.get_dy(
tokenAIndex,
tokenBIndex,
amountIn
);
// Calculate price impact (Curve has lower slippage for stablecoins)
const priceImpact = await this.calculateCurvePriceImpact(
pool,
tokenAIndex,
tokenBIndex,
amountIn,
outputAmount
);
return {
outputAmount,
priceImpact,
fee: pool.fee,
estimatedGas: 200000,
estimatedTime: 60,
reliability: 0.995, // Curve is very reliable
dexType: 'CURVE',
poolUsed: pool.name
};
} catch (error) {
throw new Error(`Curve quote failed: ${error.message}`);
}
}
async findPool(tokenA, tokenB) {
for (const pool of this.pools) {
if (pool.tokens.includes(tokenA) && pool.tokens.includes(tokenB)) {
return pool;
}
}
return null;
}
async calculateCurvePriceImpact(pool, indexA, indexB, amountIn, amountOut) {
// Curve has sophisticated bonding curve math
// This is a simplified calculation
const poolContract = this.getPoolContract(pool.address);
const balanceA = await poolContract.balances(indexA);
const balanceB = await poolContract.balances(indexB);
// Price impact is generally lower for Curve due to its design
const tradeSizeRatio = amountIn / balanceA;
return Math.min(tradeSizeRatio * 0.5, 0.02); // Max 2% impact
}
}
Gas Cost Estimation
class GasOracle {
constructor() {
this.gasPriceCache = new Map();
this.gasEstimateCache = new Map();
this.chainGasTokens = {
1: 'ETH',
137: 'MATIC',
56: 'BNB',
42161: 'ETH',
10: 'ETH',
43114: 'AVAX',
250: 'FTM',
8453: 'ETH'
};
}
async estimateGasCost(dex, operation, chainId, gasPrice) {
const cacheKey = `${dex.name}-${operation}-${chainId}`;
if (this.gasEstimateCache.has(cacheKey)) {
const cached = this.gasEstimateCache.get(cacheKey);
if (Date.now() - cached.timestamp < 300000) { // 5 minute cache
return this.calculateGasCostUSD(cached.gasUnits, gasPrice || cached.gasPrice, chainId);
}
}
const gasUnits = await this.getGasEstimate(dex, operation, chainId);
const currentGasPrice = gasPrice || await this.getCurrentGasPrice(chainId);
this.gasEstimateCache.set(cacheKey, {
gasUnits,
gasPrice: currentGasPrice,
timestamp: Date.now()
});
return this.calculateGasCostUSD(gasUnits, currentGasPrice, chainId);
}
async getGasEstimate(dex, operation, chainId) {
// Base gas estimates by DEX type and operation
const baseEstimates = {
'UNISWAP_V2': {
'SWAP': 150000,
'ADD_LIQUIDITY': 200000,
'REMOVE_LIQUIDITY': 180000
},
'UNISWAP_V3': {
'SWAP': 180000,
'ADD_LIQUIDITY': 250000,
'REMOVE_LIQUIDITY': 220000
},
'CURVE': {
'SWAP': 200000,
'ADD_LIQUIDITY': 300000,
'REMOVE_LIQUIDITY': 250000
},
'BALANCER': {
'SWAP': 220000,
'ADD_LIQUIDITY': 350000,
'REMOVE_LIQUIDITY': 300000
},
'SUSHISWAP': {
'SWAP': 150000,
'ADD_LIQUIDITY': 200000,
'REMOVE_LIQUIDITY': 180000
}
};
const estimate = baseEstimates[dex.type]?.[operation] || 200000;
// Apply chain-specific multipliers
const chainMultipliers = {
1: 1.0, // Ethereum
137: 1.2, // Polygon (more complex state)
56: 1.1, // BSC
42161: 1.0, // Arbitrum
10: 1.0, // Optimism
43114: 1.3, // Avalanche
250: 1.1, // Fantom
8453: 1.0 // Base
};
return Math.round(estimate * (chainMultipliers[chainId] || 1.0));
}
async getCurrentGasPrice(chainId) {
const cacheKey = `gasPrice-${chainId}`;
if (this.gasPriceCache.has(cacheKey)) {
const cached = this.gasPriceCache.get(cacheKey);
if (Date.now() - cached.timestamp < 60000) { // 1 minute cache
return cached.gasPrice;
}
}
let gasPrice;
try {
const provider = this.getProvider(chainId);
gasPrice = await provider.getGasPrice();
} catch (error) {
// Fallback to chain-specific defaults
const defaultGasPrices = {
1: ethers.utils.parseUnits('20', 'gwei'),
137: ethers.utils.parseUnits('30', 'gwei'),
56: ethers.utils.parseUnits('5', 'gwei'),
42161: ethers.utils.parseUnits('0.1', 'gwei'),
10: ethers.utils.parseUnits('0.001', 'gwei'),
43114: ethers.utils.parseUnits('25', 'gwei'),
250: ethers.utils.parseUnits('20', 'gwei'),
8453: ethers.utils.parseUnits('0.001', 'gwei')
};
gasPrice = defaultGasPrices[chainId] || ethers.utils.parseUnits('20', 'gwei');
}
this.gasPriceCache.set(cacheKey, {
gasPrice,
timestamp: Date.now()
});
return gasPrice;
}
async calculateGasCostUSD(gasUnits, gasPrice, chainId) {
const gasToken = this.chainGasTokens[chainId];
const gasTokenPriceUSD = await this.getTokenPriceUSD(gasToken);
const gasCostInToken = (gasUnits * gasPrice) / Math.pow(10, 18); // Convert to token units
const gasCostUSD = gasCostInToken * gasTokenPriceUSD;
return {
gasUnits,
gasPrice: gasPrice.toString(),
gasToken,
gasCostInToken,
usdValue: gasCostUSD
};
}
async getTokenPriceUSD(tokenSymbol) {
// Implementation would fetch from price oracle or DEX
// Using mock prices for demonstration
const mockPrices = {
'ETH': 2000,
'MATIC': 0.8,
'BNB': 300,
'AVAX': 25,
'FTM': 0.3
};
return mockPrices[tokenSymbol] || 1;
}
}
Quote Validation and Guarantees
class QuoteValidator {
constructor() {
this.validationRules = new Map();
this.setupValidationRules();
}
setupValidationRules() {
this.validationRules.set('MIN_OUTPUT', (quote, request) => {
const minOutput = request.amountIn * (1 - request.slippageTolerance);
return quote.outputAmount >= minOutput;
});
this.validationRules.set('MAX_PRICE_IMPACT', (quote, request) => {
const maxImpact = request.maxPriceImpact || 0.1; // 10% default
return (quote.priceImpact || 0) <= maxImpact;
});
this.validationRules.set('GAS_EFFICIENCY', (quote, request) => {
if (!quote.gasCost) return true;
const gasCostRatio = quote.gasCost.usdValue / quote.outputAmount;
return gasCostRatio <= 0.05; // Max 5% gas cost ratio
});
this.validationRules.set('LIQUIDITY_CHECK', async (quote, request) => {
// Verify sufficient liquidity exists
return await this.verifyLiquidity(quote, request);
});
this.validationRules.set('EXECUTION_PROBABILITY', (quote, request) => {
const minProbability = request.minExecutionProbability || 0.95;
return (quote.executionProbability || 0.99) >= minProbability;
});
}
async validateQuote(quote, request) {
const validationResult = {
isValid: true,
errors: [],
warnings: []
};
for (const [ruleName, rule] of this.validationRules) {
try {
const isValid = await rule(quote, request);
if (!isValid) {
validationResult.isValid = false;
validationResult.errors.push({
rule: ruleName,
message: this.getErrorMessage(ruleName, quote, request)
});
}
} catch (error) {
validationResult.warnings.push({
rule: ruleName,
message: `Validation failed: ${error.message}`
});
}
}
return validationResult;
}
getErrorMessage(ruleName, quote, request) {
const messages = {
'MIN_OUTPUT': `Output amount ${quote.outputAmount} below minimum required`,
'MAX_PRICE_IMPACT': `Price impact ${(quote.priceImpact * 100).toFixed(2)}% exceeds maximum`,
'GAS_EFFICIENCY': `Gas cost ratio too high`,
'LIQUIDITY_CHECK': `Insufficient liquidity for trade size`,
'EXECUTION_PROBABILITY': `Execution probability below minimum threshold`
};
return messages[ruleName] || `Validation failed for rule: ${ruleName}`;
}
async verifyLiquidity(quote, request) {
// Implementation would check actual DEX liquidity
// This is a simplified version
for (const step of quote.routeBreakdown || []) {
if (step.type === 'SWAP') {
const liquidity = await this.getDEXLiquidity(step.dex, step.fromToken, step.toToken);
if (liquidity < step.inputAmount * 2) { // Require 2x liquidity buffer
return false;
}
}
}
return true;
}
}
Market Analysis
class MarketAnalyzer {
async getMarketAnalysis(request) {
const analysis = {
priceComparison: await this.comparePricesAcrossDEXes(request),
liquidityAnalysis: await this.analyzeLiquidity(request),
volatilityMetrics: await this.getVolatilityMetrics(request),
marketTrends: await this.getMarketTrends(request),
optimalTiming: await this.analyzeOptimalTiming(request)
};
return analysis;
}
async comparePricesAcrossDEXes(request) {
const dexPrices = new Map();
const chainDEXes = this.getChainDEXes(request.fromChain);
for (const dex of chainDEXes) {
try {
const quote = await this.getSimpleQuote(dex, request);
if (quote) {
dexPrices.set(dex.name, {
price: quote.outputAmount / request.amountIn,
liquidity: quote.liquidity,
priceImpact: quote.priceImpact
});
}
} catch (error) {
// Skip failed quotes
}
}
const prices = Array.from(dexPrices.values()).map(d => d.price);
const avgPrice = prices.reduce((sum, price) => sum + price, 0) / prices.length;
const priceSpread = Math.max(...prices) - Math.min(...prices);
return {
dexPrices: Object.fromEntries(dexPrices),
averagePrice: avgPrice,
priceSpread,
spreadPercentage: priceSpread / avgPrice
};
}
async analyzeLiquidity(request) {
const liquidityData = {
totalLiquidity: 0,
liquidityDistribution: {},
depthAnalysis: {}
};
const chainDEXes = this.getChainDEXes(request.fromChain);
for (const dex of chainDEXes) {
try {
const liquidity = await this.getDEXLiquidity(
dex.name,
request.fromToken,
request.toToken
);
liquidityData.totalLiquidity += liquidity;
liquidityData.liquidityDistribution[dex.name] = liquidity;
// Analyze depth at different trade sizes
liquidityData.depthAnalysis[dex.name] = await this.analyzeDepth(
dex,
request,
[0.1, 0.5, 1, 2, 5] // Trade size multipliers
);
} catch (error) {
// Skip failed liquidity checks
}
}
return liquidityData;
}
async getVolatilityMetrics(request) {
const priceHistory = await this.getPriceHistory(
request.fromToken,
request.toToken,
request.fromChain,
24 // 24 hours
);
const prices = priceHistory.map(p => p.price);
const returns = [];
for (let i = 1; i < prices.length; i++) {
returns.push((prices[i] - prices[i-1]) / prices[i-1]);
}
const avgReturn = returns.reduce((sum, r) => sum + r, 0) / returns.length;
const variance = returns.reduce((sum, r) => sum + Math.pow(r - avgReturn, 2), 0) / returns.length;
const volatility = Math.sqrt(variance);
return {
dailyVolatility: volatility,
priceRange: {
min: Math.min(...prices),
max: Math.max(...prices),
current: prices[prices.length - 1]
},
trend: this.calculateTrend(prices)
};
}
calculateTrend(prices) {
const recentPrices = prices.slice(-10); // Last 10 data points
const firstPrice = recentPrices[0];
const lastPrice = recentPrices[recentPrices.length - 1];
const trendDirection = lastPrice > firstPrice ? 'UPWARD' : 'DOWNWARD';
const trendStrength = Math.abs((lastPrice - firstPrice) / firstPrice);
return {
direction: trendDirection,
strength: trendStrength,
classification: trendStrength > 0.05 ? 'STRONG' : trendStrength > 0.02 ? 'MODERATE' : 'WEAK'
};
}
}
Integration Examples
React Hook for Quotes
import { useState, useEffect, useCallback } from 'react';
import { IXFIQuoteSystem } from '@ixfi/sdk';
export function useIXFIQuote(request, options = {}) {
const [quote, setQuote] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [alternatives, setAlternatives] = useState([]);
const quoteSystem = new IXFIQuoteSystem(options.config);
const fetchQuote = useCallback(async () => {
if (!request.fromToken || !request.toToken || !request.amountIn) {
return;
}
setLoading(true);
setError(null);
try {
const result = await quoteSystem.getQuote(request);
setQuote(result.bestQuote);
setAlternatives(result.alternativeQuotes);
} catch (err) {
setError(err.message);
setQuote(null);
setAlternatives([]);
} finally {
setLoading(false);
}
}, [request, quoteSystem]);
useEffect(() => {
fetchQuote();
// Auto-refresh quotes every 30 seconds
const interval = setInterval(fetchQuote, 30000);
return () => clearInterval(interval);
}, [fetchQuote]);
return {
quote,
alternatives,
loading,
error,
refresh: fetchQuote
};
}
Node.js Integration
const { IXFIQuoteSystem } = require('@ixfi/sdk');
class TradingBot {
constructor(config) {
this.quoteSystem = new IXFIQuoteSystem(config);
this.minProfitThreshold = 0.005; // 0.5%
}
async findArbitrageOpportunities() {
const tokenPairs = this.getMonitoredPairs();
const opportunities = [];
for (const pair of tokenPairs) {
try {
const quotes = await this.quoteSystem.getQuote({
fromToken: pair.tokenA,
toToken: pair.tokenB,
amountIn: pair.testAmount,
fromChain: pair.chainId,
toChain: pair.chainId,
includeGasCosts: true
});
const reverseQuotes = await this.quoteSystem.getQuote({
fromToken: pair.tokenB,
toToken: pair.tokenA,
amountIn: quotes.bestQuote.outputAmount,
fromChain: pair.chainId,
toChain: pair.chainId,
includeGasCosts: true
});
const profit = reverseQuotes.bestQuote.outputAmount - pair.testAmount;
const profitPercentage = profit / pair.testAmount;
if (profitPercentage > this.minProfitThreshold) {
opportunities.push({
pair,
profit,
profitPercentage,
route1: quotes.bestQuote,
route2: reverseQuotes.bestQuote
});
}
} catch (error) {
console.warn(`Failed to check arbitrage for ${pair.tokenA}-${pair.tokenB}:`, error.message);
}
}
return opportunities.sort((a, b) => b.profitPercentage - a.profitPercentage);
}
}
Performance Metrics
The quote system maintains detailed performance metrics:
Response Time: Average < 500ms for simple quotes, < 2s for complex multi-chain routes
Accuracy: 99%+ quote accuracy within 1% of execution price
Coverage: 35+ DEXes across 8+ chains with 95%+ uptime
Cache Hit Rate: 85%+ for frequently requested pairs
Gas Estimation: Within 5% of actual gas usage
Best Practices
Cache Effectively: Use appropriate cache timeouts for different quote types
Handle Failures Gracefully: Always provide fallback quotes when primary sources fail
Validate Before Execution: Always re-validate quotes immediately before execution
Monitor Performance: Track quote accuracy and execution success rates
Update Regularly: Keep DEX integrations and gas estimates current
Resources
Last updated