@rabby-wallet/rabby-bridge 0.0.13 → 0.0.14-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 (200) hide show
  1. package/README.md +163 -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 +34 -0
  20. package/dist/calldata/chains.d.ts +2 -0
  21. package/dist/calldata/chains.js +36 -0
  22. package/dist/calldata/destination.d.ts +6 -0
  23. package/dist/calldata/destination.js +227 -0
  24. package/dist/calldata/destinationSwap.d.ts +14 -0
  25. package/dist/calldata/destinationSwap.js +83 -0
  26. package/dist/calldata/destinationUniswap.d.ts +7 -0
  27. package/dist/calldata/destinationUniswap.js +57 -0
  28. package/dist/calldata/diagnostics.d.ts +4 -0
  29. package/dist/calldata/diagnostics.js +18 -0
  30. package/dist/calldata/expect.d.ts +29 -0
  31. package/dist/calldata/expect.js +157 -0
  32. package/dist/calldata/hex.d.ts +6 -0
  33. package/dist/calldata/hex.js +46 -0
  34. package/dist/calldata/index.d.ts +20 -0
  35. package/dist/calldata/index.js +88 -0
  36. package/dist/calldata/lifi/across/acrossV4Erc20Min.d.ts +2 -0
  37. package/dist/calldata/lifi/across/acrossV4Erc20Min.js +27 -0
  38. package/dist/calldata/lifi/across/acrossV4NativeMin.d.ts +2 -0
  39. package/dist/calldata/lifi/across/acrossV4NativeMin.js +23 -0
  40. package/dist/calldata/lifi/across/index.d.ts +6 -0
  41. package/dist/calldata/lifi/across/index.js +19 -0
  42. package/dist/calldata/lifi/allbridge/index.d.ts +3 -0
  43. package/dist/calldata/lifi/allbridge/index.js +26 -0
  44. package/dist/calldata/lifi/celer/index.d.ts +4 -0
  45. package/dist/calldata/lifi/celer/index.js +10 -0
  46. package/dist/calldata/lifi/centrifuge/index.d.ts +3 -0
  47. package/dist/calldata/lifi/centrifuge/index.js +22 -0
  48. package/dist/calldata/lifi/destination.d.ts +5 -0
  49. package/dist/calldata/lifi/destination.js +40 -0
  50. package/dist/calldata/lifi/frax/index.d.ts +4 -0
  51. package/dist/calldata/lifi/frax/index.js +29 -0
  52. package/dist/calldata/lifi/garden/index.d.ts +3 -0
  53. package/dist/calldata/lifi/garden/index.js +22 -0
  54. package/dist/calldata/lifi/gaszip/index.d.ts +6 -0
  55. package/dist/calldata/lifi/gaszip/index.js +15 -0
  56. package/dist/calldata/lifi/index.d.ts +4 -0
  57. package/dist/calldata/lifi/index.js +62 -0
  58. package/dist/calldata/lifi/intents/index.d.ts +4 -0
  59. package/dist/calldata/lifi/intents/index.js +10 -0
  60. package/dist/calldata/lifi/layerswap/index.d.ts +4 -0
  61. package/dist/calldata/lifi/layerswap/index.js +10 -0
  62. package/dist/calldata/lifi/m0/index.d.ts +3 -0
  63. package/dist/calldata/lifi/m0/index.js +33 -0
  64. package/dist/calldata/lifi/mayan/index.d.ts +4 -0
  65. package/dist/calldata/lifi/mayan/index.js +10 -0
  66. package/dist/calldata/lifi/method.d.ts +6 -0
  67. package/dist/calldata/lifi/method.js +16 -0
  68. package/dist/calldata/lifi/native/index.d.ts +4 -0
  69. package/dist/calldata/lifi/native/index.js +80 -0
  70. package/dist/calldata/lifi/params.d.ts +28 -0
  71. package/dist/calldata/lifi/params.js +349 -0
  72. package/dist/calldata/lifi/paxos/index.d.ts +4 -0
  73. package/dist/calldata/lifi/paxos/index.js +10 -0
  74. package/dist/calldata/lifi/polymer/index.d.ts +4 -0
  75. package/dist/calldata/lifi/polymer/index.js +10 -0
  76. package/dist/calldata/lifi/relay/index.d.ts +6 -0
  77. package/dist/calldata/lifi/relay/index.js +15 -0
  78. package/dist/calldata/lifi/shape.d.ts +4 -0
  79. package/dist/calldata/lifi/shape.js +31 -0
  80. package/dist/calldata/lifi/squid/index.d.ts +6 -0
  81. package/dist/calldata/lifi/squid/index.js +15 -0
  82. package/dist/calldata/lifi/stargate/index.d.ts +5 -0
  83. package/dist/calldata/lifi/stargate/index.js +15 -0
  84. package/dist/calldata/lifi/swap/index.d.ts +5 -0
  85. package/dist/calldata/lifi/swap/index.js +18 -0
  86. package/dist/calldata/lifi/swap/swapMethod.d.ts +2 -0
  87. package/dist/calldata/lifi/swap/swapMethod.js +40 -0
  88. package/dist/calldata/lifi/swapData.d.ts +5 -0
  89. package/dist/calldata/lifi/swapData.js +33 -0
  90. package/dist/calldata/match.d.ts +3 -0
  91. package/dist/calldata/match.js +21 -0
  92. package/dist/calldata/mayan/destination.d.ts +2 -0
  93. package/dist/calldata/mayan/destination.js +13 -0
  94. package/dist/calldata/mayan/fastMctpBridge.d.ts +3 -0
  95. package/dist/calldata/mayan/fastMctpBridge.js +48 -0
  96. package/dist/calldata/mayan/fastMctpCreateOrder.d.ts +3 -0
  97. package/dist/calldata/mayan/fastMctpCreateOrder.js +39 -0
  98. package/dist/calldata/mayan/forward.d.ts +8 -0
  99. package/dist/calldata/mayan/forward.js +35 -0
  100. package/dist/calldata/mayan/forwardERC20.d.ts +2 -0
  101. package/dist/calldata/mayan/forwardERC20.js +19 -0
  102. package/dist/calldata/mayan/forwardEth.d.ts +2 -0
  103. package/dist/calldata/mayan/forwardEth.js +16 -0
  104. package/dist/calldata/mayan/index.d.ts +4 -0
  105. package/dist/calldata/mayan/index.js +21 -0
  106. package/dist/calldata/mayan/mctp.d.ts +5 -0
  107. package/dist/calldata/mayan/mctp.js +41 -0
  108. package/dist/calldata/mayan/readProtocol.d.ts +2 -0
  109. package/dist/calldata/mayan/readProtocol.js +29 -0
  110. package/dist/calldata/mayan/swapAndForwardERC20.d.ts +2 -0
  111. package/dist/calldata/mayan/swapAndForwardERC20.js +24 -0
  112. package/dist/calldata/mayan/swapAndForwardEth.d.ts +2 -0
  113. package/dist/calldata/mayan/swapAndForwardEth.js +23 -0
  114. package/dist/calldata/mayan/swiftCreateOrder.d.ts +3 -0
  115. package/dist/calldata/mayan/swiftCreateOrder.js +49 -0
  116. package/dist/calldata/mayan/validate.d.ts +3 -0
  117. package/dist/calldata/mayan/validate.js +20 -0
  118. package/dist/calldata/protocols.d.ts +9 -0
  119. package/dist/calldata/protocols.js +58 -0
  120. package/dist/calldata/relay/calls.d.ts +13 -0
  121. package/dist/calldata/relay/calls.js +58 -0
  122. package/dist/calldata/relay/depositErc20.d.ts +2 -0
  123. package/dist/calldata/relay/depositErc20.js +22 -0
  124. package/dist/calldata/relay/depositErc20Allowance.d.ts +2 -0
  125. package/dist/calldata/relay/depositErc20Allowance.js +20 -0
  126. package/dist/calldata/relay/depositNative.d.ts +2 -0
  127. package/dist/calldata/relay/depositNative.js +20 -0
  128. package/dist/calldata/relay/index.d.ts +4 -0
  129. package/dist/calldata/relay/index.js +45 -0
  130. package/dist/calldata/relay/multicall.d.ts +2 -0
  131. package/dist/calldata/relay/multicall.js +15 -0
  132. package/dist/calldata/relay/nestedDeposit.d.ts +8 -0
  133. package/dist/calldata/relay/nestedDeposit.js +107 -0
  134. package/dist/calldata/relay/permit2TransferAndMulticall.d.ts +2 -0
  135. package/dist/calldata/relay/permit2TransferAndMulticall.js +42 -0
  136. package/dist/calldata/relay/permit3009TransferAndMulticall.d.ts +2 -0
  137. package/dist/calldata/relay/permit3009TransferAndMulticall.js +41 -0
  138. package/dist/calldata/relay/permit3009TransferAndMulticallSigned.d.ts +2 -0
  139. package/dist/calldata/relay/permit3009TransferAndMulticallSigned.js +40 -0
  140. package/dist/calldata/relay/permitTransferAndMulticall.d.ts +2 -0
  141. package/dist/calldata/relay/permitTransferAndMulticall.js +34 -0
  142. package/dist/calldata/relay/permitTransferAndMulticallLegacy.d.ts +2 -0
  143. package/dist/calldata/relay/permitTransferAndMulticallLegacy.js +35 -0
  144. package/dist/calldata/relay/transferAndMulticall.d.ts +2 -0
  145. package/dist/calldata/relay/transferAndMulticall.js +26 -0
  146. package/dist/calldata/relay/validate.d.ts +3 -0
  147. package/dist/calldata/relay/validate.js +18 -0
  148. package/dist/calldata/resolve.d.ts +2 -0
  149. package/dist/calldata/resolve.js +28 -0
  150. package/dist/calldata/socket/addresses.d.ts +9 -0
  151. package/dist/calldata/socket/addresses.js +9 -0
  152. package/dist/calldata/socket/bridge.d.ts +2 -0
  153. package/dist/calldata/socket/bridge.js +28 -0
  154. package/dist/calldata/socket/exec.d.ts +2 -0
  155. package/dist/calldata/socket/exec.js +71 -0
  156. package/dist/calldata/socket/index.d.ts +4 -0
  157. package/dist/calldata/socket/index.js +13 -0
  158. package/dist/calldata/socket/params.d.ts +5 -0
  159. package/dist/calldata/socket/params.js +14 -0
  160. package/dist/calldata/socket/protocols/ccip.d.ts +2 -0
  161. package/dist/calldata/socket/protocols/ccip.js +32 -0
  162. package/dist/calldata/socket/protocols/cctp.d.ts +2 -0
  163. package/dist/calldata/socket/protocols/cctp.js +25 -0
  164. package/dist/calldata/socket/protocols/eco.d.ts +2 -0
  165. package/dist/calldata/socket/protocols/eco.js +49 -0
  166. package/dist/calldata/socket/protocols/index.d.ts +3 -0
  167. package/dist/calldata/socket/protocols/index.js +87 -0
  168. package/dist/calldata/socket/protocols/native.d.ts +2 -0
  169. package/dist/calldata/socket/protocols/native.js +71 -0
  170. package/dist/calldata/socket/protocols/oft.d.ts +2 -0
  171. package/dist/calldata/socket/protocols/oft.js +33 -0
  172. package/dist/calldata/socket/protocols/swapsXYZ.d.ts +2 -0
  173. package/dist/calldata/socket/protocols/swapsXYZ.js +62 -0
  174. package/dist/calldata/socket/swapAndBridge.d.ts +2 -0
  175. package/dist/calldata/socket/swapAndBridge.js +41 -0
  176. package/dist/calldata/socket/validate.d.ts +3 -0
  177. package/dist/calldata/socket/validate.js +24 -0
  178. package/dist/calldata/types.d.ts +86 -0
  179. package/dist/calldata/types.js +20 -0
  180. package/dist/errors/constants.d.ts +906 -0
  181. package/dist/errors/constants.js +913 -0
  182. package/dist/errors/index.d.ts +65 -0
  183. package/dist/errors/index.js +53 -0
  184. package/dist/errors/sanitize.d.ts +3 -0
  185. package/dist/errors/sanitize.js +74 -0
  186. package/dist/index.d.ts +6 -1
  187. package/dist/index.js +3 -0
  188. package/dist/providers/data.d.ts +23 -0
  189. package/dist/providers/data.js +116 -0
  190. package/dist/providers/errors.d.ts +7 -0
  191. package/dist/providers/errors.js +10 -0
  192. package/dist/providers/layerswap.d.ts +9 -0
  193. package/dist/providers/layerswap.js +95 -0
  194. package/dist/providers/relay.d.ts +62 -0
  195. package/dist/providers/relay.js +237 -0
  196. package/dist/providers/socket.d.ts +5 -0
  197. package/dist/providers/socket.js +58 -0
  198. package/dist/quote.d.ts +30 -3
  199. package/dist/quote.js +236 -66
  200. package/package.json +13 -3
@@ -0,0 +1,40 @@
1
+ import { asArray, asString, decodeCall } from '../abi.js';
2
+ import { callsParam, firstPositive, relayCall } from './calls.js';
3
+ const permits = {
4
+ name: 'permits',
5
+ kind: 'array',
6
+ item: {
7
+ name: 'permit',
8
+ kind: 'tuple',
9
+ components: [
10
+ { name: 'from', kind: 'address' },
11
+ { name: 'value', kind: 'uint' },
12
+ { name: 'validAfter', kind: 'uint' },
13
+ { name: 'validBefore', kind: 'uint' },
14
+ { name: 'v', kind: 'uint' },
15
+ { name: 'r', kind: 'bytes', size: 32 },
16
+ { name: 's', kind: 'bytes', size: 32 },
17
+ ],
18
+ },
19
+ };
20
+ export const permit3009TransferAndMulticallSigned = {
21
+ name: 'permit3009TransferAndMulticallSigned',
22
+ selector: '0x745599f3',
23
+ decode(data, value) {
24
+ const args = decodeCall([
25
+ permits,
26
+ { name: 'tokens', kind: 'array', item: { name: 'token', kind: 'address' } },
27
+ callsParam,
28
+ { name: 'refundTo', kind: 'address' },
29
+ { name: 'nftRecipient', kind: 'address' },
30
+ { name: 'metadata', kind: 'bytes' },
31
+ { name: 'multicallSignatures', kind: 'array', item: { name: 'signature', kind: 'bytes' } },
32
+ ], data);
33
+ const source = firstPositive(asArray(args.permits));
34
+ const tokens = asArray(args.tokens).map((token) => asString(token));
35
+ return relayCall('permit3009TransferAndMulticallSigned', asString(args.metadata), value, args.calls, {
36
+ token: tokens[0] ?? source.token,
37
+ amount: source.amount,
38
+ });
39
+ },
40
+ };
@@ -0,0 +1,2 @@
1
+ import type { CalldataMethod } from '../abi.js';
2
+ export declare const permitTransferAndMulticall: CalldataMethod;
@@ -0,0 +1,34 @@
1
+ import { asArray, asString, decodeCall } from '../abi.js';
2
+ import { callsParam, firstPositive, relayCall } from './calls.js';
3
+ const permits = {
4
+ name: 'permits',
5
+ kind: 'array',
6
+ item: {
7
+ name: 'permit',
8
+ kind: 'tuple',
9
+ components: [
10
+ { name: 'token', kind: 'address' },
11
+ { name: 'owner', kind: 'address' },
12
+ { name: 'value', kind: 'uint' },
13
+ { name: 'deadline', kind: 'uint' },
14
+ { name: 'v', kind: 'uint' },
15
+ { name: 'r', kind: 'bytes', size: 32 },
16
+ { name: 's', kind: 'bytes', size: 32 },
17
+ ],
18
+ },
19
+ };
20
+ export const permitTransferAndMulticall = {
21
+ name: 'permitTransferAndMulticall',
22
+ selector: '0xbd4967a9',
23
+ decode(data, value) {
24
+ const args = decodeCall([
25
+ permits,
26
+ callsParam,
27
+ { name: 'refundTo', kind: 'address' },
28
+ { name: 'nftRecipient', kind: 'address' },
29
+ { name: 'metadata', kind: 'bytes' },
30
+ ], data);
31
+ const source = firstPositive(asArray(args.permits));
32
+ return relayCall('permitTransferAndMulticall', asString(args.metadata), value, args.calls, source);
33
+ },
34
+ };
@@ -0,0 +1,2 @@
1
+ import type { CalldataMethod } from '../abi.js';
2
+ export declare const permitTransferAndMulticallLegacy: CalldataMethod;
@@ -0,0 +1,35 @@
1
+ import { asArray, asString, decodeCall } from '../abi.js';
2
+ import { callsParam, firstPositive, relayCall } from './calls.js';
3
+ const permits = {
4
+ name: 'permits',
5
+ kind: 'array',
6
+ item: {
7
+ name: 'permit',
8
+ kind: 'tuple',
9
+ components: [
10
+ { name: 'token', kind: 'address' },
11
+ { name: 'owner', kind: 'address' },
12
+ { name: 'value', kind: 'uint' },
13
+ { name: 'nonce', kind: 'uint' },
14
+ { name: 'deadline', kind: 'uint' },
15
+ { name: 'v', kind: 'uint' },
16
+ { name: 'r', kind: 'bytes', size: 32 },
17
+ { name: 's', kind: 'bytes', size: 32 },
18
+ ],
19
+ },
20
+ };
21
+ export const permitTransferAndMulticallLegacy = {
22
+ name: 'permitTransferAndMulticallLegacy',
23
+ selector: '0xfb68c293',
24
+ decode(data, value) {
25
+ const args = decodeCall([
26
+ permits,
27
+ callsParam,
28
+ { name: 'refundTo', kind: 'address' },
29
+ { name: 'nftRecipient', kind: 'address' },
30
+ { name: 'metadata', kind: 'bytes' },
31
+ ], data);
32
+ const source = firstPositive(asArray(args.permits));
33
+ return relayCall('permitTransferAndMulticallLegacy', asString(args.metadata), value, args.calls, source);
34
+ },
35
+ };
@@ -0,0 +1,2 @@
1
+ import type { CalldataMethod } from '../abi.js';
2
+ export declare const transferAndMulticall: CalldataMethod;
@@ -0,0 +1,26 @@
1
+ import { BRIDGE_ERRORS, BridgeError } from '../../errors/index.js';
2
+ import { asArray, asBigint, asString, decodeCall } from '../abi.js';
3
+ import { callsParam, relayCall } from './calls.js';
4
+ export const transferAndMulticall = {
5
+ name: 'transferAndMulticall',
6
+ selector: '0xf9e4bab4',
7
+ decode(data, value) {
8
+ const args = decodeCall([
9
+ { name: 'tokens', kind: 'array', item: { name: 'token', kind: 'address' } },
10
+ { name: 'amounts', kind: 'array', item: { name: 'amount', kind: 'uint' } },
11
+ callsParam,
12
+ { name: 'refundTo', kind: 'address' },
13
+ { name: 'nftRecipient', kind: 'address' },
14
+ { name: 'metadata', kind: 'bytes' },
15
+ ], data);
16
+ const tokens = asArray(args.tokens).map((token) => asString(token));
17
+ const amounts = asArray(args.amounts).map((amount) => asBigint(amount));
18
+ if (tokens.length !== amounts.length || new Set(tokens).size > 1) {
19
+ throw new BridgeError(BRIDGE_ERRORS.UNSUPPORTED_RELAY_SOURCE_ASSET_LIST);
20
+ }
21
+ return relayCall('transferAndMulticall', asString(args.metadata), value, args.calls, {
22
+ token: tokens[0],
23
+ amount: amounts.reduce((sum, amount) => sum + amount, 0n),
24
+ });
25
+ },
26
+ };
@@ -0,0 +1,3 @@
1
+ import type { BridgeErrorDefinition } from '../../errors/index.js';
2
+ import type { ParsedBridgeCall } from '../types.js';
3
+ export declare const relayFailure: (parsed: ParsedBridgeCall) => BridgeErrorDefinition | undefined;
@@ -0,0 +1,18 @@
1
+ import { BRIDGE_ERRORS } from '../../errors/index.js';
2
+ import { isZeroWord } from '../hex.js';
3
+ const AMOUNT_OPTIONAL = new Set(['depositErc20Allowance', 'multicall']);
4
+ export const relayFailure = (parsed) => {
5
+ if (isZeroWord(parsed.orderId) && isZeroWord(parsed.requestId)) {
6
+ return BRIDGE_ERRORS.MISSING_RELAY_ORDER_ID;
7
+ }
8
+ if (AMOUNT_OPTIONAL.has(parsed.method)) {
9
+ return undefined;
10
+ }
11
+ if ((parsed.sourceAmount ?? 0n) <= 0n) {
12
+ return BRIDGE_ERRORS.MISSING_SOURCE_AMOUNT;
13
+ }
14
+ if (parsed.sourceToken === undefined) {
15
+ return BRIDGE_ERRORS.MISSING_SOURCE_TOKEN;
16
+ }
17
+ return undefined;
18
+ };
@@ -0,0 +1,2 @@
1
+ import type { ParsedBridgeCall } from './types.js';
2
+ export declare const resolveParsed: (parsed: ParsedBridgeCall) => ParsedBridgeCall;
@@ -0,0 +1,28 @@
1
+ import { CCTP_USDC, isNative } from './protocols.js';
2
+ const tokenInfo = (reference) => {
3
+ if (reference.protocol === 'cctp' && reference.destinationChainId !== undefined) {
4
+ const token = CCTP_USDC[reference.destinationChainId.toString()];
5
+ if (token)
6
+ return { token, decimals: 6 };
7
+ }
8
+ if (reference.protocol === 'token' && reference.token && isNative(reference.token)) {
9
+ return { token: reference.token, decimals: 18 };
10
+ }
11
+ return undefined;
12
+ };
13
+ export const resolveParsed = (parsed) => {
14
+ const info = parsed.outputTokenReference ? tokenInfo(parsed.outputTokenReference) : undefined;
15
+ if (info)
16
+ parsed.outputToken = info.token;
17
+ const amount = parsed.outputAmountReference;
18
+ if (amount?.kind === 'normalized' && parsed.minOutputAmount === undefined) {
19
+ const metadata = tokenInfo(amount.token);
20
+ if (metadata) {
21
+ const sourceDecimals = Math.min(metadata.decimals, amount.decimals ?? 8);
22
+ parsed.minOutputAmount = amount.amount * 10n ** BigInt(metadata.decimals - sourceDecimals);
23
+ }
24
+ }
25
+ parsed.unresolvedFields = ['sourceToken', 'sourceAmount', 'outputToken', 'minOutputAmount', 'receiver']
26
+ .filter((field) => parsed[field] === undefined);
27
+ return parsed;
28
+ };
@@ -0,0 +1,9 @@
1
+ /** Source vault that receives every Socket RFQ deposit. Not the destination recipient. */
2
+ export declare const SOCKET_RFQ_VAULT = "0x97caca78ac2a94c67643d07843f85afaa44a3ea5";
3
+ /** Circle TokenMessenger V2 used by Socket CCTP. The same address on each EVM chain. */
4
+ export declare const SOCKET_CCTP_MESSENGER = "0x28b5a0e9c621a5badaa536219b3a228c8168cf5d";
5
+ /**
6
+ * Fixed destination mint recipient for Socket CCTP.
7
+ * The user's wallet is in a destination signature, not this field.
8
+ */
9
+ export declare const SOCKET_CCTP_MINT_RECIPIENT = "0x424a31a57f7c63918ecaa2fac38016a8af5a6ec2";
@@ -0,0 +1,9 @@
1
+ /** Source vault that receives every Socket RFQ deposit. Not the destination recipient. */
2
+ export const SOCKET_RFQ_VAULT = '0x97caca78ac2a94c67643d07843f85afaa44a3ea5';
3
+ /** Circle TokenMessenger V2 used by Socket CCTP. The same address on each EVM chain. */
4
+ export const SOCKET_CCTP_MESSENGER = '0x28b5a0e9c621a5badaa536219b3a228c8168cf5d';
5
+ /**
6
+ * Fixed destination mint recipient for Socket CCTP.
7
+ * The user's wallet is in a destination signature, not this field.
8
+ */
9
+ export const SOCKET_CCTP_MINT_RECIPIENT = '0x424a31a57f7c63918ecaa2fac38016a8af5a6ec2';
@@ -0,0 +1,2 @@
1
+ import type { CalldataMethod } from '../abi.js';
2
+ export declare const bridge: CalldataMethod;
@@ -0,0 +1,28 @@
1
+ import { BRIDGE_ERRORS, BridgeError } from '../../errors/index.js';
2
+ import { asBigint, asRecord, asString, decodeCall } from '../abi.js';
3
+ import { subtractFees } from '../protocols.js';
4
+ import { bridgeData, fee, input } from './params.js';
5
+ import { readSocketBridge } from './protocols/index.js';
6
+ export const bridge = {
7
+ name: 'bridge', selector: '0xb18248d5',
8
+ decode(data) {
9
+ const a = decodeCall([{ name: 'quoteId', kind: 'bytes', size: 32 }, input, fee, bridgeData,
10
+ { name: 'bridgeCallData', kind: 'bytes' }], data);
11
+ const source = asRecord(a.input);
12
+ const hop = asRecord(a.bridgeData);
13
+ const target = asString(hop.target);
14
+ const token = asString(source.inputToken);
15
+ const amount = subtractFees(asBigint(source.inputAmount), asBigint(asRecord(a.fee).amount));
16
+ const protocol = readSocketBridge(asString(a.bridgeCallData), target, token, asBigint(hop.value), asString(hop.approvalSpender));
17
+ if (['receiveERC20', 'receiveNative', 'depositForBurn'].includes(protocol?.protocolMethod ?? '') && protocol?.bridgeAmount !== amount) {
18
+ throw new BridgeError(BRIDGE_ERRORS.SOCKET_DEPOSIT_AMOUNT_MISMATCH, protocol?.diagnostics);
19
+ }
20
+ return {
21
+ aggregatorId: 'socket', method: 'bridge', kind: 'bridge', quoteId: asString(a.quoteId),
22
+ sourceToken: token, sourceAmount: asBigint(source.inputAmount), depositor: asString(source.user),
23
+ bridgeToken: token, bridgeAmount: amount,
24
+ referrer: asString(asRecord(a.fee).receiver), innerTarget: target,
25
+ ...protocol,
26
+ };
27
+ },
28
+ };
@@ -0,0 +1,2 @@
1
+ import type { CalldataMethod } from '../abi.js';
2
+ export declare const exec: CalldataMethod;
@@ -0,0 +1,71 @@
1
+ import { BRIDGE_ERRORS, BridgeError, asBridgeError } from '../../errors/index.js';
2
+ import { innerCallDiagnostics } from '../diagnostics.js';
3
+ import { asBigint, asString, decodeCall } from '../abi.js';
4
+ import { readSelector } from '../hex.js';
5
+ import { bridge } from './bridge.js';
6
+ import { swapAndBridge } from './swapAndBridge.js';
7
+ import { isNative, NATIVE_TOKEN } from '../protocols.js';
8
+ const readInner = (data, value) => {
9
+ const selector = readSelector(data);
10
+ if (selector === bridge.selector) {
11
+ return bridge.decode(data, value);
12
+ }
13
+ if (selector === swapAndBridge.selector) {
14
+ return swapAndBridge.decode(data, value);
15
+ }
16
+ return undefined;
17
+ };
18
+ export const exec = {
19
+ name: 'exec',
20
+ selector: '0x2213bc0b',
21
+ decode(data, value) {
22
+ const args = decodeCall([
23
+ { name: 'operator', kind: 'address' },
24
+ { name: 'token', kind: 'address' },
25
+ { name: 'amount', kind: 'uint' },
26
+ { name: 'target', kind: 'address' },
27
+ { name: 'data', kind: 'bytes' },
28
+ ], data);
29
+ const target = asString(args.target);
30
+ const diagnostics = innerCallDiagnostics(asString(args.data), 'router');
31
+ if (target !== '0x50cfe7c1938db66a1a6d2e86d36f39fbef3d5c4a' || asString(args.operator) !== target) {
32
+ throw new BridgeError(BRIDGE_ERRORS.UNSUPPORTED_SOCKET_OPERATOR_OR_ROUTER, diagnostics);
33
+ }
34
+ let inner;
35
+ try {
36
+ inner = readInner(asString(args.data), value);
37
+ }
38
+ catch (error) {
39
+ throw asBridgeError(error, BRIDGE_ERRORS.CALLDATA_DECODE_FAILED, diagnostics);
40
+ }
41
+ if (!inner) {
42
+ return {
43
+ aggregatorId: 'socket',
44
+ method: 'exec',
45
+ kind: 'bridge',
46
+ sourceToken: asString(args.token),
47
+ sourceAmount: asBigint(args.amount),
48
+ innerTarget: asString(args.target),
49
+ diagnostics,
50
+ };
51
+ }
52
+ const token = asString(args.token);
53
+ if (inner.sourceToken !== token && !(isNative(token) && isNative(inner.sourceToken ?? ''))) {
54
+ throw new BridgeError(BRIDGE_ERRORS.SOCKET_ALLOWANCE_TOKEN_MISMATCH, { ...inner.diagnostics, ...diagnostics });
55
+ }
56
+ if (!isNative(token) && asBigint(args.amount) !== inner.sourceAmount) {
57
+ throw new BridgeError(BRIDGE_ERRORS.SOCKET_ALLOWANCE_AMOUNT_MISMATCH, { ...inner.diagnostics, ...diagnostics });
58
+ }
59
+ if (['receiveERC20', 'receiveNative', 'depositForBurn'].includes(inner.protocolMethod ?? '') &&
60
+ value !== (isNative(token) ? inner.sourceAmount : 0n)) {
61
+ throw new BridgeError(BRIDGE_ERRORS.SOCKET_NATIVE_VALUE_MISMATCH, { ...inner.diagnostics, ...diagnostics });
62
+ }
63
+ return {
64
+ ...inner,
65
+ diagnostics: { ...inner.diagnostics, ...diagnostics },
66
+ sourceToken: isNative(inner.sourceToken ?? token) ? NATIVE_TOKEN : inner.sourceToken ?? token,
67
+ sourceAmount: inner.sourceAmount ?? asBigint(args.amount),
68
+ innerTarget: inner.innerTarget ?? asString(args.target),
69
+ };
70
+ },
71
+ };
@@ -0,0 +1,4 @@
1
+ import type { BridgeCallExpectation } from '../expect.js';
2
+ import type { BridgeCheck, DecodeHit } from '../types.js';
3
+ export declare const decodeSocket: (data: string, value: bigint) => DecodeHit;
4
+ export declare const validateSocket: (data: string, value: bigint, expectation?: BridgeCallExpectation, chainId?: string) => BridgeCheck;
@@ -0,0 +1,13 @@
1
+ import { matchMethod } from '../match.js';
2
+ import { finishCheck, knownCompare } from '../expect.js';
3
+ import { exec } from './exec.js';
4
+ import { socketFailure } from './validate.js';
5
+ const METHODS = [exec];
6
+ export const decodeSocket = (data, value) => matchMethod(METHODS, data, value);
7
+ export const validateSocket = (data, value, expectation, chainId = '') => {
8
+ const hit = decodeSocket(data, value);
9
+ if (!hit.ok) {
10
+ return { ...hit, aggregatorId: 'socket' };
11
+ }
12
+ return finishCheck('socket', hit.parsed, socketFailure(hit.parsed, expectation?.userAddress), expectation, chainId, knownCompare(hit.parsed));
13
+ };
@@ -0,0 +1,5 @@
1
+ import type { AbiParam } from '../abi.js';
2
+ export declare const input: AbiParam;
3
+ export declare const fee: AbiParam;
4
+ export declare const swapData: AbiParam;
5
+ export declare const bridgeData: AbiParam;
@@ -0,0 +1,14 @@
1
+ export const input = { name: 'input', kind: 'tuple', components: [
2
+ { name: 'user', kind: 'address' }, { name: 'inputToken', kind: 'address' }, { name: 'inputAmount', kind: 'uint' },
3
+ ] };
4
+ export const fee = { name: 'fee', kind: 'tuple', components: [
5
+ { name: 'receiver', kind: 'address' }, { name: 'amount', kind: 'uint' },
6
+ ] };
7
+ export const swapData = { name: 'swapData', kind: 'tuple', components: [
8
+ { name: 'target', kind: 'address' }, { name: 'approvalSpender', kind: 'address' },
9
+ { name: 'outputToken', kind: 'address' }, { name: 'value', kind: 'uint' },
10
+ { name: 'minOutput', kind: 'uint' }, { name: 'returnDataWordOffset', kind: 'uint' },
11
+ ] };
12
+ export const bridgeData = { name: 'bridgeData', kind: 'tuple', components: [
13
+ { name: 'target', kind: 'address' }, { name: 'approvalSpender', kind: 'address' }, { name: 'value', kind: 'uint' },
14
+ ] };
@@ -0,0 +1,2 @@
1
+ import type { ParsedBridgeCall } from '../../types.js';
2
+ export declare const readCcip: (data: string, target: string) => Partial<ParsedBridgeCall>;
@@ -0,0 +1,32 @@
1
+ import { BRIDGE_ERRORS, BridgeError } from '../../../errors/index.js';
2
+ import { asArray, asBigint, asRecord, asString, decodeCall, decodeParameters } from '../../abi.js';
3
+ import { CCIP_CHAINS } from '../../protocols.js';
4
+ const message = { name: 'message', kind: 'tuple', components: [
5
+ { name: 'receiver', kind: 'bytes' }, { name: 'data', kind: 'bytes' },
6
+ { name: 'tokenAmounts', kind: 'array', item: { name: 'tokenAmount', kind: 'tuple', components: [
7
+ { name: 'token', kind: 'address' }, { name: 'amount', kind: 'uint' },
8
+ ] } },
9
+ { name: 'feeToken', kind: 'address' }, { name: 'extraArgs', kind: 'bytes' },
10
+ ] };
11
+ export const readCcip = (data, target) => {
12
+ const a = decodeCall([{ name: 'destinationChainSelector', kind: 'uint' }, message], data);
13
+ const m = asRecord(a.message);
14
+ const amounts = asArray(m.tokenAmounts);
15
+ if (amounts.length !== 1)
16
+ throw new BridgeError(BRIDGE_ERRORS.CCIP_REQUIRES_ONE_BRIDGE_ASSET);
17
+ const token = asRecord(amounts[0]);
18
+ const ref = { protocol: 'ccip', contract: target, token: asString(token.token),
19
+ destinationChainId: CCIP_CHAINS[asBigint(a.destinationChainSelector).toString()],
20
+ destinationChainRef: `ccip:${asBigint(a.destinationChainSelector)}` };
21
+ const receiverData = asString(m.receiver);
22
+ const receiver = receiverData.length === 66
23
+ ? asString(decodeParameters([{ name: 'receiver', kind: 'address' }], receiverData).receiver) : undefined;
24
+ const extra = asString(m.extraArgs);
25
+ const direct = asString(m.data) === '0x' && (extra === '0x' || ['0x97a657c9', '0x181dcf10'].includes(extra.slice(0, 10)));
26
+ return { protocolMethod: 'ccipSend', destinationChainId: ref.destinationChainId,
27
+ destinationChainRef: ref.destinationChainRef, bridgeReceiver: receiver, receiver: direct ? receiver : undefined,
28
+ outputTokenReference: direct ? ref : undefined,
29
+ outputAmountReference: direct ? { kind: 'decimals', amount: asBigint(token.amount), token: ref } : undefined,
30
+ destinationCallData: direct ? undefined : asString(m.data),
31
+ };
32
+ };
@@ -0,0 +1,2 @@
1
+ import type { ParsedBridgeCall } from '../../types.js';
2
+ export declare const readCctp: (data: string) => Partial<ParsedBridgeCall>;
@@ -0,0 +1,25 @@
1
+ import { asBigint, asString, decodeCall } from '../../abi.js';
2
+ import { accountFromBytes32 } from '../../hex.js';
3
+ import { CCTP_CHAINS, CCTP_USDC, subtractFees } from '../../protocols.js';
4
+ import { SOCKET_CCTP_MINT_RECIPIENT } from '../addresses.js';
5
+ export const readCctp = (data) => {
6
+ const a = decodeCall([
7
+ { name: 'amount', kind: 'uint' }, { name: 'destinationDomain', kind: 'uint' },
8
+ { name: 'mintRecipient', kind: 'bytes', size: 32 }, { name: 'burnToken', kind: 'address' },
9
+ { name: 'destinationCaller', kind: 'bytes', size: 32 }, { name: 'maxFee', kind: 'uint' },
10
+ { name: 'minFinalityThreshold', kind: 'uint' },
11
+ ], data);
12
+ const id = asBigint(a.destinationDomain);
13
+ const destinationChainId = CCTP_CHAINS[id.toString()];
14
+ const receiver = accountFromBytes32(asString(a.mintRecipient));
15
+ const allowlisted = receiver === SOCKET_CCTP_MINT_RECIPIENT;
16
+ return { protocolMethod: 'depositForBurn', destinationChainId, destinationChainRef: `cctp:${id}`,
17
+ bridgeReceiver: receiver, receiver: allowlisted ? undefined : receiver, fixedReceiver: allowlisted,
18
+ bridgeToken: asString(a.burnToken), bridgeAmount: asBigint(a.amount),
19
+ bridgeOutputToken: CCTP_USDC[destinationChainId?.toString() ?? ''],
20
+ bridgeOutputAmount: subtractFees(asBigint(a.amount), asBigint(a.maxFee)),
21
+ outputToken: CCTP_USDC[destinationChainId?.toString() ?? ''],
22
+ minOutputAmount: allowlisted ? undefined : subtractFees(asBigint(a.amount), asBigint(a.maxFee)),
23
+ // ClaimExecutor's recipient and relay fee are signed on the destination, outside this calldata.
24
+ };
25
+ };
@@ -0,0 +1,2 @@
1
+ import type { ParsedBridgeCall } from '../../types.js';
2
+ export declare const readEco: (data: string, target: string, spender: string, value: bigint) => Partial<ParsedBridgeCall>;
@@ -0,0 +1,49 @@
1
+ import { asArray, asBigint, asRecord, asString, decodeCall, decodeParameters } from '../../abi.js';
2
+ import { destinationCall, readDestinationTransfers } from '../../destination.js';
3
+ import { readSelector } from '../../hex.js';
4
+ import { CCTP_USDC } from '../../protocols.js';
5
+ import { SOCKET_CCTP_MESSENGER } from '../addresses.js';
6
+ import { readCctp } from './cctp.js';
7
+ const tokens = { name: 'tokens', kind: 'array', item: { name: 'token', kind: 'tuple', components: [
8
+ { name: 'token', kind: 'address' }, { name: 'amount', kind: 'uint' },
9
+ ] } };
10
+ const reward = { name: 'reward', kind: 'tuple', components: [
11
+ { name: 'deadline', kind: 'uint' }, { name: 'creator', kind: 'address' }, { name: 'prover', kind: 'address' },
12
+ { name: 'nativeAmount', kind: 'uint' }, tokens,
13
+ ] };
14
+ const route = { name: 'route', kind: 'tuple', components: [
15
+ { name: 'salt', kind: 'bytes', size: 32 }, { name: 'deadline', kind: 'uint' }, { name: 'portal', kind: 'address' },
16
+ { name: 'nativeAmount', kind: 'uint' }, tokens, { name: 'calls', kind: 'array', item: destinationCall },
17
+ ] };
18
+ export const readEco = (data, target, spender, value) => {
19
+ const a = decodeCall([{ name: 'destination', kind: 'uint' }, { name: 'route', kind: 'bytes' }, reward,
20
+ { name: 'allowPartial', kind: 'bool' }], data);
21
+ const r = asRecord(decodeParameters([route], asString(a.route)).route);
22
+ const calls = asArray(r.calls).map(asRecord);
23
+ const parsed = {
24
+ protocolMethod: 'publishAndFund', destinationChainId: asBigint(a.destination),
25
+ destinationCallData: asString(a.route), ...readDestinationTransfers(calls),
26
+ };
27
+ // shortcut: the reviewed HyperEVM Portal's approve + CCTP route; review other compositions before support.
28
+ const portal = '0xec000769a73b70e16f361a442292500b3bcf4a85';
29
+ const assets = asArray(r.tokens).map(asRecord);
30
+ if (parsed.destinationChainId !== 999n || target !== portal || spender !== portal || value !== 0n ||
31
+ asString(r.portal) !== portal || asBigint(r.nativeAmount) !== 0n || assets.length !== 1 || calls.length !== 2)
32
+ return parsed;
33
+ const [approval, burn] = calls;
34
+ const token = CCTP_USDC['999'];
35
+ const amount = asBigint(assets[0].amount);
36
+ if (asString(assets[0].token) !== token || amount <= 0n || asString(approval.target) !== token ||
37
+ asBigint(approval.value) !== 0n || readSelector(asString(approval.data)) !== '0x095ea7b3' ||
38
+ asString(burn.target) !== SOCKET_CCTP_MESSENGER || asBigint(burn.value) !== 0n ||
39
+ readSelector(asString(burn.data)) !== '0x8e0250ee')
40
+ return parsed;
41
+ const approved = decodeCall([{ name: 'spender', kind: 'address' }, { name: 'amount', kind: 'uint' }], asString(approval.data));
42
+ const nested = readCctp(asString(burn.data));
43
+ if (asString(approved.spender) !== SOCKET_CCTP_MESSENGER || asBigint(approved.amount) !== amount ||
44
+ nested.bridgeToken !== token || nested.bridgeAmount !== amount || nested.fixedReceiver ||
45
+ nested.destinationChainId === undefined || !nested.receiver || !nested.outputToken)
46
+ return parsed;
47
+ return { ...parsed, destinationChainId: nested.destinationChainId, destinationChainRef: nested.destinationChainRef,
48
+ receiver: nested.receiver, outputToken: nested.outputToken, minOutputAmount: nested.minOutputAmount };
49
+ };
@@ -0,0 +1,3 @@
1
+ import type { ParsedBridgeCall } from '../../types.js';
2
+ export declare const readSocketBridge: (data: string, target: string, token: string, value: bigint, spender: string) => Partial<ParsedBridgeCall>;
3
+ export declare const spliceBridgeAmount: (data: string, flags: bigint, amount: bigint) => string;
@@ -0,0 +1,87 @@
1
+ import { BRIDGE_ERRORS, BridgeError, asBridgeError } from '../../../errors/index.js';
2
+ import { innerCallDiagnostics } from '../../diagnostics.js';
3
+ import { asBigint, asString, decodeCall } from '../../abi.js';
4
+ import { readSelector } from '../../hex.js';
5
+ import { isNative, NATIVE_TOKEN } from '../../protocols.js';
6
+ import { SOCKET_CCTP_MESSENGER, SOCKET_RFQ_VAULT } from '../addresses.js';
7
+ import { readCcip } from './ccip.js';
8
+ import { readCctp } from './cctp.js';
9
+ import { readEco } from './eco.js';
10
+ import { readNativeBridge } from './native.js';
11
+ import { readOft } from './oft.js';
12
+ import { readSwapsXYZ } from './swapsXYZ.js';
13
+ const decodeSocketBridge = (data, target, token, value, spender) => {
14
+ const selector = readSelector(data);
15
+ const native = readNativeBridge(data, target, value);
16
+ if (native)
17
+ return native;
18
+ if (selector === '0x96f4e9f9')
19
+ return readCcip(data, target);
20
+ if (selector === '0x8e0250ee') {
21
+ if (target !== SOCKET_CCTP_MESSENGER || spender !== target || value !== 0n) {
22
+ throw new BridgeError(BRIDGE_ERRORS.UNSUPPORTED_SOCKET_CCTP_TARGET_SPENDER_OR_VALUE);
23
+ }
24
+ const parsed = readCctp(data);
25
+ if (parsed.bridgeToken !== token)
26
+ throw new BridgeError(BRIDGE_ERRORS.SOCKET_CCTP_TOKEN_DOES_NOT_MATCH_BRIDGE_ASSET);
27
+ return parsed;
28
+ }
29
+ if (selector === '0xdf00f8fa')
30
+ return readEco(data, target, spender, value);
31
+ if (selector === '0xc7c7f5b3' || selector === '0x2cdf0b95')
32
+ return readOft(data, target, token);
33
+ if (selector === '0x0c751e0b' || selector === '0x9be111d1')
34
+ return readSwapsXYZ(data);
35
+ if (selector === '0x823b01f9' || selector === '0x3345e738') {
36
+ const native = selector === '0x3345e738';
37
+ if (target !== SOCKET_RFQ_VAULT || spender !== target ||
38
+ (native ? !isNative(token) : value !== 0n)) {
39
+ throw new BridgeError(BRIDGE_ERRORS.UNSUPPORTED_SOCKET_RFQ_TARGET_SPENDER_OR_VALUE);
40
+ }
41
+ const a = decodeCall([{ name: 'quoteId', kind: 'bytes', size: 32 },
42
+ ...(native ? [] : [{ name: 'token', kind: 'address' }, { name: 'amount', kind: 'uint' }])], data);
43
+ if (!native && asString(a.token) !== token)
44
+ throw new BridgeError(BRIDGE_ERRORS.SOCKET_RFQ_TOKEN_DOES_NOT_MATCH_BRIDGE_ASSET);
45
+ return { protocolMethod: native ? 'receiveNative' : 'receiveERC20', orderId: asString(a.quoteId),
46
+ bridgeToken: native ? NATIVE_TOKEN : asString(a.token), bridgeAmount: native ? value : asBigint(a.amount) };
47
+ }
48
+ return undefined;
49
+ };
50
+ export const readSocketBridge = (data, target, token, value, spender) => {
51
+ const diagnostics = innerCallDiagnostics(data, 'protocol');
52
+ try {
53
+ const parsed = decodeSocketBridge(data, target, token, value, spender);
54
+ return { ...parsed, diagnostics: { ...parsed?.diagnostics, ...diagnostics } };
55
+ }
56
+ catch (error) {
57
+ throw asBridgeError(error, BRIDGE_ERRORS.CALLDATA_DECODE_FAILED, diagnostics);
58
+ }
59
+ };
60
+ const word = (data, offset) => {
61
+ const raw = data.slice(2 + offset * 2, 2 + (offset + 32) * 2);
62
+ if (raw.length !== 64)
63
+ throw new BridgeError(BRIDGE_ERRORS.INVALID_BRIDGE_OFFSET);
64
+ const n = BigInt(`0x${raw}`);
65
+ if (n > BigInt(data.length / 2))
66
+ throw new BridgeError(BRIDGE_ERRORS.BRIDGE_OFFSET_EXCEEDS_CALLDATA);
67
+ return Number(n);
68
+ };
69
+ export const spliceBridgeAmount = (data, flags, amount) => {
70
+ if ((flags & 8n) === 0n)
71
+ return data;
72
+ const position = Number(flags >> 16n & 65535n);
73
+ const selector = readSelector(data);
74
+ let expected = {
75
+ '0xd2ce7d65': 68, '0xad58bdd1': 68, '0x8b9e4f93': 68,
76
+ '0x838b2520': 100, '0x8e0250ee': 4, '0x823b01f9': 68, '0x2cdf0b95': 100,
77
+ }[selector ?? ''];
78
+ if (selector === '0xc7c7f5b3')
79
+ expected = 4 + word(data, 4) + 64;
80
+ if (selector === '0x96f4e9f9') {
81
+ const message = 4 + word(data, 36);
82
+ expected = message + word(data, message + 64) + 64;
83
+ }
84
+ if (position !== expected || 2 + (position + 32) * 2 > data.length)
85
+ throw new BridgeError(BRIDGE_ERRORS.BRIDGE_SPLICE_DOES_NOT_TARGET_THE_INPUT_AMOUNT);
86
+ return data.slice(0, 2 + position * 2) + amount.toString(16).padStart(64, '0') + data.slice(2 + (position + 32) * 2);
87
+ };
@@ -0,0 +1,2 @@
1
+ import type { ParsedBridgeCall } from '../../types.js';
2
+ export declare const readNativeBridge: (data: string, target: string, value: bigint) => Partial<ParsedBridgeCall> | undefined;