@hyperbridge/sdk 2.8.12 → 2.8.16

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,10 +1,9 @@
1
- import { keccak256, toHex, encodeAbiParameters, encodeFunctionData, decodeFunctionData, decodeAbiParameters, numberToBytes, bytesToBigInt, recoverAddress, parseAbiParameters, concat, encodePacked, pad } from 'viem';
1
+ import { encodeAbiParameters, encodeFunctionData, decodeFunctionData, decodeAbiParameters, numberToBytes, bytesToBigInt } from 'viem';
2
2
  import '@polkadot/api';
3
- import { u8aToHex, u8aConcat, hexToU8a, stringToU8a, isHex, u8aToString } from '@polkadot/util';
4
- import { xxhashAsU8a } from '@polkadot/util-crypto';
3
+ import { hexToU8a, u8aToHex, isHex } from '@polkadot/util';
4
+ import '@polkadot/util-crypto';
5
5
  import { Struct, Vector, u8, Bytes } from 'scale-ts';
6
6
  import 'p-queue';
7
- import { privateKeyToAccount } from 'viem/accounts';
8
7
 
9
8
  // src/protocols/intents/decode-utils.ts
10
9
 
@@ -65,13 +64,70 @@ function decodeERC7821ExecuteBatch(callData) {
65
64
  }
66
65
  }
67
66
 
67
+ // src/chains/intentsCoprocessor.ts
68
+ new TextEncoder().encode("intents::bid::");
69
+ Struct({ filler: Bytes(32), user_op: Vector(u8) });
70
+ var PackedUserOperationCodec = Struct({
71
+ sender: Bytes(20),
72
+ // address is 20 bytes
73
+ nonce: Bytes(32),
74
+ // uint256 as 32 bytes
75
+ initCode: Vector(u8),
76
+ // variable length bytes
77
+ callData: Vector(u8),
78
+ // variable length bytes
79
+ accountGasLimits: Bytes(32),
80
+ // bytes32
81
+ preVerificationGas: Bytes(32),
82
+ // uint256 as 32 bytes
83
+ gasFees: Bytes(32),
84
+ // bytes32
85
+ paymasterAndData: Vector(u8),
86
+ // variable length bytes
87
+ signature: Vector(u8)
88
+ // variable length bytes
89
+ });
90
+ function encodeUserOpScale(userOp) {
91
+ const encoded = PackedUserOperationCodec.enc({
92
+ sender: hexToU8a(userOp.sender),
93
+ nonce: numberToBytes(userOp.nonce, { size: 32 }),
94
+ initCode: Array.from(hexToU8a(userOp.initCode)),
95
+ callData: Array.from(hexToU8a(userOp.callData)),
96
+ accountGasLimits: hexToU8a(userOp.accountGasLimits),
97
+ preVerificationGas: numberToBytes(userOp.preVerificationGas, { size: 32 }),
98
+ gasFees: hexToU8a(userOp.gasFees),
99
+ paymasterAndData: Array.from(hexToU8a(userOp.paymasterAndData)),
100
+ signature: Array.from(hexToU8a(userOp.signature))
101
+ });
102
+ return u8aToHex(encoded);
103
+ }
104
+ function decodeUserOpScale(hex) {
105
+ const decoded = PackedUserOperationCodec.dec(hexToU8a(hex));
106
+ return {
107
+ sender: u8aToHex(new Uint8Array(decoded.sender)),
108
+ nonce: bytesToBigInt(new Uint8Array(decoded.nonce)),
109
+ initCode: u8aToHex(new Uint8Array(decoded.initCode)),
110
+ callData: u8aToHex(new Uint8Array(decoded.callData)),
111
+ accountGasLimits: u8aToHex(new Uint8Array(decoded.accountGasLimits)),
112
+ preVerificationGas: bytesToBigInt(new Uint8Array(decoded.preVerificationGas)),
113
+ gasFees: u8aToHex(new Uint8Array(decoded.gasFees)),
114
+ paymasterAndData: u8aToHex(new Uint8Array(decoded.paymasterAndData)),
115
+ signature: u8aToHex(new Uint8Array(decoded.signature))
116
+ };
117
+ }
118
+
68
119
  // src/abis/IntentGatewayV2.ts
69
120
  var ABI2 = [
70
121
  {
71
122
  type: "constructor",
72
123
  inputs: [
73
124
  {
74
- name: "owner",
125
+ name: "intrinsic",
126
+ type: "address",
127
+ internalType: "address"
128
+ },
129
+ {
130
+ name: "extrinsic",
75
131
  type: "address",
76
132
  internalType: "address"
77
133
  }
@@ -170,8 +226,8 @@ var ABI2 = [
170
226
  },
171
227
  {
172
228
  name: "",
173
- type: "address",
174
- internalType: "address"
229
+ type: "uint256",
230
+ internalType: "uint256"
175
231
  }
176
232
  ],
177
233
  outputs: [
@@ -185,20 +241,31 @@ var ABI2 = [
185
241
  },
186
242
  {
187
243
  type: "function",
188
- name: "_owner",
189
- inputs: [],
244
+ name: "_partialFills",
245
+ inputs: [
246
+ {
247
+ name: "",
248
+ type: "bytes32",
249
+ internalType: "bytes32"
250
+ },
251
+ {
252
+ name: "",
253
+ type: "uint256",
254
+ internalType: "uint256"
255
+ }
256
+ ],
190
257
  outputs: [
191
258
  {
192
259
  name: "",
193
- type: "address",
194
- internalType: "address"
260
+ type: "uint256",
261
+ internalType: "uint256"
195
262
  }
196
263
  ],
197
264
  stateMutability: "view"
198
265
  },
199
266
  {
200
267
  type: "function",
201
- name: "_partialFills",
268
+ name: "_protocolFees",
202
269
  inputs: [
203
270
  {
204
271
  name: "",
@@ -207,19 +274,31 @@ var ABI2 = [
207
274
  },
208
275
  {
209
276
  name: "",
210
- type: "bytes32",
211
- internalType: "bytes32"
277
+ type: "uint256",
278
+ internalType: "uint256"
212
279
  }
213
280
  ],
214
281
  outputs: [
215
282
  {
216
- name: "",
283
+ name: "amount",
284
+ type: "uint256",
285
+ internalType: "uint256"
286
+ },
287
+ {
288
+ name: "committed",
217
289
  type: "uint256",
218
290
  internalType: "uint256"
219
291
  }
220
292
  ],
221
293
  stateMutability: "view"
222
294
  },
295
+ {
296
+ type: "function",
297
+ name: "acceptOwnership",
298
+ inputs: [],
299
+ outputs: [],
300
+ stateMutability: "nonpayable"
301
+ },
223
302
  {
224
303
  type: "function",
225
304
  name: "calculateCommitmentSlotHash",
@@ -429,6 +508,19 @@ var ABI2 = [
429
508
  ],
430
509
  stateMutability: "view"
431
510
  },
511
+ {
512
+ type: "function",
513
+ name: "extrinsicModule",
514
+ inputs: [],
515
+ outputs: [
516
+ {
517
+ name: "",
518
+ type: "address",
519
+ internalType: "address"
520
+ }
521
+ ],
522
+ stateMutability: "view"
523
+ },
432
524
  {
433
525
  type: "function",
434
526
  name: "fillOrder",
@@ -591,6 +683,23 @@ var ABI2 = [
591
683
  internalType: "uint256"
592
684
  }
593
685
  ]
686
+ },
687
+ {
688
+ name: "inputs",
689
+ type: "tuple[]",
690
+ internalType: "struct TokenInfo[]",
691
+ components: [
692
+ {
693
+ name: "token",
694
+ type: "bytes32",
695
+ internalType: "bytes32"
696
+ },
697
+ {
698
+ name: "amount",
699
+ type: "uint256",
700
+ internalType: "uint256"
701
+ }
702
+ ]
594
703
  }
595
704
  ]
596
705
  }
@@ -616,51 +725,63 @@ var ABI2 = [
616
725
  name: "initialize",
617
726
  inputs: [
618
727
  {
619
- name: "p",
728
+ name: "init",
620
729
  type: "tuple",
621
- internalType: "struct Params",
730
+ internalType: "struct InitParams",
622
731
  components: [
623
732
  {
624
- name: "host",
625
- type: "address",
626
- internalType: "address"
627
- },
628
- {
629
- name: "dispatcher",
630
- type: "address",
631
- internalType: "address"
632
- },
633
- {
634
- name: "solverSelection",
635
- type: "bool",
636
- internalType: "bool"
733
+ name: "params",
734
+ type: "tuple",
735
+ internalType: "struct Params",
736
+ components: [
737
+ {
738
+ name: "host",
739
+ type: "address",
740
+ internalType: "address"
741
+ },
742
+ {
743
+ name: "dispatcher",
744
+ type: "address",
745
+ internalType: "address"
746
+ },
747
+ {
748
+ name: "solverSelection",
749
+ type: "bool",
750
+ internalType: "bool"
751
+ },
752
+ {
753
+ name: "surplusShareBps",
754
+ type: "uint256",
755
+ internalType: "uint256"
756
+ },
757
+ {
758
+ name: "protocolFeeBps",
759
+ type: "uint256",
760
+ internalType: "uint256"
761
+ },
762
+ {
763
+ name: "priceOracle",
764
+ type: "address",
765
+ internalType: "address"
766
+ }
767
+ ]
637
768
  },
638
769
  {
639
- name: "surplusShareBps",
640
- type: "uint256",
641
- internalType: "uint256"
770
+ name: "peerChains",
771
+ type: "bytes[]",
772
+ internalType: "bytes[]"
642
773
  },
643
774
  {
644
- name: "protocolFeeBps",
645
- type: "uint256",
646
- internalType: "uint256"
775
+ name: "relayer",
776
+ type: "address",
777
+ internalType: "address"
647
778
  },
648
779
  {
649
- name: "priceOracle",
780
+ name: "owner",
650
781
  type: "address",
651
782
  internalType: "address"
652
783
  }
653
784
  ]
654
- },
655
- {
656
- name: "peerChains",
657
- type: "bytes[]",
658
- internalType: "bytes[]"
659
- },
660
- {
661
- name: "relayer",
662
- type: "address",
663
- internalType: "address"
664
785
  }
665
786
  ],
666
787
  outputs: [],
@@ -685,12 +806,25 @@ var ABI2 = [
685
806
  ],
686
807
  stateMutability: "view"
687
808
  },
809
+ {
810
+ type: "function",
811
+ name: "intrinsicModule",
812
+ inputs: [],
813
+ outputs: [
814
+ {
815
+ name: "",
816
+ type: "address",
817
+ internalType: "address"
818
+ }
819
+ ],
820
+ stateMutability: "view"
821
+ },
688
822
  {
689
823
  type: "function",
690
824
  name: "migrate",
691
825
  inputs: [
692
826
  {
693
- name: "relayer",
827
+ name: "owner_",
694
828
  type: "address",
695
829
  internalType: "address"
696
830
  }
@@ -765,7 +899,7 @@ var ABI2 = [
765
899
  name: "onGetResponse",
766
900
  inputs: [
767
901
  {
768
- name: "incoming",
902
+ name: "",
769
903
  type: "tuple",
770
904
  internalType: "struct IncomingGetResponse",
771
905
  components: [
@@ -980,6 +1114,19 @@ var ABI2 = [
980
1114
  outputs: [],
981
1115
  stateMutability: "nonpayable"
982
1116
  },
1117
+ {
1118
+ type: "function",
1119
+ name: "owner",
1120
+ inputs: [],
1121
+ outputs: [
1122
+ {
1123
+ name: "",
1124
+ type: "address",
1125
+ internalType: "address"
1126
+ }
1127
+ ],
1128
+ stateMutability: "view"
1129
+ },
983
1130
  {
984
1131
  type: "function",
985
1132
  name: "params",
@@ -1025,6 +1172,39 @@ var ABI2 = [
1025
1172
  ],
1026
1173
  stateMutability: "view"
1027
1174
  },
1175
+ {
1176
+ type: "function",
1177
+ name: "pause",
1178
+ inputs: [],
1179
+ outputs: [],
1180
+ stateMutability: "nonpayable"
1181
+ },
1182
+ {
1183
+ type: "function",
1184
+ name: "paused",
1185
+ inputs: [],
1186
+ outputs: [
1187
+ {
1188
+ name: "",
1189
+ type: "bool",
1190
+ internalType: "bool"
1191
+ }
1192
+ ],
1193
+ stateMutability: "view"
1194
+ },
1195
+ {
1196
+ type: "function",
1197
+ name: "pendingOwner",
1198
+ inputs: [],
1199
+ outputs: [
1200
+ {
1201
+ name: "",
1202
+ type: "address",
1203
+ internalType: "address"
1204
+ }
1205
+ ],
1206
+ stateMutability: "view"
1207
+ },
1028
1208
  {
1029
1209
  type: "function",
1030
1210
  name: "placeOrder",
@@ -1280,6 +1460,13 @@ var ABI2 = [
1280
1460
  ],
1281
1461
  stateMutability: "view"
1282
1462
  },
1463
+ {
1464
+ type: "function",
1465
+ name: "renounceOwnership",
1466
+ inputs: [],
1467
+ outputs: [],
1468
+ stateMutability: "nonpayable"
1469
+ },
1283
1470
  {
1284
1471
  type: "function",
1285
1472
  name: "select",
@@ -1318,10 +1505,10 @@ var ABI2 = [
1318
1505
  },
1319
1506
  {
1320
1507
  type: "function",
1321
- name: "setRelayer",
1508
+ name: "transferOwnership",
1322
1509
  inputs: [
1323
1510
  {
1324
- name: "relayer",
1511
+ name: "newOwner",
1325
1512
  type: "address",
1326
1513
  internalType: "address"
1327
1514
  }
@@ -1331,19 +1518,8 @@ var ABI2 = [
1331
1518
  },
1332
1519
  {
1333
1520
  type: "function",
1334
- name: "upgradeToAndCall",
1335
- inputs: [
1336
- {
1337
- name: "newImplementation",
1338
- type: "address",
1339
- internalType: "address"
1340
- },
1341
- {
1342
- name: "data",
1343
- type: "bytes",
1344
- internalType: "bytes"
1345
- }
1346
- ],
1521
+ name: "unpause",
1522
+ inputs: [],
1347
1523
  outputs: [],
1348
1524
  stateMutability: "nonpayable"
1349
1525
  },
@@ -1489,6 +1665,12 @@ var ABI2 = [
1489
1665
  indexed: true,
1490
1666
  internalType: "bytes32"
1491
1667
  },
1668
+ {
1669
+ name: "solver",
1670
+ type: "address",
1671
+ indexed: false,
1672
+ internalType: "address"
1673
+ },
1492
1674
  {
1493
1675
  name: "tokens",
1494
1676
  type: "tuple[]",
@@ -1726,12 +1908,50 @@ var ABI2 = [
1726
1908
  },
1727
1909
  {
1728
1910
  type: "event",
1729
- name: "ParamsUpdated",
1911
+ name: "OwnershipTransferStarted",
1730
1912
  inputs: [
1731
1913
  {
1732
- name: "previous",
1733
- type: "tuple",
1734
- indexed: false,
1914
+ name: "previousOwner",
1915
+ type: "address",
1916
+ indexed: true,
1917
+ internalType: "address"
1918
+ },
1919
+ {
1920
+ name: "newOwner",
1921
+ type: "address",
1922
+ indexed: true,
1923
+ internalType: "address"
1924
+ }
1925
+ ],
1926
+ anonymous: false
1927
+ },
1928
+ {
1929
+ type: "event",
1930
+ name: "OwnershipTransferred",
1931
+ inputs: [
1932
+ {
1933
+ name: "previousOwner",
1934
+ type: "address",
1935
+ indexed: true,
1936
+ internalType: "address"
1937
+ },
1938
+ {
1939
+ name: "newOwner",
1940
+ type: "address",
1941
+ indexed: true,
1942
+ internalType: "address"
1943
+ }
1944
+ ],
1945
+ anonymous: false
1946
+ },
1947
+ {
1948
+ type: "event",
1949
+ name: "ParamsUpdated",
1950
+ inputs: [
1951
+ {
1952
+ name: "previous",
1953
+ type: "tuple",
1954
+ indexed: false,
1735
1955
  internalType: "struct Params",
1736
1956
  components: [
1737
1957
  {
@@ -1864,46 +2084,73 @@ var ABI2 = [
1864
2084
  },
1865
2085
  {
1866
2086
  type: "event",
1867
- name: "RelayerUpdated",
2087
+ name: "Paused",
1868
2088
  inputs: [
1869
2089
  {
1870
- name: "previous",
2090
+ name: "account",
1871
2091
  type: "address",
1872
2092
  indexed: false,
1873
2093
  internalType: "address"
2094
+ }
2095
+ ],
2096
+ anonymous: false
2097
+ },
2098
+ {
2099
+ type: "event",
2100
+ name: "ProtocolFeeRefunded",
2101
+ inputs: [
2102
+ {
2103
+ name: "commitment",
2104
+ type: "bytes32",
2105
+ indexed: true,
2106
+ internalType: "bytes32"
1874
2107
  },
1875
2108
  {
1876
- name: "current",
2109
+ name: "token",
1877
2110
  type: "address",
1878
- indexed: false,
2111
+ indexed: true,
1879
2112
  internalType: "address"
2113
+ },
2114
+ {
2115
+ name: "amount",
2116
+ type: "uint256",
2117
+ indexed: false,
2118
+ internalType: "uint256"
1880
2119
  }
1881
2120
  ],
1882
2121
  anonymous: false
1883
2122
  },
1884
2123
  {
1885
2124
  type: "event",
1886
- name: "Upgraded",
2125
+ name: "RelayerUpdated",
1887
2126
  inputs: [
1888
2127
  {
1889
- name: "implementation",
2128
+ name: "previous",
1890
2129
  type: "address",
1891
- indexed: true,
2130
+ indexed: false,
2131
+ internalType: "address"
2132
+ },
2133
+ {
2134
+ name: "current",
2135
+ type: "address",
2136
+ indexed: false,
1892
2137
  internalType: "address"
1893
2138
  }
1894
2139
  ],
1895
2140
  anonymous: false
1896
2141
  },
1897
2142
  {
1898
- type: "error",
1899
- name: "AddressEmptyCode",
2143
+ type: "event",
2144
+ name: "Unpaused",
1900
2145
  inputs: [
1901
2146
  {
1902
- name: "target",
2147
+ name: "account",
1903
2148
  type: "address",
2149
+ indexed: false,
1904
2150
  internalType: "address"
1905
2151
  }
1906
- ]
2152
+ ],
2153
+ anonymous: false
1907
2154
  },
1908
2155
  {
1909
2156
  type: "error",
@@ -1939,28 +2186,17 @@ var ABI2 = [
1939
2186
  },
1940
2187
  {
1941
2188
  type: "error",
1942
- name: "ERC1967InvalidImplementation",
1943
- inputs: [
1944
- {
1945
- name: "implementation",
1946
- type: "address",
1947
- internalType: "address"
1948
- }
1949
- ]
1950
- },
1951
- {
1952
- type: "error",
1953
- name: "ERC1967NonPayable",
2189
+ name: "EnforcedPause",
1954
2190
  inputs: []
1955
2191
  },
1956
2192
  {
1957
2193
  type: "error",
1958
- name: "Expired",
2194
+ name: "ExpectedPause",
1959
2195
  inputs: []
1960
2196
  },
1961
2197
  {
1962
2198
  type: "error",
1963
- name: "FailedCall",
2199
+ name: "Expired",
1964
2200
  inputs: []
1965
2201
  },
1966
2202
  {
@@ -2003,11 +2239,43 @@ var ABI2 = [
2003
2239
  name: "NotInitializing",
2004
2240
  inputs: []
2005
2241
  },
2242
+ {
2243
+ type: "error",
2244
+ name: "OwnableInvalidOwner",
2245
+ inputs: [
2246
+ {
2247
+ name: "owner",
2248
+ type: "address",
2249
+ internalType: "address"
2250
+ }
2251
+ ]
2252
+ },
2253
+ {
2254
+ type: "error",
2255
+ name: "OwnableUnauthorizedAccount",
2256
+ inputs: [
2257
+ {
2258
+ name: "account",
2259
+ type: "address",
2260
+ internalType: "address"
2261
+ }
2262
+ ]
2263
+ },
2006
2264
  {
2007
2265
  type: "error",
2008
2266
  name: "PartialFillNotAllowed",
2009
2267
  inputs: []
2010
2268
  },
2269
+ {
2270
+ type: "error",
2271
+ name: "RateBelowOrder",
2272
+ inputs: []
2273
+ },
2274
+ {
2275
+ type: "error",
2276
+ name: "RateFillTooSmall",
2277
+ inputs: []
2278
+ },
2011
2279
  {
2012
2280
  type: "error",
2013
2281
  name: "ReentrancyGuardReentrantCall",
@@ -2068,60 +2336,6 @@ var ABI2 = [
2068
2336
  ];
2069
2337
  var IntentGatewayV2_default = { ABI: ABI2 };
2070
2338
 
2071
- // src/chains/intentsCoprocessor.ts
2072
- u8aToHex(u8aConcat(xxhashAsU8a("System", 128), xxhashAsU8a("Events", 128)));
2073
- new TextEncoder().encode("intents::bid::");
2074
- new TextEncoder().encode("intents::phantom::order::");
2075
- Struct({ filler: Bytes(32), user_op: Vector(u8) });
2076
- var PackedUserOperationCodec = Struct({
2077
- sender: Bytes(20),
2078
- // address is 20 bytes
2079
- nonce: Bytes(32),
2080
- // uint256 as 32 bytes
2081
- initCode: Vector(u8),
2082
- // variable length bytes
2083
- callData: Vector(u8),
2084
- // variable length bytes
2085
- accountGasLimits: Bytes(32),
2086
- // bytes32
2087
- preVerificationGas: Bytes(32),
2088
- // uint256 as 32 bytes
2089
- gasFees: Bytes(32),
2090
- // bytes32
2091
- paymasterAndData: Vector(u8),
2092
- // variable length bytes
2093
- signature: Vector(u8)
2094
- // variable length bytes
2095
- });
2096
- function encodeUserOpScale(userOp) {
2097
- const encoded = PackedUserOperationCodec.enc({
2098
- sender: hexToU8a(userOp.sender),
2099
- nonce: numberToBytes(userOp.nonce, { size: 32 }),
2100
- initCode: Array.from(hexToU8a(userOp.initCode)),
2101
- callData: Array.from(hexToU8a(userOp.callData)),
2102
- accountGasLimits: hexToU8a(userOp.accountGasLimits),
2103
- preVerificationGas: numberToBytes(userOp.preVerificationGas, { size: 32 }),
2104
- gasFees: hexToU8a(userOp.gasFees),
2105
- paymasterAndData: Array.from(hexToU8a(userOp.paymasterAndData)),
2106
- signature: Array.from(hexToU8a(userOp.signature))
2107
- });
2108
- return u8aToHex(encoded);
2109
- }
2110
- function decodeUserOpScale(hex) {
2111
- const decoded = PackedUserOperationCodec.dec(hexToU8a(hex));
2112
- return {
2113
- sender: u8aToHex(new Uint8Array(decoded.sender)),
2114
- nonce: bytesToBigInt(new Uint8Array(decoded.nonce)),
2115
- initCode: u8aToHex(new Uint8Array(decoded.initCode)),
2116
- callData: u8aToHex(new Uint8Array(decoded.callData)),
2117
- accountGasLimits: u8aToHex(new Uint8Array(decoded.accountGasLimits)),
2118
- preVerificationGas: bytesToBigInt(new Uint8Array(decoded.preVerificationGas)),
2119
- gasFees: u8aToHex(new Uint8Array(decoded.gasFees)),
2120
- paymasterAndData: u8aToHex(new Uint8Array(decoded.paymasterAndData)),
2121
- signature: u8aToHex(new Uint8Array(decoded.signature))
2122
- };
2123
- }
2124
-
2125
2339
  // src/protocols/intents/liquidity-pool.ts
2126
2340
  function sortPoolSymbols(symbolA, symbolB) {
2127
2341
  return symbolA.toLowerCase() <= symbolB.toLowerCase() ? [symbolA, symbolB] : [symbolB, symbolA];
@@ -2129,553 +2343,6 @@ function sortPoolSymbols(symbolA, symbolB) {
2129
2343
  function poolSlug(symbolA, symbolB) {
2130
2344
  return sortPoolSymbols(symbolA, symbolB).join("-");
2131
2345
  }
2132
- var FILL_ORDER_V1_ABI = [
2133
- {
2134
- type: "function",
2135
- name: "fillOrder",
2136
- stateMutability: "payable",
2137
- outputs: [],
2138
- inputs: [
2139
- ABI2.find((e) => e.type === "function" && e.name === "fillOrder").inputs[0],
2140
- {
2141
- name: "options",
2142
- type: "tuple",
2143
- internalType: "struct FillOptions",
2144
- components: [
2145
- { name: "relayerFee", type: "uint256", internalType: "uint256" },
2146
- { name: "nativeDispatchFee", type: "uint256", internalType: "uint256" },
2147
- {
2148
- name: "outputs",
2149
- type: "tuple[]",
2150
- internalType: "struct TokenInfo[]",
2151
- components: [
2152
- { name: "token", type: "bytes32", internalType: "bytes32" },
2153
- { name: "amount", type: "uint256", internalType: "uint256" }
2154
- ]
2155
- }
2156
- ]
2157
- }
2158
- ]
2159
- }
2160
- ];
2161
- function decodeFillOrder(data) {
2162
- try {
2163
- const decoded = decodeFunctionData({ abi: ABI2, data });
2164
- if (decoded.functionName === "fillOrder" && decoded.args && decoded.args.length >= 2) {
2165
- return { order: decoded.args[0], options: decoded.args[1] };
2166
- }
2167
- } catch {
2168
- }
2169
- try {
2170
- const decoded = decodeFunctionData({ abi: FILL_ORDER_V1_ABI, data });
2171
- if (decoded.functionName === "fillOrder" && decoded.args && decoded.args.length >= 2) {
2172
- const legacy = decoded.args[1];
2173
- return { order: decoded.args[0], options: { ...legacy, validUntil: 0n } };
2174
- }
2175
- } catch {
2176
- }
2177
- return null;
2178
- }
2179
- var SELECT_SOLVER_TYPEHASH = keccak256(toHex("SelectSolver(bytes32 commitment,address solver)"));
2180
- var PACKED_USEROP_TYPEHASH = keccak256(
2181
- toHex(
2182
- "PackedUserOperation(address sender,uint256 nonce,bytes initCode,bytes callData,bytes32 accountGasLimits,uint256 preVerificationGas,bytes32 gasFees,bytes paymasterAndData)"
2183
- )
2184
- );
2185
- var DOMAIN_TYPEHASH = keccak256(
2186
- toHex("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
2187
- );
2188
- var CryptoUtils = class _CryptoUtils {
2189
- /**
2190
- * @param ctx - Shared IntentsV2 context; used to access the bundler URL for
2191
- * JSON-RPC calls.
2192
- */
2193
- constructor(ctx) {
2194
- this.ctx = ctx;
2195
- }
2196
- ctx;
2197
- /**
2198
- * Computes an EIP-712 domain separator for a given contract.
2199
- *
2200
- * @param contractName - Human-readable name of the contract (e.g. `"IntentGateway"`).
2201
- * @param version - Version string (e.g. `"2"`).
2202
- * @param chainId - Chain ID of the network the contract is deployed on.
2203
- * @param contractAddress - Address of the verifying contract.
2204
- * @returns The 32-byte domain separator as a hex string.
2205
- */
2206
- static getDomainSeparator(contractName, version, chainId, contractAddress) {
2207
- return keccak256(
2208
- encodeAbiParameters(parseAbiParameters("bytes32, bytes32, bytes32, uint256, address"), [
2209
- DOMAIN_TYPEHASH,
2210
- keccak256(toHex(contractName)),
2211
- keccak256(toHex(version)),
2212
- chainId,
2213
- contractAddress
2214
- ])
2215
- );
2216
- }
2217
- /**
2218
- * Signs a `SelectSolver` EIP-712 message with a session key.
2219
- *
2220
- * The session key authorises the selection of a specific solver for the
2221
- * given order commitment. The resulting signature is appended to the
2222
- * solver's UserOperation signature before bundle submission.
2223
- *
2224
- * @param commitment - The order commitment (bytes32) being fulfilled.
2225
- * @param solverAddress - Address of the solver account selected to fill the order.
2226
- * @param domainSeparator - EIP-712 domain separator for the IntentGatewayV2 contract.
2227
- * @param privateKey - Hex-encoded private key of the session key that signs the message.
2228
- * @returns The ECDSA signature as a hex string, or `null` if signing fails.
2229
- */
2230
- static async signSolverSelection(commitment, solverAddress, domainSeparator, privateKey) {
2231
- const account = privateKeyToAccount(privateKey);
2232
- const structHash = keccak256(
2233
- encodeAbiParameters(
2234
- [{ type: "bytes32" }, { type: "bytes32" }, { type: "address" }],
2235
- [SELECT_SOLVER_TYPEHASH, commitment, solverAddress]
2236
- )
2237
- );
2238
- const digest = keccak256(concat(["0x1901", domainSeparator, structHash]));
2239
- const signature = await account.sign({ hash: digest });
2240
- return signature;
2241
- }
2242
- /**
2243
- * Computes the EIP-712 hash of a `PackedUserOperation` as defined by
2244
- * ERC-4337 EntryPoint v0.8.
2245
- *
2246
- * @param userOp - The packed UserOperation to hash.
2247
- * @param entryPoint - Address of the EntryPoint v0.8 contract.
2248
- * @param chainId - Chain ID of the network on which the operation will execute.
2249
- * @returns The UserOperation hash as a hex string.
2250
- */
2251
- static computeUserOpHash(userOp, entryPoint, chainId) {
2252
- const structHash = _CryptoUtils.getPackedUserStructHash(userOp);
2253
- const domainSeparator = _CryptoUtils.getDomainSeparator("ERC4337", "1", chainId, entryPoint);
2254
- return keccak256(
2255
- encodePacked(["bytes1", "bytes1", "bytes32", "bytes32"], ["0x19", "0x01", domainSeparator, structHash])
2256
- );
2257
- }
2258
- /**
2259
- * Derives the ERC-4337 nonce key that binds a bid UserOperation to its
2260
- * order and session key: the lower 192 bits of
2261
- * `keccak256(commitment ‖ sessionKey)`. `SolverAccount` rejects bid
2262
- * operations whose nonce key differs — this is what lets the solver sign
2263
- * the plain userOpHash while staying committed to the order and to the
2264
- * session key it bid against.
2265
- *
2266
- * @param commitment - The order commitment (`order.id`).
2267
- * @param sessionKey - The order's session key address (`order.session`).
2268
- * @returns The 192-bit nonce key as a bigint (pass to `EntryPoint.getNonce`).
2269
- */
2270
- static bidNonceKey(commitment, sessionKey) {
2271
- return BigInt(keccak256(encodePacked(["bytes32", "address"], [commitment, sessionKey]))) & (1n << 192n) - 1n;
2272
- }
2273
- /**
2274
- * Builds the EIP-712 typed-data payload whose digest is the EntryPoint v0.8
2275
- * `userOpHash` (i.e. `hashTypedData(packedUserOpTypedData(...)) ===
2276
- * computeUserOpHash(...)`). Signing this typed data is bit-identical to
2277
- * signing the raw userOpHash, but keeps the full operation visible to
2278
- * signing infrastructure (hardware wallets, MPC/TEE policy engines) instead
2279
- * of an opaque 32-byte digest.
2280
- *
2281
- * The payload must be a standard self-describing `eth_signTypedData_v4`
2282
- * payload — `EIP712Domain` listed in `types`, `chainId` as a JSON number —
2283
- * because some signing backends (e.g. MPC Vault) hash it server-side from
2284
- * the JSON rather than locally via viem. viem ignores both details when
2285
- * hashing, so the digest is unchanged for local signers.
2286
- *
2287
- * @param userOp - The packed UserOperation to sign (signature field ignored).
2288
- * @param entryPoint - Address of the EntryPoint v0.8 contract.
2289
- * @param chainId - Chain ID of the network on which the operation will execute.
2290
- * @returns A viem `TypedDataDefinition` for the operation.
2291
- */
2292
- static packedUserOpTypedData(userOp, entryPoint, chainId) {
2293
- return {
2294
- domain: {
2295
- name: "ERC4337",
2296
- version: "1",
2297
- // Runtime number so JSON.stringify emits a canonical v4 numeric chainId for
2298
- // server-side hashers; viem's uint256 type mapping wants bigint but its
2299
- // runtime accepts numbers, hence the cast.
2300
- chainId: Number(chainId),
2301
- verifyingContract: entryPoint
2302
- },
2303
- // `as const`: viem derives the domain's TYPE from `types.EIP712Domain`, so the
2304
- // entries must stay string literals — widened `string` fields make viem's
2305
- // typed-data generics reject the payload at every call site.
2306
- types: {
2307
- EIP712Domain: [
2308
- { name: "name", type: "string" },
2309
- { name: "version", type: "string" },
2310
- { name: "chainId", type: "uint256" },
2311
- { name: "verifyingContract", type: "address" }
2312
- ],
2313
- PackedUserOperation: [
2314
- { name: "sender", type: "address" },
2315
- { name: "nonce", type: "uint256" },
2316
- { name: "initCode", type: "bytes" },
2317
- { name: "callData", type: "bytes" },
2318
- { name: "accountGasLimits", type: "bytes32" },
2319
- { name: "preVerificationGas", type: "uint256" },
2320
- { name: "gasFees", type: "bytes32" },
2321
- { name: "paymasterAndData", type: "bytes" }
2322
- ]
2323
- },
2324
- primaryType: "PackedUserOperation",
2325
- message: {
2326
- sender: userOp.sender,
2327
- nonce: userOp.nonce,
2328
- initCode: userOp.initCode,
2329
- callData: userOp.callData,
2330
- accountGasLimits: userOp.accountGasLimits,
2331
- preVerificationGas: userOp.preVerificationGas,
2332
- gasFees: userOp.gasFees,
2333
- paymasterAndData: userOp.paymasterAndData
2334
- }
2335
- };
2336
- }
2337
- /**
2338
- * Computes the EIP-712 struct hash of a `PackedUserOperation`.
2339
- *
2340
- * Hashes dynamic fields (`initCode`, `callData`, `paymasterAndData`) before
2341
- * ABI-encoding so the final hash is a fixed-length 32-byte value.
2342
- *
2343
- * @param userOp - The packed UserOperation to hash.
2344
- * @returns The struct hash as a 32-byte hex string.
2345
- */
2346
- static getPackedUserStructHash(userOp) {
2347
- return keccak256(
2348
- encodeAbiParameters(
2349
- parseAbiParameters("bytes32, address, uint256, bytes32, bytes32, bytes32, uint256, bytes32, bytes32"),
2350
- [
2351
- PACKED_USEROP_TYPEHASH,
2352
- userOp.sender,
2353
- userOp.nonce,
2354
- keccak256(userOp.initCode),
2355
- keccak256(userOp.callData),
2356
- userOp.accountGasLimits,
2357
- userOp.preVerificationGas,
2358
- userOp.gasFees,
2359
- keccak256(userOp.paymasterAndData)
2360
- ]
2361
- )
2362
- );
2363
- }
2364
- /**
2365
- * Packs `verificationGasLimit` and `callGasLimit` into the ERC-4337
2366
- * `accountGasLimits` bytes32 field.
2367
- *
2368
- * The high 16 bytes hold `verificationGasLimit` and the low 16 bytes hold
2369
- * `callGasLimit`, matching the EntryPoint v0.8 packed representation.
2370
- *
2371
- * @param verificationGasLimit - Gas limit for the account verification step.
2372
- * @param callGasLimit - Gas limit for the main execution call.
2373
- * @returns A 32-byte hex string with both limits packed.
2374
- */
2375
- static packGasLimits(verificationGasLimit, callGasLimit) {
2376
- const verificationGasHex = pad(toHex(verificationGasLimit), { size: 16 });
2377
- const callGasHex = pad(toHex(callGasLimit), { size: 16 });
2378
- return concat([verificationGasHex, callGasHex]);
2379
- }
2380
- /**
2381
- * Packs `maxPriorityFeePerGas` and `maxFeePerGas` into the ERC-4337
2382
- * `gasFees` bytes32 field.
2383
- *
2384
- * The high 16 bytes hold `maxPriorityFeePerGas` and the low 16 bytes hold
2385
- * `maxFeePerGas`, matching the EntryPoint v0.8 packed representation.
2386
- *
2387
- * @param maxPriorityFeePerGas - Maximum tip per gas (EIP-1559).
2388
- * @param maxFeePerGas - Maximum total fee per gas (EIP-1559).
2389
- * @returns A 32-byte hex string with both fee values packed.
2390
- */
2391
- static packGasFees(maxPriorityFeePerGas, maxFeePerGas) {
2392
- const priorityFeeHex = pad(toHex(maxPriorityFeePerGas), { size: 16 });
2393
- const maxFeeHex = pad(toHex(maxFeePerGas), { size: 16 });
2394
- return concat([priorityFeeHex, maxFeeHex]);
2395
- }
2396
- /**
2397
- * Unpacks the `accountGasLimits` bytes32 field back into its constituent
2398
- * gas limits.
2399
- *
2400
- * @param accountGasLimits - The packed 32-byte gas limits field from a `PackedUserOperation`.
2401
- * @returns Object with `verificationGasLimit` and `callGasLimit` as bigints.
2402
- */
2403
- static unpackGasLimits(accountGasLimits) {
2404
- const hex = accountGasLimits.slice(2);
2405
- const verificationGasLimit = BigInt(`0x${hex.slice(0, 32)}`);
2406
- const callGasLimit = BigInt(`0x${hex.slice(32, 64)}`);
2407
- return { verificationGasLimit, callGasLimit };
2408
- }
2409
- /**
2410
- * Unpacks the `gasFees` bytes32 field back into its constituent fee values.
2411
- *
2412
- * @param gasFees - The packed 32-byte gas fees field from a `PackedUserOperation`.
2413
- * @returns Object with `maxPriorityFeePerGas` and `maxFeePerGas` as bigints.
2414
- */
2415
- static unpackGasFees(gasFees) {
2416
- const hex = gasFees.slice(2);
2417
- const maxPriorityFeePerGas = BigInt(`0x${hex.slice(0, 32)}`);
2418
- const maxFeePerGas = BigInt(`0x${hex.slice(32, 64)}`);
2419
- return { maxPriorityFeePerGas, maxFeePerGas };
2420
- }
2421
- /**
2422
- * Converts a packed `PackedUserOperation` into the JSON object format
2423
- * expected by ERC-4337 bundler JSON-RPC endpoints.
2424
- *
2425
- * Unpacks `accountGasLimits` and `gasFees`, separates optional factory and
2426
- * paymaster fields, and converts all numeric fields to hex strings.
2427
- *
2428
- * @param userOp - The packed UserOperation to convert.
2429
- * @returns A plain object safe to pass as the first element of bundler RPC params.
2430
- */
2431
- static prepareBundlerCall(userOp) {
2432
- const { verificationGasLimit, callGasLimit } = _CryptoUtils.unpackGasLimits(userOp.accountGasLimits);
2433
- const { maxPriorityFeePerGas, maxFeePerGas } = _CryptoUtils.unpackGasFees(userOp.gasFees);
2434
- const hasFactory = userOp.initCode && userOp.initCode !== "0x" && userOp.initCode.length > 2;
2435
- const factory = hasFactory ? `0x${userOp.initCode.slice(2, 42)}` : void 0;
2436
- const factoryData = hasFactory ? `0x${userOp.initCode.slice(42)}` : void 0;
2437
- const hasPaymaster = userOp.paymasterAndData && userOp.paymasterAndData !== "0x" && userOp.paymasterAndData.length > 2;
2438
- const pmHex = hasPaymaster ? userOp.paymasterAndData.slice(2) : "";
2439
- const paymaster = hasPaymaster ? `0x${pmHex.slice(0, 40)}` : void 0;
2440
- const paymasterVerificationGasLimit = hasPaymaster ? BigInt(`0x${pmHex.slice(40, 72)}`) : void 0;
2441
- const paymasterPostOpGasLimit = hasPaymaster ? BigInt(`0x${pmHex.slice(72, 104)}`) : void 0;
2442
- const paymasterData = hasPaymaster ? `0x${pmHex.slice(104)}` : void 0;
2443
- const userOpBundler = {
2444
- sender: userOp.sender,
2445
- nonce: toHex(userOp.nonce),
2446
- callData: userOp.callData,
2447
- callGasLimit: toHex(callGasLimit),
2448
- verificationGasLimit: toHex(verificationGasLimit),
2449
- preVerificationGas: toHex(userOp.preVerificationGas),
2450
- maxFeePerGas: toHex(maxFeePerGas),
2451
- maxPriorityFeePerGas: toHex(maxPriorityFeePerGas),
2452
- signature: userOp.signature
2453
- };
2454
- if (factory) {
2455
- userOpBundler.factory = factory;
2456
- userOpBundler.factoryData = factoryData || "0x";
2457
- }
2458
- if (paymaster) {
2459
- userOpBundler.paymaster = paymaster;
2460
- userOpBundler.paymasterData = paymasterData || "0x";
2461
- userOpBundler.paymasterVerificationGasLimit = toHex(paymasterVerificationGasLimit);
2462
- userOpBundler.paymasterPostOpGasLimit = toHex(paymasterPostOpGasLimit);
2463
- }
2464
- return userOpBundler;
2465
- }
2466
- /**
2467
- * Sends a JSON-RPC request to the configured ERC-4337 bundler endpoint.
2468
- *
2469
- * @param method - The JSON-RPC method name (one of {@link BundlerMethod}).
2470
- * @param params - Array of parameters for the RPC call.
2471
- * @returns Resolves with the `result` field of the bundler's JSON-RPC response,
2472
- * typed as `T`.
2473
- * @throws If the bundler URL is not configured or the bundler returns an error.
2474
- */
2475
- async sendBundler(method, params = []) {
2476
- if (!this.ctx.bundlerUrl) {
2477
- throw new Error("Bundler URL not configured");
2478
- }
2479
- const response = await fetch(this.ctx.bundlerUrl, {
2480
- method: "POST",
2481
- headers: { "Content-Type": "application/json" },
2482
- body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
2483
- });
2484
- const result = await response.json();
2485
- if (result.error) {
2486
- throw new Error(`Bundler error: ${result.error.message || JSON.stringify(result.error)}`);
2487
- }
2488
- return result.result;
2489
- }
2490
- /**
2491
- * Sends multiple JSON-RPC requests to the bundler in a single HTTP call
2492
- * using JSON-RPC 2.0 batch syntax. Results are returned in the same order
2493
- * as the input `requests` array.
2494
- *
2495
- * @throws If the bundler URL is not configured, the HTTP call fails, or any
2496
- * individual response contains an error.
2497
- */
2498
- async sendBundlerBatch(requests) {
2499
- if (!this.ctx.bundlerUrl) {
2500
- throw new Error("Bundler URL not configured");
2501
- }
2502
- const body = requests.map((r, i) => ({
2503
- jsonrpc: "2.0",
2504
- id: i + 1,
2505
- method: r.method,
2506
- params: r.params
2507
- }));
2508
- const response = await fetch(this.ctx.bundlerUrl, {
2509
- method: "POST",
2510
- headers: { "Content-Type": "application/json" },
2511
- body: JSON.stringify(body)
2512
- });
2513
- const results = await response.json();
2514
- results.sort((a, b) => a.id - b.id);
2515
- return results.map((r) => {
2516
- if (r.error) {
2517
- throw new Error(`Bundler error: ${r.error.message || JSON.stringify(r.error)}`);
2518
- }
2519
- return r.result;
2520
- });
2521
- }
2522
- /**
2523
- * Encodes a list of calls into ERC-7821 `execute` calldata using
2524
- * single-batch mode (`ERC7821_BATCH_MODE`).
2525
- *
2526
- * @param calls - Ordered list of calls to batch; each specifies a `target`
2527
- * address, ETH `value`, and `data`.
2528
- * @returns ABI-encoded calldata for the ERC-7821 `execute(bytes32,bytes)` function.
2529
- */
2530
- encodeERC7821Execute(calls) {
2531
- const executionData = encodeAbiParameters(
2532
- [{ type: "tuple[]", components: erc7281_default.ABI[1].components }],
2533
- [calls.map((call) => ({ target: call.target, value: call.value, data: call.data }))]
2534
- );
2535
- return encodeFunctionData({
2536
- abi: erc7281_default.ABI,
2537
- functionName: "execute",
2538
- args: [ERC7821_BATCH_MODE, executionData]
2539
- });
2540
- }
2541
- /**
2542
- * Decodes ERC-7821 `execute` calldata back into its constituent calls.
2543
- *
2544
- * Returns `null` if the calldata does not match the expected `execute`
2545
- * function signature or cannot be decoded.
2546
- *
2547
- * @param callData - Hex-encoded calldata previously produced by
2548
- * {@link encodeERC7821Execute} or an equivalent encoder.
2549
- * @returns Array of decoded {@link ERC7821Call} objects, or `null` on failure.
2550
- */
2551
- decodeERC7821Execute(callData) {
2552
- try {
2553
- const decoded = decodeFunctionData({
2554
- abi: erc7281_default.ABI,
2555
- data: callData
2556
- });
2557
- if (decoded?.functionName !== "execute" || !decoded.args || decoded.args.length < 2) {
2558
- return null;
2559
- }
2560
- const executionData = decoded.args[1];
2561
- const [calls] = decodeAbiParameters(
2562
- [{ type: "tuple[]", components: erc7281_default.ABI[1].components }],
2563
- executionData
2564
- );
2565
- return calls.map((call) => ({
2566
- target: call.target,
2567
- value: call.value,
2568
- data: call.data
2569
- }));
2570
- } catch {
2571
- return null;
2572
- }
2573
- }
2574
- };
2575
-
2576
- // src/protocols/intents/uniswap-v4-position.ts
2577
- var Q96 = 1n << 96n;
2578
- var MIN_TICK = -887272;
2579
- var MAX_TICK = 887272;
2580
- function word(data, index) {
2581
- const hex = data.startsWith("0x") ? data.slice(2) : data;
2582
- const start = index * 64;
2583
- if (hex.length < start + 64) throw new Error(`return data too short for word ${index}`);
2584
- return BigInt(`0x${hex.slice(start, start + 64)}`);
2585
- }
2586
- function asSigned(value, bits) {
2587
- const width = 1n << BigInt(bits);
2588
- const masked = value & width - 1n;
2589
- return masked >= width >> 1n ? masked - width : masked;
2590
- }
2591
- function addressFromWord(data, index) {
2592
- const hex = data.startsWith("0x") ? data.slice(2) : data;
2593
- return `0x${hex.slice(index * 64 + 24, (index + 1) * 64)}`.toLowerCase();
2594
- }
2595
- function getSqrtRatioAtTick(tick) {
2596
- if (!Number.isInteger(tick) || tick < MIN_TICK || tick > MAX_TICK) {
2597
- throw new Error(`tick out of range: ${tick}`);
2598
- }
2599
- const absTick = BigInt(Math.abs(tick));
2600
- let ratio = (absTick & 0x1n) !== 0n ? 0xfffcb933bd6fad37aa2d162d1a594001n : 0x100000000000000000000000000000000n;
2601
- const factors = [
2602
- [0x2n, 0xfff97272373d413259a46990580e213an],
2603
- [0x4n, 0xfff2e50f5f656932ef12357cf3c7fdccn],
2604
- [0x8n, 0xffe5caca7e10e4e61c3624eaa0941cd0n],
2605
- [0x10n, 0xffcb9843d60f6159c9db58835c926644n],
2606
- [0x20n, 0xff973b41fa98c081472e6896dfb254c0n],
2607
- [0x40n, 0xff2ea16466c96a3843ec78b326b52861n],
2608
- [0x80n, 0xfe5dee046a99a2a811c461f1969c3053n],
2609
- [0x100n, 0xfcbe86c7900a88aedcffc83b479aa3a4n],
2610
- [0x200n, 0xf987a7253ac413176f2b074cf7815e54n],
2611
- [0x400n, 0xf3392b0822b70005940c7a398e4b70f3n],
2612
- [0x800n, 0xe7159475a2c29b7443b29c7fa6e889d9n],
2613
- [0x1000n, 0xd097f3bdfd2022b8845ad8f792aa5825n],
2614
- [0x2000n, 0xa9f746462d870fdf8a65dc1f90e061e5n],
2615
- [0x4000n, 0x70d869a156d2a1b890bb3df62baf32f7n],
2616
- [0x8000n, 0x31be135f97d08fd981231505542fcfa6n],
2617
- [0x10000n, 0x9aa508b5b7a84e1c677de54f3e99bc9n],
2618
- [0x20000n, 0x5d6af8dedb81196699c329225ee604n],
2619
- [0x40000n, 0x2216e584f5fa1ea926041bedfe98n],
2620
- [0x80000n, 0x48a170391f7dc42444e8fa2n]
2621
- ];
2622
- for (const [bit, factor] of factors) {
2623
- if ((absTick & bit) !== 0n) ratio = ratio * factor >> 128n;
2624
- }
2625
- if (tick > 0) ratio = (1n << 256n) / ratio;
2626
- return (ratio >> 32n) + (ratio % (1n << 32n) === 0n ? 0n : 1n);
2627
- }
2628
- function positionTicks(info) {
2629
- return {
2630
- tickLower: Number(asSigned(info >> 8n, 24)),
2631
- tickUpper: Number(asSigned(info >> 32n, 24))
2632
- };
2633
- }
2634
- function getAmountsForLiquidity(params) {
2635
- let { sqrtRatioAX96, sqrtRatioBX96 } = params;
2636
- const { sqrtPriceX96, liquidity } = params;
2637
- if (sqrtRatioAX96 > sqrtRatioBX96) [sqrtRatioAX96, sqrtRatioBX96] = [sqrtRatioBX96, sqrtRatioAX96];
2638
- const amount0For = (from, to) => liquidity * Q96 * (to - from) / to / from;
2639
- const amount1For = (from, to) => liquidity * (to - from) / Q96;
2640
- if (sqrtPriceX96 <= sqrtRatioAX96) {
2641
- return { amount0: amount0For(sqrtRatioAX96, sqrtRatioBX96), amount1: 0n };
2642
- }
2643
- if (sqrtPriceX96 < sqrtRatioBX96) {
2644
- return {
2645
- amount0: amount0For(sqrtPriceX96, sqrtRatioBX96),
2646
- amount1: amount1For(sqrtRatioAX96, sqrtPriceX96)
2647
- };
2648
- }
2649
- return { amount0: 0n, amount1: amount1For(sqrtRatioAX96, sqrtRatioBX96) };
2650
- }
2651
- function decodePoolAndPositionInfo(data) {
2652
- const hex = data.startsWith("0x") ? data.slice(2) : data;
2653
- if (hex.length < 6 * 64) throw new Error("getPoolAndPositionInfo returned too little data");
2654
- const { tickLower, tickUpper } = positionTicks(word(data, 5));
2655
- return {
2656
- currency0: addressFromWord(data, 0),
2657
- currency1: addressFromWord(data, 1),
2658
- poolKeyEncoded: `0x${hex.slice(0, 5 * 64)}`,
2659
- tickLower,
2660
- tickUpper
2661
- };
2662
- }
2663
- function positionAmountOfToken(params) {
2664
- const { info, liquidity, sqrtPriceX96 } = params;
2665
- const outputToken = params.outputToken.toLowerCase();
2666
- if (outputToken !== info.currency0 && outputToken !== info.currency1) return 0n;
2667
- if (liquidity <= 0n || sqrtPriceX96 <= 0n) return 0n;
2668
- const { amount0, amount1 } = getAmountsForLiquidity({
2669
- sqrtPriceX96,
2670
- sqrtRatioAX96: getSqrtRatioAtTick(info.tickLower),
2671
- sqrtRatioBX96: getSqrtRatioAtTick(info.tickUpper),
2672
- liquidity
2673
- });
2674
- return outputToken === info.currency0 ? amount0 : amount1;
2675
- }
2676
-
2677
- // src/protocols/intents/phantom-aggregation.ts
2678
- var ENTRY_POINT_V08_ADDRESS = "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108";
2679
2346
  var injectedFetch;
2680
2347
  function setAggregationFetch(fetchImpl) {
2681
2348
  injectedFetch = fetchImpl;
@@ -2683,18 +2350,10 @@ function setAggregationFetch(fetchImpl) {
2683
2350
  function rpcFetch() {
2684
2351
  const f = injectedFetch ?? globalThis.fetch;
2685
2352
  if (typeof f !== "function") {
2686
- throw new Error("No fetch available; call setAggregationFetch() before using the aggregation helpers");
2353
+ throw new Error("No fetch available; call setAggregationFetch() before reading bids");
2687
2354
  }
2688
2355
  return f;
2689
2356
  }
2690
- var PhantomRpcError = class extends Error {
2691
- constructor(message, cause) {
2692
- super(message);
2693
- this.cause = cause;
2694
- this.name = "PhantomRpcError";
2695
- }
2696
- cause;
2697
- };
2698
2357
  async function rpcCall(url, payload) {
2699
2358
  let lastErr;
2700
2359
  for (let attempt = 0; attempt < 4; attempt++) {
@@ -2724,13 +2383,80 @@ async function rpcCall(url, payload) {
2724
2383
  if (timer) clearTimeout(timer);
2725
2384
  }
2726
2385
  }
2727
- throw new PhantomRpcError(`RPC call failed after 4 attempts: ${url}`, lastErr);
2386
+ throw new Error(`RPC call failed after 4 attempts: ${url}`, { cause: lastErr });
2387
+ }
2388
+ async function fetchBidsForOrder(nodeUrl, commitment) {
2389
+ const data = await rpcCall(nodeUrl, {
2390
+ id: 1,
2391
+ jsonrpc: "2.0",
2392
+ method: "intents_getBidsForOrder",
2393
+ params: [commitment]
2394
+ });
2395
+ return Array.isArray(data.result) ? data.result : [];
2728
2396
  }
2729
- var FILL_ORDER_ABI = IntentGatewayV2_default.ABI;
2730
2397
  var DECLARATION_V1 = 1;
2731
2398
  var DECLARATION_V2 = 2;
2399
+ var PAYMASTER_ADDRESS_BYTES = 20;
2400
+ var PAYMASTER_GAS_LIMIT_BYTES = 16;
2401
+ var PAYMASTER_DATA_OFFSET = PAYMASTER_ADDRESS_BYTES + 2 * PAYMASTER_GAS_LIMIT_BYTES;
2402
+ var SIMPLEX_MODE_PERMIT2 = 2;
2403
+ var PERMIT2_DATA_BYTES = 1 + 20 + 32 + 32 + 32 + 1 + 32 + 32;
2404
+ var PERMIT2_SPONSORSHIP_BYTES = PAYMASTER_DATA_OFFSET + PERMIT2_DATA_BYTES;
2732
2405
  var MAX_DECLARED_ENTRIES = 255;
2733
2406
  var MAX_TOKEN_ID_BYTES = 32;
2407
+ function utf8Encode(text) {
2408
+ const bytes = [];
2409
+ for (const char of text) {
2410
+ const codePoint = char.codePointAt(0);
2411
+ if (codePoint < 128) bytes.push(codePoint);
2412
+ else if (codePoint < 2048) bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);
2413
+ else if (codePoint < 65536) {
2414
+ bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
2415
+ } else {
2416
+ bytes.push(
2417
+ 240 | codePoint >> 18,
2418
+ 128 | codePoint >> 12 & 63,
2419
+ 128 | codePoint >> 6 & 63,
2420
+ 128 | codePoint & 63
2421
+ );
2422
+ }
2423
+ }
2424
+ return bytes;
2425
+ }
2426
+ function utf8Decode(bytes) {
2427
+ let text = "";
2428
+ for (let offset = 0; offset < bytes.length; ) {
2429
+ const lead = bytes[offset];
2430
+ let codePoint;
2431
+ let continuations;
2432
+ if (lead < 128) {
2433
+ codePoint = lead;
2434
+ continuations = 0;
2435
+ } else if ((lead & 224) === 192) {
2436
+ codePoint = lead & 31;
2437
+ continuations = 1;
2438
+ } else if ((lead & 240) === 224) {
2439
+ codePoint = lead & 15;
2440
+ continuations = 2;
2441
+ } else if ((lead & 248) === 240) {
2442
+ codePoint = lead & 7;
2443
+ continuations = 3;
2444
+ } else {
2445
+ return null;
2446
+ }
2447
+ if (offset + continuations >= bytes.length) return null;
2448
+ for (let index = 1; index <= continuations; index++) {
2449
+ const byte = bytes[offset + index];
2450
+ if ((byte & 192) !== 128) return null;
2451
+ codePoint = codePoint << 6 | byte & 63;
2452
+ }
2453
+ const overlong = continuations === 1 && codePoint < 128 || continuations === 2 && codePoint < 2048 || continuations === 3 && codePoint < 65536;
2454
+ if (overlong || codePoint > 1114111 || codePoint >= 55296 && codePoint <= 57343) return null;
2455
+ text += String.fromCodePoint(codePoint);
2456
+ offset += continuations + 1;
2457
+ }
2458
+ return text;
2459
+ }
2734
2460
  function tokenIdToBytes(tokenId) {
2735
2461
  if (tokenId < 0n) throw new Error(`Uniswap V4 tokenId cannot be negative: ${tokenId}`);
2736
2462
  const bytes = [];
@@ -2753,7 +2479,7 @@ function encodePhantomBidDeclaration(declaration) {
2753
2479
  const version = positions.length > 0 ? DECLARATION_V2 : DECLARATION_V1;
2754
2480
  const bytes = [version, chains.length];
2755
2481
  for (const chain of chains) {
2756
- const encoded = stringToU8a(chain);
2482
+ const encoded = utf8Encode(chain);
2757
2483
  if (encoded.length === 0 || encoded.length > 255) {
2758
2484
  throw new Error(`Invalid state machine id in source chain declaration: ${chain}`);
2759
2485
  }
@@ -2771,543 +2497,101 @@ function encodePhantomBidDeclaration(declaration) {
2771
2497
  }
2772
2498
  return u8aToHex(new Uint8Array(bytes));
2773
2499
  }
2774
- function decodePhantomBidDeclaration(paymasterAndData) {
2775
- const absent = { acceptedSources: null, uniswapV4Positions: [] };
2776
- if (!paymasterAndData || !isHex(paymasterAndData)) return absent;
2777
- const bytes = hexToU8a(paymasterAndData);
2778
- if (bytes.length < 2) return absent;
2779
- const version = bytes[0];
2780
- if (version !== DECLARATION_V1 && version !== DECLARATION_V2) return absent;
2500
+ function parseDeclaration(bytes, start) {
2501
+ if (bytes.length - start < 2) return null;
2502
+ const version = bytes[start];
2503
+ if (version !== DECLARATION_V1 && version !== DECLARATION_V2) return null;
2781
2504
  const chains = [];
2782
- let offset = 2;
2783
- for (let entry = 0; entry < bytes[1]; entry++) {
2784
- if (offset >= bytes.length) return absent;
2505
+ let offset = start + 2;
2506
+ for (let entry = 0; entry < bytes[start + 1]; entry++) {
2507
+ if (offset >= bytes.length) return null;
2785
2508
  const length = bytes[offset];
2786
2509
  offset += 1;
2787
- if (length === 0 || offset + length > bytes.length) return absent;
2788
- chains.push(u8aToString(bytes.subarray(offset, offset + length)));
2510
+ if (length === 0 || offset + length > bytes.length) return null;
2511
+ const chain = utf8Decode(bytes.subarray(offset, offset + length));
2512
+ if (chain === null) return null;
2513
+ chains.push(chain);
2789
2514
  offset += length;
2790
2515
  }
2791
2516
  const positions = [];
2792
2517
  if (version === DECLARATION_V2) {
2793
- if (offset >= bytes.length) return absent;
2518
+ if (offset >= bytes.length) return null;
2794
2519
  const count = bytes[offset];
2795
2520
  offset += 1;
2796
2521
  for (let entry = 0; entry < count; entry++) {
2797
- if (offset >= bytes.length) return absent;
2522
+ if (offset >= bytes.length) return null;
2798
2523
  const length = bytes[offset];
2799
2524
  offset += 1;
2800
- if (length === 0 || length > MAX_TOKEN_ID_BYTES || offset + length > bytes.length) return absent;
2801
- let tokenId = 0n;
2802
- for (const byte of bytes.subarray(offset, offset + length)) tokenId = tokenId << 8n | BigInt(byte);
2803
- positions.push(tokenId);
2525
+ if (length === 0 || length > MAX_TOKEN_ID_BYTES || offset + length > bytes.length) return null;
2526
+ positions.push(bytesToBigInt2(bytes.subarray(offset, offset + length)));
2804
2527
  offset += length;
2805
2528
  }
2806
2529
  }
2807
- if (offset !== bytes.length) return absent;
2530
+ if (offset !== bytes.length) return null;
2808
2531
  return { acceptedSources: chains, uniswapV4Positions: positions };
2809
2532
  }
2810
- function encodeAcceptedSourceChains(chains) {
2811
- return encodePhantomBidDeclaration({ acceptedSourceChains: chains });
2812
- }
2813
- function decodeAcceptedSourceChains(paymasterAndData) {
2814
- return decodePhantomBidDeclaration(paymasterAndData).acceptedSources;
2815
- }
2816
- function zipFillLegs(assets, outputs) {
2817
- return assets.map((asset, index) => {
2818
- const rawAmount = outputs[index]?.amount;
2819
- return {
2820
- outputToken: asset.token,
2821
- solverAmount: rawAmount === void 0 || rawAmount === null ? 0n : BigInt(rawAmount.toString())
2822
- };
2823
- });
2824
- }
2825
- var UNISWAP_QUOTE_HAIRCUT_BPS = 10n;
2826
- function haircut(amount, bps) {
2827
- return amount * (10000n - bps) / 10000n;
2828
- }
2829
- function applyUniswapQuoteHaircut(amount) {
2830
- return haircut(amount, UNISWAP_QUOTE_HAIRCUT_BPS);
2831
- }
2832
- var SELECTOR_GATEWAY_PARAMS = "0xcff0ab96";
2833
- var GATEWAY_PARAMS_WORDS = 6;
2834
- var GATEWAY_PARAMS_FEE_WORD = 4;
2835
- async function readProtocolFeeHaircutBps(evmRpcUrl, gatewayAddress) {
2836
- const result = await rpcCall(evmRpcUrl, {
2837
- id: 1,
2838
- jsonrpc: "2.0",
2839
- method: "eth_call",
2840
- params: [{ to: gatewayAddress, data: SELECTOR_GATEWAY_PARAMS }, "latest"]
2841
- });
2842
- const hex = result.result;
2843
- if (typeof hex !== "string" || hex.length < 2 + 64 * GATEWAY_PARAMS_WORDS) {
2844
- throw new PhantomRpcError(`IntentGateway.params() returned no usable result from ${gatewayAddress} on ${evmRpcUrl}`);
2845
- }
2846
- const start = 2 + 64 * GATEWAY_PARAMS_FEE_WORD;
2847
- const protocolFeeBps = BigInt(`0x${hex.slice(start, start + 64)}`);
2848
- if (protocolFeeBps >= 10000n) {
2849
- throw new PhantomRpcError(`IntentGateway ${gatewayAddress} reports an implausible protocol fee: ${protocolFeeBps} bps`);
2850
- }
2851
- return protocolFeeBps;
2852
- }
2853
- function applyProtocolFeeHaircut(amount, protocolFeeBps) {
2854
- return haircut(amount, protocolFeeBps);
2855
- }
2856
- function weightedMedian(entries) {
2857
- const sorted = [...entries].sort((a, b) => a.price < b.price ? -1 : a.price > b.price ? 1 : 0);
2858
- const totalWeight = sorted.reduce((acc, e) => e.weight > 0n ? acc + e.weight : acc, 0n);
2859
- if (totalWeight === 0n) {
2860
- return sorted[Math.floor(sorted.length / 2)].price;
2861
- }
2862
- let cumulative = 0n;
2863
- for (const entry of sorted) {
2864
- if (entry.weight <= 0n) continue;
2865
- cumulative += entry.weight;
2866
- if (cumulative * 2n >= totalWeight) return entry.price;
2867
- }
2868
- return sorted[sorted.length - 1].price;
2869
- }
2870
- function extractFillData(callData, gatewayAddress) {
2871
- const calls = decodeERC7821ExecuteBatch(callData);
2872
- if (!calls) return null;
2873
- const normalized = gatewayAddress.toLowerCase();
2874
- for (const call of calls) {
2875
- if (call.target.toLowerCase() !== normalized) continue;
2876
- try {
2877
- const decoded = decodeFillOrder(call.data);
2878
- if (!decoded) continue;
2879
- const order = decoded.order;
2880
- const options = decoded.options;
2881
- const assets = order?.output?.assets;
2882
- const outputs = options?.outputs;
2883
- if (!assets?.length || !outputs?.length) continue;
2884
- return { order, options, legs: zipFillLegs(assets, outputs) };
2885
- } catch {
2886
- continue;
2887
- }
2888
- }
2889
- return null;
2533
+ function bytesToBigInt2(bytes) {
2534
+ let value = 0n;
2535
+ for (const byte of bytes) value = value << 8n | BigInt(byte);
2536
+ return value;
2890
2537
  }
2891
- var FILL_ORDER_INPUT = FILL_ORDER_ABI.find(
2892
- (item) => item?.type === "function" && item?.name === "fillOrder"
2893
- )?.inputs?.[0];
2894
- function orderCommitmentFromDecoded(order) {
2895
- try {
2896
- if (!FILL_ORDER_INPUT) return null;
2897
- return keccak256(encodeAbiParameters([FILL_ORDER_INPUT], [order]));
2898
- } catch {
2899
- return null;
2900
- }
2538
+ function bytesToAddress(bytes) {
2539
+ return u8aToHex(bytes);
2901
2540
  }
2902
- var BID_COMMITMENT_BYTES = 32;
2903
- var SOLVER_SIGNATURE_BYTES = 65;
2904
- function splitBidSignature(signature) {
2905
- const raw = signature.replace(/^0x/, "");
2906
- const commitmentChars = BID_COMMITMENT_BYTES * 2;
2907
- const end = commitmentChars + SOLVER_SIGNATURE_BYTES * 2;
2908
- if (raw.length < end) return null;
2909
- return {
2910
- commitment: `0x${raw.slice(0, commitmentChars)}`,
2911
- solverSignature: `0x${raw.slice(commitmentChars, end)}`
2912
- };
2541
+ function hasPermit2Sponsorship(bytes) {
2542
+ return bytes.length >= PERMIT2_SPONSORSHIP_BYTES && bytes[PAYMASTER_DATA_OFFSET] === SIMPLEX_MODE_PERMIT2;
2913
2543
  }
2914
- var recoverBidSignerViem = async (userOp, entryPoint, chainId, solverSignature) => {
2915
- try {
2916
- const userOpHash = CryptoUtils.computeUserOpHash(userOp, entryPoint, chainId);
2917
- return await recoverAddress({ hash: userOpHash, signature: solverSignature });
2918
- } catch {
2919
- return null;
2920
- }
2921
- };
2922
- var DELEGATION_INDICATOR_PREFIX = "0xef0100";
2923
- async function isDelegatedToSolverAccount(evmRpcUrl, account, solverAccounts) {
2924
- const response = await rpcCall(evmRpcUrl, {
2925
- id: 1,
2926
- jsonrpc: "2.0",
2927
- method: "eth_getCode",
2928
- params: [account, "latest"]
2929
- });
2930
- if (typeof response.result !== "string") {
2931
- throw new PhantomRpcError(`eth_getCode returned no code for ${account} on ${evmRpcUrl}`);
2932
- }
2933
- const code = response.result.toLowerCase();
2934
- if (!code.startsWith(DELEGATION_INDICATOR_PREFIX)) return false;
2935
- const delegate = `0x${code.slice(DELEGATION_INDICATOR_PREFIX.length)}`;
2936
- return solverAccounts.some((solverAccount) => solverAccount.toLowerCase() === delegate);
2937
- }
2938
- function memoizedDelegationCheck() {
2939
- const cache = /* @__PURE__ */ new Map();
2940
- return (evmRpcUrl, account, solverAccounts) => {
2941
- const targets = solverAccounts.map((a) => a.toLowerCase()).sort().join(",");
2942
- const key = `${evmRpcUrl}|${account.toLowerCase()}|${targets}`;
2943
- let pending = cache.get(key);
2944
- if (!pending) {
2945
- pending = isDelegatedToSolverAccount(evmRpcUrl, account, solverAccounts).catch((err) => {
2946
- cache.delete(key);
2947
- throw err;
2948
- });
2949
- cache.set(key, pending);
2950
- }
2951
- return pending;
2544
+ function parseSponsorship(bytes) {
2545
+ let offset = 0;
2546
+ const take = (length) => {
2547
+ const slice = bytes.subarray(offset, offset + length);
2548
+ offset += length;
2549
+ return slice;
2952
2550
  };
2551
+ const paymaster = bytesToAddress(take(PAYMASTER_ADDRESS_BYTES));
2552
+ take(2 * PAYMASTER_GAS_LIMIT_BYTES);
2553
+ take(1);
2554
+ const token = bytesToAddress(take(20));
2555
+ const permitAmount = bytesToBigInt2(take(32));
2556
+ const nonce = bytesToBigInt2(take(32));
2557
+ const deadline = bytesToBigInt2(take(32));
2558
+ return { paymaster, token, permitAmount, nonce, deadline };
2953
2559
  }
2954
- function evmChainId(chain) {
2955
- const [prefix, id] = chain.split("-");
2956
- if (prefix !== "EVM" || !id || !/^\d+$/.test(id)) return null;
2957
- return BigInt(id);
2958
- }
2959
- async function isVerifiedSolverBid(params) {
2960
- const {
2961
- userOp,
2962
- commitment,
2963
- sessionKey,
2964
- chainId,
2965
- solverAccounts,
2966
- evmRpcUrl,
2967
- recoverSigner,
2968
- bidNonceKey,
2969
- isDelegated,
2970
- logger
2971
- } = params;
2972
- const solver = userOp.sender;
2973
- const parsed = splitBidSignature(userOp.signature);
2974
- if (!parsed) {
2975
- logger?.warn({ solver, commitment }, "Rejecting phantom bid: malformed userOp signature");
2976
- return false;
2977
- }
2978
- if (parsed.commitment.toLowerCase() !== commitment.toLowerCase()) {
2979
- logger?.warn(
2980
- { solver, commitment, signedFor: parsed.commitment },
2981
- "Rejecting phantom bid: signed for another order"
2982
- );
2983
- return false;
2984
- }
2985
- if (BigInt(userOp.nonce) >> 64n !== bidNonceKey(commitment, sessionKey)) {
2986
- logger?.warn({ solver, commitment }, "Rejecting phantom bid: nonce does not bind order and session key");
2987
- return false;
2988
- }
2989
- const signer = await recoverSigner(userOp, ENTRY_POINT_V08_ADDRESS, chainId, parsed.solverSignature);
2990
- if (!signer || signer.toLowerCase() !== solver.toLowerCase()) {
2991
- logger?.warn({ solver, commitment, signer }, "Rejecting phantom bid: signature does not recover to the sender");
2992
- return false;
2993
- }
2994
- if (!await isDelegated(evmRpcUrl, solver, solverAccounts)) {
2995
- logger?.warn({ solver, commitment, solverAccounts }, "Rejecting phantom bid: sender is not a delegated solver");
2996
- return false;
2997
- }
2998
- return true;
2999
- }
3000
- async function fetchBidsForOrder(nodeUrl, commitment) {
3001
- const data = await rpcCall(nodeUrl, {
3002
- id: 1,
3003
- jsonrpc: "2.0",
3004
- method: "intents_getBidsForOrder",
3005
- params: [commitment]
3006
- });
3007
- return Array.isArray(data.result) ? data.result : [];
3008
- }
3009
- async function ethCallUint(evmRpcUrl, to, data, blockTag = "latest") {
3010
- const result = await rpcCall(evmRpcUrl, {
3011
- id: 1,
3012
- jsonrpc: "2.0",
3013
- method: "eth_call",
3014
- params: [{ to, data }, blockTag]
3015
- });
3016
- if (result.result === "0x") return 0n;
3017
- if (typeof result.result !== "string") {
3018
- throw new PhantomRpcError(`eth_call returned no result for ${to} on ${evmRpcUrl}`);
3019
- }
3020
- return BigInt(result.result);
2560
+ var absentDeclaration = () => ({ acceptedSources: null, uniswapV4Positions: [] });
2561
+ function decodePhantomBidPaymasterAndData(paymasterAndData) {
2562
+ const none = { mode: "none", declaration: absentDeclaration(), sponsorship: null };
2563
+ if (!paymasterAndData || !isHex(paymasterAndData)) return none;
2564
+ const bytes = hexToU8a(paymasterAndData);
2565
+ const bare = parseDeclaration(bytes, 0);
2566
+ if (bare) return { mode: "declaration", declaration: bare, sponsorship: null };
2567
+ if (!hasPermit2Sponsorship(bytes)) return none;
2568
+ const sponsorship = parseSponsorship(bytes);
2569
+ const tail = bytes.length > PERMIT2_SPONSORSHIP_BYTES ? parseDeclaration(bytes, PERMIT2_SPONSORSHIP_BYTES) : null;
2570
+ return { mode: "permit2", declaration: tail ?? absentDeclaration(), sponsorship };
3021
2571
  }
3022
- async function getTotalSolverBalance(evmRpcUrl, chain, token, solver, yieldVaults, blockTag = "latest") {
3023
- const padded = solver.replace("0x", "").padStart(64, "0");
3024
- const raw = await ethCallUint(evmRpcUrl, token, `0x70a08231${padded}`, blockTag);
3025
- const vaults = yieldVaults[chain]?.[token.toLowerCase()] ?? [];
3026
- const vaultBalances = await Promise.all(
3027
- vaults.map((v) => ethCallUint(evmRpcUrl, v, `0xce96cb77${padded}`, blockTag))
3028
- // maxWithdraw(address)
3029
- );
3030
- return vaultBalances.reduce((acc, b) => acc + b, raw);
2572
+ function decodePhantomBidDeclaration(paymasterAndData) {
2573
+ return decodePhantomBidPaymasterAndData(paymasterAndData).declaration;
3031
2574
  }
3032
- var SELECTOR_OWNER_OF = "0x6352211e";
3033
- var SELECTOR_POSITION_LIQUIDITY = "0x1efeed33";
3034
- var SELECTOR_POOL_AND_POSITION_INFO = "0x7ba03aad";
3035
- var SELECTOR_GET_SLOT0 = "0xc815641c";
3036
- var uint256Arg = (value) => value.toString(16).padStart(64, "0");
3037
- async function readV4Position(params) {
3038
- const { evmRpcUrl, contracts, tokenId, keccak, blockTag = "latest", logger } = params;
3039
- const call = async (to, data) => {
3040
- const result = await rpcCall(evmRpcUrl, {
3041
- id: 1,
3042
- jsonrpc: "2.0",
3043
- method: "eth_call",
3044
- params: [{ to, data }, blockTag]
3045
- });
3046
- if (result.result === "0x") return null;
3047
- if (typeof result.result !== "string") {
3048
- throw new PhantomRpcError(`eth_call returned no result for ${to} on ${evmRpcUrl}`);
3049
- }
3050
- return result.result;
3051
- };
3052
- const arg = uint256Arg(tokenId);
3053
- const [ownerData, infoData, liquidityData] = await Promise.all([
3054
- call(contracts.positionManager, `${SELECTOR_OWNER_OF}${arg}`),
3055
- call(contracts.positionManager, `${SELECTOR_POOL_AND_POSITION_INFO}${arg}`),
3056
- call(contracts.positionManager, `${SELECTOR_POSITION_LIQUIDITY}${arg}`)
3057
- ]);
3058
- if (!ownerData) return null;
3059
- if (!infoData || !liquidityData) {
3060
- logger?.warn(
3061
- { tokenId: tokenId.toString(), positionManager: contracts.positionManager },
3062
- "Uniswap V4 position exists but its pool info or liquidity did not read back \u2014 check the configured PositionManager"
3063
- );
3064
- return null;
3065
- }
3066
- const info = decodePoolAndPositionInfo(infoData);
3067
- const slot0Data = await call(contracts.stateView, `${SELECTOR_GET_SLOT0}${keccak(info.poolKeyEncoded).slice(2)}`);
3068
- if (!slot0Data) {
3069
- logger?.warn(
3070
- { tokenId: tokenId.toString(), stateView: contracts.stateView, evmRpcUrl },
3071
- "Uniswap V4 slot0 read returned nothing for a live position \u2014 the configured StateView address is wrong"
2575
+ function encodePhantomBidPaymasterAndData(bid) {
2576
+ const declaration = encodePhantomBidDeclaration(bid);
2577
+ const sponsorship = bid.sponsorship;
2578
+ if (!sponsorship || sponsorship === "0x") return declaration;
2579
+ if (!isHex(sponsorship)) throw new Error("Phantom bid sponsorship is not hex");
2580
+ const bytes = hexToU8a(sponsorship);
2581
+ if (bytes.length !== PERMIT2_SPONSORSHIP_BYTES || !hasPermit2Sponsorship(bytes)) {
2582
+ throw new Error(
2583
+ `Phantom bid sponsorship must be a ${PERMIT2_SPONSORSHIP_BYTES}-byte Permit2-mode paymasterAndData, got ${bytes.length} bytes`
3072
2584
  );
3073
- return null;
3074
2585
  }
3075
- return {
3076
- owner: `0x${ownerData.slice(-40)}`.toLowerCase(),
3077
- info,
3078
- liquidity: word(liquidityData, 0),
3079
- sqrtPriceX96: word(slot0Data, 0)
3080
- };
3081
- }
3082
- function memoizedV4Position(keccak, logger) {
3083
- const cache = /* @__PURE__ */ new Map();
3084
- return (evmRpcUrl, chain, contracts, tokenId) => {
3085
- const key = `${chain}|${tokenId}`;
3086
- let pending = cache.get(key);
3087
- if (!pending) {
3088
- pending = readV4Position({ evmRpcUrl, contracts, tokenId, keccak, logger }).catch((err) => {
3089
- cache.delete(key);
3090
- throw err;
3091
- });
3092
- cache.set(key, pending);
3093
- }
3094
- return pending;
3095
- };
3096
- }
3097
- function memoizedSolverBalance(yieldVaults, blockTags = {}) {
3098
- const cache = /* @__PURE__ */ new Map();
3099
- return (evmRpcUrl, chain, token, solver) => {
3100
- const key = `${chain}|${token.toLowerCase()}|${solver.toLowerCase()}`;
3101
- let pending = cache.get(key);
3102
- if (!pending) {
3103
- pending = getTotalSolverBalance(evmRpcUrl, chain, token, solver, yieldVaults, blockTags[chain]).catch((err) => {
3104
- cache.delete(key);
3105
- throw err;
3106
- });
3107
- cache.set(key, pending);
3108
- }
3109
- return pending;
3110
- };
2586
+ return `${sponsorship}${declaration.slice(2)}`;
3111
2587
  }
3112
- async function sweepSolverLiquidity(evmRpcUrls, yieldVaults, solver, getBalance, positions) {
3113
- const balances = [];
3114
- for (const [chain, tokens] of Object.entries(yieldVaults)) {
3115
- const url = evmRpcUrls[chain];
3116
- if (!url) continue;
3117
- for (const token of Object.keys(tokens)) {
3118
- const balance = await getBalance(url, chain, token, solver);
3119
- const uniswapV4Balance = chain === positions.chain ? positions.states.reduce(
3120
- (total2, state) => total2 + positionAmountOfToken({
3121
- info: state.info,
3122
- liquidity: state.liquidity,
3123
- sqrtPriceX96: state.sqrtPriceX96,
3124
- outputToken: token
3125
- }),
3126
- 0n
3127
- ) : 0n;
3128
- const total = balance + uniswapV4Balance;
3129
- if (total === 0n) continue;
3130
- balances.push({ solver, chain, tokenAddress: token, balance: total });
3131
- }
3132
- }
3133
- return balances;
3134
- }
3135
- function toAddress(token) {
3136
- const hex = token.toLowerCase().replace(/^0x/, "");
3137
- const addr = hex.length > 40 ? hex.slice(-40) : hex.padStart(40, "0");
3138
- return `0x${addr}`;
3139
- }
3140
- async function aggregatePhantomBids(params) {
3141
- const isDelegated = memoizedDelegationCheck();
3142
- let lastErr;
3143
- for (let attempt = 1; attempt <= AGGREGATION_ATTEMPTS; attempt++) {
3144
- try {
3145
- return await runAggregation(params, isDelegated);
3146
- } catch (err) {
3147
- lastErr = err;
3148
- params.logger?.warn(
3149
- { err, commitment: params.commitment, chain: params.chain, attempt, of: AGGREGATION_ATTEMPTS },
3150
- "Phantom aggregation attempt failed"
3151
- );
3152
- if (attempt < AGGREGATION_ATTEMPTS) await new Promise((resolve) => setTimeout(resolve, 250 * attempt));
3153
- }
3154
- }
3155
- throw lastErr;
2588
+ function encodeAcceptedSourceChains(chains) {
2589
+ return encodePhantomBidDeclaration({ acceptedSourceChains: chains });
3156
2590
  }
3157
- var AGGREGATION_ATTEMPTS = 5;
3158
- async function runAggregation(params, isDelegated) {
3159
- const { nodeUrl, evmRpcUrls, chain, gatewayAddress, commitment, yieldVaults, logger } = params;
3160
- const solverAccounts = (Array.isArray(params.solverAccount) ? params.solverAccount : [params.solverAccount]).filter(
3161
- (a) => typeof a === "string" && a.length > 0
3162
- );
3163
- const extractFill = params.extractFill ?? extractFillData;
3164
- const recoverSigner = params.recoverSigner ?? recoverBidSignerViem;
3165
- const bidNonceKey = params.bidNonceKey ?? CryptoUtils.bidNonceKey;
3166
- const orderCommitment = params.orderCommitment ?? orderCommitmentFromDecoded;
3167
- const destUrl = evmRpcUrls[chain];
3168
- if (!destUrl) return null;
3169
- const chainId = evmChainId(chain);
3170
- if (solverAccounts.length === 0 || chainId === null) {
3171
- logger?.warn({ chain, commitment }, "Cannot verify phantom bids: no SolverAccount or chain id for chain");
3172
- return null;
3173
- }
3174
- const bids = await fetchBidsForOrder(nodeUrl, commitment);
3175
- if (bids.length === 0) return null;
3176
- const protocolFeeHaircutBps = await readProtocolFeeHaircutBps(destUrl, gatewayAddress);
3177
- const v4Contracts = params.uniswapV4?.[chain];
3178
- const readPosition = memoizedV4Position(params.keccak ?? keccak256, logger);
3179
- const getBalance = params.getBalance ?? memoizedSolverBalance(yieldVaults);
3180
- const quotesByLeg = /* @__PURE__ */ new Map();
3181
- const lpBalances = [];
3182
- const verifiedPositions = [];
3183
- const countedSolvers = /* @__PURE__ */ new Set();
3184
- for (const bid of bids) {
3185
- if (!bid.user_op) continue;
3186
- try {
3187
- const decoded = decodeUserOpScale(bid.user_op);
3188
- const solver = decoded.sender;
3189
- const fillData = extractFill(decoded.callData, gatewayAddress);
3190
- if (!fillData) continue;
3191
- const decodedCommitment = orderCommitment(fillData.order);
3192
- if (!decodedCommitment || decodedCommitment.toLowerCase() !== commitment.toLowerCase()) {
3193
- logger?.warn({ solver, commitment }, "Rejecting phantom bid: calldata order is not the indexed order");
3194
- continue;
3195
- }
3196
- const sessionKey = fillData.order?.session;
3197
- if (!sessionKey) {
3198
- logger?.warn({ solver, commitment }, "Rejecting phantom bid: order carries no session key");
3199
- continue;
3200
- }
3201
- const verified = await isVerifiedSolverBid({
3202
- userOp: decoded,
3203
- commitment,
3204
- sessionKey,
3205
- chainId,
3206
- solverAccounts,
3207
- evmRpcUrl: destUrl,
3208
- recoverSigner,
3209
- bidNonceKey,
3210
- isDelegated,
3211
- logger
3212
- });
3213
- if (!verified) continue;
3214
- const normalizedSolver = solver.toLowerCase();
3215
- if (countedSolvers.has(normalizedSolver)) {
3216
- logger?.warn({ solver, commitment }, "Skipping phantom bid: solver already counted for this order");
3217
- continue;
3218
- }
3219
- countedSolvers.add(normalizedSolver);
3220
- const declaration = decodePhantomBidDeclaration(decoded.paymasterAndData);
3221
- const acceptedSources = declaration.acceptedSources;
3222
- const poolPriced = declaration.uniswapV4Positions.length > 0;
3223
- const applyHaircut = (amount) => poolPriced ? applyUniswapQuoteHaircut(amount) : applyProtocolFeeHaircut(amount, protocolFeeHaircutBps);
3224
- const quotedLegs = [...fillData.legs.entries()].map(([legIndex, leg]) => [
3225
- legIndex,
3226
- { ...leg, solverAmount: applyHaircut(leg.solverAmount) }
3227
- ]).filter(([, leg]) => leg.solverAmount !== 0n);
3228
- const declaredPositions = v4Contracts ? declaration.uniswapV4Positions : [];
3229
- const ownedPositions = (await Promise.all(
3230
- declaredPositions.map(async (tokenId) => ({
3231
- tokenId,
3232
- state: await readPosition(destUrl, chain, v4Contracts, tokenId)
3233
- }))
3234
- )).filter((entry) => {
3235
- if (!entry.state) return false;
3236
- if (entry.state.owner !== normalizedSolver) {
3237
- logger?.warn(
3238
- { solver, commitment, tokenId: entry.tokenId.toString(), owner: entry.state.owner },
3239
- "Ignoring declared Uniswap V4 position: not owned by the bidding solver"
3240
- );
3241
- return false;
3242
- }
3243
- return true;
3244
- });
3245
- const positions = ownedPositions.map((entry) => entry.state);
3246
- for (const entry of ownedPositions) {
3247
- verifiedPositions.push({ solver: normalizedSolver, chain, tokenId: entry.tokenId });
3248
- }
3249
- const weights = await Promise.all(
3250
- // Price influence: the solver's liquidity in THIS leg's output token on the destination
3251
- // chain, so a leg is weighted by the inventory that actually backs it.
3252
- quotedLegs.map(async ([, leg]) => {
3253
- const outputToken = toAddress(leg.outputToken);
3254
- const balance = await getBalance(destUrl, chain, outputToken, solver);
3255
- return positions.reduce(
3256
- (total, state) => total + positionAmountOfToken({
3257
- info: state.info,
3258
- liquidity: state.liquidity,
3259
- sqrtPriceX96: state.sqrtPriceX96,
3260
- outputToken
3261
- }),
3262
- balance
3263
- );
3264
- })
3265
- );
3266
- for (const [position, [legIndex, leg]] of quotedLegs.entries()) {
3267
- const weight = weights[position];
3268
- const entry = quotesByLeg.get(legIndex) ?? { outputToken: leg.outputToken, quotes: [], bidders: [] };
3269
- entry.quotes.push({ price: leg.solverAmount, weight });
3270
- entry.bidders.push({ solver: normalizedSolver, weight, acceptedSources });
3271
- quotesByLeg.set(legIndex, entry);
3272
- }
3273
- lpBalances.push(
3274
- ...await sweepSolverLiquidity(evmRpcUrls, yieldVaults, solver, getBalance, {
3275
- chain,
3276
- states: positions
3277
- })
3278
- );
3279
- } catch (err) {
3280
- if (err instanceof PhantomRpcError) throw err;
3281
- logger?.warn({ err, filler: bid.filler }, "Failed to process bid for price snapshot");
3282
- }
3283
- }
3284
- if (quotesByLeg.size === 0) return null;
3285
- const legs = [...quotesByLeg.entries()].sort(([a], [b]) => a - b).flatMap(([legIndex, { outputToken, quotes, bidders }]) => {
3286
- const backedQuotes = quotes.filter((quote) => quote.weight > 0n);
3287
- const backedBidders = bidders.filter((bidder) => bidder.weight > 0n);
3288
- if (backedQuotes.length === 0) {
3289
- logger?.warn(
3290
- { commitment, chain, legIndex, outputToken, quotes: quotes.length },
3291
- "Dropping phantom leg: no bidder holds the output token on this chain, so no quote is backed"
3292
- );
3293
- return [];
3294
- }
3295
- const medianPrice = weightedMedian(backedQuotes);
3296
- return [
3297
- {
3298
- legIndex,
3299
- outputToken,
3300
- lowestPrice: medianPrice,
3301
- highestPrice: medianPrice,
3302
- medianPrice,
3303
- bidCount: backedQuotes.length,
3304
- bidders: backedBidders
3305
- }
3306
- ];
3307
- });
3308
- return { legs, lpBalances, positions: verifiedPositions, solvers: [...countedSolvers] };
2591
+ function decodeAcceptedSourceChains(paymasterAndData) {
2592
+ return decodePhantomBidDeclaration(paymasterAndData).acceptedSources;
3309
2593
  }
3310
2594
 
3311
- export { ENTRY_POINT_V08_ADDRESS, FILL_ORDER_ABI, FILL_ORDER_V1_ABI, IntentGatewayV2_default as IntentGatewayV2, UNISWAP_QUOTE_HAIRCUT_BPS, aggregatePhantomBids, applyProtocolFeeHaircut, applyUniswapQuoteHaircut, decodeAcceptedSourceChains, decodeERC7821ExecuteBatch, decodePhantomBidDeclaration, decodeUserOpScale, encodeAcceptedSourceChains, encodeERC7821ExecuteBatch, encodePhantomBidDeclaration, encodeUserOpScale, extractFillData, fetchBidsForOrder, getTotalSolverBalance, memoizedSolverBalance, orderCommitmentFromDecoded, poolSlug, positionAmountOfToken, readProtocolFeeHaircutBps, readV4Position, recoverBidSignerViem, setAggregationFetch, sortPoolSymbols, splitBidSignature, weightedMedian, zipFillLegs };
2595
+ export { IntentGatewayV2_default as IntentGatewayV2, MAX_DECLARED_ENTRIES, PERMIT2_SPONSORSHIP_BYTES, decodeAcceptedSourceChains, decodeERC7821ExecuteBatch, decodePhantomBidDeclaration, decodePhantomBidPaymasterAndData, decodeUserOpScale, encodeAcceptedSourceChains, encodeERC7821ExecuteBatch, encodePhantomBidDeclaration, encodePhantomBidPaymasterAndData, encodeUserOpScale, fetchBidsForOrder, poolSlug, setAggregationFetch, sortPoolSymbols };
3312
2596
  //# sourceMappingURL=intents-helpers.js.map
3313
2597
  //# sourceMappingURL=intents-helpers.js.map