Skip to content

@ludus/defi-bridge

The DeFi bridge SDK. Provides a permissioned, circuit-breaker-protected interface for agents to interact with on-chain DeFi protocols. Includes Uniswap V4 and Aave V3 adapters, EIP-712 signed policy authorization, smart routing, position tracking, and fee calculation.

Terminal window
npm install @ludus/defi-bridge

High-level API for DeFi interactions:

import { DeFiBridge } from '@ludus/defi-bridge';
import type { SwapParams, SupplyParams, BorrowParams, RepayParams, WithdrawParams } from '@ludus/defi-bridge';
const bridge = new DeFiBridge(adapterRegistry, transactionPipeline);
// Swap tokens
const result = await bridge.swap({
protocol: 'uniswap-v4',
tokenIn: { address: '0xUSDC...', symbol: 'USDC', decimals: 6 },
tokenOut: { address: '0xWETH...', symbol: 'WETH', decimals: 18 },
amountIn: 1000_000000n, // 1000 USDC
slippageBps: 50, // 0.5% slippage tolerance
});
// Supply to lending protocol
await bridge.supply({
protocol: 'aave-v3',
token: { address: '0xWETH...', symbol: 'WETH', decimals: 18 },
amount: 1_000000000000000000n, // 1 ETH
});
// Borrow
await bridge.borrow({
protocol: 'aave-v3',
token: { address: '0xUSDC...', symbol: 'USDC', decimals: 6 },
amount: 500_000000n,
rateMode: 'variable',
});
// Repay and withdraw
await bridge.repay({ protocol: 'aave-v3', token, amount, rateMode: 'variable' });
await bridge.withdraw({ protocol: 'aave-v3', token, amount });
// Quote without executing
const quote = await bridge.getSwapQuote(swapParams);
const rate = await bridge.getSupplyRate('aave-v3', token);

Tier-based authorization for agent DeFi access. Policies are EIP-712 signed by the agent owner.

TierValueAllowed ActionsLimits
NONE0NothingBlocked
CONSERVATIVE1Quotes onlyNo execution
BALANCED2Swaps10 ETH/position, 50 ETH/day
AGGRESSIVE3Swaps, supply, borrow, repay, withdraw100 ETH/position, 500 ETH/day
FULL4All actionsUnlimited
import { PermissionEngine, PermissionTier, DEFAULT_TIER_CONFIGS, PolicySigner } from '@ludus/defi-bridge';
import type { PermissionEngineConfig, DeFiPolicy, AuthorizationResult, AuthorizationContext, StoredPolicy, TierConfig } from '@ludus/defi-bridge';
const engine = new PermissionEngine(
{ defaultTier: PermissionTier.NONE },
policySigner, // optional EIP-712 signature verifier
);
// Grant a signed policy to an agent
const policy: DeFiPolicy = {
agentId: 'agent-1',
tier: PermissionTier.BALANCED,
allowedProtocols: ['uniswap-v4'],
maxPositionSizeWei: '10000000000000000000',
maxDailyVolumeWei: '50000000000000000000',
validFrom: Math.floor(Date.now() / 1000),
validUntil: Math.floor(Date.now() / 1000) + 86400 * 30,
nonce: 1,
};
engine.grantPolicy(policy, signature, signerAddress);
// Authorize an action
const result: AuthorizationResult = engine.authorize('agent-1', swapAction, {
currentTimestamp: Math.floor(Date.now() / 1000),
});
// { authorized: true, tier: PermissionTier.BALANCED }
// Query and manage policies
engine.getPolicy('agent-1');
engine.getEffectiveTier('agent-1', Date.now());
engine.revokePolicy('agent-1');
// Volume tracking
engine.recordExecution('agent-1', volumeWei, timestamp);
engine.getDailyVolume('agent-1', timestamp);
engine.resetDailyVolume('agent-1');

EIP-712 typed signing and verification for DeFi policies:

import { PolicySigner, DEFI_POLICY_DOMAIN, DEFI_POLICY_TYPES } from '@ludus/defi-bridge';
import type { TypedDataSigner, SignatureVerifier, PolicyDomain } from '@ludus/defi-bridge';

All protocol adapters implement:

import type { DeFiAdapter } from '@ludus/defi-bridge';
// quote(action) → QuoteResult
// encode(action) → EncodedTransaction
// simulate(action) → SimulationResult
// validate(action) → ValidationResult
// getRates?(tokenAddress) → RateResult (lending only)

Register and look up protocol adapters:

import { AdapterRegistry } from '@ludus/defi-bridge';
const registry = new AdapterRegistry();
registry.register('uniswap-v4', uniswapAdapter);
registry.register('aave-v3', aaveAdapter);
const adapter = registry.get('uniswap-v4');
const swapAdapter = registry.getForAction('uniswap-v4', 'swap');
const protocols = registry.getRegisteredProtocols();
const actions = registry.getSupportedActions('uniswap-v4');
import { UniswapV4Adapter } from '@ludus/defi-bridge';
import type { PoolConfig, UniswapV4Config } from '@ludus/defi-bridge';
import { AaveV3Adapter, RATE_MODES } from '@ludus/defi-bridge';
import type { AaveV3Config } from '@ludus/defi-bridge';

Stages execute in sequence: validation, permission check, simulation, gas estimation, encoding, signing, broadcast.

import { TransactionPipeline, GasEstimator, StubGasProvider } from '@ludus/defi-bridge';
import type {
PipelineStage, TransactionSigner, TransactionPipelineConfig,
GasProvider, GasEstimatorConfig, BufferStrategy,
PipelineContext,
} from '@ludus/defi-bridge';
const pipeline = new TransactionPipeline(stages, signer, config);
const result = await pipeline.execute(action);

Pipeline stage that checks the PermissionEngine before execution:

import { PermissionStage } from '@ludus/defi-bridge';
import type { PermissionStageConfig } from '@ludus/defi-bridge';

Five circuit breakers protect agents from excessive loss:

BreakerProtection
DailyLossBreakerHalts trading when daily losses exceed threshold
ProtocolAnomalyBreakerDetects unusual protocol behavior (TVL drops, depegs)
GasSpikeBreakerBlocks execution during gas price spikes
PositionSizeBreakerPrevents oversized positions
CorrelationBreakerLimits correlated exposure across positions
import {
DailyLossBreaker, ProtocolAnomalyBreaker, GasSpikeBreaker,
PositionSizeBreaker, CorrelationBreaker,
} from '@ludus/defi-bridge';
import type {
CircuitBreaker, CircuitBreakerType, BreakerState, BreakerCheckResult, BreakerContext,
DailyLossBreakerConfig, ProtocolAnomalyBreakerConfig, GasSpikeBreakerConfig,
PositionSizeBreakerConfig, CorrelationGroup, CorrelationBreakerConfig,
} from '@ludus/defi-bridge';

Collects quotes from all registered adapters for a token pair:

import { QuoteAggregator } from '@ludus/defi-bridge';
import type { AggregatedQuote, QuoteOptions } from '@ludus/defi-bridge';
const aggregator = new QuoteAggregator(adapterRegistry);
// Get all quotes, ranked by output amount
const quotes = await aggregator.getQuotes(tokenIn, tokenOut, amountIn, {
slippageBps: 50,
excludeProtocols: ['risky-dex'],
});
// Get the best single quote
const best = await aggregator.getBestQuote(tokenIn, tokenOut, amountIn);
// { protocol: 'uniswap-v4', quote: { outputAmount, priceImpactBps, ... }, score: 0.95 }

Scores routes by output amount, gas cost, price impact, and protocol reliability:

import { RouteScorer } from '@ludus/defi-bridge';
import type { ScoredRoute, RouteScoreFactors, RouteScorerConfig } from '@ludus/defi-bridge';

Splits large trades across multiple protocols for better execution:

import { SplitRouter } from '@ludus/defi-bridge';
import type { SplitAllocation, SplitRoute, SplitConfig } from '@ludus/defi-bridge';

Track open DeFi positions with P&L and exposure analysis:

import { PositionTracker } from '@ludus/defi-bridge';
import type {
Position, PositionStatus, OpenPositionParams,
CloseResult, PositionUpdate, ExposureBreakdown, PortfolioSnapshot,
} from '@ludus/defi-bridge';
const tracker = new PositionTracker();

Calculates Ludus protocol fees per trade with volume discounts:

import { FeeCalculator } from '@ludus/defi-bridge';
import type { FeeConfig, VolumeDiscount, FeeBreakdown } from '@ludus/defi-bridge';

Accumulates pending fees and handles settlement:

import { FeeCollector } from '@ludus/defi-bridge';
import type { PendingFees, FeeSettlement } from '@ludus/defi-bridge';
import type { Token, TokenAmount, TokenPair, FeeTier } from '@ludus/defi-bridge';
import { FEE_TIER_VALUES, NATIVE_TOKEN_ADDRESS } from '@ludus/defi-bridge';
import type {
DeFiActionType, // 'swap' | 'supply' | 'borrow' | 'repay' | 'withdraw'
DeFiAction, // Union type
SwapAction, SupplyAction, BorrowAction, RepayAction, WithdrawAction,
} from '@ludus/defi-bridge';
import type {
EncodedTransaction, GasEstimate, SimulationResult,
QuoteResult, RateResult, ValidationResult, TransactionResult,
} from '@ludus/defi-bridge';
ErrorWhen
AdapterNotFoundErrorProtocol not registered
UnsupportedActionErrorAdapter doesn’t support the action type
InvalidTokenErrorToken address or configuration invalid
InsufficientBalanceErrorWallet balance too low
SlippageExceededErrorPrice moved beyond tolerance
GasEstimationErrorGas estimation failed
TransactionRevertedErrorOn-chain transaction reverted
PipelineStageErrorPipeline stage failed
SimulationFailedErrorTransaction simulation failed
PermissionDeniedErrorAgent lacks permission for this action
CircuitBreakerOpenErrorCircuit breaker tripped
PolicyExpiredErrorAgent’s DeFi policy has expired
PolicySignatureInvalidErrorEIP-712 signature verification failed
NoRouteFoundErrorNo adapter can route the token pair
InsufficientLiquidityErrorNot enough liquidity for the trade