@anywalletkit/protocol-swap2-lifi 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/activity.ts","../src/solana-address.ts","../src/calldata.ts","../src/solana.ts","../src/provider.ts","../src/protocol.ts"],"sourcesContent":["export * from \"./config.js\";\nexport * from \"./provider.js\";\nexport {LifiSwap2Protocol} from \"./protocol.js\";\nexport {LifiSwap2Protocol as default} from \"./protocol.js\";\nexport * from \"./activity.js\";\nexport type { LifiSwap2Config } from \"./protocol.js\"\n","import {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\n\n// ── LI.FI — EVM calldata routes implemented by this contribution adapter ─────\n// 2026-08 sweep (li.quest/v1/chains): + Avalanche 43114, Scroll 534352,\n// Berachain 80094 (HyperEVM 999 / Robinhood 4663 were already routed by the\n// provider's own chain map). 2026-11-10: + Elysium 99901 (li.quest/v1/chains key \"ely\").\n/** The catalog's Solana id; LI.FI numbers it 1151111081099710. */\nexport const LIFI_SOLANA_CAIP2 = \"solana:mainnet\";\nconst LIFI_EVM = new Set([1, 8453, 56, 137, 42161, 10, 100, 143, 130, 999, 4663, 43114, 534352, 80094, 324, 42220, 4326, 9745, 59144, 146, 480, 1329, 57073, 98866, 196, 5042, 5000, 747474, 2818, 14, 99901]);\nexport const lifi = {\n enabled: () => true,\n apiKey: () => undefined,\n integrator: () => \"\",\n supportsChain(chain: string): boolean {\n if (isEvm(chain)) return LIFI_EVM.has(evmRef(chain));\n // Solana legs come back as a serialized transaction the account executes\n // through its `sendSerializedTransaction` guard. Tron is still excluded.\n return chain === LIFI_SOLANA_CAIP2;\n },\n supports(from: string, to: string): boolean {\n return this.supportsChain(from) && this.supportsChain(to);\n },\n};\n","/**\n * Activity recognition for LI.FI: any call into the LI.FI Diamond on an EVM\n * chain this module routes. Same-chain swaps go through GenericSwapFacetV3\n * (fixed selectors below → `swap`, \"Swapped A → B\"); every other facet is a\n * bridge facet (`swapAndStartBridgeTokensVia…`, `startBridgeTokensVia…`) whose\n * source leg we see here → `bridge`, \"Bridged A\". The destination leg lands on\n * another chain through a third-party relayer and cannot be tied back offline,\n * so `related` stays empty (the kit's intent journal links the two).\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {calledContract, callSelector, describeSwapLike} from \"@anywalletkit/protocol-swap2-core/activity\";\n\nexport const LIFI_MODULE = \"@anywalletkit/protocol-swap2-lifi\";\n\n/** GenericSwapFacetV3 — same-chain swaps (`viem toFunctionSelector`, 2026-10-14). */\nexport const LIFI_SAME_CHAIN_SELECTORS: ReadonlySet<string> = new Set([\n \"0x4666fc80\", // swapTokensSingleV3ERC20ToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool))\n \"0x733214a3\", // swapTokensSingleV3ERC20ToNative(…)\n \"0xaf7060fd\", // swapTokensSingleV3NativeToERC20(…)\n \"0x5fd9ae2e\", // swapTokensMultipleV3ERC20ToERC20(bytes32,string,string,address,uint256,(…)[])\n \"0x2c57e884\", // swapTokensMultipleV3ERC20ToNative(…[])\n \"0x736eac0b\", // swapTokensMultipleV3NativeToERC20(…[])\n]);\n\n/**\n * @param isDiamond the provider's trust check: the documented Diamond for the\n * chain plus any `trustedTransactionTargets` the caller configured.\n */\nexport function describeLifiActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n isDiamond: (chain: string, address: string) => boolean,\n): ActivityItem | null {\n if (!tx.chain.startsWith(\"eip155:\")) return null;\n const to = calledContract(tx);\n if (!to || !isDiamond(tx.chain, to)) return null;\n const selector = callSelector(tx);\n const sameChain = selector !== undefined && LIFI_SAME_CHAIN_SELECTORS.has(selector);\n return describeSwapLike(tx, ctx, {\n protocol: LIFI_MODULE,\n subtitle: \"LI.FI\",\n // Unknown selector: trust the legs — both netted here means a same-chain route.\n kind: sameChain ? \"swap\" : selector === undefined ? \"auto\" : \"bridge\",\n });\n}\n","/**\n * Solana addresses as the bridge checks read them: base58 ↔ the raw 32-byte key, and the associated token account of an\n * owner for a mint, derived the way the Associated Token Account program derives it (`findProgramAddress` over\n * [owner, token program, mint] under ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL; spl.solana.com/associated-token-account).\n * Pure functions over bytes: no RPC, no Node API, no global TextEncoder.\n */\nimport {ed25519} from \"@noble/curves/ed25519.js\";\nimport {sha256} from \"@noble/hashes/sha2.js\";\n\nconst ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\nconst BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n/** The classic SPL Token program: USDC and USDT on Solana live under it. */\nexport const SOLANA_TOKEN_PROGRAM = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\";\nconst ASSOCIATED_TOKEN_PROGRAM = \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\";\nconst PDA_MARKER = Uint8Array.from(\"ProgramDerivedAddress\", (c) => c.charCodeAt(0));\n\n/** Base58 of raw bytes (leading zero bytes as \"1\"). */\nexport function base58(bytes: Uint8Array): string {\n let n = 0n;\n for (const b of bytes) n = (n << 8n) | BigInt(b);\n let out = \"\";\n while (n > 0n) { out = ALPHABET[Number(n % 58n)]! + out; n /= 58n; }\n for (const b of bytes) { if (b !== 0) break; out = `1${out}`; }\n return out;\n}\n\n/** The 32 raw bytes of a base58 Solana address, or null when it is not exactly one. */\nexport function solanaKey(address: string): Uint8Array | null {\n if (!BASE58.test(address)) return null;\n let n = 0n;\n for (const ch of address) n = n * 58n + BigInt(ALPHABET.indexOf(ch));\n let zeros = 0;\n while (address[zeros] === \"1\") zeros++;\n const body: number[] = [];\n while (n > 0n) { body.unshift(Number(n & 0xffn)); n >>= 8n; }\n if (zeros + body.length !== 32) return null;\n const out = new Uint8Array(32);\n out.set(body, zeros);\n return out;\n}\n\nconst onCurve = (bytes: Uint8Array): boolean => {\n try { ed25519.Point.fromBytes(bytes); return true; } catch { return false; }\n};\n\n/** `findProgramAddress`: the first off-curve `sha256(seeds ‖ bump ‖ program ‖ \"ProgramDerivedAddress\")`, bump 255 → 0. */\nfunction programAddress(seeds: readonly Uint8Array[], program: Uint8Array): Uint8Array {\n for (let bump = 255; bump >= 0; bump--) {\n const parts = [...seeds, Uint8Array.of(bump), program, PDA_MARKER];\n const buf = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));\n let at = 0;\n for (const p of parts) { buf.set(p, at); at += p.length; }\n const hash = sha256(buf);\n if (!onCurve(hash)) return hash;\n }\n throw new Error(\"no program address for these seeds\");\n}\n\n/** The associated token account of `owner` for `mint` under `tokenProgram` (all raw 32-byte keys). */\nexport function associatedTokenAccount(owner: Uint8Array, mint: Uint8Array, tokenProgram: Uint8Array = solanaKey(SOLANA_TOKEN_PROGRAM)!): Uint8Array {\n return programAddress([owner, tokenProgram, mint], solanaKey(ASSOCIATED_TOKEN_PROGRAM)!);\n}\n","/**\n * What the LI.FI Diamond call really does, read from its calldata — not from the `action` /\n * `estimate` next to it (round 3, H9). The API (or an `apiUrl` proxy) could pair a reviewed\n * recipient and minimum with calldata that pays someone else, or accepts 1 wei.\n *\n * Same-chain swaps run through GenericSwapFacet(V3): receiver, minimum, the input token and amount,\n * and the output token are in the arguments. Bridges take `ILiFi.BridgeData` as their first\n * argument: its receiver, destination chain and bridged asset are checked, for the listed bridge\n * entry points only; a destination call (the final recipient sits in calldata for another chain) is\n * refused. For a Solana destination BridgeData.receiver is only LI.FI's non-EVM placeholder and the\n * recipient sits in facet-specific data: it is read for Mayan, Polymer CCTP and Chainflip\n * ({@link solanaRecipientMismatch}); any other non-EVM destination is refused. LI.FI Intents is refused on\n * every route from an EVM chain, to Solana and between EVM chains alike: its escrowed order names its own oracles, output\n * settler and output amount, none of which is pinned here ({@link INTENTS_UNPINNED}).\n *\n * A facet's own data also names who gets money back — unused native fee, swap leftovers, the whole input when an\n * order expires unfilled, a fallback when delivery fails ({@link FACET_DATA}); each such address must be the sender or\n * the recipient.\n *\n * Mostly not checked here: a bridge's OUTPUT. The destination minimum (and for some bridges, e.g.\n * Across, what the receiver finally gets) lives in facet-specific data, so for most bridges the\n * reviewed minimum still relies on LI.FI's API answering honestly. Eco and M0 are the exceptions\n * ({@link FacetData.delivery}): their facet data names the destination token, amount and (Eco) recipient\n * outright, and those are held to the quote. To Solana the delivered token is held to the quote where the\n * facet names it (a Mayan order, Chainflip; Mayan's and Polymer's CCTP legs deliver USDC);\n * the minimum is not.\n *\n * The receiver is only worth checking where the facet itself holds the bridge to it. Most do on\n * chain (Across V4, Mayan, Stargate, Chainflip, GasZip, Glacis, AllBridge, M0, Polymer CCTP) or through\n * LI.FI's backend signature over BridgeData plus the off-chain order (NEAR Intents, LayerSwap, Unit, the\n * Across Swap API). Eco v3 binds its route to BridgeData.receiver by that signature only, so the route\n * itself is read here ({@link ecoDelivery}). The facets in {@link UNBOUND_BRIDGES} do neither and are\n * refused. LI.FI Intents binds its recipient on chain, but releases the escrowed input on the word of an\n * oracle its own calldata names, so it is refused too ({@link INTENTS_UNPINNED}).\n */\n\nimport {associatedTokenAccount, base58, solanaKey} from \"./solana-address.js\";\n\n/**\n * The V3 entry points move one asset kind in and one out, and check the minimum against THAT kind's balance: a\n * `*ToNative` call measures the Diamond's native balance, so a minimum written in USDC units is enforced in wei\n * (scan 2026-10-27 modules, F20). Each selector is bound to the kinds it moves; `swapTokensGeneric` moves any.\n */\ntype Kind = \"native\" | \"erc20\";\nconst GENERIC_SWAPS: Readonly<Record<string, {single: boolean; from?: Kind; to?: Kind}>> = {\n \"0x4630a0d8\": {single: false}, // swapTokensGeneric\n \"0x4666fc80\": {single: true, from: \"erc20\", to: \"erc20\"}, // swapTokensSingleV3ERC20ToERC20\n \"0x733214a3\": {single: true, from: \"erc20\", to: \"native\"}, // swapTokensSingleV3ERC20ToNative\n \"0xaf7060fd\": {single: true, from: \"native\", to: \"erc20\"}, // swapTokensSingleV3NativeToERC20\n \"0x5fd9ae2e\": {single: false, from: \"erc20\", to: \"erc20\"}, // swapTokensMultipleV3ERC20ToERC20\n \"0x2c57e884\": {single: false, from: \"erc20\", to: \"native\"}, // swapTokensMultipleV3ERC20ToNative\n \"0x736eac0b\": {single: false, from: \"native\", to: \"erc20\"}, // swapTokensMultipleV3NativeToERC20\n};\n/** The most a bridge may keep from the input as its own fee when there are no source swaps, in basis points. */\nconst BRIDGE_INPUT_FEE_MAX_BPS = 100n;\nconst kindOf = (asset: string): Kind => (/^0x0{40}$/i.test(asset) ? \"native\" : \"erc20\");\n\n/**\n * The ABI-encoded bridge entry points of the LI.FI Diamond — `startBridgeTokensVia*` and\n * `swapAndStartBridgeTokensVia*`, whose first argument is `ILiFi.BridgeData` — computed from the\n * facet sources in lifinance/contracts (86c3729, 2026-10-26; EcoFacet v3.0.0 from 9001792, 2026-11-01, whose\n * EcoData gained `intentDestination` — the v2 selectors 0xbff90b61 / 0x762aea18 are gone from the Diamonds). Packed\n * facets and `*Min` variants read raw calldata, not BridgeData, and are not listed: any other selector is refused.\n */\nconst BRIDGE_CALLS: Readonly<Record<string, {sourceSwaps: boolean; facet: string}>> = {\n \"0x1fd8010c\": {sourceSwaps: false, facet: \"Across\"}, // startBridgeTokensViaAcross (AcrossFacet)\n \"0x3a3f7332\": {sourceSwaps: true, facet: \"Across\"}, // swapAndStartBridgeTokensViaAcross (AcrossFacet)\n \"0xa1f1ce43\": {sourceSwaps: false, facet: \"AcrossV4\"}, // startBridgeTokensViaAcrossV4 (AcrossFacetV4)\n \"0x1794958f\": {sourceSwaps: true, facet: \"AcrossV4\"}, // swapAndStartBridgeTokensViaAcrossV4 (AcrossFacetV4)\n \"0x6a90d66e\": {sourceSwaps: false, facet: \"AcrossV4Swap\"}, // startBridgeTokensViaAcrossV4Swap (AcrossV4SwapFacet)\n \"0x9b054bc4\": {sourceSwaps: true, facet: \"AcrossV4Swap\"}, // swapAndStartBridgeTokensViaAcrossV4Swap (AcrossV4SwapFacet)\n \"0x6a51e9a9\": {sourceSwaps: false, facet: \"AllBridge\"}, // startBridgeTokensViaAllBridge (AllBridgeFacet)\n \"0x63267469\": {sourceSwaps: true, facet: \"AllBridge\"}, // swapAndStartBridgeTokensViaAllBridge (AllBridgeFacet)\n \"0xc9851d0b\": {sourceSwaps: false, facet: \"ArbitrumBridge\"}, // startBridgeTokensViaArbitrumBridge (ArbitrumBridgeFacet)\n \"0x3cc9517b\": {sourceSwaps: true, facet: \"ArbitrumBridge\"}, // swapAndStartBridgeTokensViaArbitrumBridge (ArbitrumBridgeFacet)\n \"0xe0a4201c\": {sourceSwaps: false, facet: \"CelerCircleBridge\"}, // startBridgeTokensViaCelerCircleBridge (CelerCircleBridgeFacet)\n \"0x4f3b0759\": {sourceSwaps: true, facet: \"CelerCircleBridge\"}, // swapAndStartBridgeTokensViaCelerCircleBridge (CelerCircleBridgeFacet)\n \"0x0315138f\": {sourceSwaps: false, facet: \"Centrifuge\"}, // startBridgeTokensViaCentrifuge (CentrifugeFacet)\n \"0x8fd4d4dd\": {sourceSwaps: true, facet: \"Centrifuge\"}, // swapAndStartBridgeTokensViaCentrifuge (CentrifugeFacet)\n \"0x0ad553b3\": {sourceSwaps: false, facet: \"Chainflip\"}, // startBridgeTokensViaChainflip (ChainflipFacet)\n \"0xee3314a1\": {sourceSwaps: true, facet: \"Chainflip\"}, // swapAndStartBridgeTokensViaChainflip (ChainflipFacet)\n \"0x05c54990\": {sourceSwaps: false, facet: \"Eco\"}, // startBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)\n \"0x8352664c\": {sourceSwaps: true, facet: \"Eco\"}, // swapAndStartBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)\n \"0x678786ea\": {sourceSwaps: false, facet: \"Frax\"}, // startBridgeTokensViaFrax (FraxFacet)\n \"0x07b8e4c7\": {sourceSwaps: true, facet: \"Frax\"}, // swapAndStartBridgeTokensViaFrax (FraxFacet)\n \"0xfc5f1003\": {sourceSwaps: false, facet: \"GasZip\"}, // startBridgeTokensViaGasZip (GasZipFacet)\n \"0x606326ff\": {sourceSwaps: true, facet: \"GasZip\"}, // swapAndStartBridgeTokensViaGasZip (GasZipFacet)\n \"0x6f9206ba\": {sourceSwaps: false, facet: \"Glacis\"}, // startBridgeTokensViaGlacis (GlacisFacet)\n \"0x9c4b6dd9\": {sourceSwaps: true, facet: \"Glacis\"}, // swapAndStartBridgeTokensViaGlacis (GlacisFacet)\n \"0xf66fe519\": {sourceSwaps: false, facet: \"GnosisBridge\"}, // startBridgeTokensViaGnosisBridge (GnosisBridgeFacet)\n \"0x7bf96e0a\": {sourceSwaps: true, facet: \"GnosisBridge\"}, // swapAndStartBridgeTokensViaGnosisBridge (GnosisBridgeFacet)\n \"0xee9e98e0\": {sourceSwaps: false, facet: \"LayerSwap\"}, // startBridgeTokensViaLayerSwap (LayerSwapFacet)\n \"0x4c279d6b\": {sourceSwaps: true, facet: \"LayerSwap\"}, // swapAndStartBridgeTokensViaLayerSwap (LayerSwapFacet)\n \"0x7dbcf1d9\": {sourceSwaps: false, facet: \"LiFiIntentEscrowV2\"}, // startBridgeTokensViaLiFiIntentEscrowV2 (LiFiIntentEscrowFacetV2)\n \"0x6d21c5df\": {sourceSwaps: true, facet: \"LiFiIntentEscrowV2\"}, // swapAndStartBridgeTokensViaLiFiIntentEscrowV2 (LiFiIntentEscrowFacetV2)\n \"0x65782c4b\": {sourceSwaps: false, facet: \"M0\"}, // startBridgeTokensViaM0 (M0Facet)\n \"0xb9eaf86d\": {sourceSwaps: true, facet: \"M0\"}, // swapAndStartBridgeTokensViaM0 (M0Facet)\n \"0xb4875292\": {sourceSwaps: false, facet: \"Mayan\"}, // startBridgeTokensViaMayan (MayanFacet)\n \"0x80c65808\": {sourceSwaps: true, facet: \"Mayan\"}, // swapAndStartBridgeTokensViaMayan (MayanFacet)\n \"0x4213dfff\": {sourceSwaps: false, facet: \"MegaETHBridge\"}, // startBridgeTokensViaMegaETHBridge (MegaETHBridgeFacet)\n \"0x22256e89\": {sourceSwaps: true, facet: \"MegaETHBridge\"}, // swapAndStartBridgeTokensViaMegaETHBridge (MegaETHBridgeFacet)\n \"0x4698f032\": {sourceSwaps: false, facet: \"NEARIntents\"}, // startBridgeTokensViaNEARIntents (NEARIntentsFacet)\n \"0x02631b09\": {sourceSwaps: true, facet: \"NEARIntents\"}, // swapAndStartBridgeTokensViaNEARIntents (NEARIntentsFacet)\n \"0x782621d8\": {sourceSwaps: false, facet: \"OmniBridge\"}, // startBridgeTokensViaOmniBridge (OmniBridgeFacet)\n \"0x95726782\": {sourceSwaps: true, facet: \"OmniBridge\"}, // swapAndStartBridgeTokensViaOmniBridge (OmniBridgeFacet)\n \"0xce8a97a5\": {sourceSwaps: false, facet: \"OptimismBridge\"}, // startBridgeTokensViaOptimismBridge (OptimismBridgeFacet)\n \"0x5bb5d448\": {sourceSwaps: true, facet: \"OptimismBridge\"}, // swapAndStartBridgeTokensViaOptimismBridge (OptimismBridgeFacet)\n \"0xaf62c7d6\": {sourceSwaps: false, facet: \"PolygonBridge\"}, // startBridgeTokensViaPolygonBridge (PolygonBridgeFacet)\n \"0xb4f37581\": {sourceSwaps: true, facet: \"PolygonBridge\"}, // swapAndStartBridgeTokensViaPolygonBridge (PolygonBridgeFacet)\n \"0xf434d6ca\": {sourceSwaps: false, facet: \"PolymerCCTP\"}, // startBridgeTokensViaPolymerCCTP (PolymerCCTPFacet)\n \"0x17917a4e\": {sourceSwaps: true, facet: \"PolymerCCTP\"}, // swapAndStartBridgeTokensViaPolymerCCTP (PolymerCCTPFacet)\n \"0x14d53077\": {sourceSwaps: false, facet: \"Stargate\"}, // startBridgeTokensViaStargate (StargateFacetV2)\n \"0xa6010a66\": {sourceSwaps: true, facet: \"Stargate\"}, // swapAndStartBridgeTokensViaStargate (StargateFacetV2)\n \"0x0691ff78\": {sourceSwaps: false, facet: \"Superset\"}, // startBridgeTokensViaSuperset (SupersetFacet)\n \"0xf26e657f\": {sourceSwaps: true, facet: \"Superset\"}, // swapAndStartBridgeTokensViaSuperset (SupersetFacet)\n \"0x64261d58\": {sourceSwaps: false, facet: \"Unit\"}, // startBridgeTokensViaUnit (UnitFacet)\n \"0x21a3af52\": {sourceSwaps: true, facet: \"Unit\"}, // swapAndStartBridgeTokensViaUnit (UnitFacet)\n};\n\n/**\n * Bridge entry points that do not tie where the funds go to BridgeData.receiver (lifinance/contracts, main 2026-11-02):\n * Relay deposits against an `orderId` whose off-chain order names the recipient (\"We cannot validate / guarantee that the\n * off-chain-data associated with the provided orderId corresponds to the _bridgeData\"); Garden locks the funds for a\n * `redeemer` named in facet data, with the transfer details in an off-chain order; deBridge DLN passes its own\n * `receiver` and order authority through unchecked; ThorSwap pays a `vault` named in facet data with the destination in\n * a memo; Squid runs `sourceCalls` of any target on its multicall, which holds the funds, and bridges what is left\n * (only CallBridge bridges to BridgeData.receiver at all; LI.FI's live Squid quotes are BridgeCall, a destination\n * call); Symbiosis's MetaRouter path forwards `callTo` / `callData` verbatim and names the final recipient and the\n * revert address there (the facet: the emitted receiver \"is therefore descriptive, not an on-chain guarantee\"; its\n * other path bridges to Bitcoin only). A matching BridgeData.receiver proves nothing for these, so they are refused\n * by name.\n *\n * Relay's `orderId` is not opaque: it is a hash commitment, the EIP-712 `hashStruct` of the order (recipient, output\n * token, minimum, deadlines, refunds), signed by Relay's solver. What this path lacks is the preimage: a LI.FI quote\n * carries the id without the order behind it, and neither Relay nor any other party publishes an unauthenticated\n * lookup of an unfunded order by id (2026-11-02: `/intents/status` says \"unknown\", `/requests/v2` lists only indexed\n * deposits, `/requests/v3` needs an API key). With nothing to hash, the id cannot be held to the request here. Relay's\n * own quote does return the order, and `@anywalletkit/protocol-swap2-relay` verifies it on the device.\n */\nconst UNBOUND_BRIDGES: Readonly<Record<string, string>> = {\n \"0x092e8fa4\": \"Relay\", // startBridgeTokensViaRelayDepository\n \"0xa3443faa\": \"Relay\", // swapAndStartBridgeTokensViaRelayDepository\n \"0x5f9af35d\": \"Garden\", // startBridgeTokensViaGarden\n \"0x76ad76fe\": \"Garden\", // swapAndStartBridgeTokensViaGarden\n \"0x4004633e\": \"deBridge DLN\", // startBridgeTokensViaDeBridgeDln\n \"0x2c7d2db0\": \"deBridge DLN\", // swapAndStartBridgeTokensViaDeBridgeDln\n \"0x2541ec57\": \"ThorSwap\", // startBridgeTokensViaThorSwap\n \"0xad673d88\": \"ThorSwap\", // swapAndStartBridgeTokensViaThorSwap\n \"0x3f313808\": \"Squid\", // startBridgeTokensViaSquid\n \"0xa8f66666\": \"Squid\", // swapAndStartBridgeTokensViaSquid\n \"0xe23b7a08\": \"Symbiosis\", // startBridgeTokensViaSymbiosis\n \"0xc46059b2\": \"Symbiosis\", // swapAndStartBridgeTokensViaSymbiosis\n};\n\n/** What the quote promised, in the forms the calldata carries. */\nexport interface DiamondExpectation {\n /** Source token (EVM address; the zero address for the native coin). */\n fromToken: string;\n /** Destination token as LI.FI names it (the zero address for an EVM native coin). */\n toToken: string;\n /** Input, base units. */\n amountIn: bigint;\n /** The recipient (an EVM address, or another chain's address for a non-EVM destination). */\n receiver: string;\n /** The sender the quote was asked for (its `fromAddress`): where a bridge's refunds may go, besides the recipient. */\n sender: string;\n /** The floor the review shows. */\n minOut: bigint;\n /** LI.FI's id of the destination chain; equal to the source's for a swap. */\n destChainId: bigint;\n sameChain: boolean;\n /** The destination is an EVM chain (its receiver is a 20-byte address). */\n evmDestination: boolean;\n}\n\ninterface SwapStep {sendingAssetId: string; receivingAssetId: string; fromAmount: bigint; requiresDeposit: boolean}\n\nclass Reader {\n private readonly b: Uint8Array;\n constructor(src: string | Uint8Array) {\n if (typeof src !== \"string\") { this.b = src; return; }\n if (!/^0x([0-9a-fA-F]{2})*$/.test(src)) throw new Error(\"not hex\");\n this.b = Uint8Array.from(src.slice(2).match(/../g) ?? [], (h) => Number.parseInt(h, 16));\n }\n get length() { return this.b.length; }\n /** `n` raw bytes at `at`, as 0x-hex. */\n raw(at: number, n: number): string {\n if (at < 0 || at + n > this.b.length) throw new Error(\"out of bounds\");\n return `0x${Array.from(this.b.subarray(at, at + n), (x) => x.toString(16).padStart(2, \"0\")).join(\"\")}`;\n }\n /** The `bytes` whose offset word sits at `head` (relative to `base`), as a reader over its contents only. */\n bytes(base: number, head: number): Reader {\n const at = base + this.small(head);\n const n = this.small(at);\n if (at + 32 + n > this.b.length) throw new Error(\"bytes out of bounds\");\n return new Reader(this.b.subarray(at + 32, at + 32 + n));\n }\n word(at: number): bigint {\n if (at < 0 || at + 32 > this.b.length) throw new Error(\"out of bounds\");\n let v = 0n;\n for (let i = at; i < at + 32; i++) v = (v << 8n) | BigInt(this.b[i]!);\n return v;\n }\n /** A word that must fit a JS offset / length (bounded by the calldata). */\n small(at: number): number {\n const v = this.word(at);\n if (v > BigInt(this.b.length)) throw new Error(\"offset out of bounds\");\n return Number(v.toString()); // ≤ the calldata length\n }\n address(at: number): string {\n const v = this.word(at);\n if (v >> 160n !== 0n) throw new Error(\"not an address\");\n return `0x${v.toString(16).padStart(40, \"0\")}`;\n }\n bool(at: number): boolean {\n const v = this.word(at);\n if (v > 1n) throw new Error(\"not a bool\");\n return v === 1n;\n }\n}\n\nconst same = (a: string, b: string) => a.toLowerCase() === b.toLowerCase();\n\n/** SwapData tuple at `at`: (callTo, approveTo, sendingAssetId, receivingAssetId, fromAmount, callData, requiresDeposit). */\nfunction swapAt(r: Reader, at: number): SwapStep {\n r.address(at); r.address(at + 32);\n const step = {sendingAssetId: r.address(at + 64), receivingAssetId: r.address(at + 96), fromAmount: r.word(at + 128), requiresDeposit: false};\n const bytesAt = at + r.small(at + 160);\n r.small(bytesAt); // length within the calldata\n // The Diamond pulls `fromAmount` of `sendingAssetId` from the user for every step that requires a deposit.\n step.requiresDeposit = r.bool(at + 192);\n return step;\n}\n\n/** SwapData[] whose offset word sits at `head`, relative to `base`. */\nfunction swapsAt(r: Reader, base: number, head: number): SwapStep[] {\n const array = base + r.small(head);\n const n = r.small(array);\n if (n === 0 || n > 16) throw new Error(\"bad swap count\");\n const items = array + 32;\n return Array.from({length: n}, (_, i) => swapAt(r, items + r.small(items + 32 * i)));\n}\n\n/**\n * Every step, not only the ends (scan 2026-10-27 modules, F21–F23): the Diamond pulls `fromAmount` from the user for\n * each step that requires a deposit, so only steps that spend the source token may, and together at most the input —\n * a middle step depositing DAI under a leftover allowance is refused. The steps chain: each spends what the one before\n * delivered (a fee step on the input sends and receives the same asset).\n */\nfunction checkSteps(steps: SwapStep[], e: DiamondExpectation, finalAsset: string): string | null {\n const first = steps[0]!;\n const last = steps[steps.length - 1]!;\n if (!same(first.sendingAssetId, e.fromToken)) return `spends ${first.sendingAssetId}, not ${e.fromToken}`;\n if (first.fromAmount === 0n || first.fromAmount > e.amountIn) return `swaps ${first.fromAmount}, not the ${e.amountIn} spent`;\n let deposited = 0n;\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n if (i > 0 && !same(step.sendingAssetId, steps[i - 1]!.receivingAssetId)) return `step ${i} spends ${step.sendingAssetId}, which step ${i - 1} does not deliver`;\n if (!step.requiresDeposit) continue;\n if (!same(step.sendingAssetId, e.fromToken)) return `step ${i} pulls ${step.sendingAssetId} from the wallet, not the input ${e.fromToken}`;\n deposited += step.fromAmount;\n }\n if (deposited > e.amountIn) return `the steps pull ${deposited} from the wallet, more than the ${e.amountIn} spent`;\n if (!same(last.receivingAssetId, finalAsset)) return `delivers ${last.receivingAssetId}, not ${finalAsset}`;\n return null;\n}\n\n/** A Mayan Swift order refunds its input to `trader` when it is not filled, a Wormhole swap to `refundAddr`: their byte\n * offset in `protocolData` (Mayan's swap-sdk, src/evm; selectors as the facet lists them). MCTP and FastMCTP orders and\n * the HyperCore deposits carry no refund address: what they do not deliver settles to the destination address the facet\n * already checks against BridgeData.receiver. */\nconst MAYAN_REFUND_AT: Readonly<Record<string, number>> = {\n \"0xa3a30834\": 4 + 32 * 3, // Swift v2 createOrderWithToken(tokenIn, amountIn, (payloadType, trader, destAddr, …), customPayload)\n \"0x6147435b\": 4 + 32 * 3, // Swift v2 createOrderWithSig: the same order tuple\n \"0xb866e173\": 4, // Swift createOrderWithEth((trader, tokenOut, …))\n \"0x8e8d142b\": 4 + 32 * 2, // Swift createOrderWithToken(tokenIn, amountIn, (trader, tokenOut, …))\n \"0x6111ad25\": 4 + 32 * 9, // MayanSwap swap(relayerFees, (mayanAddr, mayanChainId, auctionAddr, destAddr, destChainId, referrer, refundAddr), …)\n \"0x1eb1cff0\": 4 + 32 * 9, // MayanSwap wrapAndSwapETH: the same recipient tuple\n};\nfunction mayanRefunds(r: Reader, at: number): Refund[] {\n const p = r.bytes(at, at + 32 * 2);\n const pos = MAYAN_REFUND_AT[p.raw(0, 4)];\n return pos === undefined ? [] : [[\"the Mayan order's refund address\", p.address(pos)]];\n}\n/** Chainflip refunds the whole input to the address in `cfParameters` when the swap misses its minimum price:\n * VersionedCfParameters V1 (SCALE) — version, retry duration (u32), then the refund address, 20 bytes from an EVM chain. */\nfunction chainflipRefunds(r: Reader, at: number): Refund[] {\n const p = r.bytes(at, at + 32 * 5);\n if (p.length < 25 || p.raw(0, 1) !== \"0x01\") throw new Error(\"unknown Chainflip parameters\");\n return [[\"the Chainflip refund address\", p.raw(5, 20)]];\n}\n/** The Across Swap API call, by target: the SpokePool deposit's depositor (DepositParams, depositor first) and the\n * periphery's `depositData.depositor` get an expired deposit back (and the periphery's positive slippage); the\n * sponsored OFT and CCTP flows refund to an unsigned `refundRecipient`. */\nfunction acrossSwapRefunds(r: Reader, at: number): Refund[] {\n const target = r.word(at);\n const c = r.bytes(at, at + 32);\n // The facet refuses a zero depositor / refundRecipient on every target.\n if (target === 0n) return [[\"the Across deposit's depositor\", c.address(c.small(0)), true]];\n if (target === 1n) {\n const swap = c.small(0); // SwapAndDepositData: (submissionFees.amount, submissionFees.recipient, depositData, …)\n return [[\"the Across deposit's depositor\", c.address(swap + c.small(swap + 64) + 96), true]]; // BaseDepositData word 3\n }\n if (target === 2n) return [[\"the sponsored OFT refund recipient\", c.address(c.small(0) + 32), true]]; // (Quote(signed, unsigned), signature)\n if (target === 3n) return [[\"the sponsored CCTP refund recipient\", c.address(64), true]]; // (quote, signature, refundRecipient)\n throw new Error(\"unknown Across Swap API target\");\n}\n\n/** The EVM native-token placeholder (the zero address) in the quote's destination token. */\n/** ERC-20 `transfer(address,uint256)`. */\nconst ERC20_TRANSFER = \"0xa9059cbb\";\n/**\n * Eco v3 (EcoFacet 3.0.0, lifinance/contracts 9001792): EcoData is (nonEVMReceiver, prover, rewardDeadline,\n * intentDestination, encodedRoute, solanaATA, refundRecipient, deadline, signature), a dynamic struct. v2 decoded the\n * route on chain and required its final `transfer` to pay BridgeData.receiver; v3 dropped that check (\"for EVM\n * destinations the receiver is therefore enforced only by the backend signature, not on-chain\") and lets the route\n * run on another chain than the destination (`intentDestination`: the source chain for a CCTP burn, HyperEVM for a\n * HyperCore deposit, a second intent), with calls the facet does not interpret. So the device checks what v2 did, and\n * more: the intent runs on the destination chain itself, and the route — abi.encode(Route(salt, deadline, portal,\n * nativeAmount, tokens, calls)), Call = (target, data, value) — ends in the destination token's `transfer` of at least\n * the reviewed minimum to the recipient. Whatever runs before it, the solver's fill either pays that or does not\n * happen, and the reward (the input) then goes back to refundRecipient, checked above.\n */\nfunction ecoDelivery(r: Reader, at: number, e: DiamondExpectation): string | null {\n // A native delivery has no token `transfer` to read (it would be a value call to the recipient), so it is refused\n // outright — not left to the token comparison below, where a `transfer` \"of\" the zero address would match.\n if (kindOf(e.toToken) === \"native\") return \"an Eco route to the native token cannot be checked here\";\n const destination = r.word(at + 32 * 3);\n if (destination !== e.destChainId) return `the Eco intent executes on chain ${destination}, not the destination ${e.destChainId} — a route whose delivery cannot be checked here`;\n const route = r.bytes(at, at + 32 * 4);\n const tuple = route.small(0);\n const calls = tuple + route.small(tuple + 32 * 5);\n const n = route.small(calls);\n if (n === 0) return \"the Eco route makes no calls on the destination chain\";\n if (n > 16) return `the Eco route makes ${n} calls on the destination chain, more than the 16 read here`;\n const last = calls + 32 + route.small(calls + 32 + 32 * (n - 1));\n const target = route.address(last);\n const data = route.bytes(last, last + 32);\n if (route.word(last + 64) !== 0n || data.length !== 68 || data.raw(0, 4) !== ERC20_TRANSFER) return \"the Eco route does not end in a token transfer\";\n const to = data.address(4);\n const amount = data.word(36);\n if (!same(target, e.toToken)) return `the Eco route delivers ${target}, not ${e.toToken}`;\n if (!same(to, e.receiver)) return `the Eco route pays ${to}, not ${e.receiver}`;\n if (amount < e.minOut) return `the Eco route delivers ${amount}, below the ${e.minOut} shown`;\n return null;\n}\n/**\n * M0 (M0Facet 1.0.0): an order on the M0 OrderBook asks a solver for `amountOut` of `tokenOut` on the destination\n * (M0Data words 3 and 5); the facet ties only the receiver to BridgeData. Both must be the quote's: the destination\n * token, and at least the reviewed minimum. On the swap entry point the facet scales amountOut by the swap's realised\n * output over the quoted input (never below 1×), so the calldata's value is a lower bound there too. amountOut is a\n * limit rate, not a fill guarantee: a partial fill delivers its share and refunds the rest to orderOwner (the sender).\n */\nfunction m0Delivery(r: Reader, at: number, e: DiamondExpectation): string | null {\n // M0Facet refuses a zero tokenOut (the OrderBook would escrow the input with nothing to fill): no native delivery.\n if (kindOf(e.toToken) === \"native\") return \"an M0 order cannot deliver the native token\";\n const tokenOut = r.address(at + 32 * 3);\n const amountOut = r.word(at + 32 * 5);\n if (!same(tokenOut, e.toToken)) return `the M0 order asks for ${tokenOut}, not ${e.toToken}`;\n if (amountOut < e.minOut) return `the M0 order asks for ${amountOut}, below the ${e.minOut} shown`;\n return null;\n}\n\n/**\n * Where a bridge facet's data names who gets money back: an unused native fee, swap leftovers or positive slippage, the\n * whole input when a deposit, intent or order expires unfilled, or a fallback when delivery fails. The facets only\n * require these to be non-zero (NEAR Intents, LayerSwap and Eco also sign them on LI.FI's backend, which an `apiUrl`\n * proxy cannot forge but LI.FI's API itself writes), so each must be the sender or the recipient; LI.FI's live quotes\n * set them to the sender. `refunds` are [field, word] in the facet data (lifinance/contracts, the same structs at\n * 86c3729 and on main 2026-11-02; Eco as at v3.0.0, 9001792, whose entry points are the listed ones); `inline` marks a static\n * struct, which is encoded in place among the arguments rather than behind an offset (its word count). A zero is\n * accepted where the facet itself refuses a zero in every field it uses (`zeroRefused`; Polymer CCTP reads its\n * refundRecipient on the swap entry point only): it pays no one. Stargate passes a zero to LayerZero, and Mayan and\n * Chainflip carry theirs into the protocol, so there a zero is refused like any other address.\n */\ninterface FacetData {\n inline?: number;\n refunds?: readonly (readonly [string, number])[];\n zeroRefused?: true;\n nested?: (r: Reader, at: number) => Refund[];\n /** What the facet data says the destination receives, held to the quote: a reason it does not match, or null. */\n delivery?: (r: Reader, at: number, e: DiamondExpectation) => string | null;\n}\n/** [what, address, a zero there is refused by the facet]. */\ntype Refund = [string, string, boolean?];\nconst FACET_DATA: Readonly<Record<string, FacetData>> = {\n AcrossV4: {refunds: [[\"refundAddress\", 1]], zeroRefused: true}, // the SpokePool depositor: an expired deposit refunds the input there\n AcrossV4Swap: {nested: acrossSwapRefunds},\n Centrifuge: {inline: 2, refunds: [[\"refundRecipient\", 1]], zeroRefused: true},\n Chainflip: {nested: chainflipRefunds},\n Eco: {refunds: [[\"refundRecipient\", 6]], zeroRefused: true, delivery: ecoDelivery}, // the intent's creator, refunded its reward (the input) on expiry\n Frax: {inline: 5, refunds: [[\"refundRecipient\", 3]], zeroRefused: true},\n Glacis: {inline: 4, refunds: [[\"refundAddress\", 1]], zeroRefused: true},\n LayerSwap: {refunds: [[\"refundRecipient\", 2]], zeroRefused: true},\n // The escrow order's user. Not reached while LI.FI Intents is refused on every EVM-source route (INTENTS_UNPINNED); kept for when\n // its oracles and settler are pinned.\n LiFiIntentEscrowV2: {refunds: [[\"depositAndRefundAddress\", 2]], zeroRefused: true},\n M0: {inline: 7, refunds: [[\"refundRecipient\", 1], [\"orderOwner\", 2]], zeroRefused: true, delivery: m0Delivery}, // orderOwner gets a cancelled order back\n Mayan: {refunds: [[\"refundRecipient\", 7]], nested: mayanRefunds, zeroRefused: true},\n NEARIntents: {refunds: [[\"refundRecipient\", 6]], zeroRefused: true}, // also the 1Click quote's refundTo\n PolymerCCTP: {refunds: [[\"refundRecipient\", 5]], zeroRefused: true},\n Stargate: {refunds: [[\"refundAddress\", 4]]}, // (assetId, sendParams, fee.nativeFee, fee.lzTokenFee, refundAddress): LayerZero's fee refund\n Superset: {refunds: [[\"refundAddress\", 2], [\"fallbackEoA\", 3]], zeroRefused: true},\n};\n/**\n * Facets whose data names no one to pay back: Across (the SpokePool's depositor is the Diamond), AllBridge, Celer\n * Circle, GasZip, MegaETH and Optimism (no address but the receiver the facet checks), Arbitrum (its retryable's\n * refunds go to BridgeData.receiver), Gnosis, Omni and Polygon (no facet data) and Unit (its own deposit address,\n * signed). Their excess native and swap leftovers go to the caller.\n */\nconst NO_REFUND_FIELDS = new Set([\"Across\", \"AllBridge\", \"ArbitrumBridge\", \"CelerCircleBridge\", \"GasZip\", \"GnosisBridge\", \"MegaETHBridge\", \"OmniBridge\", \"OptimismBridge\", \"PolygonBridge\", \"Unit\"]);\n\n/** Where the facet data starts: the last argument, after BridgeData's offset word (and the SwapData[]'s). */\nfunction facetDataAt(r: Reader, bridge: {sourceSwaps: boolean}, spec: FacetData): number {\n const slot = 4 + (bridge.sourceSwaps ? 64 : 32);\n return spec.inline ? slot : 4 + r.small(slot);\n}\n\n/** A refund or fallback in the bridge's facet data that pays neither the sender nor the recipient, or null. */\nfunction refundMismatch(r: Reader, bridge: {sourceSwaps: boolean; facet: string}, e: DiamondExpectation): string | null {\n const spec = FACET_DATA[bridge.facet];\n if (!spec) return NO_REFUND_FIELDS.has(bridge.facet) ? null : `no known refund layout for ${bridge.facet}`;\n const at = facetDataAt(r, bridge, spec);\n const paid: Refund[] = (spec.refunds ?? []).map(([field, word]) => [`${bridge.facet} ${field}`, r.address(at + 32 * word), spec.zeroRefused === true]);\n paid.push(...(spec.nested?.(r, at) ?? []));\n for (const [what, to, zeroRefused] of paid) {\n if (zeroRefused && /^0x0{40}$/.test(to)) continue;\n if (!same(to, e.sender) && !same(to, e.receiver)) return `${what} pays ${to}, neither the sender ${e.sender} nor the recipient`;\n }\n return null;\n}\n\n/** The refusal for a non-EVM destination whose recipient this module does not read. */\nconst NON_EVM_UNREAD = \"the recipient on a non-EVM destination sits in bridge-specific data and cannot be checked here\";\n/** LI.FI's Solana chain id and the BridgeData.receiver of a non-EVM destination (LiFiData.sol, lifinance/contracts). */\nconst LIFI_SOLANA_CHAIN_ID = 1151111081099710n;\nconst NON_EVM_ADDRESS = \"0x11f111f111f111f111f111f111f111f111f111f1\";\nconst SOLANA_USDC = \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\";\n/** Solana as Mayan names it: Wormhole chain 1, CCTP domain 5 (Mayan swap-sdk `utils.ts` / `cctp.ts`; Circle's domain list). */\nconst WORMHOLE_SOLANA = 1n;\nconst CCTP_DOMAIN_SOLANA = 5n;\n/** Chainflip's asset ids on Solana (SOL, USDC, USDT), as `@anywalletkit/protocol-swap2-chainflip` lists them. */\nconst CHAINFLIP_SOLANA_ASSETS: Readonly<Record<string, bigint>> = {\n \"11111111111111111111111111111111\": 9n,\n [SOLANA_USDC]: 10n,\n Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB: 16n,\n};\n/** Facets that pay a deposit address or a depository whose off-chain order names the recipient. */\nconst DEPOSIT_FACETS = new Set([\"NEARIntents\", \"LayerSwap\", \"Unit\"]);\n\n/** A Mayan call's Solana fields, as head words of `protocolData` after its selector (Mayan swap-sdk ABIs, selectors as MayanFacet lists them). */\ninterface MayanSolanaLayout {destAddr: number; chain: number; cctp: boolean; payloadType?: readonly [number, bigint]; tokenOut?: number}\nconst MAYAN_SOLANA: Readonly<Record<string, MayanSolanaLayout>> = {\n // Swift v2 createOrderWithToken(tokenIn, amountIn, (payloadType, trader, destAddr, destChainId, referrerAddr, tokenOut, minAmountOut, …), customPayload)\n \"0xa3a30834\": {destAddr: 4, chain: 5, cctp: false, payloadType: [2, 1n], tokenOut: 7},\n // MCTP createOrder((tokenIn, amountIn, gasDrop, destAddr, destChain, tokenOut, minAmountOut, deadline, redeemFee, referrerAddr, referrerBps))\n \"0x1c59b7fc\": {destAddr: 3, chain: 4, cctp: false, tokenOut: 5},\n // MCTP bridgeWithFee(tokenIn, amountIn, redeemFee, gasDrop, destAddr, destDomain, payloadType, customPayload): delivers USDC\n \"0x2072197f\": {destAddr: 4, chain: 5, cctp: true, payloadType: [6, 1n]},\n // Fast MCTP bridge(tokenIn, amountIn, redeemFee, circleMaxFee, gasDrop, destAddr, destDomain, referrerAddress, referrerBps, payloadType, minFinalityThreshold, customPayload): delivers USDC\n \"0xf58b6de8\": {destAddr: 5, chain: 6, cctp: true, payloadType: [9, 1n]},\n // Fast MCTP createOrder(tokenIn, amountIn, circleMaxFee, destDomain, minFinalityThreshold, (payloadType 3, destAddr, tokenOut, amountOutMin, …))\n \"0x2337e236\": {destAddr: 6, chain: 3, cctp: true, payloadType: [5, 3n], tokenOut: 7},\n};\n\n/** What a Solana delivery must name: the requested owner and mint, as raw keys and as 0x-hex words. */\ninterface SolanaTarget {owner: Uint8Array; ownerHex: string; mint: Uint8Array; mintHex: string; e: DiamondExpectation}\nconst hexOf = (b: Uint8Array): string => `0x${Array.from(b, (x) => x.toString(16).padStart(2, \"0\")).join(\"\")}`;\n/** A 0x-hex 32-byte word as a Solana address, for messages. */\nconst keyOf = (word: string): string => base58(Uint8Array.from(word.slice(2).match(/../g) ?? [], (h) => Number.parseInt(h, 16)));\n\n/**\n * Mayan (MayanFacet 2.0.0) requires MayanData.nonEVMReceiver to equal the destination address inside `protocolData`, the\n * order or transfer it forwards to Mayan; both are read. For Solana Mayan's swap-sdk writes the owner wallet there\n * (`nativeAddressToHexString(destinationAddress, solana)`), and Mayan's programs pay its associated token account. An\n * order names its output token (the mint; 32 zero bytes for SOL) and Solana as Wormhole chain 1 or CCTP domain 5; a\n * plain CCTP transfer delivers USDC. A custom payload (a handler as destAddr) is refused.\n */\nfunction mayanToSolana(r: Reader, at: number, t: SolanaTarget): string | null {\n const declared = r.raw(at, 32);\n if (declared !== t.ownerHex) return `Mayan's nonEVMReceiver is ${keyOf(declared)}, not the recipient ${t.e.receiver}`;\n const p = r.bytes(at, at + 32 * 2);\n const selector = p.raw(0, 4);\n const o = MAYAN_SOLANA[selector];\n if (!o) return `the Mayan call ${selector} is an entry point whose Solana recipient cannot be checked here`;\n const word = (i: number) => 4 + 32 * i;\n if (o.payloadType && p.word(word(o.payloadType[0])) !== o.payloadType[1]) return `the Mayan call ${selector} carries payload type ${p.word(word(o.payloadType[0]))}, not a plain delivery`;\n const dest = p.raw(word(o.destAddr), 32);\n if (dest !== t.ownerHex) return `the Mayan order pays ${keyOf(dest)} on Solana, not the recipient ${t.e.receiver}`;\n const chain = p.word(word(o.chain));\n if (chain !== (o.cctp ? CCTP_DOMAIN_SOLANA : WORMHOLE_SOLANA)) return `the Mayan order goes to ${o.cctp ? \"CCTP domain\" : \"Wormhole chain\"} ${chain}, not Solana`;\n if (o.tokenOut === undefined) return t.e.toToken === SOLANA_USDC ? null : `a Mayan CCTP transfer delivers USDC, not ${t.e.toToken}`;\n const token = p.raw(word(o.tokenOut), 32);\n return token === t.mintHex ? null : `the Mayan order delivers ${keyOf(token)}, not ${t.e.toToken}`;\n}\n\n/**\n * Polymer CCTP (PolymerCCTPFacet 3.1.0): CCTP mints to `solanaReceiverATA`, which the facet cannot check (\"must be the\n * USDC ATA of nonEVMReceiver\"; nonEVMReceiver is the owner wallet the relayer reads). It must be the associated token\n * account of the requested owner for USDC, derived here.\n */\nfunction polymerToSolana(r: Reader, at: number, t: SolanaTarget): string | null {\n const declared = r.raw(at + 32 * 2, 32);\n if (declared !== t.ownerHex) return `Polymer CCTP's nonEVMReceiver is ${keyOf(declared)}, not the recipient ${t.e.receiver}`;\n if (t.e.toToken !== SOLANA_USDC) return `Polymer CCTP delivers USDC, not ${t.e.toToken}`;\n const mintTo = r.raw(at + 32 * 3, 32);\n const account = hexOf(associatedTokenAccount(t.owner, t.mint));\n return mintTo === account ? null : `the Polymer CCTP transfer mints to ${keyOf(mintTo)}, not the recipient's USDC account ${keyOf(account)}`;\n}\n\n/** Chainflip (ChainflipFacet 1.0.1): the vault swap's dstAddress is `nonEVMReceiver` verbatim (32 bytes, the owner, for Solana) and `dstToken` Chainflip's asset id. */\nfunction chainflipToSolana(r: Reader, at: number, t: SolanaTarget): string | null {\n const dst = r.bytes(at, at);\n if (dst.length !== 32) return `Chainflip pays a ${dst.length}-byte address on Solana, not the recipient ${t.e.receiver}`;\n if (dst.raw(0, 32) !== t.ownerHex) return `Chainflip pays ${keyOf(dst.raw(0, 32))} on Solana, not the recipient ${t.e.receiver}`;\n const asset = r.word(at + 32);\n const want = CHAINFLIP_SOLANA_ASSETS[t.e.toToken];\n return want !== undefined && asset === want ? null : `Chainflip delivers its asset ${asset}, not ${t.e.toToken}`;\n}\n\nconst SOLANA_DELIVERY: Readonly<Record<string, (r: Reader, at: number, t: SolanaTarget) => string | null>> = {\n Mayan: mayanToSolana,\n PolymerCCTP: polymerToSolana,\n Chainflip: chainflipToSolana,\n};\n\n/**\n * LI.FI Intents (LiFiIntentEscrowFacetV2 2.0.0) escrows the input on the source chain for an order whose `inputOracle`,\n * `outputOracle`, `outputSettler` and `outputAmountMultiplier` come from the calldata: the escrow releases the input to\n * whoever the input oracle says filled the order, and the committed output is `input × multiplier / 1e18`. Naming the\n * recipient and the output token binds nothing while an API or proxy can name its own oracle (which then attests a fill\n * that never happened) or a near-zero multiplier, and these addresses are not pinned here for Solana's settler and\n * oracle — so an Intents order to Solana is refused, recipient read or not.\n */\nconst INTENTS_TO_SOLANA = \"a LI.FI Intents order to Solana names its own oracles, output settler and output amount, which cannot be checked here — its escrow could release the input without the delivery\";\n/**\n * The same holds between EVM chains: the escrow trusts the `inputOracle` the calldata names, the output side runs through\n * the `outputSettler` and `outputOracle` it names, and the committed output is `input × outputAmountMultiplier / 1e18`;\n * none of them is pinned or bounded here (lifinance/contracts LiFiIntentEscrowFacetV2 2.0.0 only requires the recipient\n * and a non-zero refund address). An Intents call to an EVM chain (or on a same-chain route) is refused before anything\n * else is read; to Solana with {@link INTENTS_TO_SOLANA}.\n */\nconst INTENTS_UNPINNED = \"a LI.FI Intents order to an EVM chain names its own oracles, output settler and output amount, which cannot be checked here — its escrow could release the input without the delivery\";\nconst INTENTS_FACET = \"LiFiIntentEscrowV2\";\n\n/**\n * EVM → Solana: BridgeData must name LI.FI's Solana chain id (checked by the caller) and, as its receiver, exactly the\n * NON_EVM_ADDRESS placeholder; the recipient sits in the facet's own data and is held here to the requested owner (the\n * raw 32 bytes of `destAddress`) and the requested mint, for the facets whose delivery the transaction binds (Mayan,\n * Polymer CCTP, Chainflip). NEAR Intents, LayerSwap and Unit pay a deposit address or a depository whose off-chain order\n * names the recipient: a deposit the device cannot verify, refused for this direction. LI.FI Intents is refused\n * ({@link INTENTS_TO_SOLANA}). Any other facet keeps the non-EVM refusal.\n */\nfunction solanaRecipientMismatch(r: Reader, bridge: {sourceSwaps: boolean; facet: string}, receiver: string, e: DiamondExpectation): string | null {\n if (e.destChainId !== LIFI_SOLANA_CHAIN_ID) return NON_EVM_UNREAD;\n if (!same(receiver, NON_EVM_ADDRESS)) return `BridgeData pays ${receiver}, not LI.FI's non-EVM placeholder ${NON_EVM_ADDRESS}, on a Solana route`;\n if (DEPOSIT_FACETS.has(bridge.facet)) return `${bridge.facet} pays a deposit address whose off-chain order names the Solana recipient — the transaction does not bind it`;\n if (bridge.facet === INTENTS_FACET) return INTENTS_TO_SOLANA;\n const read = SOLANA_DELIVERY[bridge.facet];\n if (!read) return NON_EVM_UNREAD;\n const owner = solanaKey(e.receiver);\n if (!owner) return `the recipient ${e.receiver} is not a Solana address`;\n const mint = solanaKey(e.toToken);\n if (!mint) return `the destination token ${e.toToken} is not a Solana mint`;\n return read(r, facetDataAt(r, bridge, FACET_DATA[bridge.facet]!), {owner, ownerHex: hexOf(owner), mint, mintHex: hexOf(mint), e});\n}\n\n/** Why the Diamond calldata does not do what the quote says, or null when it does. */\nexport function diamondCallMismatch(data: string, e: DiamondExpectation): string | null {\n let r: Reader;\n try { r = new Reader(data); } catch { return \"the calldata is not hex\"; }\n if (r.length < 4 + 32 * 2) return \"the calldata is too short\";\n const selector = data.slice(0, 10).toLowerCase();\n const generic = GENERIC_SWAPS[selector];\n try {\n if (generic) {\n if (!e.sameChain) return \"a same-chain swap call on a cross-chain route\";\n // (bytes32 txId, string integrator, string referrer, address receiver, uint256 minAmount, SwapData | SwapData[])\n const receiver = r.address(4 + 96);\n const minAmount = r.word(4 + 128);\n const steps = generic.single ? [swapAt(r, 4 + r.small(4 + 160))] : swapsAt(r, 4, 4 + 160);\n if (!e.evmDestination || !same(receiver, e.receiver)) return `pays ${receiver}, not ${e.receiver}`;\n if (minAmount < e.minOut) return `accepts ${minAmount}, below the ${e.minOut} shown`;\n if (generic.from && kindOf(e.fromToken) !== generic.from) return `${selector} swaps from ${generic.from === \"native\" ? \"the native coin\" : \"a token\"}, but the input is ${kindOf(e.fromToken) === \"native\" ? \"the native coin\" : \"a token\"}`;\n if (generic.to && (kindOf(e.toToken) !== generic.to || kindOf(steps[steps.length - 1]!.receivingAssetId) !== generic.to)) {\n return `${selector} delivers ${generic.to === \"native\" ? \"the native coin\" : \"a token\"}, but the output is ${kindOf(e.toToken) === \"native\" ? \"the native coin\" : \"a token\"} — its minimum would be counted in the wrong asset`;\n }\n return checkSteps(steps, e, e.toToken);\n }\n // Bridge facets: (BridgeData, [SwapData[],] FacetData), only the listed ABI entry points.\n // BridgeData is dynamic (it holds strings), so its offset is the head size.\n const unbound = UNBOUND_BRIDGES[selector];\n if (unbound) return `${unbound} delivers to a recipient the transaction does not bind (an off-chain order or unchecked facet data)`;\n const bridge = BRIDGE_CALLS[selector];\n if (!bridge) return `unknown Diamond call ${selector}`;\n if (bridge.facet === INTENTS_FACET && e.evmDestination) return INTENTS_UNPINNED;\n const head = r.small(4);\n if (head < (bridge.sourceSwaps ? 96 : 64) || head % 32 !== 0 || head > 32 * 32) return `unknown Diamond call ${selector}`;\n const at = 4 + head;\n // BridgeData: (txId, string bridge, string integrator, referrer, sendingAssetId, receiver, minAmount, destinationChainId, hasSourceSwaps, hasDestinationCall)\n if (r.small(at + 32) !== 320) return `unknown Diamond call ${selector}`;\n const sendingAssetId = r.address(at + 128);\n const receiver = r.address(at + 160);\n const minAmount = r.word(at + 192);\n const destinationChainId = r.word(at + 224);\n const hasSourceSwaps = r.bool(at + 256);\n const hasDestinationCall = r.bool(at + 288);\n if (e.sameChain) return \"a bridge call on a same-chain route\";\n if (destinationChainId !== e.destChainId) return `bridges to chain ${destinationChainId}, not ${e.destChainId}`;\n if (hasDestinationCall) return \"the route runs a call on the destination chain, whose recipient cannot be checked here\";\n if (!e.evmDestination) {\n const why = solanaRecipientMismatch(r, bridge, receiver, e);\n if (why) return why;\n } else if (!same(receiver, e.receiver)) return `pays ${receiver}, not ${e.receiver}`;\n if (hasSourceSwaps !== bridge.sourceSwaps) return `unknown Diamond call ${selector}`;\n const refund = refundMismatch(r, bridge, e);\n if (refund) return refund;\n const spec = FACET_DATA[bridge.facet];\n const delivery = spec?.delivery?.(r, facetDataAt(r, bridge, spec), e);\n if (delivery) return delivery;\n // After source swaps the bridged amount is in the swapped token's units: only the swaps' input is comparable.\n if (hasSourceSwaps) {\n // The swapped amount is the facet's own (it replaces minAmount after the swaps); a zero is a route that bridges nothing.\n if (minAmount === 0n) return \"bridges nothing after the source swaps\";\n return checkSteps(swapsAt(r, 4, 4 + 32), e, sendingAssetId);\n }\n // Without source swaps the Diamond pulls minAmount: the input, or the input less a bridge's own fee (Glacis takes\n // 0.25 %, matrix v7). Anything further below leaves the rest of the allowance behind for the next call to take\n // (scan 2026-10-27 modules, F22): a minAmount of 1 is refused.\n if (minAmount > e.amountIn || minAmount * 10_000n < e.amountIn * (10_000n - BRIDGE_INPUT_FEE_MAX_BPS)) return `bridges ${minAmount}, not the ${e.amountIn} spent`;\n return same(sendingAssetId, e.fromToken) ? null : `bridges ${sendingAssetId}, not ${e.fromToken}`;\n } catch (err) {\n return `the Diamond calldata does not decode (${err instanceof Error ? err.message : String(err)})`;\n }\n}\n","/**\n * A first look at LI.FI's Solana bridge transaction, from its bytes alone (no RPC: accounts loaded from lookup tables\n * stay unknown). It must be paid by the sender. A Mayan route (it calls Mayan's CPI proxy or an order program) must\n * also pay SOL directly to no wallet other than the sender or LI.FI's fee wallet: the account's guard proves its order\n * pays the reviewed recipient (`bridgeOut`). LI.FI's other Solana bridges (Relay, LayerSwap, NEAR Intents, LI.FI\n * Intents, …) deposit to an address, an order id or a program whose recipient lives off chain or in data the device\n * does not read; they pass here as they are and are held by the account to its SOL and token ceilings only.\n */\n\nimport {base64Bytes} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {base58} from \"./solana-address.js\";\n\n/** Mayan's CPI proxy and order programs (swap-sdk `src/addresses.ts`). */\nconst MAYAN_ENTRY_PROGRAMS = new Set([\n \"D8C8iW6zmoKg5TRr8nQ7h14TMWqQX8FiBdj2ju5MF3wa\", // CPI_PROXY_PROGRAM_ID\n \"BLZRi6frs4X4DNLw56V4EXai1b6QVESN1BhHBTYM9VcY\", // SWIFT_PROGRAM_ID\n \"mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny\", // SWIFT_V2_PROGRAM_ID\n \"dkpZqrxHFrhziEMQ931GLtfy11nFkCsfMftH9u6QwBU\", // MCTP_PROGRAM_ID\n \"Gx9rivpS3YR8pBFwMuP6omYqVxunpLvLkNn7ubNyuZZ5\", // FAST_MCTP_PROGRAM_ID\n]);\nconst SYSTEM_PROGRAM = \"11111111111111111111111111111111\";\n/** LI.FI's fee wallet on Solana (its `feeCollection` step pays SOL here, tokens to its token accounts). */\nexport const LIFI_SOLANA_FEE_WALLET = \"34FKjAdVcTax2DHqV2XnbXa9J3zmyKcFuFKWbcmgxjgm\";\n\nclass Cursor {\n at = 0;\n constructor(private readonly b: Uint8Array) {}\n byte(): number {\n if (this.at >= this.b.length) throw new Error(\"truncated\");\n return this.b[this.at++]!;\n }\n bytes(n: number): Uint8Array {\n if (n < 0 || this.at + n > this.b.length) throw new Error(\"truncated\");\n const out = this.b.subarray(this.at, this.at + n);\n this.at += n;\n return out;\n }\n /** compact-u16 */\n short(): number {\n let v = 0;\n for (let shift = 0; shift < 21; shift += 7) {\n const b = this.byte();\n v |= (b & 0x7f) << shift;\n if (!(b & 0x80)) return v;\n }\n throw new Error(\"bad length\");\n }\n}\n\n/** Why the transaction is visibly wrong for `sender` (see the module note), or null when its static part is consistent with a bridge. */\nexport function solanaBridgeTxMismatch(base64: string, sender: string): string | null {\n const bytes = base64Bytes(base64);\n if (!bytes) return \"the Solana transaction is not base64\";\n const c = new Cursor(bytes);\n try {\n c.bytes(64 * c.short()); // signatures\n const first = c.byte();\n if ((first & 0x80) === 0) c.at--; // legacy message: no version prefix\n c.bytes(3); // header\n const keys = Array.from({length: c.short()}, () => base58(c.bytes(32)));\n if (keys[0] !== sender) return `the Solana transaction is paid by ${keys[0] ?? \"nobody\"}, not the sender ${sender}`;\n c.bytes(32); // recent blockhash\n let mayan = false;\n const payees: string[] = [];\n const n = c.short();\n for (let i = 0; i < n; i++) {\n const program = keys[c.byte()];\n const accounts = Array.from(c.bytes(c.short()));\n const data = c.bytes(c.short());\n if (program !== undefined && MAYAN_ENTRY_PROGRAMS.has(program)) mayan = true;\n // System Transfer: u32 tag 2, u64 lamports; [from, to]. A destination in a lookup table is left to the account.\n if (program === SYSTEM_PROGRAM && data.length === 12 && data[0] === 2 && data[1] === 0 && data[2] === 0 && data[3] === 0) {\n const to = keys[accounts[1] ?? -1];\n if (to !== undefined && to !== sender && to !== LIFI_SOLANA_FEE_WALLET) payees.push(to);\n }\n }\n // A deposit to an address is how the other bridges are paid; a Mayan route moves its funds through its order.\n return mayan && payees.length ? `the Solana transaction transfers SOL to ${payees[0]}, which is neither the sender nor LI.FI's fee wallet` : null;\n } catch (err) {\n return `the Solana transaction does not decode (${err instanceof Error ? err.message : String(err)})`;\n }\n}\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {LIFI_SOLANA_CAIP2, lifi as lifiCfg} from \"./config.js\";\nimport {describeLifiActivity} from \"./activity.js\";\nimport {diamondCallMismatch} from \"./calldata.js\";\nimport {solanaBridgeTxMismatch} from \"./solana.js\";\nimport {timeoutSignal, sourceAssetOf} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {slippageFloor} from \"@anywalletkit/protocol-swap2-core/validate\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {bigintToNumber} from \"@anywalletkit/core\";\n\n/**\n * LI.FI meta-aggregator — the CALLDATA execution model: the quote returns a\n * `transactionRequest` the USER'S WALLET must execute. There is no deposit\n * address — a plain transfer to `transactionRequest.to` would lose funds, so\n * the client branches on `quote.txRequest`. Live-verified shapes (2026-07):\n * EVM → {to, data, value, chainId, gasLimit}; Solana → {data: base64 tx}, a\n * fully built v0 transaction (Jupiter route) the account signs after proving\n * its balance effects (`serializedTx`). Tron returns a raw protobuf we can't\n * hand to wallets yet — Tron stays on the direct NEAR Intents route (LI.FI\n * routes it through NEAR anyway, so nothing is lost).\n */\n\nconst DEFAULT_LIFI_BASE = \"https://li.quest/v1\";\n\n/** Our CAIP-2 → LI.FI chain ids. */\nconst LIFI_CHAIN: Record<string, string> = {\n \"eip155:1\": \"1\",\n \"eip155:8453\": \"8453\",\n \"eip155:56\": \"56\",\n \"eip155:137\": \"137\",\n \"eip155:42161\": \"42161\",\n \"eip155:10\": \"10\",\n \"eip155:100\": \"100\",\n \"eip155:143\": \"143\",\n \"eip155:130\": \"130\",\n \"eip155:999\": \"999\",\n \"eip155:4663\": \"4663\",\n // 2026-08 sweep additions (all live on li.quest/v1/chains).\n \"eip155:43114\": \"43114\",\n \"eip155:534352\": \"534352\",\n \"eip155:80094\": \"80094\",\n // 2026-10-12: zkSync Era, Celo, MegaETH (live on li.quest/v1/chains).\n \"eip155:324\": \"324\",\n \"eip155:42220\": \"42220\",\n \"eip155:4326\": \"4326\",\n \"eip155:9745\": \"9745\",\n \"eip155:59144\": \"59144\",\n \"eip155:146\": \"146\",\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer (live on li.quest/v1/chains).\n \"eip155:480\": \"480\",\n \"eip155:1329\": \"1329\",\n \"eip155:57073\": \"57073\",\n \"eip155:98866\": \"98866\",\n \"eip155:196\": \"196\",\n // 2026-10-14: Arc, Mantle, Katana, Morph, Flare (live on li.quest/v1/chains). On Arc LI.FI's \"native\" is the USDC\n // ERC-20 interface 0x3600…: a 0x0 fromToken is rewritten to it and the Diamond pulls via transferFrom (value 0), so\n // the catalog lists Arc USDC as that token — the engine then runs the ordinary approve + call path.\n \"eip155:5042\": \"5042\",\n \"eip155:5000\": \"5000\",\n \"eip155:747474\": \"747474\",\n \"eip155:2818\": \"2818\",\n \"eip155:14\": \"14\",\n // 2026-11-10: Elysium (Kinetiq; li.quest/v1/chains id 99901, key \"ely\"). LI.FI's bridges there are Relay (refused\n // below: UNBOUND_TOOLS) and LI.FI Intents (refused too: UNPINNED_TOOLS), so it has no cross-chain LI.FI route for now;\n // same-chain swaps go through GenericSwapFacetV3 (KyberSwap, Nordstern).\n \"eip155:99901\": \"99901\",\n [LIFI_SOLANA_CAIP2]: \"1151111081099710\",\n};\nconst CAIP2_BY_LIFI_CHAIN: Record<string, string> = Object.fromEntries(Object.entries(LIFI_CHAIN).map(([caip2, id]) => [id, caip2]));\n\nconst EVM_ZERO = \"0x0000000000000000000000000000000000000000\";\n/** LI.FI's native-SOL token id (the System program address). */\nconst SOLANA_NATIVE = \"11111111111111111111111111111111\";\nconst EVM_PLACEHOLDER = \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\";\n/** Dry-quote sender on Solana: the publicly known BIP-39 \"abandon\" account 0. */\nconst SOLANA_PLACEHOLDER = \"HAgk14JpMQLgt6rVgv7cBQFJWFto5Dqxi472uT3DKpqk\";\nconst isSolana = (chain: string) => chain === LIFI_SOLANA_CAIP2;\nconst BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\nconst BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;\n/** Chain-aware address equality: EVM case-insensitive, Solana exact base58. */\n/** Longest execution a same-chain route may claim and still be an atomic swap (DEX routes report 0–30 s). */\nconst SAME_CHAIN_MAX_SECONDS = 90;\n/** Largest fee a bridge may take from the input itself (glacis ≈ 0.25 %, 2026-10). Above it the quote is refused, named. */\nconst MAX_INPUT_FEE_BPS = 300;\n\nfunction sameChainAddress(chain: string, actual: string | undefined, expected: string): boolean {\n if (isSolana(chain)) return !!actual && BASE58.test(actual) && actual === expected;\n return sameAddress(actual, expected);\n}\n/** The engine's native sentinel (`0x0…`) in the chain's own notation. */\nfunction nativeFor(chain: string, token: string): string {\n if (/^0x0+$/.test(token) || token === SOLANA_NATIVE) return isSolana(chain) ? SOLANA_NATIVE : EVM_ZERO;\n return token;\n}\n/** LI.FI's documented Diamond entry point on most supported EVM networks. */\nconst LIFI_DIAMOND = \"0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE\";\n/**\n * Chains where the Diamond lives at a different address — from\n * github.com/lifinance/contracts `deployments/<chain>.json` (`LiFiDiamond`).\n * On these chains ONLY that address is the entry point; the canonical one is\n * not deployed there and is therefore not trusted.\n */\nconst LIFI_DIAMONDS: Readonly<Record<string, string>> = {\n \"eip155:4663\": \"0xB477751B76CF82d00a686A1232f5fCD772414Af3\", // Robinhood Chain (deployments/robinhood.json, verified 2026-10-09)\n \"eip155:999\": \"0x0a0758d937d1059c356D4714e57F5df0239bce1A\", // HyperEVM (deployments/hyperevm.json, verified 2026-10-09)\n \"eip155:143\": \"0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37\", // Monad (deployments/monad.json, verified 2026-10-11)\n \"eip155:130\": \"0x864b314D4C5a0399368609581d3E8933a63b9232\", // Unichain (deployments/unichain.json, verified 2026-10-11)\n \"eip155:80094\": \"0xf909c4Ae16622898b885B89d7F839E0244851c66\", // Berachain (deployments/berachain.json, verified 2026-10-11)\n \"eip155:324\": \"0x341e94069f53234fE6DabeF707aD424830525715\", // zkSync Era (deployments/zksync.json, matches a live quote 2026-10-12)\n \"eip155:9745\": \"0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37\", // Plasma (deployments/plasma.json, 2026-10-13)\n \"eip155:59144\": \"0xDE1E598b81620773454588B85D6b5D4eEC32573e\", // Linea (deployments/linea.json, 2026-10-13)\n \"eip155:57073\": \"0x864b314D4C5a0399368609581d3E8933a63b9232\", // Ink (deployments/ink.json, 2026-10-13)\n \"eip155:98866\": \"0x6f5C8Bb0C5Fe4ECeAC40EE1C238EaB6bbb29761c\", // Plume (deployments/plume.json, 2026-10-13)\n // 2026-10-14: li.quest/v1/chains `diamondAddress`, eth_getCode non-empty on each. Mantle and Flare carry the canonical\n // 0x1231… Diamond (the default).\n \"eip155:5042\": \"0xA4072583658Fae592A3506A42431cb6316a8d40b\", // Arc\n \"eip155:747474\": \"0xC59fe32C9549e3E8B5dCcdAbC45BD287Bd5bA2bc\", // Katana\n \"eip155:2818\": \"0xF7aB42D00D2399f8A4Fba2F15466Be40709fe307\", // Morph\n \"eip155:14\": \"0x198FC70Dfe05E755C81e54bd67Bff3F729344B9b\", // Flare (li.quest diamondAddress 2026-10-14; the canonical 0x1231… has no code there)\n // Elysium: li.quest diamondAddress = deployments/elysium.json LiFiDiamond; code on 99901, DiamondLoupe facets() serves\n // GenericSwapFacetV3 + LiFiIntentEscrowFacetV2; the canonical 0x1231… has no code there (all read 2026-11-10).\n \"eip155:99901\": \"0x24E6dA91AA4A8FEe2447F542c92E006243bd6Dc5\", // Elysium\n \"eip155:4326\": \"0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37\", // MegaETH (deployments/megaeth.json, matches a live quote 2026-10-12)\n};\nconst diamondFor = (chain: string): string => LIFI_DIAMONDS[chain] ?? LIFI_DIAMOND;\nconst DEFAULT_QUOTE_TTL_MS = 55_000;\n\nfunction normalizeAddress(value: string | undefined): string | null {\n return value && /^0x[0-9a-fA-F]{40}$/.test(value) ? value.toLowerCase() : null;\n}\n\nfunction sameAddress(actual: string | undefined, expected: string): boolean {\n return normalizeAddress(actual) === normalizeAddress(expected);\n}\n\nfunction isHexData(value: string | undefined): value is string {\n return !!value && /^0x(?:[0-9a-fA-F]{2})+$/.test(value);\n}\n\nfunction trustedAddress(\n chain: string,\n address: string | undefined,\n configured: ReadonlyMap<string, ReadonlySet<string>>,\n): boolean {\n const normalized = normalizeAddress(address);\n if (!normalized) return false;\n return normalizeAddress(diamondFor(chain)) === normalized || configured.get(chain)?.has(normalized) === true;\n}\n\nfunction trustMap(input: Readonly<Record<string, readonly string[]>> | undefined, label: string): ReadonlyMap<string, ReadonlySet<string>> {\n const out = new Map<string, ReadonlySet<string>>();\n for (const [chain, addresses] of Object.entries(input ?? {})) {\n const normalized = new Set<string>();\n for (const address of addresses) {\n const value = normalizeAddress(address);\n if (!value) throw new Error(`lifi: invalid ${label} address for ${chain}`);\n normalized.add(value);\n }\n out.set(chain, normalized);\n }\n return out;\n}\n\n/** LI.FI token id on the source chain: contract, or the chain's native id. */\nfunction lifiToken(params: Pick<QuoteParams, \"sourceChain\" | \"sourceToken\" | \"sourceDecimals\">): string | null {\n const sourceChain = params.sourceChain;\n const asset = sourceAssetOf(params);\n if (!asset) return null;\n if (asset.contract) return asset.contract;\n return isSolana(sourceChain) ? SOLANA_NATIVE : EVM_ZERO;\n}\n\nfunction headers(key: string | undefined): Record<string, string> {\n const h: Record<string, string> = {accept: \"application/json\"};\n if (key) h[\"x-lifi-api-key\"] = key;\n return h;\n}\n\n/** Explicit constructor configuration; no deployment environment is read. */\nexport interface LifiProviderConfig {\n enabled?: boolean;\n /** LI.FI REST base URL. Explicitly injectable for proxies and tests; must be https unless `allowInsecureApiUrl`. */\n apiUrl?: string;\n /**\n * Allow an `http:` `apiUrl` (local development only): the quotes and the Diamond calldata travel it, and over plain\n * http anyone on the path rewrites them (scan 2026-10-27 modules, F20).\n */\n allowInsecureApiUrl?: boolean;\n apiKey?: string;\n integrator?: string;\n /** Additional audited LI.FI entry points for networks whose Diamond differs. */\n trustedTransactionTargets?: Readonly<Record<string, readonly string[]>>;\n /** Additional audited ERC-20 spenders returned by LI.FI for direct routes. */\n trustedApprovalAddresses?: Readonly<Record<string, readonly string[]>>;\n /** Fail-closed local lifetime for the provider's documented ~60s quote window. */\n quoteTtlMs?: number;\n /**\n * Slippage sent when the caller names none (bps, default 50 = LI.FI's own\n * documented default). Left unset, LI.FI picks it per request and it swings\n * (0.9%–6% within a minute on Base ETH → Robinhood, 2026-10-12): the display\n * quote's minimum then sits above the live one and the execution floor\n * refuses a route that hasn't moved.\n */\n defaultSlippageBps?: number;\n /**\n * Route policy hook. When set, a cross-chain quote first asks LI.FI's\n * `/advanced/routes` for the candidates, hands them to this function and\n * restricts `/quote` to what it returns (allowBridges / denyBridges /\n * order). Returning null/undefined, or any failure of the routes call,\n * leaves LI.FI's default pick. The policy itself (tie band, max ETA, deny\n * list) belongs to the app; the module only carries the choice.\n */\n chooseRoute?: (routes: readonly LifiRouteOption[], params: QuoteParams) => LifiRouteChoice | null | undefined;\n /**\n * Ask LI.FI for one slippage budget for the whole route (`slippageScope=route`) on EVM → EVM requests, instead of\n * its default of applying the slippage to every step. The minimum is then one floor, `ceil(expected × (1 −\n * slippage))`, that the transaction (and on Across, Mayan and Stargate V2 the bridge) enforces. Only EVM routes\n * with at most one swap and no destination call can be protected so; when LI.FI has none for a request it is asked\n * again in its default (per-step) scope, held to the same floor by the module's checks. Default off: Solana legs and\n * a disabled flag keep the per-step behaviour exactly as before.\n */\n routeWideSlippage?: boolean;\n}\n\n/** One single-transaction candidate from `/advanced/routes`, as a route policy sees it. */\nexport interface LifiRouteOption {\n /** LI.FI tool key of the bridge the route crosses with (e.g. \"stargateV2\"); a same-chain route carries its swap tool. */\n tool: string;\n toAmount: bigint;\n toAmountMin: bigint;\n /** LI.FI's execution-duration estimate, seconds. */\n etaSeconds: number;\n gasCostUsd: number;\n /** LI.FI's own labels: RECOMMENDED, CHEAPEST, FASTEST, … */\n tags: readonly string[];\n}\n\n/** What `/quote` is restricted to. LI.FI tool keys; an empty choice means LI.FI's default. */\nexport interface LifiRouteChoice {\n allowBridges?: readonly string[];\n denyBridges?: readonly string[];\n order?: \"CHEAPEST\" | \"FASTEST\";\n}\n\nconst TOOL_KEY = /^[A-Za-z0-9_-]{1,64}$/;\n/**\n * LI.FI tools whose Diamond entry point does not tie the delivery to the checked receiver (see `UNBOUND_BRIDGES` in\n * calldata.ts): every cross-chain request from an EVM chain asks LI.FI to route around them, so the pairs they would\n * have served get another bridge instead of a refusal. A Solana source has no Diamond call to check and is quoted\n * through every bridge LI.FI offers (Relay included); the account checks a Mayan order's recipient on the device, the\n * other Solana bridges only against its SOL and token ceilings.\n */\nconst UNBOUND_TOOLS: readonly string[] = Object.freeze([\"relaydepository\", \"garden\", \"squid\", \"symbiosis\"]);\n/**\n * LI.FI Intents (`lifiIntents`): the escrowed order names its own input oracle, output oracle, output settler and output\n * amount multiplier, none of which is pinned here, so its Diamond call is refused on every route (calldata.ts,\n * `INTENTS_UNPINNED` / `INTENTS_TO_SOLANA`) and every cross-chain request from an EVM chain asks LI.FI to route around it,\n * like the unbound tools. A Solana source is unchanged (no Diamond call; see UNBOUND_TOOLS).\n */\nconst UNPINNED_TOOLS: readonly string[] = Object.freeze([\"lifiIntents\"]);\n/** The LI.FI tools every cross-chain request from an EVM chain is asked to avoid, and a route policy cannot pick. */\nconst REFUSED_EVM_TOOLS: readonly string[] = Object.freeze([...UNBOUND_TOOLS, ...UNPINNED_TOOLS]);\n/**\n * EVM → Solana: the LI.FI tools whose Diamond call binds the delivery to the Solana recipient the device reads\n * (calldata.ts, `solanaRecipientMismatch`): Mayan's Swift, MCTP and Fast MCTP routes, Polymer CCTP (fast and standard)\n * and Chainflip. Such requests ask LI.FI for these bridges only, so a pair is not lost to a bridge the module refuses\n * for this direction (NEAR Intents, LayerSwap and Smart Deposits pay a deposit address; LI.FI Intents names its own\n * oracles and output settler, which are not pinned here).\n */\nconst SOLANA_DESTINATION_TOOLS: readonly string[] = Object.freeze([\"mayan\", \"mayanMCTP\", \"mayanFastMCTP\", \"polymer\", \"polymerStandard\", \"chainflip\"]);\n/** LI.FI's Smart Deposits pay a deposit address; nothing in the transaction binds where it delivers. */\nconst SMART_DEPOSITS_TOOL = /^smartdeposits?$/i;\n/** A dry EVM → Solana quote without a recipient prices the publicly known BIP-39 \"abandon\" account 0 on Solana (never built: {@link placeholderIn}). */\nconst dryRecipient = (params: Pick<QuoteParams, \"sourceChain\" | \"destChain\">, fromAddress: string): string =>\n !isSolana(params.sourceChain) && isSolana(params.destChain) ? SOLANA_PLACEHOLDER : fromAddress;\n/**\n * Which address of a dry request the module fills with its placeholder: the sender when there is no `refundAddress`\n * (vitalik.eth, or the Solana \"abandon\" account from Solana), the recipient of an EVM → Solana request without a\n * `destAddress` (the \"abandon\" account) — or null when the quote is for the request's own addresses (a dry EVM → EVM or\n * Solana-source quote without a recipient prices the sender's own address). The placeholders are public accounts, and\n * the Solana one's key anyone can derive and sweep: a transaction LI.FI builds for them pays or refunds them from\n * whichever wallet signs it. Such a quote therefore prices the route and carries no transaction; `buildDeposit`\n * refuses it and {@link lifiVerifyQuote} refuses one that carries a transaction anyway.\n */\nfunction placeholderIn(params: Pick<QuoteParams, \"sourceChain\" | \"destChain\" | \"refundAddress\" | \"destAddress\">): \"sender\" | \"recipient\" | null {\n if (!params.refundAddress) return \"sender\";\n return !params.destAddress && dryRecipient(params, params.refundAddress) !== params.refundAddress ? \"recipient\" : null;\n}\nfunction routeOptions(body: unknown, excluded: readonly string[], allowed?: readonly string[]): LifiRouteOption[] {\n const routes = (body as {routes?: unknown})?.routes;\n if (!Array.isArray(routes)) return [];\n const out: LifiRouteOption[] = [];\n for (const r of routes as {toAmount?: unknown; toAmountMin?: unknown; gasCostUSD?: unknown; containsSwitchChain?: unknown; tags?: unknown; steps?: {tool?: unknown; estimate?: {executionDuration?: unknown}; includedSteps?: {tool?: unknown; type?: unknown}[]}[]}[]) {\n // The engine executes one source transaction: multi-step routes are not candidates.\n if (!Array.isArray(r?.steps) || r.steps.length !== 1 || r.containsSwitchChain === true) continue;\n const step = r.steps[0]!;\n const cross = Array.isArray(step.includedSteps) ? step.includedSteps.find((i) => i?.type === \"cross\")?.tool : undefined;\n const tool = typeof cross === \"string\" ? cross : step.tool;\n const eta = step.estimate?.executionDuration;\n if (typeof tool !== \"string\" || !TOOL_KEY.test(tool) || excluded.includes(tool) || (allowed && !allowed.includes(tool)) || typeof eta !== \"number\" || !Number.isFinite(eta) || eta < 0) continue;\n if (typeof r.toAmount !== \"string\" || typeof r.toAmountMin !== \"string\" || !/^\\d{1,60}$/.test(r.toAmount) || !/^\\d{1,60}$/.test(r.toAmountMin)) continue;\n out.push({\n tool,\n toAmount: BigInt(r.toAmount),\n toAmountMin: BigInt(r.toAmountMin),\n etaSeconds: eta,\n gasCostUsd: Number(r.gasCostUSD ?? 0) || 0,\n tags: Array.isArray(r.tags) ? r.tags.filter((t): t is string => typeof t === \"string\") : [],\n });\n }\n return out;\n}\n\nfunction cleanChoice(choice: LifiRouteChoice | null | undefined): LifiRouteChoice | null {\n if (!choice) return null;\n const allow = (choice.allowBridges ?? []).filter((t) => TOOL_KEY.test(t));\n const deny = (choice.denyBridges ?? []).filter((t) => TOOL_KEY.test(t));\n const order = choice.order === \"CHEAPEST\" || choice.order === \"FASTEST\" ? choice.order : undefined;\n if (!allow.length && !deny.length && !order) return null;\n return {...(allow.length ? {allowBridges: allow} : {}), ...(deny.length ? {denyBridges: deny} : {}), ...(order ? {order} : {})};\n}\n\nexport function lifiProvider(config: LifiProviderConfig = {}): CrossChainProvider {\n config = Object.freeze({...config});\n const apiKey = () => config.apiKey;\n const integrator = () => config.integrator ?? \"\";\n const parsedApiUrl = new URL(config.apiUrl ?? DEFAULT_LIFI_BASE);\n if (parsedApiUrl.protocol !== \"https:\" && !(parsedApiUrl.protocol === \"http:\" && config.allowInsecureApiUrl === true)) {\n throw new Error(\"lifi: apiUrl must use https (allowInsecureApiUrl for local development)\");\n }\n const apiBase = parsedApiUrl.toString().replace(/\\/$/, \"\");\n const trustedTransactionTargets = trustMap(config.trustedTransactionTargets, \"transaction target\");\n const trustedApprovalAddresses = trustMap(config.trustedApprovalAddresses, \"approval\");\n const quoteTtlMs = config.quoteTtlMs ?? DEFAULT_QUOTE_TTL_MS;\n const defaultSlippageBps = config.defaultSlippageBps ?? 50;\n if (!Number.isInteger(defaultSlippageBps) || defaultSlippageBps <= 0 || defaultSlippageBps >= 10_000) {\n throw new Error(\"lifi: defaultSlippageBps must be an integer between 1 and 9999\");\n }\n if (!Number.isInteger(quoteTtlMs) || quoteTtlMs <= 0 || quoteTtlMs > 60_000) {\n throw new Error(\"lifi: quoteTtlMs must be an integer between 1 and 60000\");\n }\n return {\n name: \"lifi\",\n describeActivity: (tx, ctx) => describeLifiActivity(tx, ctx, (chain, address) => trustedAddress(chain, address, trustedTransactionTargets)),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n\n // Capability discovery comes from the provider itself, so it can run alone\n // or inside the optional aggregator without a central capability table.\n supportsChain: (chain: string) => lifiCfg.supportsChain(chain),\n supportsChainPair: (fromChain: string, toChain: string) => lifiCfg.supports(fromChain, toChain),\n supportsRoute(from: Asset, to: Asset): boolean {\n // EVM only: LI.FI's Solana/Tron legs come back as provider-serialized\n // transactions, which the swap2 engine does not execute yet.\n return !!LIFI_CHAIN[from.chain] && !!LIFI_CHAIN[to.chain];\n },\n\n async getQuote(params: QuoteParams, signal?: AbortSignal): Promise<Quote | null> {\n /** Every refusal after LI.FI answered is named — a bare null hides which check failed (matrix v7: 4 silent nulls). */\n const reject = (why: string): null => { params.onRefusal?.(`lifi: ${why}`); return null; };\n if (params.flex) return null; // calldata model — the amount is baked in\n const fromChain = LIFI_CHAIN[params.sourceChain];\n const toChain = LIFI_CHAIN[params.destChain];\n if (!fromChain || !toChain) return null;\n const fromToken = lifiToken(params);\n if (!fromToken) return null;\n\n const solanaSource = isSolana(params.sourceChain);\n const crossChain = params.sourceChain !== params.destChain;\n // EVM → Solana: only the bridges whose Solana recipient the calldata check reads (SOLANA_DESTINATION_TOOLS).\n const evmToSolana = !solanaSource && isSolana(params.destChain);\n // The Diamond check refuses a destination call (its recipient sits in calldata for the other chain), so LI.FI is\n // asked not to offer one; the check stays as the backstop. A Solana source has no Diamond call to check.\n const noDestinationCall = crossChain && !solanaSource;\n // Route-wide slippage covers EVM routes only (LI.FI: not a route that starts or ends on a non-EVM chain).\n let routeScope = config.routeWideSlippage === true && !solanaSource && !isSolana(params.destChain);\n // The placeholders price a dry quote; a live one is built for real addresses only (round 3, H8). A quote priced for\n // a placeholder carries no transaction (placeholderIn).\n const dry = params.dry !== false;\n const fromAddress = params.refundAddress || (dry ? (solanaSource ? SOLANA_PLACEHOLDER : EVM_PLACEHOLDER) : \"\");\n const toAddress = params.destAddress || (dry ? dryRecipient(params, fromAddress) : \"\");\n if (!fromAddress) return reject(\"a live quote needs the sender's address\");\n if (!toAddress) return reject(\"a live quote needs a recipient\");\n const placeholder = dry ? placeholderIn(params) : null;\n\n // LI.FI applies `slippage` to EACH step of a multi-step route (bridge +\n // destination swap), so its minimum can sit ~2× the requested slippage\n // under the quote (seen 2026-10-10 on 479 of 4 000 matrix quotes), and\n // it truncates toAmountMin to a few significant digits. The engine\n // rejects a floor below the requested one, so the quote is asked once\n // more with the slippage scaled down to land the floor inside it.\n const slippageBps = params.slippageBps ?? defaultSlippageBps;\n let sentSlippage: number | undefined = slippageBps / 10_000;\n let deadline: AbortSignal | undefined;\n let choice: LifiRouteChoice | null = null;\n if (config.chooseRoute && crossChain) {\n try {\n const res = await fetch(`${apiBase}/advanced/routes`, {\n method: \"POST\",\n headers: {...headers(apiKey()), \"content-type\": \"application/json\"},\n body: JSON.stringify({\n fromChainId: Number(fromChain),\n toChainId: Number(toChain),\n fromTokenAddress: fromToken,\n toTokenAddress: nativeFor(params.destChain, params.destToken),\n fromAmount: params.amountIn,\n fromAddress,\n toAddress,\n options: {\n slippage: slippageBps / 10_000,\n ...(routeScope ? {slippageScope: \"route\"} : {}),\n ...(solanaSource ? {} : {bridges: {...(evmToSolana ? {allow: SOLANA_DESTINATION_TOOLS} : {}), deny: REFUSED_EVM_TOOLS}}),\n ...(noDestinationCall ? {allowDestinationCall: false} : {}),\n ...(integrator().trim() ? {integrator: integrator().trim()} : {}),\n },\n }),\n signal: signal ?? timeoutSignal(8_000),\n });\n if (res.ok) {\n const options = routeOptions(await res.json(), solanaSource ? [] : REFUSED_EVM_TOOLS, evmToSolana ? SOLANA_DESTINATION_TOOLS : undefined);\n if (options.length) choice = cleanChoice(config.chooseRoute(options, params));\n }\n } catch {\n // The policy is an optimisation: no candidates means LI.FI's default pick.\n }\n }\n for (let attempt = 0; attempt < 2; attempt++) try {\n const url = new URL(`${apiBase}/quote`);\n url.searchParams.set(\"fromChain\", fromChain);\n url.searchParams.set(\"toChain\", toChain);\n url.searchParams.set(\"fromToken\", fromToken);\n // Native dest is chain-notation-specific: EVM zero address vs the\n // Solana system program — sending the EVM zero to an SVM dest 400s.\n url.searchParams.set(\"toToken\", nativeFor(params.destChain, params.destToken));\n url.searchParams.set(\"fromAmount\", params.amountIn);\n url.searchParams.set(\"fromAddress\", fromAddress);\n url.searchParams.set(\"toAddress\", toAddress);\n const integratorId = integrator().trim();\n if (integratorId) url.searchParams.set(\"integrator\", integratorId);\n if (sentSlippage !== undefined) {\n url.searchParams.set(\"slippage\", String(sentSlippage));\n }\n if (routeScope) url.searchParams.set(\"slippageScope\", \"route\");\n if (noDestinationCall) url.searchParams.set(\"allowDestinationCall\", \"false\");\n const unbound = crossChain && !solanaSource ? REFUSED_EVM_TOOLS : [];\n const allow = (choice?.allowBridges ?? []).filter((b) => solanaSource || !REFUSED_EVM_TOOLS.includes(b));\n // EVM → Solana: the policy's pick among the readable bridges, or all of them.\n const solanaAllow = evmToSolana ? allow.filter((b) => SOLANA_DESTINATION_TOOLS.includes(b)) : [];\n for (const t of evmToSolana ? (solanaAllow.length ? solanaAllow : SOLANA_DESTINATION_TOOLS) : allow) url.searchParams.append(\"allowBridges\", t);\n for (const t of new Set([...(choice?.denyBridges ?? []), ...unbound])) url.searchParams.append(\"denyBridges\", t);\n if (choice?.order) url.searchParams.set(\"order\", choice.order);\n deadline = signal ? undefined : timeoutSignal(12_000);\n const res = await fetch(url, {headers: headers(apiKey()), signal: signal ?? deadline!});\n if (!res.ok && choice) {\n // The chosen bridge went away between the two calls: LI.FI's default pick instead.\n choice = null;\n attempt--;\n continue;\n }\n if (!res.ok) {\n // LI.FI's 404 \"No available quotes for the requested transfer\" and\n // 400 validation messages are the caller's answer, not a silent null.\n const body = (await res.json().catch(() => null)) as {message?: unknown; errors?: {filteredOut?: {reason?: unknown}[]}} | null;\n // When every candidate route was dropped for the same reason (Sei: \"wallet is not linked to\n // the original SEI address\"), that reason is the real answer — the message alone is generic.\n const reasons = [...new Set((body?.errors?.filteredOut ?? []).map((f) => f.reason).filter((r): r is string => typeof r === \"string\"))];\n if (routeScope && [typeof body?.message === \"string\" ? body.message : \"\", ...reasons].some((r) => /^ROUTE_SLIPPAGE_(UNSUPPORTED|UNAVAILABLE)/.test(r))) {\n // No route LI.FI can protect route-wide (or the feature is off): its default per-step scope instead,\n // whose minimum the floor check below still holds to the requested slippage. Both reasons are LI.FI's\n // documented stable prefixes (docs.li.fi/api-reference/error-codes, \"Route-wide slippage errors\";\n // docs.li.fi/guides/route-wide-slippage#errors): ROUTE_SLIPPAGE_UNSUPPORTED in errors.filteredOut when no\n // route can be protected, ROUTE_SLIPPAGE_UNAVAILABLE (422, code 1004) in `message` when route-wide\n // slippage is switched off. This happens before any quote is shown: the user reviews the step-scope one.\n routeScope = false;\n attempt--;\n continue;\n }\n const why = reasons.length === 1 ? ` (${reasons[0]!.slice(0, 200)})` : \"\";\n params.onRefusal?.(`lifi: ${typeof body?.message === \"string\" ? body.message.slice(0, 200) : `HTTP ${res.status}`}${why}`);\n return null;\n }\n const q = (await res.json()) as {\n type?: string;\n id?: string;\n action?: {\n fromToken?: {address?: string; chainId?: number};\n toToken?: {address?: string; chainId?: number; decimals?: number};\n fromAmount?: string;\n fromChainId?: number;\n toChainId?: number;\n slippage?: number;\n fromAddress?: string;\n toAddress?: string;\n };\n estimate?: {\n fromAmount?: string;\n toAmount?: string;\n toAmountMin?: string;\n executionDuration?: number;\n approvalAddress?: string;\n feeCosts?: {amountUSD?: string}[];\n gasCosts?: {amountUSD?: string}[];\n };\n transactionRequest?: {\n to?: string;\n data?: string;\n value?: string;\n chainId?: number;\n gasLimit?: string;\n from?: string;\n };\n };\n const receivedAt = Date.now();\n if (evmToSolana) {\n const steps = (q as {includedSteps?: unknown}).includedSteps;\n const tools = [(q as {tool?: unknown}).tool, ...(Array.isArray(steps) ? steps.map((i: {tool?: unknown} | null) => i?.tool) : [])];\n if (tools.some((t) => typeof t === \"string\" && SMART_DEPOSITS_TOOL.test(t))) {\n return reject(\"LI.FI Smart Deposits pay a deposit address whose recipient the transaction does not bind — refused for a Solana destination\");\n }\n }\n const action = q.action;\n const est = q.estimate;\n const tr = q.transactionRequest;\n const expectedToToken = nativeFor(params.destChain, params.destToken);\n const expectedFromChain = Number(fromChain);\n const expectedToChain = Number(toChain);\n if (q.type !== \"lifi\" || !q.id || !action || !est?.toAmount || !est.fromAmount || !tr) return reject(\"incomplete quote (no action, estimate or transaction)\");\n const mismatch = [\n action.fromChainId !== expectedFromChain && \"source chain\",\n action.toChainId !== expectedToChain && \"destination chain\",\n (action.fromToken?.chainId !== expectedFromChain || !sameChainAddress(params.sourceChain, action.fromToken?.address, fromToken)) && \"source token\",\n (action.toToken?.chainId !== expectedToChain || !sameChainAddress(params.destChain, action.toToken?.address, expectedToToken)) && \"destination token\",\n action.fromAmount !== params.amountIn && \"amount spent\",\n !sameChainAddress(params.sourceChain, action.fromAddress, fromAddress) && \"sender\",\n !sameChainAddress(params.destChain, action.toAddress, toAddress) && \"recipient\",\n ].filter(Boolean);\n if (mismatch.length) return reject(`quote does not match the request (${mismatch.join(\", \")})`);\n // The transaction spends exactly the input (action.fromAmount, checked above). Some bridges\n // (glacis, 2026-10) take their fee from the input, so estimate.fromAmount — what is bridged —\n // is a little lower and toAmount already reflects it. Accept a bounded input-side fee instead\n // of a silent null; never an estimate that bridges MORE than is spent.\n const bridged = BigInt(est.fromAmount);\n const spent = BigInt(params.amountIn);\n if (bridged > spent) return reject(`the estimate bridges ${est.fromAmount}, more than the ${params.amountIn} spent`);\n if ((spent - bridged) * 10_000n > spent * BigInt(MAX_INPUT_FEE_BPS)) {\n return reject(`the route takes ${bigintToNumber(((spent - bridged) * 10_000n) / spent) / 100}% of the input as a fee (over ${MAX_INPUT_FEE_BPS / 100}%)`);\n }\n // Source-VM execution payload. EVM: calldata to a trusted target.\n // Solana: a base64 transaction the account proves before signing —\n // there is no target to trust here, the balance proof replaces it.\n if (solanaSource) {\n if (!tr.data || tr.data.length < 64 || tr.data.length % 4 !== 0 || !BASE64.test(tr.data)) return reject(\"the Solana transaction is not base64\");\n if (tr.to !== undefined || tr.value !== undefined || tr.gasLimit !== undefined) return reject(\"the Solana transaction carries EVM fields\");\n if (fromChain !== toChain) {\n const why = solanaBridgeTxMismatch(tr.data, fromAddress);\n if (why) return reject(why);\n }\n // `estimate.approvalAddress` is ignored for a Solana source: LI.FI\n // returns its EVM diamond here on Mayan routes too (seen 2026-10-09,\n // SOL → Base USDC via mayanFastMCTP), and Solana has no allowances —\n // the account's post-state balance proof is the guard, not an\n // approval target. It is never propagated.\n } else if (\n !isHexData(tr.data) || !normalizeAddress(tr.to) || !normalizeAddress(tr.from) ||\n tr.chainId !== expectedFromChain || !tr.value || !tr.gasLimit ||\n !trustedAddress(params.sourceChain, tr.to, trustedTransactionTargets) ||\n !sameAddress(tr.from, fromAddress)\n ) return reject(\"the transaction is malformed or targets an untrusted contract\");\n if (\n sentSlippage !== undefined &&\n (typeof action.slippage !== \"number\" || Math.abs(action.slippage - sentSlippage) > 1e-12)\n ) return reject(\"the quote ignored the requested slippage\");\n\n const sourceIsToken = fromToken !== EVM_ZERO && fromToken !== SOLANA_NATIVE;\n if (solanaSource) {\n // No allowances on Solana; nothing to trust beyond the balance proof.\n } else if (sourceIsToken) {\n if (!trustedAddress(params.sourceChain, est.approvalAddress, trustedApprovalAddresses)) return reject(\"the approval target is not a trusted LI.FI contract\");\n } else if (est.approvalAddress !== undefined) {\n // LI.FI started returning an approvalAddress for NATIVE sources too\n // (seen 2026-09 on every ETH-source quote, e.g. ETH → Robinhood via\n // relay: approvalAddress = the diamond the tx already calls). An\n // approval is meaningless for the native asset, so it is not a\n // reason to refuse the quote — but it must still be a trusted\n // target, and it is never propagated for a native source.\n if (!trustedAddress(params.sourceChain, est.approvalAddress, trustedApprovalAddresses)) return reject(\"the approval target is not a trusted LI.FI contract\");\n }\n\n let txRequest: NonNullable<Quote[\"txRequest\"]>;\n // The bridge's native fee on top of the input (EVM source); a price-only quote declares it in providerData.\n let nativeFee = 0n;\n if (solanaSource) {\n // `value` declares what the account may let the tx take in native\n // coin: the input for a SOL source, nothing for a token source.\n txRequest = {serializedTx: tr.data!, value: sourceIsToken ? \"0\" : params.amountIn};\n } else {\n try {\n if (BigInt(tr.value!) < 0n || BigInt(tr.gasLimit!) <= 0n) return reject(\"the transaction has a negative value or no gas limit\");\n } catch {\n return reject(\"the transaction value or gas limit is not a number\");\n }\n // Some bridges charge a native messaging fee inside `value`: for a\n // token source the whole value is that fee; for a native source it\n // is whatever exceeds the input (seen 2026-10-10: DAI Optimism →\n // Base, POL Polygon → Optimism). Declared here, sealed with the\n // quote, bounded by the engine — never silently attached.\n const value = BigInt(tr.value!);\n nativeFee = sourceIsToken ? value : value > BigInt(params.amountIn) ? value - BigInt(params.amountIn) : 0n;\n if (!sourceIsToken && value < BigInt(params.amountIn)) return reject(\"the transaction sends less native coin than the input\");\n txRequest = {\n to: tr.to!,\n data: tr.data!,\n value: value.toString(),\n chainId: tr.chainId!,\n gasLimit: BigInt(tr.gasLimit!).toString(),\n ...(sourceIsToken && est.approvalAddress ? {approvalAddress: est.approvalAddress} : {}),\n ...(nativeFee > 0n ? {nativeFee: nativeFee.toString()} : {}),\n };\n }\n\n // Route fees only (bridge / protocol / integrator). The source\n // transaction's gas is the network fee the wallet shows on its own line —\n // counting it here too made LI.FI look dearer than on-chain venues whose\n // fee excludes gas (2026-10-13).\n const feeUsd = (est.feeCosts ?? []).reduce((a, f) => a + Number(f.amountUSD ?? 0), 0);\n\n // The optimistic output is not a safety floor. A quote without the\n // provider's minimum cannot satisfy an exact-input execution contract.\n if (!est.toAmountMin) return reject(\"the quote has no minimum output\");\n const minDestAmount = est.toAmountMin;\n if (sentSlippage !== undefined) {\n const dest = BigInt(est.toAmount);\n const min = BigInt(minDestAmount);\n if (dest > 0n && min < slippageFloor(dest, slippageBps)) {\n const effective = bigintToNumber(((dest - min) * 1_000_000n) / dest) / 1_000_000;\n const requested = slippageBps / 10_000;\n const scaled: number = Math.floor(((sentSlippage * requested) / effective) * 0.995 * 1_000_000) / 1_000_000;\n if (attempt === 0 && effective > 0 && scaled > 0) {\n sentSlippage = scaled;\n continue;\n }\n params.onRefusal?.(\n `lifi: this route's minimum is ${(effective * 100).toFixed(2)}% under the quote (LI.FI applies slippage on every step) — more than the requested ${slippageBps / 100}%`,\n );\n return null;\n }\n }\n if (params.minAmountOut !== undefined && BigInt(minDestAmount) < BigInt(params.minAmountOut)) {\n params.onRefusal?.(`lifi: floor breach (min=${minDestAmount} < floor=${params.minAmountOut})`);\n return null;\n }\n // A same-chain swap must deliver in the same transaction. LI.FI sometimes routes a\n // same-chain pair through a solver (Relay-style intents, 2026-10: USDC → ARB on\n // Ethereum, 625 s): the tx only takes the input and the output arrives later from the\n // solver, so the engine's \"output ≥ quoted minimum\" preflight would refuse it anyway.\n // Name it here, before anything is built.\n const duration = est.executionDuration ?? 0;\n if (fromChain === toChain && duration > SAME_CHAIN_MAX_SECONDS) {\n params.onRefusal?.(`lifi: same-chain route settles asynchronously (${duration} s via ${(q as {tool?: string}).tool ?? \"unknown tool\"}) — a same-chain swap must deliver in the same transaction`);\n return null;\n }\n // The calldata is what gets signed: it must pay the reviewed recipient at least the reviewed\n // minimum, in the requested tokens (round 3, H9), and refund only the sender or the recipient.\n if (!solanaSource) {\n const why = diamondCallMismatch(tr.data!, {\n fromToken, toToken: expectedToToken, amountIn: BigInt(params.amountIn), receiver: toAddress, sender: fromAddress, minOut: BigInt(minDestAmount),\n destChainId: BigInt(toChain), sameChain: fromChain === toChain, evmDestination: !isSolana(params.destChain),\n });\n if (why) return reject(`the transaction does not match the quote: ${why}`);\n }\n return {\n provider: \"lifi\",\n // Status is tracked by SOURCE TX HASH + the chain pair.\n intentId: `lifi:${fromChain}:${toChain}`,\n depositAddress: \"\",\n depositMemo: null,\n // Every check above ran on LI.FI's transaction; one built for a placeholder is not handed out (placeholderIn).\n // Its bridge fee on top of the input still is, as `providerData.nativeFee`, so the router's value nets it out\n // (usdValue reads it when there is no txRequest) instead of ranking the route on its gross output.\n ...(placeholder ? {providerData: {placeholder, ...(nativeFee > 0n ? {nativeFee: nativeFee.toString()} : {})}} : {txRequest}),\n // What the wallet spends (action.fromAmount, = the input); an input-side bridge fee is inside destAmount.\n sourceAmount: params.amountIn,\n destAmount: est.toAmount,\n minDestAmount,\n ...(Number.isInteger(action.toToken?.decimals) && action.toToken!.decimals! >= 0 && action.toToken!.decimals! <= 36 ? {destDecimals: action.toToken!.decimals!} : {}),\n feeUsd,\n etaSeconds: est.executionDuration ?? 120,\n reliability: 0.97,\n // LI.FI documents an approximately 60-second lifetime. Use a slightly\n // shorter local deadline and re-quote again at execution time.\n validUntilMs: receivedAt + quoteTtlMs,\n };\n } catch {\n // Our own 12 s deadline (not the caller's signal): say so instead of a silent null.\n if (deadline?.aborted) params.onRefusal?.(\"lifi: no quote within 12 s\");\n return null;\n }\n return null;\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n // A dry quote priced for a placeholder sender or recipient (placeholderIn) is never built, even with a transaction attached.\n const placeholder = quote.providerData?.placeholder;\n if (placeholder !== undefined) {\n throw new Error(`swap2: this LI.FI quote was priced for a placeholder ${String(placeholder).slice(0, 20)} (a dry quote without that address) and has no transaction to build — quote again with the sender and the recipient`);\n }\n const tx = quote.txRequest;\n if (!tx) throw new Error(\"swap2: LI.FI quote has no transaction request\");\n // The intent id carries the LI.FI source chain; a serialized leg names\n // its chain so the engine can refuse a mismatched account.\n const [, fromChain] = quote.intentId.split(\":\");\n return {\n chain: tx.serializedTx ? CAIP2_BY_LIFI_CHAIN[fromChain ?? \"\"] ?? \"\" : \"\",\n to: tx.to ?? \"\",\n value: tx.value ?? \"0\",\n ...(tx.data ? {data: tx.data} : {}),\n ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}),\n ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {}),\n ...(tx.approvalAddress ? {approvalAddress: tx.approvalAddress} : {}),\n ...(tx.serializedTx ? {serializedTx: tx.serializedTx} : {}),\n };\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"}; // not broadcast yet\n const [, fromChain, toChain] = ref.intentId.split(\":\");\n try {\n const url = new URL(`${apiBase}/status`);\n url.searchParams.set(\"txHash\", ref.sourceTxHash);\n if (fromChain) url.searchParams.set(\"fromChain\", fromChain);\n if (toChain) url.searchParams.set(\"toChain\", toChain);\n const res = await fetch(url, {headers: headers(apiKey()), signal: timeoutSignal(12_000)});\n if (!res.ok) return {state: \"pending\"};\n const s = (await res.json()) as {status?: string; substatus?: string; receiving?: {txHash?: string}};\n const map: Record<string, IntentStatus[\"state\"]> = {\n DONE: \"completed\",\n FAILED: \"failed\",\n // LI.FI cannot process the transaction: it never completes (round 3, L17).\n INVALID: \"failed\",\n PENDING: \"pending\",\n NOT_FOUND: \"pending\",\n };\n // LI.FI reports refunds and partial fills as top-level DONE. Treating\n // those as completed would falsely claim that the destination was fully\n // funded. Keep the explicit partial/refund lifecycle states.\n const state = s.substatus === \"REFUNDED\"\n ? \"refunded\"\n : s.substatus === \"EXPIRED\"\n ? \"expired\"\n : s.substatus === \"NOT_PROCESSABLE_REFUND_NEEDED\"\n ? \"action-required\"\n : s.substatus === \"REFUND_IN_PROGRESS\"\n ? \"refund-pending\"\n : s.status === \"DONE\" && s.substatus === \"PARTIAL\"\n ? \"partial\"\n : map[s.status ?? \"PENDING\"] ?? \"pending\";\n const depositReceived = state === \"pending\" && s.status === \"PENDING\";\n const destTxHash = typeof s.receiving?.txHash === \"string\" && s.receiving.txHash.length > 0\n ? s.receiving.txHash\n : undefined;\n return {\n state,\n depositReceived,\n ...(destTxHash ? {destTxHash} : {}),\n };\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\n/**\n * A remote LI.FI quote's Diamond call, decoded on the device against the app's own request (scan 2026-10-30, F3) —\n * the same {@link diamondCallMismatch} the provider runs on LI.FI's answer, with the expectation it builds: the input\n * token and amount, the requested output token, the recipient, the quoted minimum (at least the caller's floor), the\n * destination chain. A native input is paid in value (any excess is the declared bridge fee); a token input attaches\n * only that declared fee and approves the Diamond. A Solana source carries a serialized transaction instead, which the\n * account proves before signing (for a Mayan bridge, against the engine's `bridgeOut`); here only its static part is\n * read (paid by the sender; a Mayan route pays SOL to no other wallet). A dry request without the sender, or an EVM →\n * Solana one without the recipient, is priced for a placeholder: its quote must carry no transaction and is held to its\n * terms only. The reason it fails, or null.\n */\nexport function lifiVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n const fromChain = LIFI_CHAIN[params.sourceChain];\n const toChain = LIFI_CHAIN[params.destChain];\n if (!fromChain || !toChain) return \"not a LI.FI chain pair\";\n // A dry quote priced for a placeholder sender or recipient (placeholderIn) prices the route only: with a transaction\n // it would pay or refund that public account from whichever wallet signs it.\n const placeholder = params.dry !== false ? placeholderIn(params) : null;\n if (placeholder) {\n if (quote.txRequest !== undefined) return `a dry quote priced for a placeholder ${placeholder} carries a transaction — it would pay or refund that placeholder, not the wallet that signs it`;\n return priceOnlyMismatch(params, quote, `lifi:${fromChain}:${toChain}`);\n }\n const tx = quote.txRequest;\n if (!tx) return \"the quote carries no transaction\";\n if (isSolana(params.sourceChain)) {\n if (!tx.serializedTx || tx.data !== undefined || tx.to !== undefined) return \"a Solana source carries a serialized transaction only\";\n // The static part of a bridge (see solanaBridgeTxMismatch); the account proves a Mayan order's recipient (bridgeOut).\n return fromChain === toChain ? null : solanaBridgeTxMismatch(tx.serializedTx, params.refundAddress || (params.dry !== false ? SOLANA_PLACEHOLDER : \"\"));\n }\n if (!isHexData(tx.data) || !tx.to || tx.serializedTx !== undefined) return \"the quote carries no Diamond call\";\n if (!sameAddress(tx.to, diamondFor(params.sourceChain))) return `the call targets ${tx.to}, not the LI.FI Diamond`;\n if (tx.chainId !== undefined && String(tx.chainId) !== fromChain) return `the call is for chain ${tx.chainId}, not ${fromChain}`;\n const fromToken = lifiToken(params);\n if (!fromToken) return `unknown source token ${params.sourceToken}`;\n const sourceIsToken = fromToken !== EVM_ZERO;\n // The same addresses the provider quotes for: a dry quote without them prices the placeholder (never built).\n const dry = params.dry !== false;\n const fromAddress = params.refundAddress || (dry ? EVM_PLACEHOLDER : \"\");\n const toAddress = params.destAddress || (dry ? dryRecipient(params, fromAddress) : \"\");\n if (!fromAddress || !toAddress) return \"a live quote needs the sender and the recipient\";\n let amountIn: bigint, minOut: bigint, value: bigint, nativeFee: bigint;\n try {\n amountIn = BigInt(params.amountIn);\n minOut = BigInt(quote.minDestAmount);\n value = BigInt(tx.value ?? \"0\");\n nativeFee = BigInt(tx.nativeFee ?? \"0\");\n } catch {\n return \"the quote's amounts are not integers\";\n }\n if (BigInt(quote.sourceAmount) !== amountIn) return `the quote spends ${quote.sourceAmount}, not the ${amountIn} input`;\n if (params.minAmountOut !== undefined && minOut < BigInt(params.minAmountOut)) return `the quoted minimum ${minOut} is below the caller's floor ${params.minAmountOut}`;\n if (sourceIsToken) {\n if (value !== nativeFee) return \"a token input attaches only its declared bridge fee\";\n if (!tx.approvalAddress || !sameAddress(tx.approvalAddress, diamondFor(params.sourceChain))) return \"a token input approves the LI.FI Diamond\";\n } else {\n if (value < amountIn || value - amountIn !== nativeFee) return \"a native input is paid as the input plus its declared bridge fee\";\n if (tx.approvalAddress !== undefined) return \"a native input approves nothing\";\n }\n if (quote.intentId.replace(/~[0-9a-f]{32}$/, \"\") !== `lifi:${fromChain}:${toChain}`) return \"the intent id does not name this route\";\n const why = diamondCallMismatch(tx.data, {\n fromToken, toToken: nativeFor(params.destChain, params.destToken), amountIn, receiver: toAddress, sender: fromAddress, minOut,\n destChainId: BigInt(toChain), sameChain: fromChain === toChain, evmDestination: !isSolana(params.destChain),\n });\n return why ? `the transaction does not match the request: ${why}` : null;\n}\n\n/**\n * A dry quote with no transaction (priced for a placeholder): what it spends, its minimum against the caller's floor and\n * the route its intent id names are still held to the request; it pays no deposit address, and the bridge fee it declares\n * (`providerData.nativeFee`, which the router nets out of its value) is a base-unit integer. The reason, or null.\n */\nfunction priceOnlyMismatch(params: QuoteParams, quote: Quote, route: string): string | null {\n if (quote.depositAddress !== \"\") return `a LI.FI quote pays no deposit address, but this one names ${String(quote.depositAddress).slice(0, 64)}`;\n const fee = quote.providerData?.nativeFee;\n if (fee !== undefined && !/^\\d{1,80}$/.test(String(fee))) return `the price-only quote declares a native fee of ${String(fee).slice(0, 40)}, not a base-unit integer`;\n try {\n if (BigInt(quote.sourceAmount) !== BigInt(params.amountIn)) return `the quote spends ${quote.sourceAmount}, not the ${params.amountIn} input`;\n const minOut = BigInt(quote.minDestAmount);\n if (params.minAmountOut !== undefined && minOut < BigInt(params.minAmountOut)) return `the quoted minimum ${minOut} is below the caller's floor ${params.minAmountOut}`;\n } catch {\n return \"the quote's amounts are not integers\";\n }\n return quote.intentId.replace(/~[0-9a-f]{32}$/, \"\") === route ? null : \"the intent id does not name this route\";\n}\n\n/**\n * The LI.FI Diamond an EVM route calls and approves on a chain (the canonical one, or the chain's own\n * where it differs), and {@link lifiVerifyQuote} — the app's pins for `remoteProvider({name: \"lifi\", baseUrl,\n * ...lifiPins})` (scan 2026-10-27 modules, F8/F16; the Diamond call itself since scan 2026-10-30, F3). Extra audited\n * targets an app configures on the provider (`trustedTransactionTargets` / `trustedApprovalAddresses`) are added on\n * the app side too.\n */\nexport const lifiPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => (/^eip155:[0-9]+$/.test(chain) ? [diamondFor(chain)] : []),\n spenders: (chain: string): readonly string[] => (/^eip155:[0-9]+$/.test(chain) ? [diamondFor(chain)] : []),\n verifyQuote: lifiVerifyQuote,\n});\n","import {SingleProviderSwap2} from \"@anywalletkit/protocol-swap2-core/swap2/single\";\nimport type {Swap2Account, Swap2EngineConfig} from \"@anywalletkit/protocol-swap2-core/swap2/base\";\nimport {lifi as lifiCfg} from \"./config.js\";\nimport {lifiProvider, type LifiProviderConfig} from \"./provider.js\";\n\nexport interface LifiSwap2Config extends Swap2EngineConfig, LifiProviderConfig {}\n\nexport class LifiSwap2Protocol extends SingleProviderSwap2 {\n protected readonly provider;\n constructor(account: Swap2Account | undefined, config: LifiSwap2Config) {\n super(account, config);\n this.provider = lifiProvider(config);\n }\n protected override chainSupported(caip2: string): boolean {\n return lifiCfg.supportsChain(caip2);\n }\n protected override pairSupported(fromChain: string, toChain: string): boolean {\n return lifiCfg.supports(fromChain, toChain);\n }\n}\n"],"mappings":"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","names":["receiver","minAmount","import_util","import_util","BASE58"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/activity.ts","../src/solana-address.ts","../src/refusals.ts","../src/calldata.ts","../src/solana.ts","../src/provider.ts","../src/protocol.ts"],"sourcesContent":["export * from \"./config.js\";\nexport * from \"./provider.js\";\nexport {LifiSwap2Protocol} from \"./protocol.js\";\nexport {LifiSwap2Protocol as default} from \"./protocol.js\";\nexport * from \"./activity.js\";\nexport type { LifiSwap2Config } from \"./protocol.js\"\n","import {evmRef, isEvm} from \"@anywalletkit/protocol-swap2-core/util\";\n\n// ── LI.FI — EVM calldata routes implemented by this contribution adapter ─────\n// 2026-08 sweep (li.quest/v1/chains): + Avalanche 43114, Scroll 534352,\n// Berachain 80094 (HyperEVM 999 / Robinhood 4663 were already routed by the\n// provider's own chain map). 2026-11-10: + Elysium 99901 (li.quest/v1/chains key \"ely\").\n/** The catalog's Solana id; LI.FI numbers it 1151111081099710. */\nexport const LIFI_SOLANA_CAIP2 = \"solana:mainnet\";\nconst LIFI_EVM = new Set([1, 8453, 56, 137, 42161, 10, 100, 143, 130, 999, 4663, 43114, 534352, 80094, 324, 42220, 4326, 9745, 59144, 146, 480, 1329, 57073, 98866, 196, 5042, 5000, 747474, 2818, 14, 99901]);\nexport const lifi = {\n enabled: () => true,\n apiKey: () => undefined,\n integrator: () => \"\",\n supportsChain(chain: string): boolean {\n if (isEvm(chain)) return LIFI_EVM.has(evmRef(chain));\n // Solana legs come back as a serialized transaction the account executes\n // through its `sendSerializedTransaction` guard. Tron is still excluded.\n return chain === LIFI_SOLANA_CAIP2;\n },\n supports(from: string, to: string): boolean {\n return this.supportsChain(from) && this.supportsChain(to);\n },\n};\n","/**\n * Activity recognition for LI.FI: any call into the LI.FI Diamond on an EVM\n * chain this module routes. Same-chain swaps go through GenericSwapFacetV3\n * (fixed selectors below → `swap`, \"Swapped A → B\"); every other facet is a\n * bridge facet (`swapAndStartBridgeTokensVia…`, `startBridgeTokensVia…`) whose\n * source leg we see here → `bridge`, \"Bridged A\". The destination leg lands on\n * another chain through a third-party relayer and cannot be tied back offline,\n * so `related` stays empty (the kit's intent journal links the two).\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {calledContract, callSelector, describeSwapLike} from \"@anywalletkit/protocol-swap2-core/activity\";\n\nexport const LIFI_MODULE = \"@anywalletkit/protocol-swap2-lifi\";\n\n/** GenericSwapFacetV3 — same-chain swaps (`viem toFunctionSelector`, 2026-10-14). */\nexport const LIFI_SAME_CHAIN_SELECTORS: ReadonlySet<string> = new Set([\n \"0x4666fc80\", // swapTokensSingleV3ERC20ToERC20(bytes32,string,string,address,uint256,(address,address,address,address,uint256,bytes,bool))\n \"0x733214a3\", // swapTokensSingleV3ERC20ToNative(…)\n \"0xaf7060fd\", // swapTokensSingleV3NativeToERC20(…)\n \"0x5fd9ae2e\", // swapTokensMultipleV3ERC20ToERC20(bytes32,string,string,address,uint256,(…)[])\n \"0x2c57e884\", // swapTokensMultipleV3ERC20ToNative(…[])\n \"0x736eac0b\", // swapTokensMultipleV3NativeToERC20(…[])\n]);\n\n/**\n * @param isDiamond the provider's trust check: the documented Diamond for the\n * chain plus any `trustedTransactionTargets` the caller configured.\n */\nexport function describeLifiActivity(\n tx: ChainTx,\n ctx: DescribeActivityContext,\n isDiamond: (chain: string, address: string) => boolean,\n): ActivityItem | null {\n if (!tx.chain.startsWith(\"eip155:\")) return null;\n const to = calledContract(tx);\n if (!to || !isDiamond(tx.chain, to)) return null;\n const selector = callSelector(tx);\n const sameChain = selector !== undefined && LIFI_SAME_CHAIN_SELECTORS.has(selector);\n return describeSwapLike(tx, ctx, {\n protocol: LIFI_MODULE,\n subtitle: \"LI.FI\",\n // Unknown selector: trust the legs — both netted here means a same-chain route.\n kind: sameChain ? \"swap\" : selector === undefined ? \"auto\" : \"bridge\",\n });\n}\n","/**\n * Solana addresses as the bridge checks read them: base58 ↔ the raw 32-byte key, and the associated token account of an\n * owner for a mint, derived the way the Associated Token Account program derives it (`findProgramAddress` over\n * [owner, token program, mint] under ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL; spl.solana.com/associated-token-account).\n * Pure functions over bytes: no RPC, no Node API, no global TextEncoder.\n */\nimport {ed25519} from \"@noble/curves/ed25519.js\";\nimport {sha256} from \"@noble/hashes/sha2.js\";\n\nconst ALPHABET = \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\nconst BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\n/** The classic SPL Token program: USDC and USDT on Solana live under it. */\nexport const SOLANA_TOKEN_PROGRAM = \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\";\nconst ASSOCIATED_TOKEN_PROGRAM = \"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\";\nconst PDA_MARKER = Uint8Array.from(\"ProgramDerivedAddress\", (c) => c.charCodeAt(0));\n\n/** Base58 of raw bytes (leading zero bytes as \"1\"). */\nexport function base58(bytes: Uint8Array): string {\n let n = 0n;\n for (const b of bytes) n = (n << 8n) | BigInt(b);\n let out = \"\";\n while (n > 0n) { out = ALPHABET[Number(n % 58n)]! + out; n /= 58n; }\n for (const b of bytes) { if (b !== 0) break; out = `1${out}`; }\n return out;\n}\n\n/** The 32 raw bytes of a base58 Solana address, or null when it is not exactly one. */\nexport function solanaKey(address: string): Uint8Array | null {\n if (!BASE58.test(address)) return null;\n let n = 0n;\n for (const ch of address) n = n * 58n + BigInt(ALPHABET.indexOf(ch));\n let zeros = 0;\n while (address[zeros] === \"1\") zeros++;\n const body: number[] = [];\n while (n > 0n) { body.unshift(Number(n & 0xffn)); n >>= 8n; }\n if (zeros + body.length !== 32) return null;\n const out = new Uint8Array(32);\n out.set(body, zeros);\n return out;\n}\n\nconst onCurve = (bytes: Uint8Array): boolean => {\n try { ed25519.Point.fromBytes(bytes); return true; } catch { return false; }\n};\n\n/** `findProgramAddress`: the first off-curve `sha256(seeds ‖ bump ‖ program ‖ \"ProgramDerivedAddress\")`, bump 255 → 0. */\nfunction programAddress(seeds: readonly Uint8Array[], program: Uint8Array): Uint8Array {\n for (let bump = 255; bump >= 0; bump--) {\n const parts = [...seeds, Uint8Array.of(bump), program, PDA_MARKER];\n const buf = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));\n let at = 0;\n for (const p of parts) { buf.set(p, at); at += p.length; }\n const hash = sha256(buf);\n if (!onCurve(hash)) return hash;\n }\n throw new Error(\"no program address for these seeds\");\n}\n\n/** The associated token account of `owner` for `mint` under `tokenProgram` (all raw 32-byte keys). */\nexport function associatedTokenAccount(owner: Uint8Array, mint: Uint8Array, tokenProgram: Uint8Array = solanaKey(SOLANA_TOKEN_PROGRAM)!): Uint8Array {\n return programAddress([owner, tokenProgram, mint], solanaKey(ASSOCIATED_TOKEN_PROGRAM)!);\n}\n","import {refusalNotes} from \"@anywalletkit/protocol-swap2-core/errors\";\n\n/**\n * The reasons of the texts this package's checks return as strings (the Diamond calldata, the Solana bridge\n * transaction, a remote quote): `note` hands a text back unchanged and remembers its reason, `reasonOf` reads it back\n * for the provider's refusals and for `lifiPins.reasonOf`. Bounded; a text always gets the same reason.\n */\nconst notes = refusalNotes();\n\nexport const note = notes.note;\nexport const reasonOf = notes.reasonOf;\n","/**\n * What the LI.FI Diamond call really does, read from its calldata — not from the `action` /\n * `estimate` next to it (round 3, H9). The API (or an `apiUrl` proxy) could pair a reviewed\n * recipient and minimum with calldata that pays someone else, or accepts 1 wei.\n *\n * Same-chain swaps run through GenericSwapFacet(V3): receiver, minimum, the input token and amount,\n * and the output token are in the arguments. Bridges take `ILiFi.BridgeData` as their first\n * argument: its receiver, destination chain and bridged asset are checked, for the listed bridge\n * entry points only; a destination call (the final recipient sits in calldata for another chain) is\n * refused. For a Solana destination BridgeData.receiver is only LI.FI's non-EVM placeholder and the\n * recipient sits in facet-specific data: it is read for Mayan, Polymer CCTP and Chainflip\n * ({@link solanaRecipientMismatch}); any other non-EVM destination is refused. LI.FI Intents is refused on\n * every route from an EVM chain, to Solana and between EVM chains alike: its escrowed order names its own oracles, output\n * settler and output amount, none of which is pinned here ({@link INTENTS_UNPINNED}).\n *\n * A facet's own data also names who gets money back — unused native fee, swap leftovers, the whole input when an\n * order expires unfilled, a fallback when delivery fails ({@link FACET_DATA}); each such address must be the sender or\n * the recipient.\n *\n * Mostly not checked here: a bridge's OUTPUT. The destination minimum (and for some bridges, e.g.\n * Across, what the receiver finally gets) lives in facet-specific data, so for most bridges the\n * reviewed minimum still relies on LI.FI's API answering honestly. Eco and M0 are the exceptions\n * ({@link FacetData.delivery}): their facet data names the destination token, amount and (Eco) recipient\n * outright, and those are held to the quote. To Solana the delivered token is held to the quote where the\n * facet names it (a Mayan order, Chainflip; Mayan's and Polymer's CCTP legs deliver USDC);\n * the minimum is not.\n *\n * The receiver is only worth checking where the facet itself holds the bridge to it. Most do on\n * chain (Across V4, Mayan, Stargate, Chainflip, GasZip, Glacis, AllBridge, M0, Polymer CCTP) or through\n * LI.FI's backend signature over BridgeData plus the off-chain order (NEAR Intents, LayerSwap, Unit, the\n * Across Swap API). Eco v3 binds its route to BridgeData.receiver by that signature only, so the route\n * itself is read here ({@link ecoDelivery}). The facets in {@link UNBOUND_BRIDGES} do neither and are\n * refused. LI.FI Intents binds its recipient on chain, but releases the escrowed input on the word of an\n * oracle its own calldata names, so it is refused too ({@link INTENTS_UNPINNED}).\n */\n\nimport {associatedTokenAccount, base58, solanaKey} from \"./solana-address.js\";\nimport {note} from \"./refusals.js\";\n\n/**\n * The V3 entry points move one asset kind in and one out, and check the minimum against THAT kind's balance: a\n * `*ToNative` call measures the Diamond's native balance, so a minimum written in USDC units is enforced in wei\n * (scan 2026-10-27 modules, F20). Each selector is bound to the kinds it moves; `swapTokensGeneric` moves any.\n */\ntype Kind = \"native\" | \"erc20\";\nconst GENERIC_SWAPS: Readonly<Record<string, {single: boolean; from?: Kind; to?: Kind}>> = {\n \"0x4630a0d8\": {single: false}, // swapTokensGeneric\n \"0x4666fc80\": {single: true, from: \"erc20\", to: \"erc20\"}, // swapTokensSingleV3ERC20ToERC20\n \"0x733214a3\": {single: true, from: \"erc20\", to: \"native\"}, // swapTokensSingleV3ERC20ToNative\n \"0xaf7060fd\": {single: true, from: \"native\", to: \"erc20\"}, // swapTokensSingleV3NativeToERC20\n \"0x5fd9ae2e\": {single: false, from: \"erc20\", to: \"erc20\"}, // swapTokensMultipleV3ERC20ToERC20\n \"0x2c57e884\": {single: false, from: \"erc20\", to: \"native\"}, // swapTokensMultipleV3ERC20ToNative\n \"0x736eac0b\": {single: false, from: \"native\", to: \"erc20\"}, // swapTokensMultipleV3NativeToERC20\n};\n/** The most a bridge may keep from the input as its own fee when there are no source swaps, in basis points. */\nconst BRIDGE_INPUT_FEE_MAX_BPS = 100n;\nconst kindOf = (asset: string): Kind => (/^0x0{40}$/i.test(asset) ? \"native\" : \"erc20\");\n\n/**\n * The ABI-encoded bridge entry points of the LI.FI Diamond — `startBridgeTokensVia*` and\n * `swapAndStartBridgeTokensVia*`, whose first argument is `ILiFi.BridgeData` — computed from the\n * facet sources in lifinance/contracts (86c3729, 2026-10-26; EcoFacet v3.0.0 from 9001792, 2026-11-01, whose\n * EcoData gained `intentDestination` — the v2 selectors 0xbff90b61 / 0x762aea18 are gone from the Diamonds). Packed\n * facets and `*Min` variants read raw calldata, not BridgeData, and are not listed: any other selector is refused.\n */\nconst BRIDGE_CALLS: Readonly<Record<string, {sourceSwaps: boolean; facet: string}>> = {\n \"0x1fd8010c\": {sourceSwaps: false, facet: \"Across\"}, // startBridgeTokensViaAcross (AcrossFacet)\n \"0x3a3f7332\": {sourceSwaps: true, facet: \"Across\"}, // swapAndStartBridgeTokensViaAcross (AcrossFacet)\n \"0xa1f1ce43\": {sourceSwaps: false, facet: \"AcrossV4\"}, // startBridgeTokensViaAcrossV4 (AcrossFacetV4)\n \"0x1794958f\": {sourceSwaps: true, facet: \"AcrossV4\"}, // swapAndStartBridgeTokensViaAcrossV4 (AcrossFacetV4)\n \"0x6a90d66e\": {sourceSwaps: false, facet: \"AcrossV4Swap\"}, // startBridgeTokensViaAcrossV4Swap (AcrossV4SwapFacet)\n \"0x9b054bc4\": {sourceSwaps: true, facet: \"AcrossV4Swap\"}, // swapAndStartBridgeTokensViaAcrossV4Swap (AcrossV4SwapFacet)\n \"0x6a51e9a9\": {sourceSwaps: false, facet: \"AllBridge\"}, // startBridgeTokensViaAllBridge (AllBridgeFacet)\n \"0x63267469\": {sourceSwaps: true, facet: \"AllBridge\"}, // swapAndStartBridgeTokensViaAllBridge (AllBridgeFacet)\n \"0xc9851d0b\": {sourceSwaps: false, facet: \"ArbitrumBridge\"}, // startBridgeTokensViaArbitrumBridge (ArbitrumBridgeFacet)\n \"0x3cc9517b\": {sourceSwaps: true, facet: \"ArbitrumBridge\"}, // swapAndStartBridgeTokensViaArbitrumBridge (ArbitrumBridgeFacet)\n \"0xe0a4201c\": {sourceSwaps: false, facet: \"CelerCircleBridge\"}, // startBridgeTokensViaCelerCircleBridge (CelerCircleBridgeFacet)\n \"0x4f3b0759\": {sourceSwaps: true, facet: \"CelerCircleBridge\"}, // swapAndStartBridgeTokensViaCelerCircleBridge (CelerCircleBridgeFacet)\n \"0x0315138f\": {sourceSwaps: false, facet: \"Centrifuge\"}, // startBridgeTokensViaCentrifuge (CentrifugeFacet)\n \"0x8fd4d4dd\": {sourceSwaps: true, facet: \"Centrifuge\"}, // swapAndStartBridgeTokensViaCentrifuge (CentrifugeFacet)\n \"0x0ad553b3\": {sourceSwaps: false, facet: \"Chainflip\"}, // startBridgeTokensViaChainflip (ChainflipFacet)\n \"0xee3314a1\": {sourceSwaps: true, facet: \"Chainflip\"}, // swapAndStartBridgeTokensViaChainflip (ChainflipFacet)\n \"0x05c54990\": {sourceSwaps: false, facet: \"Eco\"}, // startBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)\n \"0x8352664c\": {sourceSwaps: true, facet: \"Eco\"}, // swapAndStartBridgeTokensViaEco (EcoFacet v3.0.0, 9001792)\n \"0x678786ea\": {sourceSwaps: false, facet: \"Frax\"}, // startBridgeTokensViaFrax (FraxFacet)\n \"0x07b8e4c7\": {sourceSwaps: true, facet: \"Frax\"}, // swapAndStartBridgeTokensViaFrax (FraxFacet)\n \"0xfc5f1003\": {sourceSwaps: false, facet: \"GasZip\"}, // startBridgeTokensViaGasZip (GasZipFacet)\n \"0x606326ff\": {sourceSwaps: true, facet: \"GasZip\"}, // swapAndStartBridgeTokensViaGasZip (GasZipFacet)\n \"0x6f9206ba\": {sourceSwaps: false, facet: \"Glacis\"}, // startBridgeTokensViaGlacis (GlacisFacet)\n \"0x9c4b6dd9\": {sourceSwaps: true, facet: \"Glacis\"}, // swapAndStartBridgeTokensViaGlacis (GlacisFacet)\n \"0xf66fe519\": {sourceSwaps: false, facet: \"GnosisBridge\"}, // startBridgeTokensViaGnosisBridge (GnosisBridgeFacet)\n \"0x7bf96e0a\": {sourceSwaps: true, facet: \"GnosisBridge\"}, // swapAndStartBridgeTokensViaGnosisBridge (GnosisBridgeFacet)\n \"0xee9e98e0\": {sourceSwaps: false, facet: \"LayerSwap\"}, // startBridgeTokensViaLayerSwap (LayerSwapFacet)\n \"0x4c279d6b\": {sourceSwaps: true, facet: \"LayerSwap\"}, // swapAndStartBridgeTokensViaLayerSwap (LayerSwapFacet)\n \"0x7dbcf1d9\": {sourceSwaps: false, facet: \"LiFiIntentEscrowV2\"}, // startBridgeTokensViaLiFiIntentEscrowV2 (LiFiIntentEscrowFacetV2)\n \"0x6d21c5df\": {sourceSwaps: true, facet: \"LiFiIntentEscrowV2\"}, // swapAndStartBridgeTokensViaLiFiIntentEscrowV2 (LiFiIntentEscrowFacetV2)\n \"0x65782c4b\": {sourceSwaps: false, facet: \"M0\"}, // startBridgeTokensViaM0 (M0Facet)\n \"0xb9eaf86d\": {sourceSwaps: true, facet: \"M0\"}, // swapAndStartBridgeTokensViaM0 (M0Facet)\n \"0xb4875292\": {sourceSwaps: false, facet: \"Mayan\"}, // startBridgeTokensViaMayan (MayanFacet)\n \"0x80c65808\": {sourceSwaps: true, facet: \"Mayan\"}, // swapAndStartBridgeTokensViaMayan (MayanFacet)\n \"0x4213dfff\": {sourceSwaps: false, facet: \"MegaETHBridge\"}, // startBridgeTokensViaMegaETHBridge (MegaETHBridgeFacet)\n \"0x22256e89\": {sourceSwaps: true, facet: \"MegaETHBridge\"}, // swapAndStartBridgeTokensViaMegaETHBridge (MegaETHBridgeFacet)\n \"0x4698f032\": {sourceSwaps: false, facet: \"NEARIntents\"}, // startBridgeTokensViaNEARIntents (NEARIntentsFacet)\n \"0x02631b09\": {sourceSwaps: true, facet: \"NEARIntents\"}, // swapAndStartBridgeTokensViaNEARIntents (NEARIntentsFacet)\n \"0x782621d8\": {sourceSwaps: false, facet: \"OmniBridge\"}, // startBridgeTokensViaOmniBridge (OmniBridgeFacet)\n \"0x95726782\": {sourceSwaps: true, facet: \"OmniBridge\"}, // swapAndStartBridgeTokensViaOmniBridge (OmniBridgeFacet)\n \"0xce8a97a5\": {sourceSwaps: false, facet: \"OptimismBridge\"}, // startBridgeTokensViaOptimismBridge (OptimismBridgeFacet)\n \"0x5bb5d448\": {sourceSwaps: true, facet: \"OptimismBridge\"}, // swapAndStartBridgeTokensViaOptimismBridge (OptimismBridgeFacet)\n \"0xaf62c7d6\": {sourceSwaps: false, facet: \"PolygonBridge\"}, // startBridgeTokensViaPolygonBridge (PolygonBridgeFacet)\n \"0xb4f37581\": {sourceSwaps: true, facet: \"PolygonBridge\"}, // swapAndStartBridgeTokensViaPolygonBridge (PolygonBridgeFacet)\n \"0xf434d6ca\": {sourceSwaps: false, facet: \"PolymerCCTP\"}, // startBridgeTokensViaPolymerCCTP (PolymerCCTPFacet)\n \"0x17917a4e\": {sourceSwaps: true, facet: \"PolymerCCTP\"}, // swapAndStartBridgeTokensViaPolymerCCTP (PolymerCCTPFacet)\n \"0x14d53077\": {sourceSwaps: false, facet: \"Stargate\"}, // startBridgeTokensViaStargate (StargateFacetV2)\n \"0xa6010a66\": {sourceSwaps: true, facet: \"Stargate\"}, // swapAndStartBridgeTokensViaStargate (StargateFacetV2)\n \"0x0691ff78\": {sourceSwaps: false, facet: \"Superset\"}, // startBridgeTokensViaSuperset (SupersetFacet)\n \"0xf26e657f\": {sourceSwaps: true, facet: \"Superset\"}, // swapAndStartBridgeTokensViaSuperset (SupersetFacet)\n \"0x64261d58\": {sourceSwaps: false, facet: \"Unit\"}, // startBridgeTokensViaUnit (UnitFacet)\n \"0x21a3af52\": {sourceSwaps: true, facet: \"Unit\"}, // swapAndStartBridgeTokensViaUnit (UnitFacet)\n};\n\n/**\n * Bridge entry points that do not tie where the funds go to BridgeData.receiver (lifinance/contracts, main 2026-11-02):\n * Relay deposits against an `orderId` whose off-chain order names the recipient (\"We cannot validate / guarantee that the\n * off-chain-data associated with the provided orderId corresponds to the _bridgeData\"); Garden locks the funds for a\n * `redeemer` named in facet data, with the transfer details in an off-chain order; deBridge DLN passes its own\n * `receiver` and order authority through unchecked; ThorSwap pays a `vault` named in facet data with the destination in\n * a memo; Squid runs `sourceCalls` of any target on its multicall, which holds the funds, and bridges what is left\n * (only CallBridge bridges to BridgeData.receiver at all; LI.FI's live Squid quotes are BridgeCall, a destination\n * call); Symbiosis's MetaRouter path forwards `callTo` / `callData` verbatim and names the final recipient and the\n * revert address there (the facet: the emitted receiver \"is therefore descriptive, not an on-chain guarantee\"; its\n * other path bridges to Bitcoin only). A matching BridgeData.receiver proves nothing for these, so they are refused\n * by name.\n *\n * Relay's `orderId` is not opaque: it is a hash commitment, the EIP-712 `hashStruct` of the order (recipient, output\n * token, minimum, deadlines, refunds), signed by Relay's solver. What this path lacks is the preimage: a LI.FI quote\n * carries the id without the order behind it, and neither Relay nor any other party publishes an unauthenticated\n * lookup of an unfunded order by id (2026-11-02: `/intents/status` says \"unknown\", `/requests/v2` lists only indexed\n * deposits, `/requests/v3` needs an API key). With nothing to hash, the id cannot be held to the request here. Relay's\n * own quote does return the order, and `@anywalletkit/protocol-swap2-relay` verifies it on the device.\n */\nconst UNBOUND_BRIDGES: Readonly<Record<string, string>> = {\n \"0x092e8fa4\": \"Relay\", // startBridgeTokensViaRelayDepository\n \"0xa3443faa\": \"Relay\", // swapAndStartBridgeTokensViaRelayDepository\n \"0x5f9af35d\": \"Garden\", // startBridgeTokensViaGarden\n \"0x76ad76fe\": \"Garden\", // swapAndStartBridgeTokensViaGarden\n \"0x4004633e\": \"deBridge DLN\", // startBridgeTokensViaDeBridgeDln\n \"0x2c7d2db0\": \"deBridge DLN\", // swapAndStartBridgeTokensViaDeBridgeDln\n \"0x2541ec57\": \"ThorSwap\", // startBridgeTokensViaThorSwap\n \"0xad673d88\": \"ThorSwap\", // swapAndStartBridgeTokensViaThorSwap\n \"0x3f313808\": \"Squid\", // startBridgeTokensViaSquid\n \"0xa8f66666\": \"Squid\", // swapAndStartBridgeTokensViaSquid\n \"0xe23b7a08\": \"Symbiosis\", // startBridgeTokensViaSymbiosis\n \"0xc46059b2\": \"Symbiosis\", // swapAndStartBridgeTokensViaSymbiosis\n};\n\n/** What the quote promised, in the forms the calldata carries. */\nexport interface DiamondExpectation {\n /** Source token (EVM address; the zero address for the native coin). */\n fromToken: string;\n /** Destination token as LI.FI names it (the zero address for an EVM native coin). */\n toToken: string;\n /** Input, base units. */\n amountIn: bigint;\n /** The recipient (an EVM address, or another chain's address for a non-EVM destination). */\n receiver: string;\n /** The sender the quote was asked for (its `fromAddress`): where a bridge's refunds may go, besides the recipient. */\n sender: string;\n /** The floor the review shows. */\n minOut: bigint;\n /** LI.FI's id of the destination chain; equal to the source's for a swap. */\n destChainId: bigint;\n sameChain: boolean;\n /** The destination is an EVM chain (its receiver is a 20-byte address). */\n evmDestination: boolean;\n}\n\ninterface SwapStep {sendingAssetId: string; receivingAssetId: string; fromAmount: bigint; requiresDeposit: boolean}\n\nclass Reader {\n private readonly b: Uint8Array;\n constructor(src: string | Uint8Array) {\n if (typeof src !== \"string\") { this.b = src; return; }\n if (!/^0x([0-9a-fA-F]{2})*$/.test(src)) throw new Error(\"not hex\");\n this.b = Uint8Array.from(src.slice(2).match(/../g) ?? [], (h) => Number.parseInt(h, 16));\n }\n get length() { return this.b.length; }\n /** `n` raw bytes at `at`, as 0x-hex. */\n raw(at: number, n: number): string {\n if (at < 0 || at + n > this.b.length) throw new Error(\"out of bounds\");\n return `0x${Array.from(this.b.subarray(at, at + n), (x) => x.toString(16).padStart(2, \"0\")).join(\"\")}`;\n }\n /** The `bytes` whose offset word sits at `head` (relative to `base`), as a reader over its contents only. */\n bytes(base: number, head: number): Reader {\n const at = base + this.small(head);\n const n = this.small(at);\n if (at + 32 + n > this.b.length) throw new Error(\"bytes out of bounds\");\n return new Reader(this.b.subarray(at + 32, at + 32 + n));\n }\n word(at: number): bigint {\n if (at < 0 || at + 32 > this.b.length) throw new Error(\"out of bounds\");\n let v = 0n;\n for (let i = at; i < at + 32; i++) v = (v << 8n) | BigInt(this.b[i]!);\n return v;\n }\n /** A word that must fit a JS offset / length (bounded by the calldata). */\n small(at: number): number {\n const v = this.word(at);\n if (v > BigInt(this.b.length)) throw new Error(\"offset out of bounds\");\n return Number(v.toString()); // ≤ the calldata length\n }\n address(at: number): string {\n const v = this.word(at);\n if (v >> 160n !== 0n) throw new Error(\"not an address\");\n return `0x${v.toString(16).padStart(40, \"0\")}`;\n }\n bool(at: number): boolean {\n const v = this.word(at);\n if (v > 1n) throw new Error(\"not a bool\");\n return v === 1n;\n }\n}\n\nconst same = (a: string, b: string) => a.toLowerCase() === b.toLowerCase();\n\n/** SwapData tuple at `at`: (callTo, approveTo, sendingAssetId, receivingAssetId, fromAmount, callData, requiresDeposit). */\nfunction swapAt(r: Reader, at: number): SwapStep {\n r.address(at); r.address(at + 32);\n const step = {sendingAssetId: r.address(at + 64), receivingAssetId: r.address(at + 96), fromAmount: r.word(at + 128), requiresDeposit: false};\n const bytesAt = at + r.small(at + 160);\n r.small(bytesAt); // length within the calldata\n // The Diamond pulls `fromAmount` of `sendingAssetId` from the user for every step that requires a deposit.\n step.requiresDeposit = r.bool(at + 192);\n return step;\n}\n\n/** SwapData[] whose offset word sits at `head`, relative to `base`. */\nfunction swapsAt(r: Reader, base: number, head: number): SwapStep[] {\n const array = base + r.small(head);\n const n = r.small(array);\n if (n === 0 || n > 16) throw new Error(\"bad swap count\");\n const items = array + 32;\n return Array.from({length: n}, (_, i) => swapAt(r, items + r.small(items + 32 * i)));\n}\n\n/**\n * Every step, not only the ends (scan 2026-10-27 modules, F21–F23): the Diamond pulls `fromAmount` from the user for\n * each step that requires a deposit, so only steps that spend the source token may, and together at most the input —\n * a middle step depositing DAI under a leftover allowance is refused. The steps chain: each spends what the one before\n * delivered (a fee step on the input sends and receives the same asset).\n */\nfunction checkSteps(steps: SwapStep[], e: DiamondExpectation, finalAsset: string): string | null {\n const first = steps[0]!;\n const last = steps[steps.length - 1]!;\n if (!same(first.sendingAssetId, e.fromToken)) return note(`spends ${first.sendingAssetId}, not ${e.fromToken}`, \"policy_refused\");\n if (first.fromAmount === 0n || first.fromAmount > e.amountIn) return note(`swaps ${first.fromAmount}, not the ${e.amountIn} spent`, \"policy_refused\");\n let deposited = 0n;\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i]!;\n if (i > 0 && !same(step.sendingAssetId, steps[i - 1]!.receivingAssetId)) return note(`step ${i} spends ${step.sendingAssetId}, which step ${i - 1} does not deliver`, \"policy_refused\");\n if (!step.requiresDeposit) continue;\n if (!same(step.sendingAssetId, e.fromToken)) return note(`step ${i} pulls ${step.sendingAssetId} from the wallet, not the input ${e.fromToken}`, \"policy_refused\");\n deposited += step.fromAmount;\n }\n if (deposited > e.amountIn) return note(`the steps pull ${deposited} from the wallet, more than the ${e.amountIn} spent`, \"policy_refused\");\n if (!same(last.receivingAssetId, finalAsset)) return note(`delivers ${last.receivingAssetId}, not ${finalAsset}`, \"policy_refused\");\n return null;\n}\n\n/** A Mayan Swift order refunds its input to `trader` when it is not filled, a Wormhole swap to `refundAddr`: their byte\n * offset in `protocolData` (Mayan's swap-sdk, src/evm; selectors as the facet lists them). MCTP and FastMCTP orders and\n * the HyperCore deposits carry no refund address: what they do not deliver settles to the destination address the facet\n * already checks against BridgeData.receiver. */\nconst MAYAN_REFUND_AT: Readonly<Record<string, number>> = {\n \"0xa3a30834\": 4 + 32 * 3, // Swift v2 createOrderWithToken(tokenIn, amountIn, (payloadType, trader, destAddr, …), customPayload)\n \"0x6147435b\": 4 + 32 * 3, // Swift v2 createOrderWithSig: the same order tuple\n \"0xb866e173\": 4, // Swift createOrderWithEth((trader, tokenOut, …))\n \"0x8e8d142b\": 4 + 32 * 2, // Swift createOrderWithToken(tokenIn, amountIn, (trader, tokenOut, …))\n \"0x6111ad25\": 4 + 32 * 9, // MayanSwap swap(relayerFees, (mayanAddr, mayanChainId, auctionAddr, destAddr, destChainId, referrer, refundAddr), …)\n \"0x1eb1cff0\": 4 + 32 * 9, // MayanSwap wrapAndSwapETH: the same recipient tuple\n};\nfunction mayanRefunds(r: Reader, at: number): Refund[] {\n const p = r.bytes(at, at + 32 * 2);\n const pos = MAYAN_REFUND_AT[p.raw(0, 4)];\n return pos === undefined ? [] : [[\"the Mayan order's refund address\", p.address(pos)]];\n}\n/** Chainflip refunds the whole input to the address in `cfParameters` when the swap misses its minimum price:\n * VersionedCfParameters V1 (SCALE) — version, retry duration (u32), then the refund address, 20 bytes from an EVM chain. */\nfunction chainflipRefunds(r: Reader, at: number): Refund[] {\n const p = r.bytes(at, at + 32 * 5);\n if (p.length < 25 || p.raw(0, 1) !== \"0x01\") throw new Error(\"unknown Chainflip parameters\");\n return [[\"the Chainflip refund address\", p.raw(5, 20)]];\n}\n/** The Across Swap API call, by target: the SpokePool deposit's depositor (DepositParams, depositor first) and the\n * periphery's `depositData.depositor` get an expired deposit back (and the periphery's positive slippage); the\n * sponsored OFT and CCTP flows refund to an unsigned `refundRecipient`. */\nfunction acrossSwapRefunds(r: Reader, at: number): Refund[] {\n const target = r.word(at);\n const c = r.bytes(at, at + 32);\n // The facet refuses a zero depositor / refundRecipient on every target.\n if (target === 0n) return [[\"the Across deposit's depositor\", c.address(c.small(0)), true]];\n if (target === 1n) {\n const swap = c.small(0); // SwapAndDepositData: (submissionFees.amount, submissionFees.recipient, depositData, …)\n return [[\"the Across deposit's depositor\", c.address(swap + c.small(swap + 64) + 96), true]]; // BaseDepositData word 3\n }\n if (target === 2n) return [[\"the sponsored OFT refund recipient\", c.address(c.small(0) + 32), true]]; // (Quote(signed, unsigned), signature)\n if (target === 3n) return [[\"the sponsored CCTP refund recipient\", c.address(64), true]]; // (quote, signature, refundRecipient)\n throw new Error(\"unknown Across Swap API target\");\n}\n\n/** The EVM native-token placeholder (the zero address) in the quote's destination token. */\n/** ERC-20 `transfer(address,uint256)`. */\nconst ERC20_TRANSFER = \"0xa9059cbb\";\n/**\n * Eco v3 (EcoFacet 3.0.0, lifinance/contracts 9001792): EcoData is (nonEVMReceiver, prover, rewardDeadline,\n * intentDestination, encodedRoute, solanaATA, refundRecipient, deadline, signature), a dynamic struct. v2 decoded the\n * route on chain and required its final `transfer` to pay BridgeData.receiver; v3 dropped that check (\"for EVM\n * destinations the receiver is therefore enforced only by the backend signature, not on-chain\") and lets the route\n * run on another chain than the destination (`intentDestination`: the source chain for a CCTP burn, HyperEVM for a\n * HyperCore deposit, a second intent), with calls the facet does not interpret. So the device checks what v2 did, and\n * more: the intent runs on the destination chain itself, and the route — abi.encode(Route(salt, deadline, portal,\n * nativeAmount, tokens, calls)), Call = (target, data, value) — ends in the destination token's `transfer` of at least\n * the reviewed minimum to the recipient. Whatever runs before it, the solver's fill either pays that or does not\n * happen, and the reward (the input) then goes back to refundRecipient, checked above.\n */\nfunction ecoDelivery(r: Reader, at: number, e: DiamondExpectation): string | null {\n // A native delivery has no token `transfer` to read (it would be a value call to the recipient), so it is refused\n // outright — not left to the token comparison below, where a `transfer` \"of\" the zero address would match.\n if (kindOf(e.toToken) === \"native\") return note(\"an Eco route to the native token cannot be checked here\", \"recipient_unverifiable\");\n const destination = r.word(at + 32 * 3);\n if (destination !== e.destChainId) return note(`the Eco intent executes on chain ${destination}, not the destination ${e.destChainId} — a route whose delivery cannot be checked here`, \"recipient_unverifiable\");\n const route = r.bytes(at, at + 32 * 4);\n const tuple = route.small(0);\n const calls = tuple + route.small(tuple + 32 * 5);\n const n = route.small(calls);\n if (n === 0) return note(\"the Eco route makes no calls on the destination chain\", \"recipient_unverifiable\");\n if (n > 16) return note(`the Eco route makes ${n} calls on the destination chain, more than the 16 read here`, \"recipient_unverifiable\");\n const last = calls + 32 + route.small(calls + 32 + 32 * (n - 1));\n const target = route.address(last);\n const data = route.bytes(last, last + 32);\n if (route.word(last + 64) !== 0n || data.length !== 68 || data.raw(0, 4) !== ERC20_TRANSFER) return note(\"the Eco route does not end in a token transfer\", \"recipient_unverifiable\");\n const to = data.address(4);\n const amount = data.word(36);\n if (!same(target, e.toToken)) return note(`the Eco route delivers ${target}, not ${e.toToken}`, \"policy_refused\");\n if (!same(to, e.receiver)) return note(`the Eco route pays ${to}, not ${e.receiver}`, \"recipient_mismatch\");\n if (amount < e.minOut) return note(`the Eco route delivers ${amount}, below the ${e.minOut} shown`, \"price_check_failed\");\n return null;\n}\n/**\n * M0 (M0Facet 1.0.0): an order on the M0 OrderBook asks a solver for `amountOut` of `tokenOut` on the destination\n * (M0Data words 3 and 5); the facet ties only the receiver to BridgeData. Both must be the quote's: the destination\n * token, and at least the reviewed minimum. On the swap entry point the facet scales amountOut by the swap's realised\n * output over the quoted input (never below 1×), so the calldata's value is a lower bound there too. amountOut is a\n * limit rate, not a fill guarantee: a partial fill delivers its share and refunds the rest to orderOwner (the sender).\n */\nfunction m0Delivery(r: Reader, at: number, e: DiamondExpectation): string | null {\n // M0Facet refuses a zero tokenOut (the OrderBook would escrow the input with nothing to fill): no native delivery.\n if (kindOf(e.toToken) === \"native\") return note(\"an M0 order cannot deliver the native token\", \"unsupported_pair\");\n const tokenOut = r.address(at + 32 * 3);\n const amountOut = r.word(at + 32 * 5);\n if (!same(tokenOut, e.toToken)) return note(`the M0 order asks for ${tokenOut}, not ${e.toToken}`, \"policy_refused\");\n if (amountOut < e.minOut) return note(`the M0 order asks for ${amountOut}, below the ${e.minOut} shown`, \"price_check_failed\");\n return null;\n}\n\n/**\n * Where a bridge facet's data names who gets money back: an unused native fee, swap leftovers or positive slippage, the\n * whole input when a deposit, intent or order expires unfilled, or a fallback when delivery fails. The facets only\n * require these to be non-zero (NEAR Intents, LayerSwap and Eco also sign them on LI.FI's backend, which an `apiUrl`\n * proxy cannot forge but LI.FI's API itself writes), so each must be the sender or the recipient; LI.FI's live quotes\n * set them to the sender. `refunds` are [field, word] in the facet data (lifinance/contracts, the same structs at\n * 86c3729 and on main 2026-11-02; Eco as at v3.0.0, 9001792, whose entry points are the listed ones); `inline` marks a static\n * struct, which is encoded in place among the arguments rather than behind an offset (its word count). A zero is\n * accepted where the facet itself refuses a zero in every field it uses (`zeroRefused`; Polymer CCTP reads its\n * refundRecipient on the swap entry point only): it pays no one. Stargate passes a zero to LayerZero, and Mayan and\n * Chainflip carry theirs into the protocol, so there a zero is refused like any other address.\n */\ninterface FacetData {\n inline?: number;\n refunds?: readonly (readonly [string, number])[];\n zeroRefused?: true;\n nested?: (r: Reader, at: number) => Refund[];\n /** What the facet data says the destination receives, held to the quote: a reason it does not match, or null. */\n delivery?: (r: Reader, at: number, e: DiamondExpectation) => string | null;\n}\n/** [what, address, a zero there is refused by the facet]. */\ntype Refund = [string, string, boolean?];\nconst FACET_DATA: Readonly<Record<string, FacetData>> = {\n AcrossV4: {refunds: [[\"refundAddress\", 1]], zeroRefused: true}, // the SpokePool depositor: an expired deposit refunds the input there\n AcrossV4Swap: {nested: acrossSwapRefunds},\n Centrifuge: {inline: 2, refunds: [[\"refundRecipient\", 1]], zeroRefused: true},\n Chainflip: {nested: chainflipRefunds},\n Eco: {refunds: [[\"refundRecipient\", 6]], zeroRefused: true, delivery: ecoDelivery}, // the intent's creator, refunded its reward (the input) on expiry\n Frax: {inline: 5, refunds: [[\"refundRecipient\", 3]], zeroRefused: true},\n Glacis: {inline: 4, refunds: [[\"refundAddress\", 1]], zeroRefused: true},\n LayerSwap: {refunds: [[\"refundRecipient\", 2]], zeroRefused: true},\n // The escrow order's user. Not reached while LI.FI Intents is refused on every EVM-source route (INTENTS_UNPINNED); kept for when\n // its oracles and settler are pinned.\n LiFiIntentEscrowV2: {refunds: [[\"depositAndRefundAddress\", 2]], zeroRefused: true},\n M0: {inline: 7, refunds: [[\"refundRecipient\", 1], [\"orderOwner\", 2]], zeroRefused: true, delivery: m0Delivery}, // orderOwner gets a cancelled order back\n Mayan: {refunds: [[\"refundRecipient\", 7]], nested: mayanRefunds, zeroRefused: true},\n NEARIntents: {refunds: [[\"refundRecipient\", 6]], zeroRefused: true}, // also the 1Click quote's refundTo\n PolymerCCTP: {refunds: [[\"refundRecipient\", 5]], zeroRefused: true},\n Stargate: {refunds: [[\"refundAddress\", 4]]}, // (assetId, sendParams, fee.nativeFee, fee.lzTokenFee, refundAddress): LayerZero's fee refund\n Superset: {refunds: [[\"refundAddress\", 2], [\"fallbackEoA\", 3]], zeroRefused: true},\n};\n/**\n * Facets whose data names no one to pay back: Across (the SpokePool's depositor is the Diamond), AllBridge, Celer\n * Circle, GasZip, MegaETH and Optimism (no address but the receiver the facet checks), Arbitrum (its retryable's\n * refunds go to BridgeData.receiver), Gnosis, Omni and Polygon (no facet data) and Unit (its own deposit address,\n * signed). Their excess native and swap leftovers go to the caller.\n */\nconst NO_REFUND_FIELDS = new Set([\"Across\", \"AllBridge\", \"ArbitrumBridge\", \"CelerCircleBridge\", \"GasZip\", \"GnosisBridge\", \"MegaETHBridge\", \"OmniBridge\", \"OptimismBridge\", \"PolygonBridge\", \"Unit\"]);\n\n/** Where the facet data starts: the last argument, after BridgeData's offset word (and the SwapData[]'s). */\nfunction facetDataAt(r: Reader, bridge: {sourceSwaps: boolean}, spec: FacetData): number {\n const slot = 4 + (bridge.sourceSwaps ? 64 : 32);\n return spec.inline ? slot : 4 + r.small(slot);\n}\n\n/** A refund or fallback in the bridge's facet data that pays neither the sender nor the recipient, or null. */\nfunction refundMismatch(r: Reader, bridge: {sourceSwaps: boolean; facet: string}, e: DiamondExpectation): string | null {\n const spec = FACET_DATA[bridge.facet];\n if (!spec) return NO_REFUND_FIELDS.has(bridge.facet) ? null : note(`no known refund layout for ${bridge.facet}`, \"recipient_unverifiable\");\n const at = facetDataAt(r, bridge, spec);\n const paid: Refund[] = (spec.refunds ?? []).map(([field, word]) => [`${bridge.facet} ${field}`, r.address(at + 32 * word), spec.zeroRefused === true]);\n paid.push(...(spec.nested?.(r, at) ?? []));\n for (const [what, to, zeroRefused] of paid) {\n if (zeroRefused && /^0x0{40}$/.test(to)) continue;\n if (!same(to, e.sender) && !same(to, e.receiver)) return note(`${what} pays ${to}, neither the sender ${e.sender} nor the recipient`, \"recipient_mismatch\");\n }\n return null;\n}\n\n/** The refusal for a non-EVM destination whose recipient this module does not read. */\nconst NON_EVM_UNREAD = \"the recipient on a non-EVM destination sits in bridge-specific data and cannot be checked here\";\n/** LI.FI's Solana chain id and the BridgeData.receiver of a non-EVM destination (LiFiData.sol, lifinance/contracts). */\nconst LIFI_SOLANA_CHAIN_ID = 1151111081099710n;\nconst NON_EVM_ADDRESS = \"0x11f111f111f111f111f111f111f111f111f111f1\";\nconst SOLANA_USDC = \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\";\n/** Solana as Mayan names it: Wormhole chain 1, CCTP domain 5 (Mayan swap-sdk `utils.ts` / `cctp.ts`; Circle's domain list). */\nconst WORMHOLE_SOLANA = 1n;\nconst CCTP_DOMAIN_SOLANA = 5n;\n/** Chainflip's asset ids on Solana (SOL, USDC, USDT), as `@anywalletkit/protocol-swap2-chainflip` lists them. */\nconst CHAINFLIP_SOLANA_ASSETS: Readonly<Record<string, bigint>> = {\n \"11111111111111111111111111111111\": 9n,\n [SOLANA_USDC]: 10n,\n Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB: 16n,\n};\n/** Facets that pay a deposit address or a depository whose off-chain order names the recipient. */\nconst DEPOSIT_FACETS = new Set([\"NEARIntents\", \"LayerSwap\", \"Unit\"]);\n\n/** A Mayan call's Solana fields, as head words of `protocolData` after its selector (Mayan swap-sdk ABIs, selectors as MayanFacet lists them). */\ninterface MayanSolanaLayout {destAddr: number; chain: number; cctp: boolean; payloadType?: readonly [number, bigint]; tokenOut?: number}\nconst MAYAN_SOLANA: Readonly<Record<string, MayanSolanaLayout>> = {\n // Swift v2 createOrderWithToken(tokenIn, amountIn, (payloadType, trader, destAddr, destChainId, referrerAddr, tokenOut, minAmountOut, …), customPayload)\n \"0xa3a30834\": {destAddr: 4, chain: 5, cctp: false, payloadType: [2, 1n], tokenOut: 7},\n // MCTP createOrder((tokenIn, amountIn, gasDrop, destAddr, destChain, tokenOut, minAmountOut, deadline, redeemFee, referrerAddr, referrerBps))\n \"0x1c59b7fc\": {destAddr: 3, chain: 4, cctp: false, tokenOut: 5},\n // MCTP bridgeWithFee(tokenIn, amountIn, redeemFee, gasDrop, destAddr, destDomain, payloadType, customPayload): delivers USDC\n \"0x2072197f\": {destAddr: 4, chain: 5, cctp: true, payloadType: [6, 1n]},\n // Fast MCTP bridge(tokenIn, amountIn, redeemFee, circleMaxFee, gasDrop, destAddr, destDomain, referrerAddress, referrerBps, payloadType, minFinalityThreshold, customPayload): delivers USDC\n \"0xf58b6de8\": {destAddr: 5, chain: 6, cctp: true, payloadType: [9, 1n]},\n // Fast MCTP createOrder(tokenIn, amountIn, circleMaxFee, destDomain, minFinalityThreshold, (payloadType 3, destAddr, tokenOut, amountOutMin, …))\n \"0x2337e236\": {destAddr: 6, chain: 3, cctp: true, payloadType: [5, 3n], tokenOut: 7},\n};\n\n/** What a Solana delivery must name: the requested owner and mint, as raw keys and as 0x-hex words. */\ninterface SolanaTarget {owner: Uint8Array; ownerHex: string; mint: Uint8Array; mintHex: string; e: DiamondExpectation}\nconst hexOf = (b: Uint8Array): string => `0x${Array.from(b, (x) => x.toString(16).padStart(2, \"0\")).join(\"\")}`;\n/** A 0x-hex 32-byte word as a Solana address, for messages. */\nconst keyOf = (word: string): string => base58(Uint8Array.from(word.slice(2).match(/../g) ?? [], (h) => Number.parseInt(h, 16)));\n\n/**\n * Mayan (MayanFacet 2.0.0) requires MayanData.nonEVMReceiver to equal the destination address inside `protocolData`, the\n * order or transfer it forwards to Mayan; both are read. For Solana Mayan's swap-sdk writes the owner wallet there\n * (`nativeAddressToHexString(destinationAddress, solana)`), and Mayan's programs pay its associated token account. An\n * order names its output token (the mint; 32 zero bytes for SOL) and Solana as Wormhole chain 1 or CCTP domain 5; a\n * plain CCTP transfer delivers USDC. A custom payload (a handler as destAddr) is refused.\n */\nfunction mayanToSolana(r: Reader, at: number, t: SolanaTarget): string | null {\n const declared = r.raw(at, 32);\n if (declared !== t.ownerHex) return note(`Mayan's nonEVMReceiver is ${keyOf(declared)}, not the recipient ${t.e.receiver}`, \"recipient_mismatch\");\n const p = r.bytes(at, at + 32 * 2);\n const selector = p.raw(0, 4);\n const o = MAYAN_SOLANA[selector];\n if (!o) return note(`the Mayan call ${selector} is an entry point whose Solana recipient cannot be checked here`, \"recipient_unverifiable\");\n const word = (i: number) => 4 + 32 * i;\n if (o.payloadType && p.word(word(o.payloadType[0])) !== o.payloadType[1]) return note(`the Mayan call ${selector} carries payload type ${p.word(word(o.payloadType[0]))}, not a plain delivery`, \"recipient_unverifiable\");\n const dest = p.raw(word(o.destAddr), 32);\n if (dest !== t.ownerHex) return note(`the Mayan order pays ${keyOf(dest)} on Solana, not the recipient ${t.e.receiver}`, \"recipient_mismatch\");\n const chain = p.word(word(o.chain));\n if (chain !== (o.cctp ? CCTP_DOMAIN_SOLANA : WORMHOLE_SOLANA)) return note(`the Mayan order goes to ${o.cctp ? \"CCTP domain\" : \"Wormhole chain\"} ${chain}, not Solana`, \"policy_refused\");\n if (o.tokenOut === undefined) return t.e.toToken === SOLANA_USDC ? null : note(`a Mayan CCTP transfer delivers USDC, not ${t.e.toToken}`, \"policy_refused\");\n const token = p.raw(word(o.tokenOut), 32);\n return token === t.mintHex ? null : note(`the Mayan order delivers ${keyOf(token)}, not ${t.e.toToken}`, \"policy_refused\");\n}\n\n/**\n * Polymer CCTP (PolymerCCTPFacet 3.1.0): CCTP mints to `solanaReceiverATA`, which the facet cannot check (\"must be the\n * USDC ATA of nonEVMReceiver\"; nonEVMReceiver is the owner wallet the relayer reads). It must be the associated token\n * account of the requested owner for USDC, derived here.\n */\nfunction polymerToSolana(r: Reader, at: number, t: SolanaTarget): string | null {\n const declared = r.raw(at + 32 * 2, 32);\n if (declared !== t.ownerHex) return note(`Polymer CCTP's nonEVMReceiver is ${keyOf(declared)}, not the recipient ${t.e.receiver}`, \"recipient_mismatch\");\n if (t.e.toToken !== SOLANA_USDC) return note(`Polymer CCTP delivers USDC, not ${t.e.toToken}`, \"policy_refused\");\n const mintTo = r.raw(at + 32 * 3, 32);\n const account = hexOf(associatedTokenAccount(t.owner, t.mint));\n return mintTo === account ? null : note(`the Polymer CCTP transfer mints to ${keyOf(mintTo)}, not the recipient's USDC account ${keyOf(account)}`, \"recipient_mismatch\");\n}\n\n/** Chainflip (ChainflipFacet 1.0.1): the vault swap's dstAddress is `nonEVMReceiver` verbatim (32 bytes, the owner, for Solana) and `dstToken` Chainflip's asset id. */\nfunction chainflipToSolana(r: Reader, at: number, t: SolanaTarget): string | null {\n const dst = r.bytes(at, at);\n if (dst.length !== 32) return note(`Chainflip pays a ${dst.length}-byte address on Solana, not the recipient ${t.e.receiver}`, \"recipient_mismatch\");\n if (dst.raw(0, 32) !== t.ownerHex) return note(`Chainflip pays ${keyOf(dst.raw(0, 32))} on Solana, not the recipient ${t.e.receiver}`, \"recipient_mismatch\");\n const asset = r.word(at + 32);\n const want = CHAINFLIP_SOLANA_ASSETS[t.e.toToken];\n return want !== undefined && asset === want ? null : note(`Chainflip delivers its asset ${asset}, not ${t.e.toToken}`, \"policy_refused\");\n}\n\nconst SOLANA_DELIVERY: Readonly<Record<string, (r: Reader, at: number, t: SolanaTarget) => string | null>> = {\n Mayan: mayanToSolana,\n PolymerCCTP: polymerToSolana,\n Chainflip: chainflipToSolana,\n};\n\n/**\n * LI.FI Intents (LiFiIntentEscrowFacetV2 2.0.0) escrows the input on the source chain for an order whose `inputOracle`,\n * `outputOracle`, `outputSettler` and `outputAmountMultiplier` come from the calldata: the escrow releases the input to\n * whoever the input oracle says filled the order, and the committed output is `input × multiplier / 1e18`. Naming the\n * recipient and the output token binds nothing while an API or proxy can name its own oracle (which then attests a fill\n * that never happened) or a near-zero multiplier, and these addresses are not pinned here for Solana's settler and\n * oracle — so an Intents order to Solana is refused, recipient read or not.\n */\nconst INTENTS_TO_SOLANA = \"a LI.FI Intents order to Solana names its own oracles, output settler and output amount, which cannot be checked here — its escrow could release the input without the delivery\";\n/**\n * The same holds between EVM chains: the escrow trusts the `inputOracle` the calldata names, the output side runs through\n * the `outputSettler` and `outputOracle` it names, and the committed output is `input × outputAmountMultiplier / 1e18`;\n * none of them is pinned or bounded here (lifinance/contracts LiFiIntentEscrowFacetV2 2.0.0 only requires the recipient\n * and a non-zero refund address). An Intents call to an EVM chain (or on a same-chain route) is refused before anything\n * else is read; to Solana with {@link INTENTS_TO_SOLANA}.\n */\nconst INTENTS_UNPINNED = \"a LI.FI Intents order to an EVM chain names its own oracles, output settler and output amount, which cannot be checked here — its escrow could release the input without the delivery\";\nconst INTENTS_FACET = \"LiFiIntentEscrowV2\";\n\n/**\n * EVM → Solana: BridgeData must name LI.FI's Solana chain id (checked by the caller) and, as its receiver, exactly the\n * NON_EVM_ADDRESS placeholder; the recipient sits in the facet's own data and is held here to the requested owner (the\n * raw 32 bytes of `destAddress`) and the requested mint, for the facets whose delivery the transaction binds (Mayan,\n * Polymer CCTP, Chainflip). NEAR Intents, LayerSwap and Unit pay a deposit address or a depository whose off-chain order\n * names the recipient: a deposit the device cannot verify, refused for this direction. LI.FI Intents is refused\n * ({@link INTENTS_TO_SOLANA}). Any other facet keeps the non-EVM refusal.\n */\nfunction solanaRecipientMismatch(r: Reader, bridge: {sourceSwaps: boolean; facet: string}, receiver: string, e: DiamondExpectation): string | null {\n if (e.destChainId !== LIFI_SOLANA_CHAIN_ID) return note(NON_EVM_UNREAD, \"recipient_unverifiable\");\n if (!same(receiver, NON_EVM_ADDRESS)) return note(`BridgeData pays ${receiver}, not LI.FI's non-EVM placeholder ${NON_EVM_ADDRESS}, on a Solana route`, \"recipient_mismatch\");\n if (DEPOSIT_FACETS.has(bridge.facet)) return note(`${bridge.facet} pays a deposit address whose off-chain order names the Solana recipient — the transaction does not bind it`, \"recipient_unverifiable\");\n if (bridge.facet === INTENTS_FACET) return note(INTENTS_TO_SOLANA, \"recipient_unverifiable\");\n const read = SOLANA_DELIVERY[bridge.facet];\n if (!read) return note(NON_EVM_UNREAD, \"recipient_unverifiable\");\n const owner = solanaKey(e.receiver);\n if (!owner) return note(`the recipient ${e.receiver} is not a Solana address`, \"recipient_mismatch\");\n const mint = solanaKey(e.toToken);\n if (!mint) return note(`the destination token ${e.toToken} is not a Solana mint`, \"unsupported_pair\");\n return read(r, facetDataAt(r, bridge, FACET_DATA[bridge.facet]!), {owner, ownerHex: hexOf(owner), mint, mintHex: hexOf(mint), e});\n}\n\n/** Why the Diamond calldata does not do what the quote says, or null when it does. */\nexport function diamondCallMismatch(data: string, e: DiamondExpectation): string | null {\n let r: Reader;\n try { r = new Reader(data); } catch { return note(\"the calldata is not hex\", \"upstream_unavailable\"); }\n if (r.length < 4 + 32 * 2) return note(\"the calldata is too short\", \"upstream_unavailable\");\n const selector = data.slice(0, 10).toLowerCase();\n const generic = GENERIC_SWAPS[selector];\n try {\n if (generic) {\n if (!e.sameChain) return note(\"a same-chain swap call on a cross-chain route\", \"policy_refused\");\n // (bytes32 txId, string integrator, string referrer, address receiver, uint256 minAmount, SwapData | SwapData[])\n const receiver = r.address(4 + 96);\n const minAmount = r.word(4 + 128);\n const steps = generic.single ? [swapAt(r, 4 + r.small(4 + 160))] : swapsAt(r, 4, 4 + 160);\n if (!e.evmDestination || !same(receiver, e.receiver)) return note(`pays ${receiver}, not ${e.receiver}`, \"recipient_mismatch\");\n if (minAmount < e.minOut) return note(`accepts ${minAmount}, below the ${e.minOut} shown`, \"price_check_failed\");\n if (generic.from && kindOf(e.fromToken) !== generic.from) return note(`${selector} swaps from ${generic.from === \"native\" ? \"the native coin\" : \"a token\"}, but the input is ${kindOf(e.fromToken) === \"native\" ? \"the native coin\" : \"a token\"}`, \"policy_refused\");\n if (generic.to && (kindOf(e.toToken) !== generic.to || kindOf(steps[steps.length - 1]!.receivingAssetId) !== generic.to)) {\n return note(`${selector} delivers ${generic.to === \"native\" ? \"the native coin\" : \"a token\"}, but the output is ${kindOf(e.toToken) === \"native\" ? \"the native coin\" : \"a token\"} — its minimum would be counted in the wrong asset`, \"policy_refused\");\n }\n return checkSteps(steps, e, e.toToken);\n }\n // Bridge facets: (BridgeData, [SwapData[],] FacetData), only the listed ABI entry points.\n // BridgeData is dynamic (it holds strings), so its offset is the head size.\n const unbound = UNBOUND_BRIDGES[selector];\n if (unbound) return note(`${unbound} delivers to a recipient the transaction does not bind (an off-chain order or unchecked facet data)`, \"recipient_unverifiable\");\n const bridge = BRIDGE_CALLS[selector];\n if (!bridge) return note(`unknown Diamond call ${selector}`, \"policy_refused\");\n if (bridge.facet === INTENTS_FACET && e.evmDestination) return note(INTENTS_UNPINNED, \"recipient_unverifiable\");\n const head = r.small(4);\n if (head < (bridge.sourceSwaps ? 96 : 64) || head % 32 !== 0 || head > 32 * 32) return note(`unknown Diamond call ${selector}`, \"policy_refused\");\n const at = 4 + head;\n // BridgeData: (txId, string bridge, string integrator, referrer, sendingAssetId, receiver, minAmount, destinationChainId, hasSourceSwaps, hasDestinationCall)\n if (r.small(at + 32) !== 320) return note(`unknown Diamond call ${selector}`, \"policy_refused\");\n const sendingAssetId = r.address(at + 128);\n const receiver = r.address(at + 160);\n const minAmount = r.word(at + 192);\n const destinationChainId = r.word(at + 224);\n const hasSourceSwaps = r.bool(at + 256);\n const hasDestinationCall = r.bool(at + 288);\n if (e.sameChain) return note(\"a bridge call on a same-chain route\", \"policy_refused\");\n if (destinationChainId !== e.destChainId) return note(`bridges to chain ${destinationChainId}, not ${e.destChainId}`, \"policy_refused\");\n if (hasDestinationCall) return note(\"the route runs a call on the destination chain, whose recipient cannot be checked here\", \"recipient_unverifiable\");\n if (!e.evmDestination) {\n const why = solanaRecipientMismatch(r, bridge, receiver, e);\n if (why) return why;\n } else if (!same(receiver, e.receiver)) return note(`pays ${receiver}, not ${e.receiver}`, \"recipient_mismatch\");\n if (hasSourceSwaps !== bridge.sourceSwaps) return note(`unknown Diamond call ${selector}`, \"policy_refused\");\n const refund = refundMismatch(r, bridge, e);\n if (refund) return refund;\n const spec = FACET_DATA[bridge.facet];\n const delivery = spec?.delivery?.(r, facetDataAt(r, bridge, spec), e);\n if (delivery) return delivery;\n // After source swaps the bridged amount is in the swapped token's units: only the swaps' input is comparable.\n if (hasSourceSwaps) {\n // The swapped amount is the facet's own (it replaces minAmount after the swaps); a zero is a route that bridges nothing.\n if (minAmount === 0n) return note(\"bridges nothing after the source swaps\", \"policy_refused\");\n return checkSteps(swapsAt(r, 4, 4 + 32), e, sendingAssetId);\n }\n // Without source swaps the Diamond pulls minAmount: the input, or the input less a bridge's own fee (Glacis takes\n // 0.25 %, matrix v7). Anything further below leaves the rest of the allowance behind for the next call to take\n // (scan 2026-10-27 modules, F22): a minAmount of 1 is refused.\n if (minAmount > e.amountIn || minAmount * 10_000n < e.amountIn * (10_000n - BRIDGE_INPUT_FEE_MAX_BPS)) return note(`bridges ${minAmount}, not the ${e.amountIn} spent`, \"policy_refused\");\n return same(sendingAssetId, e.fromToken) ? null : note(`bridges ${sendingAssetId}, not ${e.fromToken}`, \"policy_refused\");\n } catch (err) {\n return note(`the Diamond calldata does not decode (${err instanceof Error ? err.message : String(err)})`, \"policy_refused\");\n }\n}\n","/**\n * A first look at LI.FI's Solana bridge transaction, from its bytes alone (no RPC: accounts loaded from lookup tables\n * stay unknown). It must be paid by the sender. A Mayan route (it calls Mayan's CPI proxy or an order program) must\n * also pay SOL directly to no wallet other than the sender or LI.FI's fee wallet: the account's guard proves its order\n * pays the reviewed recipient (`bridgeOut`). LI.FI's other Solana bridges (Relay, LayerSwap, NEAR Intents, LI.FI\n * Intents, …) deposit to an address, an order id or a program whose recipient lives off chain or in data the device\n * does not read; they pass here as they are and are held by the account to its SOL and token ceilings only.\n */\n\nimport {base64Bytes} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {base58} from \"./solana-address.js\";\nimport {note} from \"./refusals.js\";\n\n/** Mayan's CPI proxy and order programs (swap-sdk `src/addresses.ts`). */\nconst MAYAN_ENTRY_PROGRAMS = new Set([\n \"D8C8iW6zmoKg5TRr8nQ7h14TMWqQX8FiBdj2ju5MF3wa\", // CPI_PROXY_PROGRAM_ID\n \"BLZRi6frs4X4DNLw56V4EXai1b6QVESN1BhHBTYM9VcY\", // SWIFT_PROGRAM_ID\n \"mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny\", // SWIFT_V2_PROGRAM_ID\n \"dkpZqrxHFrhziEMQ931GLtfy11nFkCsfMftH9u6QwBU\", // MCTP_PROGRAM_ID\n \"Gx9rivpS3YR8pBFwMuP6omYqVxunpLvLkNn7ubNyuZZ5\", // FAST_MCTP_PROGRAM_ID\n]);\nconst SYSTEM_PROGRAM = \"11111111111111111111111111111111\";\n/** LI.FI's fee wallet on Solana (its `feeCollection` step pays SOL here, tokens to its token accounts). */\nexport const LIFI_SOLANA_FEE_WALLET = \"34FKjAdVcTax2DHqV2XnbXa9J3zmyKcFuFKWbcmgxjgm\";\n\nclass Cursor {\n at = 0;\n constructor(private readonly b: Uint8Array) {}\n byte(): number {\n if (this.at >= this.b.length) throw new Error(\"truncated\");\n return this.b[this.at++]!;\n }\n bytes(n: number): Uint8Array {\n if (n < 0 || this.at + n > this.b.length) throw new Error(\"truncated\");\n const out = this.b.subarray(this.at, this.at + n);\n this.at += n;\n return out;\n }\n /** compact-u16 */\n short(): number {\n let v = 0;\n for (let shift = 0; shift < 21; shift += 7) {\n const b = this.byte();\n v |= (b & 0x7f) << shift;\n if (!(b & 0x80)) return v;\n }\n throw new Error(\"bad length\");\n }\n}\n\n/** Why the transaction is visibly wrong for `sender` (see the module note), or null when its static part is consistent with a bridge. */\nexport function solanaBridgeTxMismatch(base64: string, sender: string): string | null {\n const bytes = base64Bytes(base64);\n if (!bytes) return note(\"the Solana transaction is not base64\", \"upstream_unavailable\");\n const c = new Cursor(bytes);\n try {\n c.bytes(64 * c.short()); // signatures\n const first = c.byte();\n if ((first & 0x80) === 0) c.at--; // legacy message: no version prefix\n c.bytes(3); // header\n const keys = Array.from({length: c.short()}, () => base58(c.bytes(32)));\n if (keys[0] !== sender) return note(`the Solana transaction is paid by ${keys[0] ?? \"nobody\"}, not the sender ${sender}`, \"policy_refused\");\n c.bytes(32); // recent blockhash\n let mayan = false;\n const payees: string[] = [];\n const n = c.short();\n for (let i = 0; i < n; i++) {\n const program = keys[c.byte()];\n const accounts = Array.from(c.bytes(c.short()));\n const data = c.bytes(c.short());\n if (program !== undefined && MAYAN_ENTRY_PROGRAMS.has(program)) mayan = true;\n // System Transfer: u32 tag 2, u64 lamports; [from, to]. A destination in a lookup table is left to the account.\n if (program === SYSTEM_PROGRAM && data.length === 12 && data[0] === 2 && data[1] === 0 && data[2] === 0 && data[3] === 0) {\n const to = keys[accounts[1] ?? -1];\n if (to !== undefined && to !== sender && to !== LIFI_SOLANA_FEE_WALLET) payees.push(to);\n }\n }\n // A deposit to an address is how the other bridges are paid; a Mayan route moves its funds through its order.\n return mayan && payees.length ? note(`the Solana transaction transfers SOL to ${payees[0]}, which is neither the sender nor LI.FI's fee wallet`, \"recipient_mismatch\") : null;\n } catch (err) {\n return note(`the Solana transaction does not decode (${err instanceof Error ? err.message : String(err)})`, \"policy_refused\");\n }\n}\n","import type {RemotePins} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {LIFI_SOLANA_CAIP2, lifi as lifiCfg} from \"./config.js\";\nimport {describeLifiActivity} from \"./activity.js\";\nimport {diamondCallMismatch} from \"./calldata.js\";\nimport {solanaBridgeTxMismatch} from \"./solana.js\";\nimport {timeoutSignal, sourceAssetOf} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {slippageFloor} from \"@anywalletkit/protocol-swap2-core/validate\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {httpRefusal, parseRetryAfter, refusal, type Swap2RefusalInfo, type Swap2RefusalReason} from \"@anywalletkit/protocol-swap2-core/errors\";\nimport {bigintToNumber} from \"@anywalletkit/core\";\nimport {note, reasonOf} from \"./refusals.js\";\n\n/**\n * LI.FI meta-aggregator — the CALLDATA execution model: the quote returns a\n * `transactionRequest` the USER'S WALLET must execute. There is no deposit\n * address — a plain transfer to `transactionRequest.to` would lose funds, so\n * the client branches on `quote.txRequest`. Live-verified shapes (2026-07):\n * EVM → {to, data, value, chainId, gasLimit}; Solana → {data: base64 tx}, a\n * fully built v0 transaction (Jupiter route) the account signs after proving\n * its balance effects (`serializedTx`). Tron returns a raw protobuf we can't\n * hand to wallets yet — Tron stays on the direct NEAR Intents route (LI.FI\n * routes it through NEAR anyway, so nothing is lost).\n */\n\nconst DEFAULT_LIFI_BASE = \"https://li.quest/v1\";\n\n/** Our CAIP-2 → LI.FI chain ids. */\nconst LIFI_CHAIN: Record<string, string> = {\n \"eip155:1\": \"1\",\n \"eip155:8453\": \"8453\",\n \"eip155:56\": \"56\",\n \"eip155:137\": \"137\",\n \"eip155:42161\": \"42161\",\n \"eip155:10\": \"10\",\n \"eip155:100\": \"100\",\n \"eip155:143\": \"143\",\n \"eip155:130\": \"130\",\n \"eip155:999\": \"999\",\n \"eip155:4663\": \"4663\",\n // 2026-08 sweep additions (all live on li.quest/v1/chains).\n \"eip155:43114\": \"43114\",\n \"eip155:534352\": \"534352\",\n \"eip155:80094\": \"80094\",\n // 2026-10-12: zkSync Era, Celo, MegaETH (live on li.quest/v1/chains).\n \"eip155:324\": \"324\",\n \"eip155:42220\": \"42220\",\n \"eip155:4326\": \"4326\",\n \"eip155:9745\": \"9745\",\n \"eip155:59144\": \"59144\",\n \"eip155:146\": \"146\",\n // 2026-10-13: World Chain, Sei, Ink, Plume, X Layer (live on li.quest/v1/chains).\n \"eip155:480\": \"480\",\n \"eip155:1329\": \"1329\",\n \"eip155:57073\": \"57073\",\n \"eip155:98866\": \"98866\",\n \"eip155:196\": \"196\",\n // 2026-10-14: Arc, Mantle, Katana, Morph, Flare (live on li.quest/v1/chains). On Arc LI.FI's \"native\" is the USDC\n // ERC-20 interface 0x3600…: a 0x0 fromToken is rewritten to it and the Diamond pulls via transferFrom (value 0), so\n // the catalog lists Arc USDC as that token — the engine then runs the ordinary approve + call path.\n \"eip155:5042\": \"5042\",\n \"eip155:5000\": \"5000\",\n \"eip155:747474\": \"747474\",\n \"eip155:2818\": \"2818\",\n \"eip155:14\": \"14\",\n // 2026-11-10: Elysium (Kinetiq; li.quest/v1/chains id 99901, key \"ely\"). LI.FI's bridges there are Relay (refused\n // below: UNBOUND_TOOLS) and LI.FI Intents (refused too: UNPINNED_TOOLS), so it has no cross-chain LI.FI route for now;\n // same-chain swaps go through GenericSwapFacetV3 (KyberSwap, Nordstern).\n \"eip155:99901\": \"99901\",\n [LIFI_SOLANA_CAIP2]: \"1151111081099710\",\n};\nconst CAIP2_BY_LIFI_CHAIN: Record<string, string> = Object.fromEntries(Object.entries(LIFI_CHAIN).map(([caip2, id]) => [id, caip2]));\n\nconst EVM_ZERO = \"0x0000000000000000000000000000000000000000\";\n/** LI.FI's native-SOL token id (the System program address). */\nconst SOLANA_NATIVE = \"11111111111111111111111111111111\";\nconst EVM_PLACEHOLDER = \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\";\n/** Dry-quote sender on Solana: the publicly known BIP-39 \"abandon\" account 0. */\nconst SOLANA_PLACEHOLDER = \"HAgk14JpMQLgt6rVgv7cBQFJWFto5Dqxi472uT3DKpqk\";\nconst isSolana = (chain: string) => chain === LIFI_SOLANA_CAIP2;\nconst BASE58 = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\nconst BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;\n/** Chain-aware address equality: EVM case-insensitive, Solana exact base58. */\n/** Longest execution a same-chain route may claim and still be an atomic swap (DEX routes report 0–30 s). */\nconst SAME_CHAIN_MAX_SECONDS = 90;\n/** Largest fee a bridge may take from the input itself (glacis ≈ 0.25 %, 2026-10). Above it the quote is refused, named. */\nconst MAX_INPUT_FEE_BPS = 300;\n\nfunction sameChainAddress(chain: string, actual: string | undefined, expected: string): boolean {\n if (isSolana(chain)) return !!actual && BASE58.test(actual) && actual === expected;\n return sameAddress(actual, expected);\n}\n/** The engine's native sentinel (`0x0…`) in the chain's own notation. */\nfunction nativeFor(chain: string, token: string): string {\n if (/^0x0+$/.test(token) || token === SOLANA_NATIVE) return isSolana(chain) ? SOLANA_NATIVE : EVM_ZERO;\n return token;\n}\n/** LI.FI's documented Diamond entry point on most supported EVM networks. */\nconst LIFI_DIAMOND = \"0x1231DEB6f5749EF6cE6943a275A1D3E7486F4EaE\";\n/**\n * Chains where the Diamond lives at a different address — from\n * github.com/lifinance/contracts `deployments/<chain>.json` (`LiFiDiamond`).\n * On these chains ONLY that address is the entry point; the canonical one is\n * not deployed there and is therefore not trusted.\n */\nconst LIFI_DIAMONDS: Readonly<Record<string, string>> = {\n \"eip155:4663\": \"0xB477751B76CF82d00a686A1232f5fCD772414Af3\", // Robinhood Chain (deployments/robinhood.json, verified 2026-10-09)\n \"eip155:999\": \"0x0a0758d937d1059c356D4714e57F5df0239bce1A\", // HyperEVM (deployments/hyperevm.json, verified 2026-10-09)\n \"eip155:143\": \"0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37\", // Monad (deployments/monad.json, verified 2026-10-11)\n \"eip155:130\": \"0x864b314D4C5a0399368609581d3E8933a63b9232\", // Unichain (deployments/unichain.json, verified 2026-10-11)\n \"eip155:80094\": \"0xf909c4Ae16622898b885B89d7F839E0244851c66\", // Berachain (deployments/berachain.json, verified 2026-10-11)\n \"eip155:324\": \"0x341e94069f53234fE6DabeF707aD424830525715\", // zkSync Era (deployments/zksync.json, matches a live quote 2026-10-12)\n \"eip155:9745\": \"0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37\", // Plasma (deployments/plasma.json, 2026-10-13)\n \"eip155:59144\": \"0xDE1E598b81620773454588B85D6b5D4eEC32573e\", // Linea (deployments/linea.json, 2026-10-13)\n \"eip155:57073\": \"0x864b314D4C5a0399368609581d3E8933a63b9232\", // Ink (deployments/ink.json, 2026-10-13)\n \"eip155:98866\": \"0x6f5C8Bb0C5Fe4ECeAC40EE1C238EaB6bbb29761c\", // Plume (deployments/plume.json, 2026-10-13)\n // 2026-10-14: li.quest/v1/chains `diamondAddress`, eth_getCode non-empty on each. Mantle and Flare carry the canonical\n // 0x1231… Diamond (the default).\n \"eip155:5042\": \"0xA4072583658Fae592A3506A42431cb6316a8d40b\", // Arc\n \"eip155:747474\": \"0xC59fe32C9549e3E8B5dCcdAbC45BD287Bd5bA2bc\", // Katana\n \"eip155:2818\": \"0xF7aB42D00D2399f8A4Fba2F15466Be40709fe307\", // Morph\n \"eip155:14\": \"0x198FC70Dfe05E755C81e54bd67Bff3F729344B9b\", // Flare (li.quest diamondAddress 2026-10-14; the canonical 0x1231… has no code there)\n // Elysium: li.quest diamondAddress = deployments/elysium.json LiFiDiamond; code on 99901, DiamondLoupe facets() serves\n // GenericSwapFacetV3 + LiFiIntentEscrowFacetV2; the canonical 0x1231… has no code there (all read 2026-11-10).\n \"eip155:99901\": \"0x24E6dA91AA4A8FEe2447F542c92E006243bd6Dc5\", // Elysium\n \"eip155:4326\": \"0x026F252016A7C47CDEf1F05a3Fc9E20C92a49C37\", // MegaETH (deployments/megaeth.json, matches a live quote 2026-10-12)\n};\nconst diamondFor = (chain: string): string => LIFI_DIAMONDS[chain] ?? LIFI_DIAMOND;\nconst DEFAULT_QUOTE_TTL_MS = 55_000;\n\nfunction normalizeAddress(value: string | undefined): string | null {\n return value && /^0x[0-9a-fA-F]{40}$/.test(value) ? value.toLowerCase() : null;\n}\n\nfunction sameAddress(actual: string | undefined, expected: string): boolean {\n return normalizeAddress(actual) === normalizeAddress(expected);\n}\n\nfunction isHexData(value: string | undefined): value is string {\n return !!value && /^0x(?:[0-9a-fA-F]{2})+$/.test(value);\n}\n\nfunction trustedAddress(\n chain: string,\n address: string | undefined,\n configured: ReadonlyMap<string, ReadonlySet<string>>,\n): boolean {\n const normalized = normalizeAddress(address);\n if (!normalized) return false;\n return normalizeAddress(diamondFor(chain)) === normalized || configured.get(chain)?.has(normalized) === true;\n}\n\nfunction trustMap(input: Readonly<Record<string, readonly string[]>> | undefined, label: string): ReadonlyMap<string, ReadonlySet<string>> {\n const out = new Map<string, ReadonlySet<string>>();\n for (const [chain, addresses] of Object.entries(input ?? {})) {\n const normalized = new Set<string>();\n for (const address of addresses) {\n const value = normalizeAddress(address);\n if (!value) throw new Error(`lifi: invalid ${label} address for ${chain}`);\n normalized.add(value);\n }\n out.set(chain, normalized);\n }\n return out;\n}\n\n/** LI.FI token id on the source chain: contract, or the chain's native id. */\nfunction lifiToken(params: Pick<QuoteParams, \"sourceChain\" | \"sourceToken\" | \"sourceDecimals\">): string | null {\n const sourceChain = params.sourceChain;\n const asset = sourceAssetOf(params);\n if (!asset) return null;\n if (asset.contract) return asset.contract;\n return isSolana(sourceChain) ? SOLANA_NATIVE : EVM_ZERO;\n}\n\nfunction headers(key: string | undefined): Record<string, string> {\n const h: Record<string, string> = {accept: \"application/json\"};\n if (key) h[\"x-lifi-api-key\"] = key;\n return h;\n}\n\n/** Explicit constructor configuration; no deployment environment is read. */\nexport interface LifiProviderConfig {\n enabled?: boolean;\n /** LI.FI REST base URL. Explicitly injectable for proxies and tests; must be https unless `allowInsecureApiUrl`. */\n apiUrl?: string;\n /**\n * Allow an `http:` `apiUrl` (local development only): the quotes and the Diamond calldata travel it, and over plain\n * http anyone on the path rewrites them (scan 2026-10-27 modules, F20).\n */\n allowInsecureApiUrl?: boolean;\n apiKey?: string;\n integrator?: string;\n /** Additional audited LI.FI entry points for networks whose Diamond differs. */\n trustedTransactionTargets?: Readonly<Record<string, readonly string[]>>;\n /** Additional audited ERC-20 spenders returned by LI.FI for direct routes. */\n trustedApprovalAddresses?: Readonly<Record<string, readonly string[]>>;\n /** Fail-closed local lifetime for the provider's documented ~60s quote window. */\n quoteTtlMs?: number;\n /**\n * Slippage sent when the caller names none (bps, default 50 = LI.FI's own\n * documented default). Left unset, LI.FI picks it per request and it swings\n * (0.9%–6% within a minute on Base ETH → Robinhood, 2026-10-12): the display\n * quote's minimum then sits above the live one and the execution floor\n * refuses a route that hasn't moved.\n */\n defaultSlippageBps?: number;\n /**\n * Route policy hook. When set, a cross-chain quote first asks LI.FI's\n * `/advanced/routes` for the candidates, hands them to this function and\n * restricts `/quote` to what it returns (allowBridges / denyBridges /\n * order). Returning null/undefined, or any failure of the routes call,\n * leaves LI.FI's default pick. The policy itself (tie band, max ETA, deny\n * list) belongs to the app; the module only carries the choice.\n */\n chooseRoute?: (routes: readonly LifiRouteOption[], params: QuoteParams) => LifiRouteChoice | null | undefined;\n /**\n * Ask LI.FI for one slippage budget for the whole route (`slippageScope=route`) on EVM → EVM requests, instead of\n * its default of applying the slippage to every step. The minimum is then one floor, `ceil(expected × (1 −\n * slippage))`, that the transaction (and on Across, Mayan and Stargate V2 the bridge) enforces. Only EVM routes\n * with at most one swap and no destination call can be protected so; when LI.FI has none for a request it is asked\n * again in its default (per-step) scope, held to the same floor by the module's checks. Default off: Solana legs and\n * a disabled flag keep the per-step behaviour exactly as before.\n */\n routeWideSlippage?: boolean;\n}\n\n/** One single-transaction candidate from `/advanced/routes`, as a route policy sees it. */\nexport interface LifiRouteOption {\n /** LI.FI tool key of the bridge the route crosses with (e.g. \"stargateV2\"); a same-chain route carries its swap tool. */\n tool: string;\n toAmount: bigint;\n toAmountMin: bigint;\n /** LI.FI's execution-duration estimate, seconds. */\n etaSeconds: number;\n gasCostUsd: number;\n /** LI.FI's own labels: RECOMMENDED, CHEAPEST, FASTEST, … */\n tags: readonly string[];\n}\n\n/** What `/quote` is restricted to. LI.FI tool keys; an empty choice means LI.FI's default. */\nexport interface LifiRouteChoice {\n allowBridges?: readonly string[];\n denyBridges?: readonly string[];\n order?: \"CHEAPEST\" | \"FASTEST\";\n}\n\nconst TOOL_KEY = /^[A-Za-z0-9_-]{1,64}$/;\n/**\n * LI.FI tools whose Diamond entry point does not tie the delivery to the checked receiver (see `UNBOUND_BRIDGES` in\n * calldata.ts): every cross-chain request from an EVM chain asks LI.FI to route around them, so the pairs they would\n * have served get another bridge instead of a refusal. A Solana source has no Diamond call to check and is quoted\n * through every bridge LI.FI offers (Relay included); the account checks a Mayan order's recipient on the device, the\n * other Solana bridges only against its SOL and token ceilings.\n */\nconst UNBOUND_TOOLS: readonly string[] = Object.freeze([\"relaydepository\", \"garden\", \"squid\", \"symbiosis\"]);\n/**\n * LI.FI Intents (`lifiIntents`): the escrowed order names its own input oracle, output oracle, output settler and output\n * amount multiplier, none of which is pinned here, so its Diamond call is refused on every route (calldata.ts,\n * `INTENTS_UNPINNED` / `INTENTS_TO_SOLANA`) and every cross-chain request from an EVM chain asks LI.FI to route around it,\n * like the unbound tools. A Solana source is unchanged (no Diamond call; see UNBOUND_TOOLS).\n */\nconst UNPINNED_TOOLS: readonly string[] = Object.freeze([\"lifiIntents\"]);\n/** The LI.FI tools every cross-chain request from an EVM chain is asked to avoid, and a route policy cannot pick. */\nconst REFUSED_EVM_TOOLS: readonly string[] = Object.freeze([...UNBOUND_TOOLS, ...UNPINNED_TOOLS]);\n/**\n * EVM → Solana: the LI.FI tools whose Diamond call binds the delivery to the Solana recipient the device reads\n * (calldata.ts, `solanaRecipientMismatch`): Mayan's Swift, MCTP and Fast MCTP routes, Polymer CCTP (fast and standard)\n * and Chainflip. Such requests ask LI.FI for these bridges only, so a pair is not lost to a bridge the module refuses\n * for this direction (NEAR Intents, LayerSwap and Smart Deposits pay a deposit address; LI.FI Intents names its own\n * oracles and output settler, which are not pinned here).\n */\nconst SOLANA_DESTINATION_TOOLS: readonly string[] = Object.freeze([\"mayan\", \"mayanMCTP\", \"mayanFastMCTP\", \"polymer\", \"polymerStandard\", \"chainflip\"]);\n/** LI.FI's Smart Deposits pay a deposit address; nothing in the transaction binds where it delivers. */\nconst SMART_DEPOSITS_TOOL = /^smartdeposits?$/i;\n/** A dry EVM → Solana quote without a recipient prices the publicly known BIP-39 \"abandon\" account 0 on Solana (never built: {@link placeholderIn}). */\nconst dryRecipient = (params: Pick<QuoteParams, \"sourceChain\" | \"destChain\">, fromAddress: string): string =>\n !isSolana(params.sourceChain) && isSolana(params.destChain) ? SOLANA_PLACEHOLDER : fromAddress;\n/**\n * Which address of a dry request the module fills with its placeholder: the sender when there is no `refundAddress`\n * (vitalik.eth, or the Solana \"abandon\" account from Solana), the recipient of an EVM → Solana request without a\n * `destAddress` (the \"abandon\" account) — or null when the quote is for the request's own addresses (a dry EVM → EVM or\n * Solana-source quote without a recipient prices the sender's own address). The placeholders are public accounts, and\n * the Solana one's key anyone can derive and sweep: a transaction LI.FI builds for them pays or refunds them from\n * whichever wallet signs it. Such a quote therefore prices the route and carries no transaction; `buildDeposit`\n * refuses it and {@link lifiVerifyQuote} refuses one that carries a transaction anyway.\n */\nfunction placeholderIn(params: Pick<QuoteParams, \"sourceChain\" | \"destChain\" | \"refundAddress\" | \"destAddress\">): \"sender\" | \"recipient\" | null {\n if (!params.refundAddress) return \"sender\";\n return !params.destAddress && dryRecipient(params, params.refundAddress) !== params.refundAddress ? \"recipient\" : null;\n}\nfunction routeOptions(body: unknown, excluded: readonly string[], allowed?: readonly string[]): LifiRouteOption[] {\n const routes = (body as {routes?: unknown})?.routes;\n if (!Array.isArray(routes)) return [];\n const out: LifiRouteOption[] = [];\n for (const r of routes as {toAmount?: unknown; toAmountMin?: unknown; gasCostUSD?: unknown; containsSwitchChain?: unknown; tags?: unknown; steps?: {tool?: unknown; estimate?: {executionDuration?: unknown}; includedSteps?: {tool?: unknown; type?: unknown}[]}[]}[]) {\n // The engine executes one source transaction: multi-step routes are not candidates.\n if (!Array.isArray(r?.steps) || r.steps.length !== 1 || r.containsSwitchChain === true) continue;\n const step = r.steps[0]!;\n const cross = Array.isArray(step.includedSteps) ? step.includedSteps.find((i) => i?.type === \"cross\")?.tool : undefined;\n const tool = typeof cross === \"string\" ? cross : step.tool;\n const eta = step.estimate?.executionDuration;\n if (typeof tool !== \"string\" || !TOOL_KEY.test(tool) || excluded.includes(tool) || (allowed && !allowed.includes(tool)) || typeof eta !== \"number\" || !Number.isFinite(eta) || eta < 0) continue;\n if (typeof r.toAmount !== \"string\" || typeof r.toAmountMin !== \"string\" || !/^\\d{1,60}$/.test(r.toAmount) || !/^\\d{1,60}$/.test(r.toAmountMin)) continue;\n out.push({\n tool,\n toAmount: BigInt(r.toAmount),\n toAmountMin: BigInt(r.toAmountMin),\n etaSeconds: eta,\n gasCostUsd: Number(r.gasCostUSD ?? 0) || 0,\n tags: Array.isArray(r.tags) ? r.tags.filter((t): t is string => typeof t === \"string\") : [],\n });\n }\n return out;\n}\n\n/** LI.FI's tool error codes (docs.li.fi/api-reference/error-codes, \"Tool errors\") that name one reason. */\nconst LIFI_TOOL_REASONS: Readonly<Record<string, Swap2RefusalReason>> = {\n NO_POSSIBLE_ROUTE: \"no_route\",\n INSUFFICIENT_LIQUIDITY: \"insufficient_liquidity\",\n TOOL_TIMEOUT: \"upstream_unavailable\",\n RPC_ERROR: \"upstream_unavailable\",\n AMOUNT_TOO_LOW: \"amount_too_small\",\n AMOUNT_TOO_HIGH: \"amount_too_large\",\n FEES_HIGHER_THAN_AMOUNT: \"amount_too_small\",\n FEES_HGHER_THAN_AMOUNT: \"amount_too_small\", // an older spelling of the same code\n DIFFERENT_RECIPIENT_NOT_SUPPORTED: \"unsupported_pair\",\n CANNOT_GUARANTEE_MIN_AMOUNT: \"price_check_failed\",\n};\n/** LI.FI's API error codes (the same page) that name one reason. */\nconst LIFI_ERROR_REASONS: Readonly<Record<number, Swap2RefusalReason>> = {\n 1001: \"no_route\", // FailedToBuildTransactionError: \"None of the available routes could successfully generate a tx\"\n 1002: \"no_route\", // NoQuoteError: \"No available quotes for the requested transfer\"\n 1003: \"no_route\", // NotFoundError\n 1005: \"rate_limited\", // RateLimitError\n 1006: \"upstream_unavailable\", // ServerError\n 1007: \"price_check_failed\", // SlippageError\n 1008: \"upstream_unavailable\", // ThirdPartyError\n 1009: \"upstream_unavailable\", // TimeoutError\n 1010: \"key_rejected\", // UnauthorizedError\n 1012: \"upstream_unavailable\", // RpcFailure\n};\n/** LI.FI's messages, read when no code says more. */\nconst LIFI_MESSAGE_REASONS: readonly (readonly [RegExp, Swap2RefusalReason])[] = [\n [/no available quotes|unable to find a quote|none of the available routes|no route/i, \"no_route\"],\n [/rate limit|too many requests/i, \"rate_limited\"],\n [/api[ -]?key|unauthori[sz]ed/i, \"key_rejected\"],\n [/insufficient liquidity|not enough liquidity/i, \"insufficient_liquidity\"],\n [/amount (?:is )?too (?:low|small)|below the minimum/i, \"amount_too_small\"],\n [/amount (?:is )?too (?:high|large)|above the maximum/i, \"amount_too_large\"],\n [/not supported|unsupported|unknown token|invalid token/i, \"unsupported_pair\"],\n [/halted|paused|maintenance/i, \"chain_halted\"],\n];\n\n/** The tool error codes in a LI.FI error body (`errors`, its `failed[].subpaths` or a plain list), bounded. */\nfunction lifiToolCodes(errors: unknown): string[] {\n const out = new Set<string>();\n const stack: unknown[] = [errors];\n for (let visited = 0; stack.length > 0 && visited < 256; visited++) {\n const node = stack.pop();\n if (Array.isArray(node)) {\n stack.push(...node.slice(0, 64));\n continue;\n }\n if (!node || typeof node !== \"object\") continue;\n const code = (node as {code?: unknown}).code;\n if (typeof code === \"string\" && Object.prototype.hasOwnProperty.call(LIFI_TOOL_REASONS, code)) out.add(code);\n for (const [key, value] of Object.entries(node).slice(0, 64)) if (key !== \"action\" && value && typeof value === \"object\") stack.push(value);\n }\n return [...out];\n}\n\n/** What LI.FI's body says, in order: the tool codes when they agree, the route-floor filter, the API code, the message. */\nfunction lifiBodyReason(body: unknown, filteredOut: readonly string[]): Swap2RefusalReason | undefined {\n const b = body && typeof body === \"object\" ? (body as {message?: unknown; code?: unknown; errors?: unknown}) : {};\n const tools = [...new Set(lifiToolCodes(b.errors).map((code) => LIFI_TOOL_REASONS[code]!))];\n if (tools.length === 1) return tools[0]!;\n if (filteredOut.length > 0 && filteredOut.every((r) => /^ROUTE_SLIPPAGE_FLOOR_UNREACHABLE/.test(r))) return \"price_check_failed\";\n const byCode = typeof b.code === \"number\" ? LIFI_ERROR_REASONS[b.code] : undefined;\n if (byCode) return byCode;\n const message = typeof b.message === \"string\" ? b.message : \"\";\n return LIFI_MESSAGE_REASONS.find(([pattern]) => pattern.test(message))?.[1];\n}\n\n/** What the body may still name on a 408 / 425 / 5xx: a passing condition, never a verdict on the pair or the route. */\nconst LIFI_TRANSIENT_REASONS: ReadonlySet<Swap2RefusalReason> = new Set([\"rate_limited\", \"insufficient_liquidity\", \"chain_halted\"]);\n\n/**\n * Why LI.FI answered a quote with an error status: 429 (with Retry-After) and 401 / 403 by their status; 408 / 425 /\n * 5xx as `upstream_unavailable` unless the body names a passing condition (throttling, liquidity, a halt), since a\n * failing LI.FI says nothing about the pair or the route; any other status by what its body says (the tool codes\n * when they agree, the API code, the message), else LI.FI declining to route the request (`no_route`).\n */\nfunction lifiHttpRefusal(status: number, retryAfter: string | null | undefined, body: unknown, filteredOut: readonly string[]): Swap2RefusalInfo {\n const http = httpRefusal(status, retryAfter);\n if (http && http.reason !== \"upstream_unavailable\") return http;\n const info = (reason: Swap2RefusalReason): Swap2RefusalInfo => {\n if (reason === \"rate_limited\") {\n const wait = parseRetryAfter(retryAfter);\n return {reason, httpStatus: status, ...(wait !== undefined ? {retryAfterMs: wait} : {})};\n }\n return reason === \"upstream_unavailable\" || reason === \"key_rejected\" ? {reason, httpStatus: status} : {reason};\n };\n const byBody = lifiBodyReason(body, filteredOut);\n if (http) return byBody !== undefined && LIFI_TRANSIENT_REASONS.has(byBody) ? info(byBody) : http;\n return byBody !== undefined ? info(byBody) : {reason: \"no_route\"};\n}\n\nfunction cleanChoice(choice: LifiRouteChoice | null | undefined): LifiRouteChoice | null {\n if (!choice) return null;\n const allow = (choice.allowBridges ?? []).filter((t) => TOOL_KEY.test(t));\n const deny = (choice.denyBridges ?? []).filter((t) => TOOL_KEY.test(t));\n const order = choice.order === \"CHEAPEST\" || choice.order === \"FASTEST\" ? choice.order : undefined;\n if (!allow.length && !deny.length && !order) return null;\n return {...(allow.length ? {allowBridges: allow} : {}), ...(deny.length ? {denyBridges: deny} : {}), ...(order ? {order} : {})};\n}\n\nexport function lifiProvider(config: LifiProviderConfig = {}): CrossChainProvider {\n config = Object.freeze({...config});\n const apiKey = () => config.apiKey;\n const integrator = () => config.integrator ?? \"\";\n const parsedApiUrl = new URL(config.apiUrl ?? DEFAULT_LIFI_BASE);\n if (parsedApiUrl.protocol !== \"https:\" && !(parsedApiUrl.protocol === \"http:\" && config.allowInsecureApiUrl === true)) {\n throw new Error(\"lifi: apiUrl must use https (allowInsecureApiUrl for local development)\");\n }\n const apiBase = parsedApiUrl.toString().replace(/\\/$/, \"\");\n const trustedTransactionTargets = trustMap(config.trustedTransactionTargets, \"transaction target\");\n const trustedApprovalAddresses = trustMap(config.trustedApprovalAddresses, \"approval\");\n const quoteTtlMs = config.quoteTtlMs ?? DEFAULT_QUOTE_TTL_MS;\n const defaultSlippageBps = config.defaultSlippageBps ?? 50;\n if (!Number.isInteger(defaultSlippageBps) || defaultSlippageBps <= 0 || defaultSlippageBps >= 10_000) {\n throw new Error(\"lifi: defaultSlippageBps must be an integer between 1 and 9999\");\n }\n if (!Number.isInteger(quoteTtlMs) || quoteTtlMs <= 0 || quoteTtlMs > 60_000) {\n throw new Error(\"lifi: quoteTtlMs must be an integer between 1 and 60000\");\n }\n return {\n name: \"lifi\",\n describeActivity: (tx, ctx) => describeLifiActivity(tx, ctx, (chain, address) => trustedAddress(chain, address, trustedTransactionTargets)),\n supportsSameChain: true,\n enabled: () => config.enabled ?? true,\n\n // Capability discovery comes from the provider itself, so it can run alone\n // or inside the optional aggregator without a central capability table.\n supportsChain: (chain: string) => lifiCfg.supportsChain(chain),\n supportsChainPair: (fromChain: string, toChain: string) => lifiCfg.supports(fromChain, toChain),\n supportsRoute(from: Asset, to: Asset): boolean {\n // EVM only: LI.FI's Solana/Tron legs come back as provider-serialized\n // transactions, which the swap2 engine does not execute yet.\n return !!LIFI_CHAIN[from.chain] && !!LIFI_CHAIN[to.chain];\n },\n\n async getQuote(params: QuoteParams, signal?: AbortSignal): Promise<Quote | null> {\n /** Every refusal after LI.FI answered is named — a bare null hides which check failed (matrix v7: 4 silent nulls). */\n const reject = (why: string, reason?: Swap2RefusalReason | Swap2RefusalInfo): null => {\n const info = typeof reason === \"string\" ? {reason} : reason;\n if (info) params.onRefusal?.(`lifi: ${why}`, info);\n else params.onRefusal?.(`lifi: ${why}`);\n return null;\n };\n if (params.flex) return null; // calldata model — the amount is baked in\n const fromChain = LIFI_CHAIN[params.sourceChain];\n const toChain = LIFI_CHAIN[params.destChain];\n if (!fromChain || !toChain) return null;\n const fromToken = lifiToken(params);\n if (!fromToken) return null;\n\n const solanaSource = isSolana(params.sourceChain);\n const crossChain = params.sourceChain !== params.destChain;\n // EVM → Solana: only the bridges whose Solana recipient the calldata check reads (SOLANA_DESTINATION_TOOLS).\n const evmToSolana = !solanaSource && isSolana(params.destChain);\n // The Diamond check refuses a destination call (its recipient sits in calldata for the other chain), so LI.FI is\n // asked not to offer one; the check stays as the backstop. A Solana source has no Diamond call to check.\n const noDestinationCall = crossChain && !solanaSource;\n // Route-wide slippage covers EVM routes only (LI.FI: not a route that starts or ends on a non-EVM chain).\n let routeScope = config.routeWideSlippage === true && !solanaSource && !isSolana(params.destChain);\n // The placeholders price a dry quote; a live one is built for real addresses only (round 3, H8). A quote priced for\n // a placeholder carries no transaction (placeholderIn).\n const dry = params.dry !== false;\n const fromAddress = params.refundAddress || (dry ? (solanaSource ? SOLANA_PLACEHOLDER : EVM_PLACEHOLDER) : \"\");\n const toAddress = params.destAddress || (dry ? dryRecipient(params, fromAddress) : \"\");\n if (!fromAddress) return reject(\"a live quote needs the sender's address\");\n if (!toAddress) return reject(\"a live quote needs a recipient\");\n const placeholder = dry ? placeholderIn(params) : null;\n\n // LI.FI applies `slippage` to EACH step of a multi-step route (bridge +\n // destination swap), so its minimum can sit ~2× the requested slippage\n // under the quote (seen 2026-10-10 on 479 of 4 000 matrix quotes), and\n // it truncates toAmountMin to a few significant digits. The engine\n // rejects a floor below the requested one, so the quote is asked once\n // more with the slippage scaled down to land the floor inside it.\n const slippageBps = params.slippageBps ?? defaultSlippageBps;\n let sentSlippage: number | undefined = slippageBps / 10_000;\n let deadline: AbortSignal | undefined;\n let choice: LifiRouteChoice | null = null;\n if (config.chooseRoute && crossChain) {\n try {\n const res = await fetch(`${apiBase}/advanced/routes`, {\n method: \"POST\",\n headers: {...headers(apiKey()), \"content-type\": \"application/json\"},\n body: JSON.stringify({\n fromChainId: Number(fromChain),\n toChainId: Number(toChain),\n fromTokenAddress: fromToken,\n toTokenAddress: nativeFor(params.destChain, params.destToken),\n fromAmount: params.amountIn,\n fromAddress,\n toAddress,\n options: {\n slippage: slippageBps / 10_000,\n ...(routeScope ? {slippageScope: \"route\"} : {}),\n ...(solanaSource ? {} : {bridges: {...(evmToSolana ? {allow: SOLANA_DESTINATION_TOOLS} : {}), deny: REFUSED_EVM_TOOLS}}),\n ...(noDestinationCall ? {allowDestinationCall: false} : {}),\n ...(integrator().trim() ? {integrator: integrator().trim()} : {}),\n },\n }),\n signal: signal ?? timeoutSignal(8_000),\n });\n if (res.ok) {\n const options = routeOptions(await res.json(), solanaSource ? [] : REFUSED_EVM_TOOLS, evmToSolana ? SOLANA_DESTINATION_TOOLS : undefined);\n if (options.length) choice = cleanChoice(config.chooseRoute(options, params));\n }\n } catch {\n // The policy is an optimisation: no candidates means LI.FI's default pick.\n }\n }\n for (let attempt = 0; attempt < 2; attempt++) try {\n const url = new URL(`${apiBase}/quote`);\n url.searchParams.set(\"fromChain\", fromChain);\n url.searchParams.set(\"toChain\", toChain);\n url.searchParams.set(\"fromToken\", fromToken);\n // Native dest is chain-notation-specific: EVM zero address vs the\n // Solana system program — sending the EVM zero to an SVM dest 400s.\n url.searchParams.set(\"toToken\", nativeFor(params.destChain, params.destToken));\n url.searchParams.set(\"fromAmount\", params.amountIn);\n url.searchParams.set(\"fromAddress\", fromAddress);\n url.searchParams.set(\"toAddress\", toAddress);\n const integratorId = integrator().trim();\n if (integratorId) url.searchParams.set(\"integrator\", integratorId);\n if (sentSlippage !== undefined) {\n url.searchParams.set(\"slippage\", String(sentSlippage));\n }\n if (routeScope) url.searchParams.set(\"slippageScope\", \"route\");\n if (noDestinationCall) url.searchParams.set(\"allowDestinationCall\", \"false\");\n const unbound = crossChain && !solanaSource ? REFUSED_EVM_TOOLS : [];\n const allow = (choice?.allowBridges ?? []).filter((b) => solanaSource || !REFUSED_EVM_TOOLS.includes(b));\n // EVM → Solana: the policy's pick among the readable bridges, or all of them.\n const solanaAllow = evmToSolana ? allow.filter((b) => SOLANA_DESTINATION_TOOLS.includes(b)) : [];\n for (const t of evmToSolana ? (solanaAllow.length ? solanaAllow : SOLANA_DESTINATION_TOOLS) : allow) url.searchParams.append(\"allowBridges\", t);\n for (const t of new Set([...(choice?.denyBridges ?? []), ...unbound])) url.searchParams.append(\"denyBridges\", t);\n if (choice?.order) url.searchParams.set(\"order\", choice.order);\n deadline = signal ? undefined : timeoutSignal(12_000);\n const res = await fetch(url, {headers: headers(apiKey()), signal: signal ?? deadline!});\n if (!res.ok && choice) {\n // The chosen bridge went away between the two calls: LI.FI's default pick instead.\n choice = null;\n attempt--;\n continue;\n }\n if (!res.ok) {\n // LI.FI's 404 \"No available quotes for the requested transfer\" and\n // 400 validation messages are the caller's answer, not a silent null.\n const body = (await res.json().catch(() => null)) as {message?: unknown; errors?: {filteredOut?: {reason?: unknown}[]}} | null;\n // When every candidate route was dropped for the same reason (Sei: \"wallet is not linked to\n // the original SEI address\"), that reason is the real answer — the message alone is generic.\n const reasons = [...new Set((body?.errors?.filteredOut ?? []).map((f) => f.reason).filter((r): r is string => typeof r === \"string\"))];\n if (routeScope && [typeof body?.message === \"string\" ? body.message : \"\", ...reasons].some((r) => /^ROUTE_SLIPPAGE_(UNSUPPORTED|UNAVAILABLE)/.test(r))) {\n // No route LI.FI can protect route-wide (or the feature is off): its default per-step scope instead,\n // whose minimum the floor check below still holds to the requested slippage. Both reasons are LI.FI's\n // documented stable prefixes (docs.li.fi/api-reference/error-codes, \"Route-wide slippage errors\";\n // docs.li.fi/guides/route-wide-slippage#errors): ROUTE_SLIPPAGE_UNSUPPORTED in errors.filteredOut when no\n // route can be protected, ROUTE_SLIPPAGE_UNAVAILABLE (422, code 1004) in `message` when route-wide\n // slippage is switched off. This happens before any quote is shown: the user reviews the step-scope one.\n routeScope = false;\n attempt--;\n continue;\n }\n const why = reasons.length === 1 ? ` (${reasons[0]!.slice(0, 200)})` : \"\";\n params.onRefusal?.(\n `lifi: ${typeof body?.message === \"string\" ? body.message.slice(0, 200) : `HTTP ${res.status}`}${why}`,\n lifiHttpRefusal(res.status, res.headers?.get?.(\"retry-after\"), body, reasons),\n );\n return null;\n }\n const q = (await res.json()) as {\n type?: string;\n id?: string;\n action?: {\n fromToken?: {address?: string; chainId?: number};\n toToken?: {address?: string; chainId?: number; decimals?: number};\n fromAmount?: string;\n fromChainId?: number;\n toChainId?: number;\n slippage?: number;\n fromAddress?: string;\n toAddress?: string;\n };\n estimate?: {\n fromAmount?: string;\n toAmount?: string;\n toAmountMin?: string;\n executionDuration?: number;\n approvalAddress?: string;\n feeCosts?: {amountUSD?: string}[];\n gasCosts?: {amountUSD?: string}[];\n };\n transactionRequest?: {\n to?: string;\n data?: string;\n value?: string;\n chainId?: number;\n gasLimit?: string;\n from?: string;\n };\n };\n const receivedAt = Date.now();\n if (evmToSolana) {\n const steps = (q as {includedSteps?: unknown}).includedSteps;\n const tools = [(q as {tool?: unknown}).tool, ...(Array.isArray(steps) ? steps.map((i: {tool?: unknown} | null) => i?.tool) : [])];\n if (tools.some((t) => typeof t === \"string\" && SMART_DEPOSITS_TOOL.test(t))) {\n return reject(\"LI.FI Smart Deposits pay a deposit address whose recipient the transaction does not bind — refused for a Solana destination\", \"recipient_unverifiable\");\n }\n }\n const action = q.action;\n const est = q.estimate;\n const tr = q.transactionRequest;\n const expectedToToken = nativeFor(params.destChain, params.destToken);\n const expectedFromChain = Number(fromChain);\n const expectedToChain = Number(toChain);\n if (q.type !== \"lifi\" || !q.id || !action || !est?.toAmount || !est.fromAmount || !tr) return reject(\"incomplete quote (no action, estimate or transaction)\", \"upstream_unavailable\");\n const mismatch = [\n action.fromChainId !== expectedFromChain && \"source chain\",\n action.toChainId !== expectedToChain && \"destination chain\",\n (action.fromToken?.chainId !== expectedFromChain || !sameChainAddress(params.sourceChain, action.fromToken?.address, fromToken)) && \"source token\",\n (action.toToken?.chainId !== expectedToChain || !sameChainAddress(params.destChain, action.toToken?.address, expectedToToken)) && \"destination token\",\n action.fromAmount !== params.amountIn && \"amount spent\",\n !sameChainAddress(params.sourceChain, action.fromAddress, fromAddress) && \"sender\",\n !sameChainAddress(params.destChain, action.toAddress, toAddress) && \"recipient\",\n ].filter(Boolean);\n if (mismatch.length) {\n return reject(\n `quote does not match the request (${mismatch.join(\", \")})`,\n // LI.FI refunds to the sender it was asked for (fromAddress): either address differing pays or refunds someone else.\n mismatch.includes(\"recipient\") || mismatch.includes(\"sender\") ? \"recipient_mismatch\" : \"policy_refused\",\n );\n }\n // The transaction spends exactly the input (action.fromAmount, checked above). Some bridges\n // (glacis, 2026-10) take their fee from the input, so estimate.fromAmount — what is bridged —\n // is a little lower and toAmount already reflects it. Accept a bounded input-side fee instead\n // of a silent null; never an estimate that bridges MORE than is spent.\n const bridged = BigInt(est.fromAmount);\n const spent = BigInt(params.amountIn);\n if (bridged > spent) return reject(`the estimate bridges ${est.fromAmount}, more than the ${params.amountIn} spent`, \"price_check_failed\");\n if ((spent - bridged) * 10_000n > spent * BigInt(MAX_INPUT_FEE_BPS)) {\n return reject(`the route takes ${bigintToNumber(((spent - bridged) * 10_000n) / spent) / 100}% of the input as a fee (over ${MAX_INPUT_FEE_BPS / 100}%)`, \"policy_refused\");\n }\n // Source-VM execution payload. EVM: calldata to a trusted target.\n // Solana: a base64 transaction the account proves before signing —\n // there is no target to trust here, the balance proof replaces it.\n if (solanaSource) {\n if (!tr.data || tr.data.length < 64 || tr.data.length % 4 !== 0 || !BASE64.test(tr.data)) return reject(\"the Solana transaction is not base64\", \"upstream_unavailable\");\n if (tr.to !== undefined || tr.value !== undefined || tr.gasLimit !== undefined) return reject(\"the Solana transaction carries EVM fields\", \"upstream_unavailable\");\n if (fromChain !== toChain) {\n const why = solanaBridgeTxMismatch(tr.data, fromAddress);\n if (why) return reject(why, reasonOf(why));\n }\n // `estimate.approvalAddress` is ignored for a Solana source: LI.FI\n // returns its EVM diamond here on Mayan routes too (seen 2026-10-09,\n // SOL → Base USDC via mayanFastMCTP), and Solana has no allowances —\n // the account's post-state balance proof is the guard, not an\n // approval target. It is never propagated.\n } else if (\n !isHexData(tr.data) || !normalizeAddress(tr.to) || !normalizeAddress(tr.from) ||\n tr.chainId !== expectedFromChain || !tr.value || !tr.gasLimit ||\n !trustedAddress(params.sourceChain, tr.to, trustedTransactionTargets) ||\n !sameAddress(tr.from, fromAddress)\n ) {\n return reject(\n \"the transaction is malformed or targets an untrusted contract\",\n !isHexData(tr.data) || !normalizeAddress(tr.to) || !normalizeAddress(tr.from) || !tr.value || !tr.gasLimit\n ? \"upstream_unavailable\"\n : !trustedAddress(params.sourceChain, tr.to, trustedTransactionTargets) ? \"vault_mismatch\" : \"policy_refused\",\n );\n }\n if (\n sentSlippage !== undefined &&\n (typeof action.slippage !== \"number\" || Math.abs(action.slippage - sentSlippage) > 1e-12)\n ) return reject(\"the quote ignored the requested slippage\", \"price_check_failed\");\n\n const sourceIsToken = fromToken !== EVM_ZERO && fromToken !== SOLANA_NATIVE;\n if (solanaSource) {\n // No allowances on Solana; nothing to trust beyond the balance proof.\n } else if (sourceIsToken) {\n if (!trustedAddress(params.sourceChain, est.approvalAddress, trustedApprovalAddresses)) return reject(\"the approval target is not a trusted LI.FI contract\", \"vault_mismatch\");\n } else if (est.approvalAddress !== undefined) {\n // LI.FI started returning an approvalAddress for NATIVE sources too\n // (seen 2026-09 on every ETH-source quote, e.g. ETH → Robinhood via\n // relay: approvalAddress = the diamond the tx already calls). An\n // approval is meaningless for the native asset, so it is not a\n // reason to refuse the quote — but it must still be a trusted\n // target, and it is never propagated for a native source.\n if (!trustedAddress(params.sourceChain, est.approvalAddress, trustedApprovalAddresses)) return reject(\"the approval target is not a trusted LI.FI contract\", \"vault_mismatch\");\n }\n\n let txRequest: NonNullable<Quote[\"txRequest\"]>;\n // The bridge's native fee on top of the input (EVM source); a price-only quote declares it in providerData.\n let nativeFee = 0n;\n if (solanaSource) {\n // `value` declares what the account may let the tx take in native\n // coin: the input for a SOL source, nothing for a token source.\n txRequest = {serializedTx: tr.data!, value: sourceIsToken ? \"0\" : params.amountIn};\n } else {\n try {\n if (BigInt(tr.value!) < 0n || BigInt(tr.gasLimit!) <= 0n) return reject(\"the transaction has a negative value or no gas limit\", \"upstream_unavailable\");\n } catch {\n return reject(\"the transaction value or gas limit is not a number\", \"upstream_unavailable\");\n }\n // Some bridges charge a native messaging fee inside `value`: for a\n // token source the whole value is that fee; for a native source it\n // is whatever exceeds the input (seen 2026-10-10: DAI Optimism →\n // Base, POL Polygon → Optimism). Declared here, sealed with the\n // quote, bounded by the engine — never silently attached.\n const value = BigInt(tr.value!);\n nativeFee = sourceIsToken ? value : value > BigInt(params.amountIn) ? value - BigInt(params.amountIn) : 0n;\n if (!sourceIsToken && value < BigInt(params.amountIn)) return reject(\"the transaction sends less native coin than the input\", \"policy_refused\");\n txRequest = {\n to: tr.to!,\n data: tr.data!,\n value: value.toString(),\n chainId: tr.chainId!,\n gasLimit: BigInt(tr.gasLimit!).toString(),\n ...(sourceIsToken && est.approvalAddress ? {approvalAddress: est.approvalAddress} : {}),\n ...(nativeFee > 0n ? {nativeFee: nativeFee.toString()} : {}),\n };\n }\n\n // Route fees only (bridge / protocol / integrator). The source\n // transaction's gas is the network fee the wallet shows on its own line —\n // counting it here too made LI.FI look dearer than on-chain venues whose\n // fee excludes gas (2026-10-13).\n const feeUsd = (est.feeCosts ?? []).reduce((a, f) => a + Number(f.amountUSD ?? 0), 0);\n\n // The optimistic output is not a safety floor. A quote without the\n // provider's minimum cannot satisfy an exact-input execution contract.\n if (!est.toAmountMin) return reject(\"the quote has no minimum output\", \"upstream_unavailable\");\n const minDestAmount = est.toAmountMin;\n if (sentSlippage !== undefined) {\n const dest = BigInt(est.toAmount);\n const min = BigInt(minDestAmount);\n if (dest > 0n && min < slippageFloor(dest, slippageBps)) {\n const effective = bigintToNumber(((dest - min) * 1_000_000n) / dest) / 1_000_000;\n const requested = slippageBps / 10_000;\n const scaled: number = Math.floor(((sentSlippage * requested) / effective) * 0.995 * 1_000_000) / 1_000_000;\n if (attempt === 0 && effective > 0 && scaled > 0) {\n sentSlippage = scaled;\n continue;\n }\n params.onRefusal?.(\n `lifi: this route's minimum is ${(effective * 100).toFixed(2)}% under the quote (LI.FI applies slippage on every step) — more than the requested ${slippageBps / 100}%`,\n {reason: \"price_check_failed\"},\n );\n return null;\n }\n }\n if (params.minAmountOut !== undefined && BigInt(minDestAmount) < BigInt(params.minAmountOut)) {\n params.onRefusal?.(`lifi: floor breach (min=${minDestAmount} < floor=${params.minAmountOut})`, {reason: \"price_check_failed\"});\n return null;\n }\n // A same-chain swap must deliver in the same transaction. LI.FI sometimes routes a\n // same-chain pair through a solver (Relay-style intents, 2026-10: USDC → ARB on\n // Ethereum, 625 s): the tx only takes the input and the output arrives later from the\n // solver, so the engine's \"output ≥ quoted minimum\" preflight would refuse it anyway.\n // Name it here, before anything is built.\n const duration = est.executionDuration ?? 0;\n if (fromChain === toChain && duration > SAME_CHAIN_MAX_SECONDS) {\n params.onRefusal?.(\n `lifi: same-chain route settles asynchronously (${duration} s via ${(q as {tool?: string}).tool ?? \"unknown tool\"}) — a same-chain swap must deliver in the same transaction`,\n {reason: \"unsupported_pair\"},\n );\n return null;\n }\n // The calldata is what gets signed: it must pay the reviewed recipient at least the reviewed\n // minimum, in the requested tokens (round 3, H9), and refund only the sender or the recipient.\n if (!solanaSource) {\n const why = diamondCallMismatch(tr.data!, {\n fromToken, toToken: expectedToToken, amountIn: BigInt(params.amountIn), receiver: toAddress, sender: fromAddress, minOut: BigInt(minDestAmount),\n destChainId: BigInt(toChain), sameChain: fromChain === toChain, evmDestination: !isSolana(params.destChain),\n });\n if (why) return reject(`the transaction does not match the quote: ${why}`, reasonOf(why) ?? \"policy_refused\");\n }\n return {\n provider: \"lifi\",\n // Status is tracked by SOURCE TX HASH + the chain pair.\n intentId: `lifi:${fromChain}:${toChain}`,\n depositAddress: \"\",\n depositMemo: null,\n // Every check above ran on LI.FI's transaction; one built for a placeholder is not handed out (placeholderIn).\n // Its bridge fee on top of the input still is, as `providerData.nativeFee`, so the router's value nets it out\n // (usdValue reads it when there is no txRequest) instead of ranking the route on its gross output.\n ...(placeholder ? {providerData: {placeholder, ...(nativeFee > 0n ? {nativeFee: nativeFee.toString()} : {})}} : {txRequest}),\n // What the wallet spends (action.fromAmount, = the input); an input-side bridge fee is inside destAmount.\n sourceAmount: params.amountIn,\n destAmount: est.toAmount,\n minDestAmount,\n ...(Number.isInteger(action.toToken?.decimals) && action.toToken!.decimals! >= 0 && action.toToken!.decimals! <= 36 ? {destDecimals: action.toToken!.decimals!} : {}),\n feeUsd,\n etaSeconds: est.executionDuration ?? 120,\n reliability: 0.97,\n // LI.FI documents an approximately 60-second lifetime. Use a slightly\n // shorter local deadline and re-quote again at execution time.\n validUntilMs: receivedAt + quoteTtlMs,\n };\n } catch {\n // Our own 12 s deadline (not the caller's signal): say so instead of a silent null.\n if (deadline?.aborted) params.onRefusal?.(\"lifi: no quote within 12 s\", {reason: \"upstream_unavailable\"});\n return null;\n }\n return null;\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n // A dry quote priced for a placeholder sender or recipient (placeholderIn) is never built, even with a transaction attached.\n const placeholder = quote.providerData?.placeholder;\n if (placeholder !== undefined) {\n throw refusal(\"policy_refused\", `swap2: this LI.FI quote was priced for a placeholder ${String(placeholder).slice(0, 20)} (a dry quote without that address) and has no transaction to build — quote again with the sender and the recipient`);\n }\n const tx = quote.txRequest;\n if (!tx) throw refusal(\"policy_refused\", \"swap2: LI.FI quote has no transaction request\");\n // The intent id carries the LI.FI source chain; a serialized leg names\n // its chain so the engine can refuse a mismatched account.\n const [, fromChain] = quote.intentId.split(\":\");\n return {\n chain: tx.serializedTx ? CAIP2_BY_LIFI_CHAIN[fromChain ?? \"\"] ?? \"\" : \"\",\n to: tx.to ?? \"\",\n value: tx.value ?? \"0\",\n ...(tx.data ? {data: tx.data} : {}),\n ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}),\n ...(tx.gasLimit ? {gasLimit: tx.gasLimit} : {}),\n ...(tx.approvalAddress ? {approvalAddress: tx.approvalAddress} : {}),\n ...(tx.serializedTx ? {serializedTx: tx.serializedTx} : {}),\n };\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"}; // not broadcast yet\n const [, fromChain, toChain] = ref.intentId.split(\":\");\n try {\n const url = new URL(`${apiBase}/status`);\n url.searchParams.set(\"txHash\", ref.sourceTxHash);\n if (fromChain) url.searchParams.set(\"fromChain\", fromChain);\n if (toChain) url.searchParams.set(\"toChain\", toChain);\n const res = await fetch(url, {headers: headers(apiKey()), signal: timeoutSignal(12_000)});\n if (!res.ok) return {state: \"pending\"};\n const s = (await res.json()) as {status?: string; substatus?: string; receiving?: {txHash?: string}};\n const map: Record<string, IntentStatus[\"state\"]> = {\n DONE: \"completed\",\n FAILED: \"failed\",\n // LI.FI cannot process the transaction: it never completes (round 3, L17).\n INVALID: \"failed\",\n PENDING: \"pending\",\n NOT_FOUND: \"pending\",\n };\n // LI.FI reports refunds and partial fills as top-level DONE. Treating\n // those as completed would falsely claim that the destination was fully\n // funded. Keep the explicit partial/refund lifecycle states.\n const state = s.substatus === \"REFUNDED\"\n ? \"refunded\"\n : s.substatus === \"EXPIRED\"\n ? \"expired\"\n : s.substatus === \"NOT_PROCESSABLE_REFUND_NEEDED\"\n ? \"action-required\"\n : s.substatus === \"REFUND_IN_PROGRESS\"\n ? \"refund-pending\"\n : s.status === \"DONE\" && s.substatus === \"PARTIAL\"\n ? \"partial\"\n : map[s.status ?? \"PENDING\"] ?? \"pending\";\n const depositReceived = state === \"pending\" && s.status === \"PENDING\";\n const destTxHash = typeof s.receiving?.txHash === \"string\" && s.receiving.txHash.length > 0\n ? s.receiving.txHash\n : undefined;\n return {\n state,\n depositReceived,\n ...(destTxHash ? {destTxHash} : {}),\n };\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\n/**\n * A remote LI.FI quote's Diamond call, decoded on the device against the app's own request (scan 2026-10-30, F3) —\n * the same {@link diamondCallMismatch} the provider runs on LI.FI's answer, with the expectation it builds: the input\n * token and amount, the requested output token, the recipient, the quoted minimum (at least the caller's floor), the\n * destination chain. A native input is paid in value (any excess is the declared bridge fee); a token input attaches\n * only that declared fee and approves the Diamond. A Solana source carries a serialized transaction instead, which the\n * account proves before signing (for a Mayan bridge, against the engine's `bridgeOut`); here only its static part is\n * read (paid by the sender; a Mayan route pays SOL to no other wallet). A dry request without the sender, or an EVM →\n * Solana one without the recipient, is priced for a placeholder: its quote must carry no transaction and is held to its\n * terms only. The reason it fails, or null.\n */\nexport function lifiVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n const fromChain = LIFI_CHAIN[params.sourceChain];\n const toChain = LIFI_CHAIN[params.destChain];\n if (!fromChain || !toChain) return note(\"not a LI.FI chain pair\", \"unsupported_pair\");\n // A dry quote priced for a placeholder sender or recipient (placeholderIn) prices the route only: with a transaction\n // it would pay or refund that public account from whichever wallet signs it.\n const placeholder = params.dry !== false ? placeholderIn(params) : null;\n if (placeholder) {\n if (quote.txRequest !== undefined) return note(`a dry quote priced for a placeholder ${placeholder} carries a transaction — it would pay or refund that placeholder, not the wallet that signs it`, \"recipient_mismatch\");\n return priceOnlyMismatch(params, quote, `lifi:${fromChain}:${toChain}`);\n }\n const tx = quote.txRequest;\n if (!tx) return note(\"the quote carries no transaction\", \"policy_refused\");\n if (isSolana(params.sourceChain)) {\n if (!tx.serializedTx || tx.data !== undefined || tx.to !== undefined) return note(\"a Solana source carries a serialized transaction only\", \"policy_refused\");\n // The static part of a bridge (see solanaBridgeTxMismatch); the account proves a Mayan order's recipient (bridgeOut).\n return fromChain === toChain ? null : solanaBridgeTxMismatch(tx.serializedTx, params.refundAddress || (params.dry !== false ? SOLANA_PLACEHOLDER : \"\"));\n }\n if (!isHexData(tx.data) || !tx.to || tx.serializedTx !== undefined) return note(\"the quote carries no Diamond call\", \"policy_refused\");\n if (!sameAddress(tx.to, diamondFor(params.sourceChain))) return note(`the call targets ${tx.to}, not the LI.FI Diamond`, \"vault_mismatch\");\n if (tx.chainId !== undefined && String(tx.chainId) !== fromChain) return note(`the call is for chain ${tx.chainId}, not ${fromChain}`, \"policy_refused\");\n const fromToken = lifiToken(params);\n if (!fromToken) return note(`unknown source token ${params.sourceToken}`, \"unsupported_pair\");\n const sourceIsToken = fromToken !== EVM_ZERO;\n // The same addresses the provider quotes for: a dry quote without them prices the placeholder (never built).\n const dry = params.dry !== false;\n const fromAddress = params.refundAddress || (dry ? EVM_PLACEHOLDER : \"\");\n const toAddress = params.destAddress || (dry ? dryRecipient(params, fromAddress) : \"\");\n if (!fromAddress || !toAddress) return \"a live quote needs the sender and the recipient\";\n let amountIn: bigint, minOut: bigint, value: bigint, nativeFee: bigint;\n try {\n amountIn = BigInt(params.amountIn);\n minOut = BigInt(quote.minDestAmount);\n value = BigInt(tx.value ?? \"0\");\n nativeFee = BigInt(tx.nativeFee ?? \"0\");\n } catch {\n return note(\"the quote's amounts are not integers\", \"upstream_unavailable\");\n }\n if (BigInt(quote.sourceAmount) !== amountIn) return note(`the quote spends ${quote.sourceAmount}, not the ${amountIn} input`, \"policy_refused\");\n if (params.minAmountOut !== undefined && minOut < BigInt(params.minAmountOut)) return note(`the quoted minimum ${minOut} is below the caller's floor ${params.minAmountOut}`, \"price_check_failed\");\n if (sourceIsToken) {\n if (value !== nativeFee) return note(\"a token input attaches only its declared bridge fee\", \"policy_refused\");\n if (!tx.approvalAddress || !sameAddress(tx.approvalAddress, diamondFor(params.sourceChain))) return note(\"a token input approves the LI.FI Diamond\", \"vault_mismatch\");\n } else {\n if (value < amountIn || value - amountIn !== nativeFee) return note(\"a native input is paid as the input plus its declared bridge fee\", \"policy_refused\");\n if (tx.approvalAddress !== undefined) return note(\"a native input approves nothing\", \"vault_mismatch\");\n }\n if (quote.intentId.replace(/~[0-9a-f]{32}$/, \"\") !== `lifi:${fromChain}:${toChain}`) return note(\"the intent id does not name this route\", \"policy_refused\");\n const why = diamondCallMismatch(tx.data, {\n fromToken, toToken: nativeFor(params.destChain, params.destToken), amountIn, receiver: toAddress, sender: fromAddress, minOut,\n destChainId: BigInt(toChain), sameChain: fromChain === toChain, evmDestination: !isSolana(params.destChain),\n });\n return why ? note(`the transaction does not match the request: ${why}`, reasonOf(why) ?? \"policy_refused\") : null;\n}\n\n/**\n * A dry quote with no transaction (priced for a placeholder): what it spends, its minimum against the caller's floor and\n * the route its intent id names are still held to the request; it pays no deposit address, and the bridge fee it declares\n * (`providerData.nativeFee`, which the router nets out of its value) is a base-unit integer. The reason, or null.\n */\nfunction priceOnlyMismatch(params: QuoteParams, quote: Quote, route: string): string | null {\n if (quote.depositAddress !== \"\") return note(`a LI.FI quote pays no deposit address, but this one names ${String(quote.depositAddress).slice(0, 64)}`, \"vault_mismatch\");\n const fee = quote.providerData?.nativeFee;\n if (fee !== undefined && !/^\\d{1,80}$/.test(String(fee))) return note(`the price-only quote declares a native fee of ${String(fee).slice(0, 40)}, not a base-unit integer`, \"upstream_unavailable\");\n try {\n if (BigInt(quote.sourceAmount) !== BigInt(params.amountIn)) return note(`the quote spends ${quote.sourceAmount}, not the ${params.amountIn} input`, \"policy_refused\");\n const minOut = BigInt(quote.minDestAmount);\n if (params.minAmountOut !== undefined && minOut < BigInt(params.minAmountOut)) return note(`the quoted minimum ${minOut} is below the caller's floor ${params.minAmountOut}`, \"price_check_failed\");\n } catch {\n return note(\"the quote's amounts are not integers\", \"upstream_unavailable\");\n }\n return quote.intentId.replace(/~[0-9a-f]{32}$/, \"\") === route ? null : note(\"the intent id does not name this route\", \"policy_refused\");\n}\n\n/**\n * The LI.FI Diamond an EVM route calls and approves on a chain (the canonical one, or the chain's own\n * where it differs), and {@link lifiVerifyQuote} — the app's pins for `remoteProvider({name: \"lifi\", baseUrl,\n * ...lifiPins})` (scan 2026-10-27 modules, F8/F16; the Diamond call itself since scan 2026-10-30, F3). Extra audited\n * targets an app configures on the provider (`trustedTransactionTargets` / `trustedApprovalAddresses`) are added on\n * the app side too.\n */\nexport const lifiPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => (/^eip155:[0-9]+$/.test(chain) ? [diamondFor(chain)] : []),\n spenders: (chain: string): readonly string[] => (/^eip155:[0-9]+$/.test(chain) ? [diamondFor(chain)] : []),\n verifyQuote: lifiVerifyQuote,\n /** The reason of a text {@link lifiVerifyQuote} returned (`remoteProvider` puts it on the stub's refusal). */\n reasonOf: (text: string): Swap2RefusalInfo | undefined => reasonOf(text),\n});\n","import {SingleProviderSwap2} from \"@anywalletkit/protocol-swap2-core/swap2/single\";\nimport type {Swap2Account, Swap2EngineConfig} from \"@anywalletkit/protocol-swap2-core/swap2/base\";\nimport {lifi as lifiCfg} from \"./config.js\";\nimport {lifiProvider, type LifiProviderConfig} from \"./provider.js\";\n\nexport interface LifiSwap2Config extends Swap2EngineConfig, LifiProviderConfig {}\n\nexport class LifiSwap2Protocol extends SingleProviderSwap2 {\n protected readonly provider;\n constructor(account: Swap2Account | undefined, config: LifiSwap2Config) {\n super(account, config);\n this.provider = lifiProvider(config);\n }\n protected override chainSupported(caip2: string): boolean {\n return lifiCfg.supportsChain(caip2);\n }\n protected override pairSupported(fromChain: string, toChain: string): boolean {\n return lifiCfg.supports(fromChain, toChain);\n }\n}\n"],"mappings":"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","names":["receiver","minAmount","import_util","import_util","import_errors","BASE58"]}