Docs
Docs/Configuration

Configuration

Tuning the MNMX routing engine for different use cases and environments.

Full Configuration Reference

Every configurable parameter with its type, default value, and description:

typescript
1const router = new MnmxRouter({
2 // ─── Routing Strategy ────────────────────────────────
3 strategy: 'minimax', // minimax | cheapest | fastest | safest
4
5 // ─── Tolerance ────────────────────────────────────────
6 slippageTolerance: 0.5, // Max acceptable slippage (%)
7 timeout: 30_000, // Max quote computation time (ms)
8 executionTimeout: 1_200_000, // Max total execution time (ms) — 20 min
9 quoteRefreshInterval: 10_000, // Auto-refresh quotes every 10s
10
11 // ─── Path Constraints ────────────────────────────────
12 maxHops: 3, // Maximum bridge hops (swaps don't count)
13 maxSwapsPerHop: 2, // Maximum swap steps per chain
14 maxCandidatePaths: 50, // Cap on raw candidate paths
15 maxEvaluatedPaths: 15, // Cap on paths after pruning
16
17 // ─── Bridge Selection ────────────────────────────────
18 bridges: ['wormhole', 'debridge', 'layerzero', 'allbridge'],
19 excludeBridges: [], // Bridges to exclude
20 customBridges: [], // Custom BridgeAdapter instances
21
22 // ─── Scoring Weights (must sum to 1.0) ────────────────
23 weights: {
24 fees: 0.25, // Total fee weight
25 slippage: 0.25, // Slippage impact weight
26 speed: 0.15, // Transfer speed weight
27 reliability: 0.20, // Bridge reliability weight
28 mevExposure: 0.15, // MEV exposure weight
29 },
30
31 // ─── Adversarial Model ────────────────────────────────
32 adversarialModel: {
33 slippageMultiplier: 2.0, // Worst-case slippage = quoted * 2.0
34 gasMultiplier: 1.5, // Worst-case gas = current * 1.5
35 bridgeDelayMultiplier: 3.0, // Worst-case delay = median * 3.0
36 mevExtraction: 0.003, // 0.3% of value on unprotected swaps
37 priceMovement: 0.005, // 0.5% adverse price change per bridge hop
38 },
39
40 // ─── Chain RPC Configuration ──────────────────────────
41 chains: {
42 ethereum: {
43 rpc: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',
44 fallbackRpcs: [
45 'https://mainnet.infura.io/v3/YOUR_KEY',
46 'https://rpc.ankr.com/eth',
47 ],
48 blockConfirmations: 2,
49 maxGasPrice: '100000000000', // 100 gwei max gas price
50 },
51 solana: {
52 rpc: 'https://mainnet.helius-rpc.com/?api-key=YOUR_KEY',
53 fallbackRpcs: [
54 'https://api.mainnet-beta.solana.com',
55 ],
56 commitment: 'confirmed',
57 maxComputeUnits: 400_000,
58 },
59 arbitrum: {
60 rpc: 'https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY',
61 fallbackRpcs: [
62 'https://arb1.arbitrum.io/rpc',
63 ],
64 blockConfirmations: 1,
65 },
66 base: {
67 rpc: 'https://mainnet.base.org',
68 fallbackRpcs: [],
69 blockConfirmations: 1,
70 },
71 polygon: {
72 rpc: 'https://polygon-mainnet.g.alchemy.com/v2/YOUR_KEY',
73 fallbackRpcs: [
74 'https://polygon-rpc.com',
75 ],
76 blockConfirmations: 30,
77 },
78 bsc: {
79 rpc: 'https://bsc-dataseed1.binance.org',
80 fallbackRpcs: [
81 'https://bsc-dataseed2.binance.org',
82 'https://bsc-dataseed3.binance.org',
83 ],
84 blockConfirmations: 15,
85 },
86 avalanche: {
87 rpc: 'https://api.avax.network/ext/bc/C/rpc',
88 fallbackRpcs: [],
89 blockConfirmations: 1,
90 },
91 optimism: {
92 rpc: 'https://mainnet.optimism.io',
93 fallbackRpcs: [],
94 blockConfirmations: 1,
95 },
96 },
97
98 // ─── Cache Configuration ──────────────────────────────
99 cache: {
100 driver: 'memory', // 'memory' | 'redis'
101 redis: {
102 host: 'localhost',
103 port: 6379,
104 password: undefined,
105 keyPrefix: 'mnmx:',
106 db: 0,
107 },
108 ttl: {
109 bridgeQuote: 10_000, // Bridge quotes: 10s
110 dexQuote: 5_000, // DEX quotes: 5s
111 gasEstimate: 15_000, // Gas estimates: 15s
112 bridgeHealth: 60_000, // Health checks: 60s
113 poolReserves: 30_000, // Pool reserves: 30s
114 tokenPrice: 10_000, // Token prices: 10s
115 chainGraph: 300_000, // Chain topology: 5 min
116 tokenMetadata: 86_400_000, // Token metadata: 24h
117 },
118 maxMemoryMB: 256,
119 evictionPolicy: 'lru',
120 },
121
122 // ─── Logging ───────────────────────────────────────────
123 logLevel: 'info', // 'debug' | 'info' | 'warn' | 'error'
124 logFormat: 'json', // 'json' | 'text'
125 logDestination: 'stdout', // 'stdout' | 'file' | 'none'
126 logFile: undefined, // Path to log file (when logDestination='file')
127
128 // ─── Telemetry ─────────────────────────────────────────
129 telemetry: {
130 enabled: true,
131 collectExecutionMetrics: true,
132 collectQuoteMetrics: true,
133 collectBridgeMetrics: true,
134 metricsInterval: 60_000, // Aggregate metrics every 60s
135 },
136
137 // ─── Gas Management ────────────────────────────────────
138 gas: {
139 bufferMultiplier: 1.15, // Add 15% buffer to gas estimates
140 maxPriorityFeeGwei: 3, // Max EIP-1559 priority fee
141 useEIP1559: true, // Use EIP-1559 tx format when available
142 speedUpAfter: 60_000, // Speed up stuck tx after 60s
143 speedUpGasMultiplier: 1.3, // Increase gas by 30% on speed-up
144 },
145
146 // ─── Token Approvals ───────────────────────────────────
147 approvals: {
148 usePermit2: true, // Use Permit2 when available
149 infiniteApproval: false, // Use infinite approval (less gas, less safe)
150 revokeAfterExecution: false, // Revoke approval after execution
151 },
152});

Strategy Profiles

Preset configurations for common use cases. Each strategy adjusts the scoring weights to prioritize different trade-offs:

StrategyFeesSlippageSpeedReliabilityMEVUse Case
minimax0.250.250.150.200.15Best guaranteed outcome (default)
cheapest0.450.300.050.100.10Minimize total cost
fastest0.100.150.500.150.10Minimize transfer time
safest0.100.150.100.400.25Maximize security and reliability

Custom Strategy

Define custom scoring weights for specialized use cases:

typescript
1// Whale strategy: prioritize low slippage and reliability for large transfers
2const router = new MnmxRouter({
3 strategy: 'minimax',
4 weights: {
5 fees: 0.10, // Fees are negligible relative to transfer size
6 slippage: 0.35, // Slippage is the dominant cost for large amounts
7 speed: 0.05, // Speed doesn't matter for large transfers
8 reliability: 0.30, // Cannot afford a failed bridge on $500K+
9 mevExposure: 0.20, // MEV extraction scales with transfer size
10 },
11});
12
13// DeFi arbitrage strategy: speed is everything
14const router = new MnmxRouter({
15 strategy: 'fastest',
16 weights: {
17 fees: 0.15,
18 slippage: 0.15,
19 speed: 0.55, // Arbitrage windows close fast
20 reliability: 0.10,
21 mevExposure: 0.05,
22 },
23 maxHops: 2, // Fewer hops = faster
24 timeout: 5_000, // Quick quote timeout
25});
26
27// Conservative treasury strategy: safety above all
28const router = new MnmxRouter({
29 strategy: 'safest',
30 weights: {
31 fees: 0.05,
32 slippage: 0.15,
33 speed: 0.05,
34 reliability: 0.45, // Only use the most reliable bridges
35 mevExposure: 0.30, // Minimize all extraction risk
36 },
37 bridges: ['wormhole'], // Only use the most established bridge
38 adversarialModel: {
39 slippageMultiplier: 3.0, // Very conservative
40 gasMultiplier: 2.0,
41 bridgeDelayMultiplier: 5.0,
42 mevExtraction: 0.005,
43 priceMovement: 0.01,
44 },
45});

Adversarial Model Tuning

The adversarial model controls how the minimax engine estimates worst-case outcomes. Adjust based on your risk tolerance:

ParameterTypeDefaultConservativeAggressiveDescription
slippageMultipliernumber2.0x3.0x1.5xMultiplier applied to quoted slippage for worst-case estimate
gasMultipliernumber1.5x2.0x1.2xMultiplier applied to current gas price for surge modeling
bridgeDelayMultipliernumber3.0x5.0x2.0xMultiplier applied to median bridge confirmation time
mevExtractionnumber0.3%0.5%0.1%Percentage of swap value assumed extracted by MEV bots
priceMovementnumber0.5%1.0%0.2%Adverse price change assumed per bridge transit period
Higher multipliers = more conservative routing. The engine will prefer routes with lower variance over routes with higher expected value. This is appropriate when protecting large transfers. For small, frequent transfers where individual outcomes matter less, lower multipliers will produce slightly better average results.

When to Adjust the Adversarial Model

ScenarioRecommended Adjustment
Large transfers (>$100K)Increase slippageMultiplier to 3.0x, mevExtraction to 0.5%
Stablecoin-to-stablecoinDecrease priceMovement to 0.1% (pegged assets have minimal price risk)
During high network congestionIncrease gasMultiplier to 2.5x, bridgeDelayMultiplier to 5.0x
Using MEV-protected RPCs (Flashbots)Decrease mevExtraction to 0.05%
Small, frequent transfers (<$1K)Decrease all multipliers by 30% for better average outcomes
Time-sensitive (arbitrage)Decrease bridgeDelayMultiplier to 1.5x, increase speed weight

Bridge Configuration

Include or exclude specific bridges, or configure bridge-specific parameters:

typescript
1// Only use specific bridges
2const router = new MnmxRouter({
3 bridges: ['wormhole', 'debridge'],
4});
5
6// Exclude specific bridges
7const router = new MnmxRouter({
8 excludeBridges: ['allbridge'],
9});
10
11// Per-route bridge exclusion
12const route = await router.findRoute({
13 from: { chain: 'ethereum', token: 'ETH', amount: '1.0' },
14 to: { chain: 'solana', token: 'SOL' },
15 options: { excludeBridges: ['layerzero'] },
16});
17
18// Bridge-specific configuration
19const router = new MnmxRouter({
20 bridgeConfig: {
21 wormhole: {
22 guardianRpc: 'https://wormhole-v2-mainnet-api.certus.one',
23 consistencyLevel: 'finalized', // 'instant' | 'safe' | 'finalized'
24 relayerEnabled: true,
25 },
26 debridge: {
27 dlnApiUrl: 'https://dln.debridge.finance',
28 minMakerLiquidity: '10000', // Minimum maker liquidity in USD
29 preferDln: true, // Prefer DLN over native bridge
30 },
31 layerzero: {
32 dvnConfig: {
33 required: ['google-cloud', 'polyhedra'],
34 optional: ['animoca', 'bware', 'horizen'],
35 threshold: 2,
36 },
37 },
38 allbridge: {
39 minPoolUtilization: 20, // Skip pools below 20% utilization
40 maxSlippageFromVirtualPrice: 2, // Max 2% virtual price deviation
41 },
42 },
43});

Chain Configuration

Configure RPC endpoints, confirmation requirements, and gas limits per chain:

typescript
1const router = new MnmxRouter({
2 chains: {
3 ethereum: {
4 rpc: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',
5 fallbackRpcs: [
6 'https://mainnet.infura.io/v3/YOUR_KEY',
7 'https://rpc.ankr.com/eth',
8 ],
9 blockConfirmations: 2, // Wait for 2 block confirmations
10 maxGasPrice: '100000000000', // 100 gwei — reject tx if gas exceeds this
11 chainId: 1,
12 },
13 solana: {
14 rpc: 'https://mainnet.helius-rpc.com/?api-key=YOUR_KEY',
15 fallbackRpcs: [
16 'https://api.mainnet-beta.solana.com',
17 ],
18 commitment: 'confirmed', // 'processed' | 'confirmed' | 'finalized'
19 maxComputeUnits: 400_000, // Max compute units per transaction
20 priorityFee: 10_000, // Priority fee in microlamports
21 },
22 arbitrum: {
23 rpc: 'https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY',
24 fallbackRpcs: [
25 'https://arb1.arbitrum.io/rpc',
26 ],
27 blockConfirmations: 1,
28 maxGasPrice: '1000000000', // 1 gwei (Arbitrum gas is cheap)
29 },
30 },
31});

RPC Fallback Behavior

When the primary RPC endpoint fails, the system automatically tries fallback endpoints in order. Each endpoint is tracked for latency and error rate:

BehaviorThresholdAction
Primary endpoint timeout5 secondsTry first fallback
Primary error rate > 10%Rolling 100 requestsDemote to fallback, promote next
All endpoints failAll return errorsThrow AllEndpointsFailedError
Latency > 3x medianRolling 50 requestsFlag as degraded, prefer faster endpoints

Cache Configuration

The state cache reduces RPC calls and improves quote latency. Two backends are supported:

typescript
1// In-memory cache (default) — suitable for single-instance deployments
2const router = new MnmxRouter({
3 cache: {
4 driver: 'memory',
5 maxMemoryMB: 256,
6 evictionPolicy: 'lru',
7 },
8});
9
10// Redis cache — required for multi-instance deployments
11const router = new MnmxRouter({
12 cache: {
13 driver: 'redis',
14 redis: {
15 host: process.env.REDIS_HOST || 'localhost',
16 port: 6379,
17 password: process.env.REDIS_PASSWORD,
18 keyPrefix: 'mnmx:state:',
19 db: 0,
20 tls: process.env.NODE_ENV === 'production',
21 maxRetriesPerRequest: 3,
22 connectTimeout: 5_000,
23 },
24 maxMemoryMB: 512,
25 },
26});

Cache TTL Reference

Data TypeDefault TTLMin RecommendedMax RecommendedImpact of Staleness
Bridge quotes10s5s30sStale quotes lead to slippage exceeded errors on execution
DEX quotes5s2s15sStale quotes produce inaccurate slippage estimates
Gas estimates15s5s60sStale estimates cause underpaid gas (tx stuck) or overpaid gas
Bridge health60s30s300sStale health data may route through degraded bridges
Pool reserves30s5s60sStale reserves cause incorrect slippage calculations
Token prices10s5s30sStale prices affect USD-normalized scoring
Chain graph5 min1 min15 minNew bridges/tokens not discovered until refresh
Token metadata24h1h7 daysMinimal — decimals and addresses rarely change

Gas Management

Fine-tune gas estimation and submission behavior:

typescript
1const router = new MnmxRouter({
2 gas: {
3 // Gas estimation
4 bufferMultiplier: 1.15, // 15% buffer on gas estimates
5 maxPriorityFeeGwei: 3, // Max EIP-1559 priority fee
6
7 // Transaction format
8 useEIP1559: true, // Use EIP-1559 when available
9
10 // Stuck transaction handling
11 speedUpAfter: 60_000, // Speed up if not confirmed after 60s
12 speedUpGasMultiplier: 1.3, // Increase gas by 30% on speed-up
13 maxSpeedUpAttempts: 3, // Maximum speed-up attempts
14
15 // Chain-specific gas limits
16 perChain: {
17 ethereum: {
18 maxGasPriceGwei: 100, // Reject if gas > 100 gwei
19 maxTransactionCostUSD: 50, // Reject if tx cost > $50
20 },
21 solana: {
22 maxComputeUnits: 400_000,
23 priorityFeeLamports: 10_000,
24 },
25 arbitrum: {
26 maxGasPriceGwei: 5, // Arbitrum gas is cheap
27 maxTransactionCostUSD: 2,
28 },
29 },
30 },
31});

Token Approval Configuration

typescript
1const router = new MnmxRouter({
2 approvals: {
3 // Use Permit2 for gasless approvals when supported
4 usePermit2: true,
5
6 // Infinite approval: approve max uint256 once, skip future approvals
7 // Saves ~21,000 gas per future transfer but grants permanent access
8 infiniteApproval: false,
9
10 // Revoke approval after execution completes
11 // Costs extra gas but ensures no residual approvals
12 revokeAfterExecution: false,
13
14 // Approval amount when not using infinite approval
15 // 'exact': approve exactly the transfer amount (safest)
16 // 'padded': approve 1.1x the amount (handles slight quote changes)
17 approvalMode: 'padded',
18 },
19});
Security note: Enabling infiniteApprovalgrants permanent token access to bridge and DEX contracts. While this saves gas on repeated transfers, it increases exposure if a contract is compromised. For high-security deployments, keep this disabled and use revokeAfterExecution: true.

Environment Variables

All configuration options can be set via environment variables. Environment variables override programmatic configuration:

VariableTypeDefaultDescription
MNMX_STRATEGYstringminimaxDefault routing strategy
MNMX_MAX_HOPSnumber3Maximum intermediate bridge hops
MNMX_TIMEOUTnumber30000Quote computation timeout (ms)
MNMX_EXEC_TIMEOUTnumber1200000Execution timeout (ms)
MNMX_SLIPPAGEnumber0.5Default slippage tolerance (%)
MNMX_LOG_LEVELstringinfoLogging level (debug/info/warn/error)
MNMX_LOG_FORMATstringjsonLog format (json/text)
MNMX_CACHE_DRIVERstringmemoryCache backend (memory/redis)
MNMX_CACHE_MAX_MBnumber256Maximum cache memory (MB)
MNMX_BRIDGESstringallComma-separated bridge list
MNMX_GAS_BUFFERnumber1.15Gas estimate buffer multiplier
MNMX_USE_EIP1559booleantrueUse EIP-1559 transactions
MNMX_TELEMETRYbooleantrueEnable telemetry collection
ETH_RPC_URLstring-Ethereum RPC endpoint
SOL_RPC_URLstring-Solana RPC endpoint
ARB_RPC_URLstring-Arbitrum RPC endpoint
BASE_RPC_URLstring-Base RPC endpoint
POLYGON_RPC_URLstring-Polygon RPC endpoint
BSC_RPC_URLstring-BNB Chain RPC endpoint
AVAX_RPC_URLstring-Avalanche RPC endpoint
OP_RPC_URLstring-Optimism RPC endpoint
REDIS_HOSTstringlocalhostRedis host (when cache driver is redis)
REDIS_PORTnumber6379Redis port
REDIS_PASSWORDstring-Redis password

.mnmxrc Configuration File

Configuration can also be loaded from a .mnmxrc JSON file in the project root:

json
1{
2 "strategy": "minimax",
3 "slippageTolerance": 0.5,
4 "maxHops": 3,
5 "bridges": ["wormhole", "debridge", "layerzero", "allbridge"],
6 "logLevel": "info",
7 "chains": {
8 "ethereum": {
9 "rpc": "$ETH_RPC_URL"
10 },
11 "solana": {
12 "rpc": "$SOL_RPC_URL"
13 }
14 },
15 "adversarialModel": {
16 "slippageMultiplier": 2.0,
17 "gasMultiplier": 1.5,
18 "bridgeDelayMultiplier": 3.0,
19 "mevExtraction": 0.003,
20 "priceMovement": 0.005
21 }
22}

Configuration precedence (highest to lowest):

  1. Constructor arguments — Programmatic config in new MnmxRouter({...})
  2. Environment variablesMNMX_* prefixed variables
  3. .mnmxrc file — JSON config file in project root
  4. Built-in defaults — Calibrated default values