import type { Logger } from 'pino'; import type { ChainMap, ChainMetadata } from '@hyperlane-xyz/sdk'; import { ProtocolType } from '@hyperlane-xyz/utils'; import type { ExternalBridgeType } from '../config/types.js'; /** * Configuration for an external bridge. */ export interface ExternalBridgeConfig { integrator: string; // Required: dApp/company name for bridge integration apiKey?: string; // Optional: API key for higher rate limits defaultSlippage?: number; // Default slippage tolerance (e.g., 0.005 = 0.5%) chainMetadata?: ChainMap; // Optional: chain metadata for resolving RPC URLs by chainId } /** * Parameters for requesting a bridge quote. * Either fromAmount OR toAmount must be provided (mutually exclusive). * - fromAmount: "I'm sending X, what do I get?" (standard quote) * - toAmount: "I want X on destination, how much do I send?" (reverse quote) */ export interface BridgeQuoteParams { fromChain: number; // Source chain ID toChain: number; // Destination chain ID fromToken: string; // Source token address toToken: string; // Destination token address fromAmount?: bigint; // Amount to send (in token decimals) - use for "I'm sending X" toAmount?: bigint; // Amount to receive (in token decimals) - use for "I want X" fromAddress: string; // Sender address toAddress?: string; // Recipient address (defaults to fromAddress) slippage?: number; // Slippage tolerance (overrides default) } /** * Quote response from a bridge. */ export interface BridgeQuote { id: string; // Unique quote identifier tool: string; // Bridge/DEX tool used (e.g., 'stargate', 'across') fromAmount: bigint; // Amount being sent (input required) toAmount: bigint; // Expected amount to receive toAmountMin: bigint; // Minimum amount to receive (after slippage) executionDuration: number; // Estimated execution time in seconds gasCosts: bigint; // Sum of gas costs for the bridge operation feeCosts: bigint; // Sum of non-included fee costs (protocol fees, etc.) route: R; // Bridge-specific route data for execution requestParams: BridgeQuoteParams; // Original request parameters } /** * Result of executing a bridge transfer. */ export interface BridgeTransferResult { txHash: string; // Origin chain transaction hash fromChain: number; // Source chain ID toChain: number; // Destination chain ID transferId?: string; // Bridge-specific transfer identifier } /** * Status of a bridge transfer. */ export type BridgeTransferStatus = | { status: 'pending'; substatus?: string } | { status: 'complete'; receivingTxHash: string; receivedAmount: bigint } | { status: 'failed'; error?: string } | { status: 'not_found' }; /** * Interface for external bridge implementations (e.g., LiFi, Socket). * * External bridges are used for inventory rebalancing when chains don't support * MovableCollateralRouter. The flow is: * 1. quote() - Get a quote for bridging tokens * 2. execute() - Execute the bridge transfer * 3. getStatus() - Poll for transfer completion */ export interface IExternalBridge { readonly externalBridgeId: string; readonly logger: Logger; getNativeTokenAddress?(): string; quote(params: BridgeQuoteParams): Promise; /** * Execute a bridge transfer using a previously obtained quote. * @param quote - Quote obtained from quote() * @param privateKeys - Private keys keyed by ProtocolType (e.g., { [ProtocolType.Ethereum]: '0x...' }) */ execute( quote: BridgeQuote, privateKeys: Partial>, ): Promise; /** * Get the status of a bridge transfer. * @param txHash - Origin chain transaction hash * @param fromChain - Source chain ID * @param toChain - Destination chain ID */ getStatus( txHash: string, fromChain: number, toChain: number, ): Promise; } /** * Registry mapping external bridge types to their implementations. */ export type ExternalBridgeRegistry = Record< ExternalBridgeType, IExternalBridge >;