@rabby-wallet/rabby-bridge 0.0.12 → 0.0.13-alpha.0

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.
Files changed (194) hide show
  1. package/README.md +131 -1
  2. package/dist/calldata/abi.d.ts +29 -0
  3. package/dist/calldata/abi.js +160 -0
  4. package/dist/calldata/across/deposit.d.ts +2 -0
  5. package/dist/calldata/across/deposit.js +36 -0
  6. package/dist/calldata/across/depositNative.d.ts +2 -0
  7. package/dist/calldata/across/depositNative.js +45 -0
  8. package/dist/calldata/across/depositNow.d.ts +2 -0
  9. package/dist/calldata/across/depositNow.js +35 -0
  10. package/dist/calldata/across/depositV3.d.ts +2 -0
  11. package/dist/calldata/across/depositV3.js +35 -0
  12. package/dist/calldata/across/depositV3Now.d.ts +2 -0
  13. package/dist/calldata/across/depositV3Now.js +34 -0
  14. package/dist/calldata/across/index.d.ts +4 -0
  15. package/dist/calldata/across/index.js +31 -0
  16. package/dist/calldata/across/swapAndBridge.d.ts +2 -0
  17. package/dist/calldata/across/swapAndBridge.js +70 -0
  18. package/dist/calldata/across/validate.d.ts +3 -0
  19. package/dist/calldata/across/validate.js +30 -0
  20. package/dist/calldata/chains.d.ts +2 -0
  21. package/dist/calldata/chains.js +35 -0
  22. package/dist/calldata/destination.d.ts +6 -0
  23. package/dist/calldata/destination.js +148 -0
  24. package/dist/calldata/diagnostics.d.ts +4 -0
  25. package/dist/calldata/diagnostics.js +18 -0
  26. package/dist/calldata/expect.d.ts +25 -0
  27. package/dist/calldata/expect.js +129 -0
  28. package/dist/calldata/hex.d.ts +6 -0
  29. package/dist/calldata/hex.js +46 -0
  30. package/dist/calldata/index.d.ts +20 -0
  31. package/dist/calldata/index.js +85 -0
  32. package/dist/calldata/lifi/across/acrossV4Erc20Min.d.ts +2 -0
  33. package/dist/calldata/lifi/across/acrossV4Erc20Min.js +26 -0
  34. package/dist/calldata/lifi/across/acrossV4NativeMin.d.ts +2 -0
  35. package/dist/calldata/lifi/across/acrossV4NativeMin.js +22 -0
  36. package/dist/calldata/lifi/across/index.d.ts +6 -0
  37. package/dist/calldata/lifi/across/index.js +19 -0
  38. package/dist/calldata/lifi/allbridge/index.d.ts +3 -0
  39. package/dist/calldata/lifi/allbridge/index.js +26 -0
  40. package/dist/calldata/lifi/celer/index.d.ts +4 -0
  41. package/dist/calldata/lifi/celer/index.js +10 -0
  42. package/dist/calldata/lifi/centrifuge/index.d.ts +3 -0
  43. package/dist/calldata/lifi/centrifuge/index.js +22 -0
  44. package/dist/calldata/lifi/frax/index.d.ts +4 -0
  45. package/dist/calldata/lifi/frax/index.js +29 -0
  46. package/dist/calldata/lifi/garden/index.d.ts +3 -0
  47. package/dist/calldata/lifi/garden/index.js +22 -0
  48. package/dist/calldata/lifi/gaszip/index.d.ts +6 -0
  49. package/dist/calldata/lifi/gaszip/index.js +15 -0
  50. package/dist/calldata/lifi/index.d.ts +4 -0
  51. package/dist/calldata/lifi/index.js +60 -0
  52. package/dist/calldata/lifi/intents/index.d.ts +4 -0
  53. package/dist/calldata/lifi/intents/index.js +10 -0
  54. package/dist/calldata/lifi/layerswap/index.d.ts +4 -0
  55. package/dist/calldata/lifi/layerswap/index.js +10 -0
  56. package/dist/calldata/lifi/m0/index.d.ts +3 -0
  57. package/dist/calldata/lifi/m0/index.js +33 -0
  58. package/dist/calldata/lifi/mayan/index.d.ts +4 -0
  59. package/dist/calldata/lifi/mayan/index.js +10 -0
  60. package/dist/calldata/lifi/method.d.ts +6 -0
  61. package/dist/calldata/lifi/method.js +16 -0
  62. package/dist/calldata/lifi/native/index.d.ts +4 -0
  63. package/dist/calldata/lifi/native/index.js +80 -0
  64. package/dist/calldata/lifi/params.d.ts +30 -0
  65. package/dist/calldata/lifi/params.js +370 -0
  66. package/dist/calldata/lifi/paxos/index.d.ts +4 -0
  67. package/dist/calldata/lifi/paxos/index.js +10 -0
  68. package/dist/calldata/lifi/polymer/index.d.ts +4 -0
  69. package/dist/calldata/lifi/polymer/index.js +10 -0
  70. package/dist/calldata/lifi/relay/index.d.ts +6 -0
  71. package/dist/calldata/lifi/relay/index.js +15 -0
  72. package/dist/calldata/lifi/shape.d.ts +4 -0
  73. package/dist/calldata/lifi/shape.js +31 -0
  74. package/dist/calldata/lifi/squid/index.d.ts +6 -0
  75. package/dist/calldata/lifi/squid/index.js +15 -0
  76. package/dist/calldata/lifi/stargate/index.d.ts +5 -0
  77. package/dist/calldata/lifi/stargate/index.js +15 -0
  78. package/dist/calldata/lifi/swap/index.d.ts +5 -0
  79. package/dist/calldata/lifi/swap/index.js +18 -0
  80. package/dist/calldata/lifi/swap/swapMethod.d.ts +2 -0
  81. package/dist/calldata/lifi/swap/swapMethod.js +40 -0
  82. package/dist/calldata/match.d.ts +3 -0
  83. package/dist/calldata/match.js +21 -0
  84. package/dist/calldata/mayan/destination.d.ts +2 -0
  85. package/dist/calldata/mayan/destination.js +13 -0
  86. package/dist/calldata/mayan/fastMctpBridge.d.ts +3 -0
  87. package/dist/calldata/mayan/fastMctpBridge.js +43 -0
  88. package/dist/calldata/mayan/fastMctpCreateOrder.d.ts +3 -0
  89. package/dist/calldata/mayan/fastMctpCreateOrder.js +39 -0
  90. package/dist/calldata/mayan/forward.d.ts +8 -0
  91. package/dist/calldata/mayan/forward.js +35 -0
  92. package/dist/calldata/mayan/forwardERC20.d.ts +2 -0
  93. package/dist/calldata/mayan/forwardERC20.js +19 -0
  94. package/dist/calldata/mayan/forwardEth.d.ts +2 -0
  95. package/dist/calldata/mayan/forwardEth.js +16 -0
  96. package/dist/calldata/mayan/index.d.ts +4 -0
  97. package/dist/calldata/mayan/index.js +21 -0
  98. package/dist/calldata/mayan/mctp.d.ts +5 -0
  99. package/dist/calldata/mayan/mctp.js +41 -0
  100. package/dist/calldata/mayan/readProtocol.d.ts +2 -0
  101. package/dist/calldata/mayan/readProtocol.js +29 -0
  102. package/dist/calldata/mayan/swapAndForwardERC20.d.ts +2 -0
  103. package/dist/calldata/mayan/swapAndForwardERC20.js +24 -0
  104. package/dist/calldata/mayan/swapAndForwardEth.d.ts +2 -0
  105. package/dist/calldata/mayan/swapAndForwardEth.js +23 -0
  106. package/dist/calldata/mayan/swiftCreateOrder.d.ts +3 -0
  107. package/dist/calldata/mayan/swiftCreateOrder.js +49 -0
  108. package/dist/calldata/mayan/validate.d.ts +3 -0
  109. package/dist/calldata/mayan/validate.js +20 -0
  110. package/dist/calldata/protocols.d.ts +9 -0
  111. package/dist/calldata/protocols.js +56 -0
  112. package/dist/calldata/relay/calls.d.ts +13 -0
  113. package/dist/calldata/relay/calls.js +54 -0
  114. package/dist/calldata/relay/depositErc20.d.ts +2 -0
  115. package/dist/calldata/relay/depositErc20.js +22 -0
  116. package/dist/calldata/relay/depositErc20Allowance.d.ts +2 -0
  117. package/dist/calldata/relay/depositErc20Allowance.js +20 -0
  118. package/dist/calldata/relay/depositNative.d.ts +2 -0
  119. package/dist/calldata/relay/depositNative.js +20 -0
  120. package/dist/calldata/relay/index.d.ts +4 -0
  121. package/dist/calldata/relay/index.js +40 -0
  122. package/dist/calldata/relay/multicall.d.ts +2 -0
  123. package/dist/calldata/relay/multicall.js +15 -0
  124. package/dist/calldata/relay/permit2TransferAndMulticall.d.ts +2 -0
  125. package/dist/calldata/relay/permit2TransferAndMulticall.js +42 -0
  126. package/dist/calldata/relay/permit3009TransferAndMulticall.d.ts +2 -0
  127. package/dist/calldata/relay/permit3009TransferAndMulticall.js +41 -0
  128. package/dist/calldata/relay/permit3009TransferAndMulticallSigned.d.ts +2 -0
  129. package/dist/calldata/relay/permit3009TransferAndMulticallSigned.js +40 -0
  130. package/dist/calldata/relay/permitTransferAndMulticall.d.ts +2 -0
  131. package/dist/calldata/relay/permitTransferAndMulticall.js +34 -0
  132. package/dist/calldata/relay/permitTransferAndMulticallLegacy.d.ts +2 -0
  133. package/dist/calldata/relay/permitTransferAndMulticallLegacy.js +35 -0
  134. package/dist/calldata/relay/transferAndMulticall.d.ts +2 -0
  135. package/dist/calldata/relay/transferAndMulticall.js +26 -0
  136. package/dist/calldata/relay/validate.d.ts +3 -0
  137. package/dist/calldata/relay/validate.js +18 -0
  138. package/dist/calldata/resolve.d.ts +2 -0
  139. package/dist/calldata/resolve.js +28 -0
  140. package/dist/calldata/socket/bridge.d.ts +2 -0
  141. package/dist/calldata/socket/bridge.js +28 -0
  142. package/dist/calldata/socket/exec.d.ts +2 -0
  143. package/dist/calldata/socket/exec.js +71 -0
  144. package/dist/calldata/socket/index.d.ts +4 -0
  145. package/dist/calldata/socket/index.js +13 -0
  146. package/dist/calldata/socket/params.d.ts +5 -0
  147. package/dist/calldata/socket/params.js +14 -0
  148. package/dist/calldata/socket/protocols/ccip.d.ts +2 -0
  149. package/dist/calldata/socket/protocols/ccip.js +32 -0
  150. package/dist/calldata/socket/protocols/cctp.d.ts +2 -0
  151. package/dist/calldata/socket/protocols/cctp.js +24 -0
  152. package/dist/calldata/socket/protocols/eco.d.ts +2 -0
  153. package/dist/calldata/socket/protocols/eco.js +20 -0
  154. package/dist/calldata/socket/protocols/index.d.ts +3 -0
  155. package/dist/calldata/socket/protocols/index.js +81 -0
  156. package/dist/calldata/socket/protocols/native.d.ts +2 -0
  157. package/dist/calldata/socket/protocols/native.js +70 -0
  158. package/dist/calldata/socket/protocols/oft.d.ts +2 -0
  159. package/dist/calldata/socket/protocols/oft.js +31 -0
  160. package/dist/calldata/socket/protocols/swapsXYZ.d.ts +2 -0
  161. package/dist/calldata/socket/protocols/swapsXYZ.js +62 -0
  162. package/dist/calldata/socket/swapAndBridge.d.ts +2 -0
  163. package/dist/calldata/socket/swapAndBridge.js +37 -0
  164. package/dist/calldata/socket/validate.d.ts +3 -0
  165. package/dist/calldata/socket/validate.js +21 -0
  166. package/dist/calldata/types.d.ts +82 -0
  167. package/dist/calldata/types.js +20 -0
  168. package/dist/errors/constants.d.ts +876 -0
  169. package/dist/errors/constants.js +883 -0
  170. package/dist/errors/index.d.ts +61 -0
  171. package/dist/errors/index.js +53 -0
  172. package/dist/errors/sanitize.d.ts +3 -0
  173. package/dist/errors/sanitize.js +75 -0
  174. package/dist/index.d.ts +7 -1
  175. package/dist/index.js +3 -0
  176. package/dist/providers/data.d.ts +23 -0
  177. package/dist/providers/data.js +116 -0
  178. package/dist/providers/errors.d.ts +7 -0
  179. package/dist/providers/errors.js +10 -0
  180. package/dist/providers/index.d.ts +7 -0
  181. package/dist/providers/index.js +340 -0
  182. package/dist/providers/layerswap.d.ts +9 -0
  183. package/dist/providers/layerswap.js +95 -0
  184. package/dist/providers/relay.d.ts +59 -0
  185. package/dist/providers/relay.js +185 -0
  186. package/dist/providers/request.d.ts +23 -0
  187. package/dist/providers/request.js +69 -0
  188. package/dist/providers/socket.d.ts +5 -0
  189. package/dist/providers/socket.js +57 -0
  190. package/dist/providers/types.d.ts +36 -0
  191. package/dist/providers/types.js +1 -0
  192. package/dist/quote.d.ts +18 -4
  193. package/dist/quote.js +282 -65
  194. package/package.json +13 -3
@@ -0,0 +1,30 @@
1
+ import { BRIDGE_ERRORS } from '../../errors/index.js';
2
+ import { getBridgeRouter } from '../../list.js';
3
+ import { evmChainId } from '../chains.js';
4
+ import { isZeroWord } from '../hex.js';
5
+ export const acrossFailure = (parsed, chainId, expectedDepositor) => {
6
+ if (expectedDepositor && parsed.depositor?.toLowerCase() !== expectedDepositor.toLowerCase()) {
7
+ return BRIDGE_ERRORS.DEPOSITOR_MISMATCH;
8
+ }
9
+ if (parsed.destinationChainId === undefined || parsed.destinationChainId <= 0n) {
10
+ return BRIDGE_ERRORS.MISSING_DESTINATION_CHAIN;
11
+ }
12
+ if (isZeroWord(parsed.receiver ?? parsed.bridgeReceiver)) {
13
+ return BRIDGE_ERRORS.MISSING_RECEIVER;
14
+ }
15
+ if ((parsed.sourceAmount ?? 0n) <= 0n) {
16
+ return BRIDGE_ERRORS.MISSING_SOURCE_AMOUNT;
17
+ }
18
+ if (!parsed.spokePool) {
19
+ return undefined;
20
+ }
21
+ const spoke = parsed.spokePool.toLowerCase();
22
+ // BSC's configured outer router is a periphery, separate from its canonical SpokePool.
23
+ const expectedSpoke = evmChainId(chainId) === 56n
24
+ ? '0x4e8e101924ede233c13e2d8622dc8aed2872d505'
25
+ : getBridgeRouter('across', chainId)?.toLowerCase();
26
+ if (expectedSpoke !== spoke) {
27
+ return BRIDGE_ERRORS.SPOKE_POOL_IS_NOT_IN_THE_ALLOWLIST;
28
+ }
29
+ return undefined;
30
+ };
@@ -0,0 +1,2 @@
1
+ export declare const evmChainId: (chain: string) => bigint | undefined;
2
+ export declare const sourceChainMismatch: (expected: string, actual?: string | number | bigint) => boolean;
@@ -0,0 +1,35 @@
1
+ import { CHAIN_ENUM_TO_SERVER_ID, normalizeChainEnum } from '../chains.js';
2
+ const CHAIN_IDS = {
3
+ eth: 1n, op: 10n, flr: 14n, cro: 25n, rsk: 30n, xdc: 50n, bsc: 56n,
4
+ xdai: 100n, fuse: 122n, uni: 130n, matic: 137n, monad: 143n, sonic: 146n,
5
+ manta: 169n, xlayer: 196n, opbnb: 204n, lens: 232n, frax: 252n, era: 324n,
6
+ stable: 988n, hyper: 999n, metis: 1088n, lisk: 1135n, sei: 1329n, story: 1514n,
7
+ gravity: 1625n, soneium: 1868n, swell: 1923n, ron: 2020n, abs: 2741n,
8
+ morph: 2818n, tempo: 4217n, megaeth: 4326n, hood: 4663n, world: 480n,
9
+ mnt: 5000n, arc: 5042n, cyber: 7560n, klay: 8217n, base: 8453n, plasma: 9745n,
10
+ ape: 33139n, mode: 34443n, arb: 42161n, celo: 42220n, hemi: 43111n, avax: 43114n,
11
+ zircuit: 48900n, sophon: 50104n, ink: 57073n, linea: 59144n, bob: 60808n,
12
+ bera: 80094n, blast: 81457n, plume: 98866n, taiko: 167000n, scrl: 534352n,
13
+ katana: 747474n, zora: 7777777n,
14
+ ethereum: 1n, optimism: 10n, gnosis: 100n, polygon: 137n, mantle: 5000n,
15
+ arbitrum: 42161n, avalanche: 43114n, fraxtal: 252n,
16
+ };
17
+ export const evmChainId = (chain) => {
18
+ if (/^\d+$/.test(chain)) {
19
+ const id = BigInt(chain);
20
+ return id > 0n ? id : undefined;
21
+ }
22
+ const chainEnum = normalizeChainEnum(chain);
23
+ return CHAIN_IDS[chainEnum ? CHAIN_ENUM_TO_SERVER_ID[chainEnum] : chain.toLowerCase()];
24
+ };
25
+ export const sourceChainMismatch = (expected, actual) => {
26
+ if (actual === undefined)
27
+ return false;
28
+ try {
29
+ return (typeof actual === 'number' && !Number.isSafeInteger(actual)) ||
30
+ evmChainId(expected) === undefined || BigInt(actual) !== evmChainId(expected);
31
+ }
32
+ catch {
33
+ return true;
34
+ }
35
+ };
@@ -0,0 +1,6 @@
1
+ import { type AbiParam, type AbiValue } from './abi.js';
2
+ import type { ParsedBridgeCall } from './types.js';
3
+ export declare const destinationCall: AbiParam;
4
+ export declare const readTransfer: (target: string, data: string, value: bigint) => Partial<ParsedBridgeCall> | undefined;
5
+ export declare const readDestinationTransfers: (calls: AbiValue[]) => Partial<ParsedBridgeCall>;
6
+ export declare const applyAcrossMessage: (parsed: ParsedBridgeCall, message: string) => ParsedBridgeCall;
@@ -0,0 +1,148 @@
1
+ import { BRIDGE_ERRORS, BridgeError, asBridgeError } from '../errors/index.js';
2
+ import { asArray, asBigint, asRecord, asString, decodeCall, decodeParameters } from './abi.js';
3
+ import { isZeroWord, readSelector } from './hex.js';
4
+ import { NATIVE_TOKEN, WRAPPED_NATIVE_TOKENS, subtractFees } from './protocols.js';
5
+ import { calldataDiagnostics } from './diagnostics.js';
6
+ export const destinationCall = {
7
+ name: 'call', kind: 'tuple', components: [
8
+ { name: 'target', kind: 'address' }, { name: 'data', kind: 'bytes' }, { name: 'value', kind: 'uint' },
9
+ ],
10
+ };
11
+ export const readTransfer = (target, data, value) => {
12
+ if (data === '0x' && value > 0n)
13
+ return { receiver: target, outputToken: NATIVE_TOKEN, minOutputAmount: value };
14
+ if (readSelector(data) !== '0xa9059cbb')
15
+ return undefined;
16
+ const args = decodeCall([{ name: 'to', kind: 'address' }, { name: 'amount', kind: 'uint' }], data);
17
+ return { receiver: asString(args.to), outputToken: target, minOutputAmount: asBigint(args.amount) };
18
+ };
19
+ export const readDestinationTransfers = (calls) => {
20
+ const diagnostics = { destinationCallCount: calls.length,
21
+ destinationSelectors: [...new Set(calls.map((call) => calldataDiagnostics(asRecord(call).data).selector)
22
+ .filter((selector) => Boolean(selector)))].slice(0, 16) };
23
+ const transfers = calls.map((call) => {
24
+ const c = asRecord(call);
25
+ return readTransfer(asString(c.target), asString(c.data), asBigint(c.value));
26
+ });
27
+ if (!transfers.length || transfers.some((transfer) => !transfer))
28
+ return { diagnostics };
29
+ const first = transfers[0];
30
+ if (!transfers.every((transfer) => transfer !== undefined && transfer.receiver === first.receiver && transfer.outputToken === first.outputToken))
31
+ return { diagnostics };
32
+ return { ...first, diagnostics, minOutputAmount: transfers.reduce((sum, transfer) => sum + (transfer?.minOutputAmount ?? 0n), 0n) };
33
+ };
34
+ const instructions = {
35
+ name: 'instructions', kind: 'tuple', components: [
36
+ { name: 'calls', kind: 'array', item: { name: 'call', kind: 'tuple', components: [
37
+ { name: 'target', kind: 'address' }, { name: 'callData', kind: 'bytes' }, { name: 'value', kind: 'uint' },
38
+ ] } },
39
+ { name: 'fallbackRecipient', kind: 'address' },
40
+ ],
41
+ };
42
+ const ACROSS_MESSAGE_HANDLERS = {
43
+ 999: '0x5e7840e06faccb6d1c3b5f5e0d1d3d07f2829bba',
44
+ 4663: '0xa8ad2e87e2043711d8bec77e8bc3e2683c0ab6bd',
45
+ 43114: '0x9610954acdca5ff7905f051a040ce33fe613c60e',
46
+ };
47
+ const readAcrossMessage = (parsed, message) => {
48
+ if (message === '0x') {
49
+ const wrapped = WRAPPED_NATIVE_TOKENS[parsed.destinationChainId?.toString() ?? ''];
50
+ if (parsed.outputToken !== undefined && (wrapped === undefined || parsed.outputToken === wrapped)) {
51
+ parsed.bridgeOutputToken = parsed.outputToken;
52
+ parsed.outputTokenReference = { protocol: 'across-native', token: parsed.outputToken,
53
+ destinationChainId: parsed.destinationChainId, destinationContract: parsed.receiver };
54
+ delete parsed.outputToken;
55
+ }
56
+ return parsed;
57
+ }
58
+ const handler = parsed.receiver;
59
+ parsed.bridgeReceiver = handler;
60
+ parsed.bridgeOutputToken = parsed.outputToken;
61
+ parsed.bridgeOutputAmount = parsed.minOutputAmount;
62
+ parsed.destinationCallData = message;
63
+ parsed.diagnostics = { hasDestinationCall: true, destinationCalldataBytes: calldataDiagnostics(message).calldataBytes };
64
+ delete parsed.receiver;
65
+ delete parsed.outputToken;
66
+ delete parsed.minOutputAmount;
67
+ // Other message handlers can implement arbitrary destination logic.
68
+ const expectedHandler = ACROSS_MESSAGE_HANDLERS[parsed.destinationChainId?.toString() ?? ''] ??
69
+ '0x0f7ae28de1c8532170ad4ee566b5801485c13a0e';
70
+ if (handler !== expectedHandler)
71
+ return parsed;
72
+ const emitter = parsed.destinationChainId === 43114n
73
+ ? '0x25b15fc38d6a2c13feddd9cb51f184f7cf0d4c11' : '0xbf75133b48b0a42ab9374027902e83c5e2949034';
74
+ const args = asRecord(decodeParameters([instructions], message).instructions);
75
+ const calls = asArray(args.calls);
76
+ parsed.diagnostics.destinationCallCount = calls.length;
77
+ parsed.diagnostics.destinationSelectors = [...new Set(calls.map((call) => calldataDiagnostics(asRecord(call).callData).selector)
78
+ .filter((selector) => Boolean(selector)))].slice(0, 16);
79
+ const balances = new Map([[parsed.bridgeOutputToken, parsed.bridgeOutputAmount]]);
80
+ const payouts = [];
81
+ for (const raw of calls) {
82
+ const call = asRecord(raw);
83
+ const target = asString(call.target);
84
+ const data = asString(call.callData);
85
+ const value = asBigint(call.value);
86
+ const selector = readSelector(data);
87
+ // emitData is telemetry; its amounts are not an enforced receive floor.
88
+ if (selector === '0xd836083e' && target === emitter && value === 0n)
89
+ continue;
90
+ if (selector === '0xc41e8295' && target === handler) {
91
+ if (value !== 0n)
92
+ return parsed;
93
+ const nested = decodeCall([
94
+ { name: 'target', kind: 'address' }, { name: 'data', kind: 'bytes' }, { name: 'value', kind: 'uint' },
95
+ { name: 'replacements', kind: 'array', item: { name: 'replacement', kind: 'tuple', components: [
96
+ { name: 'token', kind: 'address' }, { name: 'offset', kind: 'uint' },
97
+ ] } },
98
+ ], data);
99
+ const token = asString(nested.target);
100
+ const replacements = asArray(nested.replacements).map(asRecord);
101
+ const withdrawal = asString(nested.data);
102
+ if (readSelector(withdrawal) !== '0x2e1a7d4d' || replacements.length !== 1 ||
103
+ asBigint(decodeCall([{ name: 'amount', kind: 'uint' }], withdrawal).amount) !== 0n ||
104
+ asBigint(nested.value) !== 0n ||
105
+ asString(replacements[0].token) !== token || asBigint(replacements[0].offset) !== 4n || !balances.has(token) ||
106
+ WRAPPED_NATIVE_TOKENS[parsed.destinationChainId?.toString() ?? ''] !== token)
107
+ return parsed;
108
+ balances.set(NATIVE_TOKEN, (balances.get(NATIVE_TOKEN) ?? 0n) + (balances.get(token) ?? 0n));
109
+ balances.set(token, 0n);
110
+ continue;
111
+ }
112
+ if (selector === '0xef8738d3' && target === handler) {
113
+ if (value !== 0n)
114
+ return parsed;
115
+ const drain = decodeCall([{ name: 'token', kind: 'address' }, { name: 'receiver', kind: 'address' }], data);
116
+ const token = asString(drain.token);
117
+ const amount = balances.get(token) ?? 0n;
118
+ if (amount > 0n)
119
+ payouts.push({ outputToken: token, minOutputAmount: amount, receiver: asString(drain.receiver) });
120
+ balances.set(token, 0n);
121
+ continue;
122
+ }
123
+ const transfer = readTransfer(target, data, value);
124
+ if (!transfer || !balances.has(transfer.outputToken))
125
+ return parsed;
126
+ const token = transfer.outputToken;
127
+ balances.set(token, subtractFees(balances.get(token) ?? 0n, transfer.minOutputAmount ?? 0n));
128
+ }
129
+ if (payouts.length === 1) {
130
+ const fallback = asString(args.fallbackRecipient);
131
+ if (!isZeroWord(fallback) && fallback !== payouts[0].receiver) {
132
+ throw new BridgeError(BRIDGE_ERRORS.ACROSS_FALLBACK_RECEIVER_MISMATCH);
133
+ }
134
+ if (!isZeroWord(fallback) && parsed.bridgeOutputToken !== payouts[0].outputToken) {
135
+ throw new BridgeError(BRIDGE_ERRORS.ACROSS_FALLBACK_TOKEN_MISMATCH);
136
+ }
137
+ Object.assign(parsed, payouts[0]);
138
+ }
139
+ return parsed;
140
+ };
141
+ export const applyAcrossMessage = (parsed, message) => {
142
+ try {
143
+ return readAcrossMessage(parsed, message);
144
+ }
145
+ catch (error) {
146
+ throw asBridgeError(error, BRIDGE_ERRORS.CALLDATA_DECODE_FAILED, parsed.diagnostics);
147
+ }
148
+ };
@@ -0,0 +1,4 @@
1
+ import type { BridgeErrorContext } from '../errors/index.js';
2
+ /** Inspect call structure only. Never retain arguments or scan arbitrary payloads for selectors. */
3
+ export declare const calldataDiagnostics: (data: unknown) => BridgeErrorContext;
4
+ export declare const innerCallDiagnostics: (data: string, layer: "router" | "protocol") => BridgeErrorContext;
@@ -0,0 +1,18 @@
1
+ /** Inspect call structure only. Never retain arguments or scan arbitrary payloads for selectors. */
2
+ export const calldataDiagnostics = (data) => {
3
+ if (typeof data !== 'string')
4
+ return { calldataFormat: 'missing' };
5
+ const valid = /^0x(?:[0-9a-f]{2})*$/i.test(data);
6
+ const selector = /^0x[0-9a-f]{8}/i.test(data) ? data.slice(0, 10).toLowerCase() : undefined;
7
+ return {
8
+ selector,
9
+ calldataFormat: valid ? (data.length === 2 ? 'empty' : 'valid') : 'invalid',
10
+ ...(valid ? { calldataBytes: (data.length - 2) / 2 } : {}),
11
+ };
12
+ };
13
+ export const innerCallDiagnostics = (data, layer) => {
14
+ const { selector, calldataBytes } = calldataDiagnostics(data);
15
+ return layer === 'router'
16
+ ? { routerSelector: selector, routerCalldataBytes: calldataBytes }
17
+ : { protocolSelector: selector, protocolCalldataBytes: calldataBytes };
18
+ };
@@ -0,0 +1,25 @@
1
+ import type { BridgeErrorDefinition } from '../errors/index.js';
2
+ import type { BridgeCheck, ParsedBridgeCall } from './types.js';
3
+ export type BridgeCallExpectation = {
4
+ userAddress: string;
5
+ fromTokenId: string;
6
+ fromTokenRawAmount: string;
7
+ toTokenId: string;
8
+ /** 目标链 id。目标币是原生币时,用它识别 `hood` 这类链 id,而不是源链 id。 */
9
+ toChainId?: string;
10
+ toTokenRawAmount?: string;
11
+ /** 小数滑点。0.01 表示 1%。 */
12
+ slippage?: string | number;
13
+ };
14
+ export type CompareMask = {
15
+ fromToken: boolean;
16
+ fromAmount: boolean;
17
+ toToken: boolean;
18
+ toAmount: boolean;
19
+ receiver: boolean;
20
+ };
21
+ export declare const knownCompare: (parsed: ParsedBridgeCall) => CompareMask;
22
+ /** Actual source payment may exceed local intent by at most 0.1%; lower payments still reject. */
23
+ export declare const sourceAmountMatches: (actual: bigint | undefined, expected: bigint) => boolean;
24
+ export declare const expectationFailures: (parsed: ParsedBridgeCall, expectation: BridgeCallExpectation, chainId: string, mask: CompareMask) => BridgeErrorDefinition[];
25
+ export declare const finishCheck: (aggregatorId: string, parsed: ParsedBridgeCall, structural: BridgeErrorDefinition | undefined, expectation: BridgeCallExpectation | undefined, chainId: string, mask: CompareMask) => BridgeCheck;
@@ -0,0 +1,129 @@
1
+ import { BRIDGE_ERRORS, bridgeFailure } from '../errors/index.js';
2
+ import { evmChainId } from './chains.js';
3
+ const NATIVE_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
4
+ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
5
+ const RATIO_SCALE = 1000000n;
6
+ export const knownCompare = (parsed) => ({
7
+ fromToken: parsed.sourceToken !== undefined,
8
+ fromAmount: parsed.sourceAmount !== undefined,
9
+ toToken: parsed.outputToken !== undefined,
10
+ toAmount: parsed.minOutputAmount !== undefined,
11
+ receiver: parsed.receiver !== undefined,
12
+ });
13
+ const isHexAddress = (value) => /^0x[0-9a-f]{40}$/i.test(value);
14
+ const isNativeToken = (value, chainId) => {
15
+ const normalized = value.toLowerCase();
16
+ const network = evmChainId(normalized);
17
+ return (normalized === NATIVE_ADDRESS ||
18
+ normalized === ZERO_ADDRESS ||
19
+ normalized === chainId.toLowerCase() ||
20
+ (network !== undefined && network === evmChainId(chainId)));
21
+ };
22
+ const sameToken = (actual, expected, chainId) => {
23
+ if (!actual) {
24
+ return false;
25
+ }
26
+ if (isNativeToken(actual, chainId) && isNativeToken(expected, chainId)) {
27
+ return true;
28
+ }
29
+ if (!isHexAddress(actual) || !isHexAddress(expected)) {
30
+ return actual.toLowerCase() === expected.toLowerCase();
31
+ }
32
+ return actual.toLowerCase() === expected.toLowerCase();
33
+ };
34
+ const parseAmount = (amount) => {
35
+ try {
36
+ return BigInt(amount);
37
+ }
38
+ catch {
39
+ return undefined;
40
+ }
41
+ };
42
+ /** Actual source payment may exceed local intent by at most 0.1%; lower payments still reject. */
43
+ export const sourceAmountMatches = (actual, expected) => actual !== undefined && expected >= 0n && actual >= expected && (actual - expected) * 1000n <= expected;
44
+ /** Allow a 5% relative difference from the quote's slippage-adjusted minimum. */
45
+ const minReceiveMatches = (minReceive, quoted, slippage) => {
46
+ if (minReceive <= 0n || quoted <= 0n || slippage < 0 || slippage >= 1) {
47
+ return false;
48
+ }
49
+ const ratioScaled = BigInt(Math.round((1 - slippage) * Number(RATIO_SCALE)));
50
+ const minimum = (quoted * ratioScaled) / RATIO_SCALE;
51
+ if (minimum <= 0n) {
52
+ return false;
53
+ }
54
+ if (minReceive === minimum) {
55
+ return true;
56
+ }
57
+ const difference = minReceive > minimum ? minReceive - minimum : minimum - minReceive;
58
+ return difference * 20n <= minimum;
59
+ };
60
+ export const expectationFailures = (parsed, expectation, chainId, mask) => {
61
+ const reasons = [];
62
+ if (expectation.toChainId && parsed.destinationChainRef && parsed.destinationChainId === undefined) {
63
+ reasons.push(BRIDGE_ERRORS.TO_CHAIN_MISMATCH);
64
+ }
65
+ if (expectation.toChainId && parsed.destinationChainId !== undefined) {
66
+ const expectedChain = evmChainId(expectation.toChainId);
67
+ if (expectedChain !== undefined && parsed.destinationChainId !== expectedChain)
68
+ reasons.push(BRIDGE_ERRORS.TO_CHAIN_MISMATCH);
69
+ }
70
+ if (mask.fromToken && !sameToken(parsed.sourceToken, expectation.fromTokenId, chainId)) {
71
+ reasons.push(BRIDGE_ERRORS.FROM_TOKEN_MISMATCH);
72
+ }
73
+ if (mask.fromAmount) {
74
+ const expectedAmount = parseAmount(expectation.fromTokenRawAmount);
75
+ if (expectedAmount === undefined || !sourceAmountMatches(parsed.sourceAmount, expectedAmount)) {
76
+ reasons.push(BRIDGE_ERRORS.FROM_AMOUNT_MISMATCH);
77
+ }
78
+ }
79
+ if (mask.toToken &&
80
+ !sameToken(parsed.outputToken, expectation.toTokenId, expectation.toChainId || chainId)) {
81
+ reasons.push(BRIDGE_ERRORS.TO_TOKEN_MISMATCH);
82
+ }
83
+ if (mask.toAmount && expectation.toTokenRawAmount !== undefined) {
84
+ const quoted = parseAmount(expectation.toTokenRawAmount);
85
+ const slippage = Number(expectation.slippage);
86
+ if (quoted === undefined ||
87
+ parsed.minOutputAmount === undefined ||
88
+ !Number.isFinite(slippage) ||
89
+ !minReceiveMatches(parsed.minOutputAmount, quoted, slippage)) {
90
+ reasons.push(BRIDGE_ERRORS.MIN_RECEIVE_MISMATCH);
91
+ }
92
+ }
93
+ if (mask.receiver && !sameToken(parsed.receiver, expectation.userAddress, chainId)) {
94
+ reasons.push(BRIDGE_ERRORS.RECEIVER_MISMATCH);
95
+ }
96
+ return reasons;
97
+ };
98
+ export const finishCheck = (aggregatorId, parsed, structural, expectation, chainId, mask) => {
99
+ mask = {
100
+ ...mask,
101
+ toToken: mask.toToken && !(parsed.outputToken === undefined && parsed.outputTokenReference),
102
+ toAmount: mask.toAmount && !(parsed.minOutputAmount === undefined && parsed.outputAmountReference),
103
+ };
104
+ const expected = expectation
105
+ ? expectationFailures(parsed, expectation, chainId, mask)
106
+ : [];
107
+ const unsupportedCall = (parsed.hasDestinationCall || parsed.destinationCallData !== undefined) &&
108
+ (parsed.receiver === undefined ||
109
+ (parsed.outputToken === undefined && !parsed.outputTokenReference) ||
110
+ (parsed.minOutputAmount === undefined && !parsed.outputAmountReference));
111
+ const errors = [
112
+ ...(structural ? [structural] : []),
113
+ ...(unsupportedCall ? [BRIDGE_ERRORS.UNSUPPORTED_DESTINATION_CALL] : []),
114
+ ...expected,
115
+ ].map((error) => ({ ...error, ...parsed.diagnostics, aggregatorId, chainId, method: parsed.method,
116
+ hasDestinationCall: Boolean(parsed.hasDestinationCall || parsed.destinationCallData !== undefined) }));
117
+ const unverifiedFields = Object.entries({
118
+ sourceToken: mask.fromToken, sourceAmount: mask.fromAmount, outputToken: mask.toToken,
119
+ minOutputAmount: mask.toAmount && expectation?.toTokenRawAmount !== undefined,
120
+ receiver: mask.receiver,
121
+ }).filter(([, checked]) => !expectation || !checked).map(([field]) => field);
122
+ if (expectation?.toChainId && (parsed.destinationChainId === undefined || evmChainId(expectation.toChainId) === undefined)) {
123
+ unverifiedFields.push('destinationChainId');
124
+ }
125
+ if (errors.length) {
126
+ return { ...bridgeFailure(errors), aggregatorId, method: parsed.method, parsed, unverifiedFields };
127
+ }
128
+ return { ok: true, aggregatorId, method: parsed.method, parsed, unverifiedFields, errors: [] };
129
+ };
@@ -0,0 +1,6 @@
1
+ export declare const normalizeHex: (value: string) => string;
2
+ export declare const hexToBytes: (value: string) => Uint8Array;
3
+ export declare const bytesToHex: (bytes: Uint8Array) => string;
4
+ export declare const readSelector: (data: string) => string | null;
5
+ export declare const isZeroWord: (value?: string) => boolean;
6
+ export declare const accountFromBytes32: (word: string) => string;
@@ -0,0 +1,46 @@
1
+ import { BRIDGE_ERRORS, BridgeError } from '../errors/index.js';
2
+ const HEX = '0123456789abcdef';
3
+ export const normalizeHex = (value) => {
4
+ const hex = value.startsWith('0x') || value.startsWith('0X') ? value.slice(2) : value;
5
+ if (hex.length % 2 !== 0 || /[^0-9a-fA-F]/.test(hex)) {
6
+ throw new BridgeError(BRIDGE_ERRORS.INVALID_HEX);
7
+ }
8
+ return hex.toLowerCase();
9
+ };
10
+ export const hexToBytes = (value) => {
11
+ const hex = normalizeHex(value);
12
+ const bytes = new Uint8Array(hex.length / 2);
13
+ for (let index = 0; index < bytes.length; index += 1) {
14
+ bytes[index] = Number.parseInt(hex.slice(index * 2, index * 2 + 2), 16);
15
+ }
16
+ return bytes;
17
+ };
18
+ export const bytesToHex = (bytes) => {
19
+ let hex = '0x';
20
+ for (const byte of bytes) {
21
+ hex += HEX[byte >> 4] + HEX[byte & 15];
22
+ }
23
+ return hex;
24
+ };
25
+ export const readSelector = (data) => {
26
+ try {
27
+ const hex = normalizeHex(data || '0x');
28
+ if (hex.length < 8 || /^0+$/.test(hex.slice(0, 8))) {
29
+ return null;
30
+ }
31
+ return `0x${hex.slice(0, 8)}`;
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ };
37
+ export const isZeroWord = (value) => {
38
+ return !value || /^0x0*$/i.test(value);
39
+ };
40
+ export const accountFromBytes32 = (word) => {
41
+ const body = word.toLowerCase().replace(/^0x/, '').padStart(64, '0');
42
+ if (body.slice(0, 24) === '0'.repeat(24)) {
43
+ return `0x${body.slice(24)}`;
44
+ }
45
+ return `0x${body}`;
46
+ };
@@ -0,0 +1,20 @@
1
+ import { BridgeError } from '../errors/index.js';
2
+ import type { BridgeErrorDetail } from '../errors/index.js';
3
+ import type { BridgeAggregatorId } from '../consts.js';
4
+ import type { BridgeCallExpectation } from './expect.js';
5
+ import type { BridgeCalldataTx, BridgeCheck, DecodeHit, ParsedBridgeCall } from './types.js';
6
+ export declare const CALLDATA_AGGREGATORS: BridgeAggregatorId[];
7
+ export declare class InvalidBridgeCalldataError extends BridgeError {
8
+ readonly aggregatorId: string;
9
+ readonly chainId: string;
10
+ readonly method: string | undefined;
11
+ readonly reason: string;
12
+ constructor(aggregatorId: string, chainId: string, method: string | undefined, reason: string, errors?: BridgeErrorDetail[]);
13
+ }
14
+ export declare const hasBridgeCalldata: (tx: BridgeCalldataTx) => boolean;
15
+ /** Detailed decoding for callers that need failures instead of a nullable result. */
16
+ export declare const decodeBridgeCalldataResult: (aggregatorId: string, tx: BridgeCalldataTx) => DecodeHit;
17
+ export declare const decodeBridgeCalldata: (aggregatorId: string, tx: BridgeCalldataTx) => ParsedBridgeCall | null;
18
+ export declare const validateBridgeCalldata: (aggregatorId: string, chainId: string, tx: BridgeCalldataTx, expectation?: BridgeCallExpectation) => BridgeCheck;
19
+ export type { BridgeCallExpectation } from './expect.js';
20
+ export type { BridgeCalldataTx, BridgeCheck, BridgeTokenReference, BridgeAmountReference, ParsedBridgeCall, DecodeHit } from './types.js';
@@ -0,0 +1,85 @@
1
+ import { BRIDGE_ERRORS, BridgeError, asBridgeError, bridgeFailure } from '../errors/index.js';
2
+ import { decodeAcross, validateAcross } from './across/index.js';
3
+ import { readSelector } from './hex.js';
4
+ import { decodeLifi, validateLifi } from './lifi/index.js';
5
+ import { decodeMayan, validateMayan } from './mayan/index.js';
6
+ import { decodeRelay, validateRelay } from './relay/index.js';
7
+ import { decodeSocket, validateSocket } from './socket/index.js';
8
+ import { txCalldata, txValue } from './types.js';
9
+ import { sourceChainMismatch } from './chains.js';
10
+ import { calldataDiagnostics } from './diagnostics.js';
11
+ import { sanitizeBridgeError } from '../errors/sanitize.js';
12
+ const DECODERS = {
13
+ across: decodeAcross,
14
+ lifi: decodeLifi,
15
+ mayan: decodeMayan,
16
+ relay: decodeRelay,
17
+ socket: decodeSocket,
18
+ };
19
+ const VALIDATORS = {
20
+ across: validateAcross,
21
+ lifi: validateLifi,
22
+ mayan: validateMayan,
23
+ relay: validateRelay,
24
+ socket: validateSocket,
25
+ };
26
+ export const CALLDATA_AGGREGATORS = Object.keys(VALIDATORS);
27
+ export class InvalidBridgeCalldataError extends BridgeError {
28
+ constructor(aggregatorId, chainId, method, reason, errors) {
29
+ super(BRIDGE_ERRORS.INVALID_CALLDATA, { aggregatorId, chainId, method }, errors);
30
+ this.aggregatorId = aggregatorId;
31
+ this.chainId = chainId;
32
+ this.method = method;
33
+ this.reason = reason;
34
+ this.message = `Invalid bridge calldata for ${aggregatorId} on ${chainId}: ${reason}`;
35
+ this.name = 'InvalidBridgeCalldataError';
36
+ }
37
+ }
38
+ export const hasBridgeCalldata = (tx) => {
39
+ return readSelector(txCalldata(tx)) !== null;
40
+ };
41
+ /** Detailed decoding for callers that need failures instead of a nullable result. */
42
+ export const decodeBridgeCalldataResult = (aggregatorId, tx) => {
43
+ const context = { aggregatorId, ...calldataDiagnostics(tx.data || tx.input) };
44
+ const decode = DECODERS[aggregatorId];
45
+ if (!decode)
46
+ return bridgeFailure([{ ...BRIDGE_ERRORS.UNSUPPORTED_CALLDATA_AGGREGATOR, ...context }]);
47
+ let value;
48
+ try {
49
+ value = txValue(tx);
50
+ }
51
+ catch (error) {
52
+ return bridgeFailure(asBridgeError(error, BRIDGE_ERRORS.INVALID_TRANSACTION_VALUE, context).errors);
53
+ }
54
+ const hit = decode(txCalldata(tx), value);
55
+ return hit.ok ? hit : { ...hit, errors: hit.errors.map((error) => sanitizeBridgeError({ ...error, ...context })) };
56
+ };
57
+ export const decodeBridgeCalldata = (aggregatorId, tx) => {
58
+ const hit = decodeBridgeCalldataResult(aggregatorId, tx);
59
+ return hit.ok ? hit.parsed : null;
60
+ };
61
+ export const validateBridgeCalldata = (aggregatorId, chainId, tx, expectation) => {
62
+ const context = { aggregatorId, chainId, toChainId: expectation?.toChainId, ...calldataDiagnostics(tx.data || tx.input) };
63
+ if (sourceChainMismatch(chainId, tx.chainId))
64
+ return { ...bridgeFailure([{ ...BRIDGE_ERRORS.FROM_CHAIN_MISMATCH, ...context }]), aggregatorId };
65
+ if (expectation && tx.from !== undefined &&
66
+ (typeof tx.from !== 'string' || tx.from.toLowerCase() !== expectation.userAddress.toLowerCase())) {
67
+ return { ...bridgeFailure([{ ...BRIDGE_ERRORS.FROM_ADDRESS_MISMATCH, ...context }]), aggregatorId };
68
+ }
69
+ const validate = VALIDATORS[aggregatorId];
70
+ if (!validate) {
71
+ return {
72
+ ...bridgeFailure([{ ...BRIDGE_ERRORS.UNSUPPORTED_CALLDATA_AGGREGATOR, ...context }]),
73
+ aggregatorId,
74
+ };
75
+ }
76
+ let value;
77
+ try {
78
+ value = txValue(tx);
79
+ }
80
+ catch (error) {
81
+ return { ...bridgeFailure(asBridgeError(error, BRIDGE_ERRORS.INVALID_TRANSACTION_VALUE, context).errors), aggregatorId };
82
+ }
83
+ const check = validate(txCalldata(tx), value, expectation, chainId);
84
+ return { ...check, errors: check.errors.map((error) => sanitizeBridgeError({ ...error, ...context })) };
85
+ };
@@ -0,0 +1,2 @@
1
+ import type { CalldataMethod } from '../../abi.js';
2
+ export declare const startBridgeTokensViaAcrossV4ERC20Min: CalldataMethod;
@@ -0,0 +1,26 @@
1
+ import { asBigint, asRecord, asString, decodeCall } from '../../abi.js';
2
+ import { accountFromBytes32 } from '../../hex.js';
3
+ import { acrossPackedParam } from '../params.js';
4
+ export const startBridgeTokensViaAcrossV4ERC20Min = {
5
+ name: 'startBridgeTokensViaAcrossV4ERC20Min',
6
+ selector: '0x7260352d',
7
+ decode(data) {
8
+ const args = decodeCall([
9
+ acrossPackedParam,
10
+ { name: 'sendingAssetId', kind: 'bytes', size: 32 },
11
+ { name: 'inputAmount', kind: 'uint' },
12
+ ], data);
13
+ const parameters = asRecord(args.parameters);
14
+ return {
15
+ aggregatorId: 'lifi',
16
+ method: 'startBridgeTokensViaAcrossV4ERC20Min',
17
+ kind: 'bridge',
18
+ sourceToken: accountFromBytes32(asString(args.sendingAssetId)),
19
+ sourceAmount: asBigint(args.inputAmount),
20
+ destinationChainId: asBigint(parameters.destinationChainId),
21
+ receiver: accountFromBytes32(asString(parameters.receiver)),
22
+ outputToken: accountFromBytes32(asString(parameters.receivingAssetId)),
23
+ minOutputAmount: asBigint(parameters.outputAmount),
24
+ };
25
+ },
26
+ };
@@ -0,0 +1,2 @@
1
+ import type { CalldataMethod } from '../../abi.js';
2
+ export declare const startBridgeTokensViaAcrossV4NativeMin: CalldataMethod;
@@ -0,0 +1,22 @@
1
+ import { asBigint, asRecord, asString, decodeCall } from '../../abi.js';
2
+ import { accountFromBytes32 } from '../../hex.js';
3
+ import { acrossPackedParam } from '../params.js';
4
+ export const startBridgeTokensViaAcrossV4NativeMin = {
5
+ name: 'startBridgeTokensViaAcrossV4NativeMin',
6
+ selector: '0x72dd147e',
7
+ decode(data, value) {
8
+ const args = decodeCall([acrossPackedParam], data);
9
+ const parameters = asRecord(args.parameters);
10
+ return {
11
+ aggregatorId: 'lifi',
12
+ method: 'startBridgeTokensViaAcrossV4NativeMin',
13
+ kind: 'bridge',
14
+ sourceToken: '0x0000000000000000000000000000000000000000',
15
+ sourceAmount: value,
16
+ destinationChainId: asBigint(parameters.destinationChainId),
17
+ receiver: accountFromBytes32(asString(parameters.receiver)),
18
+ outputToken: accountFromBytes32(asString(parameters.receivingAssetId)),
19
+ minOutputAmount: asBigint(parameters.outputAmount),
20
+ };
21
+ },
22
+ };
@@ -0,0 +1,6 @@
1
+ import type { CalldataMethod } from '../../abi.js';
2
+ import type { CompareMask } from '../../expect.js';
3
+ import type { ParsedBridgeCall } from '../../types.js';
4
+ export declare const methods: CalldataMethod[];
5
+ export declare const compare: (parsed: ParsedBridgeCall) => CompareMask;
6
+ export declare const check: (parsed: ParsedBridgeCall) => import("../../../index.js").BridgeErrorDefinition | undefined;
@@ -0,0 +1,19 @@
1
+ import { bridgeShape } from '../shape.js';
2
+ import { startBridgeTokensViaAcrossV4ERC20Min } from './acrossV4Erc20Min.js';
3
+ import { startBridgeTokensViaAcrossV4NativeMin } from './acrossV4NativeMin.js';
4
+ import { acrossDataParam, applyAcrossData } from '../params.js';
5
+ import { lifiBridgeMethod } from '../method.js';
6
+ export const methods = [
7
+ lifiBridgeMethod('startBridgeTokensViaAcrossV4', '0xa1f1ce43', [acrossDataParam], false, (parsed, args) => applyAcrossData(parsed, args.acrossData)),
8
+ lifiBridgeMethod('swapAndStartBridgeTokensViaAcrossV4', '0x1794958f', [acrossDataParam], true, (parsed, args) => applyAcrossData(parsed, args.acrossData)),
9
+ startBridgeTokensViaAcrossV4ERC20Min,
10
+ startBridgeTokensViaAcrossV4NativeMin,
11
+ ];
12
+ export const compare = (parsed) => ({
13
+ fromToken: parsed.sourceToken !== undefined,
14
+ fromAmount: parsed.sourceAmount !== undefined,
15
+ toToken: true,
16
+ toAmount: true,
17
+ receiver: true,
18
+ });
19
+ export const check = bridgeShape;