Docs
Docs/Bridge Adapters

Bridge Adapters

How MNMX integrates with cross-chain bridges and how to add new ones.

Supported Bridges

BridgeChainsAvg. TimeSecurity Model
Wormhole25+ chains including Ethereum, Solana, Arbitrum, Base2–15 minGuardian network (19 validators)
deBridge15+ chains including Ethereum, Solana, BNB Chain1–5 minValidator network + DLN
LayerZero30+ chains including Ethereum, Arbitrum, Optimism2–10 minUltra Light Node + DVN
Allbridge10+ chains including Ethereum, Solana, BNB Chain2–10 minMulti-sig + liquidity pools

Adapter Interface

Every bridge adapter implements the BridgeAdapter interface:

typescript
1interface BridgeAdapter {
2 // Identity
3 name: string;
4 supportedChains: Chain[];
5
6 // Quote a transfer
7 getQuote(params: QuoteParams): Promise<BridgeQuote>;
8
9 // Execute a quoted transfer
10 execute(quote: BridgeQuote, signer: Signer): Promise<BridgeResult>;
11
12 // Monitor transfer status
13 getStatus(txHash: string): Promise<BridgeStatus>;
14
15 // Health check
16 getHealth(): Promise<BridgeHealth>;
17}
18
19interface QuoteParams {
20 fromChain: string;
21 toChain: string;
22 token: string;
23 amount: string;
24}
25
26interface BridgeQuote {
27 bridge: string;
28 inputAmount: string;
29 outputAmount: string;
30 fee: string;
31 estimatedTime: number;
32 liquidityDepth: string;
33 expiresAt: number;
34}
35
36interface BridgeHealth {
37 online: boolean;
38 congestion: 'low' | 'medium' | 'high';
39 recentSuccessRate: number;
40 medianConfirmTime: number;
41}

Adding a New Bridge

To add a new bridge adapter:

typescript
1import { BridgeAdapter, QuoteParams, BridgeQuote } from '@mnmx/core';
2
3class MyBridgeAdapter implements BridgeAdapter {
4 name = 'my-bridge';
5 supportedChains = ['ethereum', 'solana', 'arbitrum'];
6
7 async getQuote(params: QuoteParams): Promise<BridgeQuote> {
8 // Call your bridge's API to get a quote
9 const response = await fetch(`https://api.mybridge.com/quote?${qs}`);
10 const data = await response.json();
11
12 return {
13 bridge: this.name,
14 inputAmount: params.amount,
15 outputAmount: data.outputAmount,
16 fee: data.fee,
17 estimatedTime: data.estimatedTime,
18 liquidityDepth: data.availableLiquidity,
19 expiresAt: Date.now() + 30_000,
20 };
21 }
22
23 async execute(quote: BridgeQuote, signer: Signer): Promise<BridgeResult> {
24 // Initiate the bridge transfer
25 // ...
26 }
27
28 async getStatus(txHash: string): Promise<BridgeStatus> {
29 // Check transfer status
30 // ...
31 }
32
33 async getHealth(): Promise<BridgeHealth> {
34 // Health check
35 // ...
36 }
37}
38
39// Register the adapter
40router.registerBridge(new MyBridgeAdapter());

Once registered, the routing engine automatically includes the new bridge in path discovery. No changes to the routing logic needed.

Health Monitoring

The routing engine continuously monitors bridge health. Unhealthy bridges are deprioritized or excluded from routing:

ConditionAction
Bridge offlineExclude from all routes
High congestionIncrease worst-case time estimate by 3x
Success rate < 95%Increase bridge risk penalty in scoring
Confirm time > 2x medianFlag as degraded, deprioritize

How the Engine Selects Bridges

The minimax engine doesn't pick a "best bridge." It evaluates complete paths that may use different bridges for different hops. A single route might use Wormhole for the first hop and deBridge for the second if that combination produces the best minimax score.

Bridge selection factors:

  • Liquidity — Higher liquidity means lower slippage
  • Speed — Faster bridges score better on the speed dimension
  • Cost — Lower bridge fees reduce total path cost
  • Reliability — Historical success rate affects risk scoring
  • Chain coverage — Some bridges are the only option for certain chain pairs
More bridges = better routing. Each new bridge adapter adds more candidate paths to the search space, increasing the probability of finding a superior minimax-optimal route.