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