@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.
- package/dist/browser/index.d.ts +807 -906
- package/dist/browser/index.js +1487 -2099
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +1510 -2117
- 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 +1487 -2099
- package/dist/node/index.js.map +1 -1
- package/dist/node/{intents-helpers-C9PJp8rx.d.cts → intents-helpers-BHl2If1T.d.cts} +909 -2908
- package/dist/node/{intents-helpers-C9PJp8rx.d.ts → intents-helpers-BHl2If1T.d.ts} +909 -2908
- package/dist/node/intents-helpers.cjs +499 -1229
- 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 +498 -1214
- 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,13 +2385,80 @@ 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;
|
|
2401
|
+
var PAYMASTER_ADDRESS_BYTES = 20;
|
|
2402
|
+
var PAYMASTER_GAS_LIMIT_BYTES = 16;
|
|
2403
|
+
var PAYMASTER_DATA_OFFSET = PAYMASTER_ADDRESS_BYTES + 2 * PAYMASTER_GAS_LIMIT_BYTES;
|
|
2404
|
+
var SIMPLEX_MODE_PERMIT2 = 2;
|
|
2405
|
+
var PERMIT2_DATA_BYTES = 1 + 20 + 32 + 32 + 32 + 1 + 32 + 32;
|
|
2406
|
+
var PERMIT2_SPONSORSHIP_BYTES = PAYMASTER_DATA_OFFSET + PERMIT2_DATA_BYTES;
|
|
2734
2407
|
var MAX_DECLARED_ENTRIES = 255;
|
|
2735
2408
|
var MAX_TOKEN_ID_BYTES = 32;
|
|
2409
|
+
function utf8Encode(text) {
|
|
2410
|
+
const bytes = [];
|
|
2411
|
+
for (const char of text) {
|
|
2412
|
+
const codePoint = char.codePointAt(0);
|
|
2413
|
+
if (codePoint < 128) bytes.push(codePoint);
|
|
2414
|
+
else if (codePoint < 2048) bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);
|
|
2415
|
+
else if (codePoint < 65536) {
|
|
2416
|
+
bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
|
|
2417
|
+
} else {
|
|
2418
|
+
bytes.push(
|
|
2419
|
+
240 | codePoint >> 18,
|
|
2420
|
+
128 | codePoint >> 12 & 63,
|
|
2421
|
+
128 | codePoint >> 6 & 63,
|
|
2422
|
+
128 | codePoint & 63
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
return bytes;
|
|
2427
|
+
}
|
|
2428
|
+
function utf8Decode(bytes) {
|
|
2429
|
+
let text = "";
|
|
2430
|
+
for (let offset = 0; offset < bytes.length; ) {
|
|
2431
|
+
const lead = bytes[offset];
|
|
2432
|
+
let codePoint;
|
|
2433
|
+
let continuations;
|
|
2434
|
+
if (lead < 128) {
|
|
2435
|
+
codePoint = lead;
|
|
2436
|
+
continuations = 0;
|
|
2437
|
+
} else if ((lead & 224) === 192) {
|
|
2438
|
+
codePoint = lead & 31;
|
|
2439
|
+
continuations = 1;
|
|
2440
|
+
} else if ((lead & 240) === 224) {
|
|
2441
|
+
codePoint = lead & 15;
|
|
2442
|
+
continuations = 2;
|
|
2443
|
+
} else if ((lead & 248) === 240) {
|
|
2444
|
+
codePoint = lead & 7;
|
|
2445
|
+
continuations = 3;
|
|
2446
|
+
} else {
|
|
2447
|
+
return null;
|
|
2448
|
+
}
|
|
2449
|
+
if (offset + continuations >= bytes.length) return null;
|
|
2450
|
+
for (let index = 1; index <= continuations; index++) {
|
|
2451
|
+
const byte = bytes[offset + index];
|
|
2452
|
+
if ((byte & 192) !== 128) return null;
|
|
2453
|
+
codePoint = codePoint << 6 | byte & 63;
|
|
2454
|
+
}
|
|
2455
|
+
const overlong = continuations === 1 && codePoint < 128 || continuations === 2 && codePoint < 2048 || continuations === 3 && codePoint < 65536;
|
|
2456
|
+
if (overlong || codePoint > 1114111 || codePoint >= 55296 && codePoint <= 57343) return null;
|
|
2457
|
+
text += String.fromCodePoint(codePoint);
|
|
2458
|
+
offset += continuations + 1;
|
|
2459
|
+
}
|
|
2460
|
+
return text;
|
|
2461
|
+
}
|
|
2736
2462
|
function tokenIdToBytes(tokenId) {
|
|
2737
2463
|
if (tokenId < 0n) throw new Error(`Uniswap V4 tokenId cannot be negative: ${tokenId}`);
|
|
2738
2464
|
const bytes = [];
|
|
@@ -2755,7 +2481,7 @@ function encodePhantomBidDeclaration(declaration) {
|
|
|
2755
2481
|
const version = positions.length > 0 ? DECLARATION_V2 : DECLARATION_V1;
|
|
2756
2482
|
const bytes = [version, chains.length];
|
|
2757
2483
|
for (const chain of chains) {
|
|
2758
|
-
const encoded =
|
|
2484
|
+
const encoded = utf8Encode(chain);
|
|
2759
2485
|
if (encoded.length === 0 || encoded.length > 255) {
|
|
2760
2486
|
throw new Error(`Invalid state machine id in source chain declaration: ${chain}`);
|
|
2761
2487
|
}
|
|
@@ -2773,573 +2499,117 @@ function encodePhantomBidDeclaration(declaration) {
|
|
|
2773
2499
|
}
|
|
2774
2500
|
return util.u8aToHex(new Uint8Array(bytes));
|
|
2775
2501
|
}
|
|
2776
|
-
function
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
if (bytes.length < 2) return absent;
|
|
2781
|
-
const version = bytes[0];
|
|
2782
|
-
if (version !== DECLARATION_V1 && version !== DECLARATION_V2) return absent;
|
|
2502
|
+
function parseDeclaration(bytes, start) {
|
|
2503
|
+
if (bytes.length - start < 2) return null;
|
|
2504
|
+
const version = bytes[start];
|
|
2505
|
+
if (version !== DECLARATION_V1 && version !== DECLARATION_V2) return null;
|
|
2783
2506
|
const chains = [];
|
|
2784
|
-
let offset = 2;
|
|
2785
|
-
for (let entry = 0; entry < bytes[1]; entry++) {
|
|
2786
|
-
if (offset >= bytes.length) return
|
|
2507
|
+
let offset = start + 2;
|
|
2508
|
+
for (let entry = 0; entry < bytes[start + 1]; entry++) {
|
|
2509
|
+
if (offset >= bytes.length) return null;
|
|
2787
2510
|
const length = bytes[offset];
|
|
2788
2511
|
offset += 1;
|
|
2789
|
-
if (length === 0 || offset + length > bytes.length) return
|
|
2790
|
-
|
|
2512
|
+
if (length === 0 || offset + length > bytes.length) return null;
|
|
2513
|
+
const chain = utf8Decode(bytes.subarray(offset, offset + length));
|
|
2514
|
+
if (chain === null) return null;
|
|
2515
|
+
chains.push(chain);
|
|
2791
2516
|
offset += length;
|
|
2792
2517
|
}
|
|
2793
2518
|
const positions = [];
|
|
2794
2519
|
if (version === DECLARATION_V2) {
|
|
2795
|
-
if (offset >= bytes.length) return
|
|
2520
|
+
if (offset >= bytes.length) return null;
|
|
2796
2521
|
const count = bytes[offset];
|
|
2797
2522
|
offset += 1;
|
|
2798
2523
|
for (let entry = 0; entry < count; entry++) {
|
|
2799
|
-
if (offset >= bytes.length) return
|
|
2524
|
+
if (offset >= bytes.length) return null;
|
|
2800
2525
|
const length = bytes[offset];
|
|
2801
2526
|
offset += 1;
|
|
2802
|
-
if (length === 0 || length > MAX_TOKEN_ID_BYTES || offset + length > bytes.length) return
|
|
2803
|
-
|
|
2804
|
-
for (const byte of bytes.subarray(offset, offset + length)) tokenId = tokenId << 8n | BigInt(byte);
|
|
2805
|
-
positions.push(tokenId);
|
|
2527
|
+
if (length === 0 || length > MAX_TOKEN_ID_BYTES || offset + length > bytes.length) return null;
|
|
2528
|
+
positions.push(bytesToBigInt2(bytes.subarray(offset, offset + length)));
|
|
2806
2529
|
offset += length;
|
|
2807
2530
|
}
|
|
2808
2531
|
}
|
|
2809
|
-
if (offset !== bytes.length) return
|
|
2532
|
+
if (offset !== bytes.length) return null;
|
|
2810
2533
|
return { acceptedSources: chains, uniswapV4Positions: positions };
|
|
2811
2534
|
}
|
|
2812
|
-
function
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
return decodePhantomBidDeclaration(paymasterAndData).acceptedSources;
|
|
2817
|
-
}
|
|
2818
|
-
function zipFillLegs(assets, outputs) {
|
|
2819
|
-
return assets.map((asset, index) => {
|
|
2820
|
-
const rawAmount = outputs[index]?.amount;
|
|
2821
|
-
return {
|
|
2822
|
-
outputToken: asset.token,
|
|
2823
|
-
solverAmount: rawAmount === void 0 || rawAmount === null ? 0n : BigInt(rawAmount.toString())
|
|
2824
|
-
};
|
|
2825
|
-
});
|
|
2826
|
-
}
|
|
2827
|
-
var UNISWAP_QUOTE_HAIRCUT_BPS = 10n;
|
|
2828
|
-
function haircut(amount, bps) {
|
|
2829
|
-
return amount * (10000n - bps) / 10000n;
|
|
2830
|
-
}
|
|
2831
|
-
function applyUniswapQuoteHaircut(amount) {
|
|
2832
|
-
return haircut(amount, UNISWAP_QUOTE_HAIRCUT_BPS);
|
|
2833
|
-
}
|
|
2834
|
-
var SELECTOR_GATEWAY_PARAMS = "0xcff0ab96";
|
|
2835
|
-
var GATEWAY_PARAMS_WORDS = 6;
|
|
2836
|
-
var GATEWAY_PARAMS_FEE_WORD = 4;
|
|
2837
|
-
async function readProtocolFeeHaircutBps(evmRpcUrl, gatewayAddress) {
|
|
2838
|
-
const result = await rpcCall(evmRpcUrl, {
|
|
2839
|
-
id: 1,
|
|
2840
|
-
jsonrpc: "2.0",
|
|
2841
|
-
method: "eth_call",
|
|
2842
|
-
params: [{ to: gatewayAddress, data: SELECTOR_GATEWAY_PARAMS }, "latest"]
|
|
2843
|
-
});
|
|
2844
|
-
const hex = result.result;
|
|
2845
|
-
if (typeof hex !== "string" || hex.length < 2 + 64 * GATEWAY_PARAMS_WORDS) {
|
|
2846
|
-
throw new PhantomRpcError(`IntentGateway.params() returned no usable result from ${gatewayAddress} on ${evmRpcUrl}`);
|
|
2847
|
-
}
|
|
2848
|
-
const start = 2 + 64 * GATEWAY_PARAMS_FEE_WORD;
|
|
2849
|
-
const protocolFeeBps = BigInt(`0x${hex.slice(start, start + 64)}`);
|
|
2850
|
-
if (protocolFeeBps >= 10000n) {
|
|
2851
|
-
throw new PhantomRpcError(`IntentGateway ${gatewayAddress} reports an implausible protocol fee: ${protocolFeeBps} bps`);
|
|
2852
|
-
}
|
|
2853
|
-
return protocolFeeBps;
|
|
2854
|
-
}
|
|
2855
|
-
function applyProtocolFeeHaircut(amount, protocolFeeBps) {
|
|
2856
|
-
return haircut(amount, protocolFeeBps);
|
|
2857
|
-
}
|
|
2858
|
-
function weightedMedian(entries) {
|
|
2859
|
-
const sorted = [...entries].sort((a, b) => a.price < b.price ? -1 : a.price > b.price ? 1 : 0);
|
|
2860
|
-
const totalWeight = sorted.reduce((acc, e) => e.weight > 0n ? acc + e.weight : acc, 0n);
|
|
2861
|
-
if (totalWeight === 0n) {
|
|
2862
|
-
return sorted[Math.floor(sorted.length / 2)].price;
|
|
2863
|
-
}
|
|
2864
|
-
let cumulative = 0n;
|
|
2865
|
-
for (const entry of sorted) {
|
|
2866
|
-
if (entry.weight <= 0n) continue;
|
|
2867
|
-
cumulative += entry.weight;
|
|
2868
|
-
if (cumulative * 2n >= totalWeight) return entry.price;
|
|
2869
|
-
}
|
|
2870
|
-
return sorted[sorted.length - 1].price;
|
|
2871
|
-
}
|
|
2872
|
-
function extractFillData(callData, gatewayAddress) {
|
|
2873
|
-
const calls = decodeERC7821ExecuteBatch(callData);
|
|
2874
|
-
if (!calls) return null;
|
|
2875
|
-
const normalized = gatewayAddress.toLowerCase();
|
|
2876
|
-
for (const call of calls) {
|
|
2877
|
-
if (call.target.toLowerCase() !== normalized) continue;
|
|
2878
|
-
try {
|
|
2879
|
-
const decoded = decodeFillOrder(call.data);
|
|
2880
|
-
if (!decoded) continue;
|
|
2881
|
-
const order = decoded.order;
|
|
2882
|
-
const options = decoded.options;
|
|
2883
|
-
const assets = order?.output?.assets;
|
|
2884
|
-
const outputs = options?.outputs;
|
|
2885
|
-
if (!assets?.length || !outputs?.length) continue;
|
|
2886
|
-
return { order, options, legs: zipFillLegs(assets, outputs) };
|
|
2887
|
-
} catch {
|
|
2888
|
-
continue;
|
|
2889
|
-
}
|
|
2890
|
-
}
|
|
2891
|
-
return null;
|
|
2535
|
+
function bytesToBigInt2(bytes) {
|
|
2536
|
+
let value = 0n;
|
|
2537
|
+
for (const byte of bytes) value = value << 8n | BigInt(byte);
|
|
2538
|
+
return value;
|
|
2892
2539
|
}
|
|
2893
|
-
|
|
2894
|
-
(
|
|
2895
|
-
)?.inputs?.[0];
|
|
2896
|
-
function orderCommitmentFromDecoded(order) {
|
|
2897
|
-
try {
|
|
2898
|
-
if (!FILL_ORDER_INPUT) return null;
|
|
2899
|
-
return viem.keccak256(viem.encodeAbiParameters([FILL_ORDER_INPUT], [order]));
|
|
2900
|
-
} catch {
|
|
2901
|
-
return null;
|
|
2902
|
-
}
|
|
2540
|
+
function bytesToAddress(bytes) {
|
|
2541
|
+
return util.u8aToHex(bytes);
|
|
2903
2542
|
}
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
function splitBidSignature(signature) {
|
|
2907
|
-
const raw = signature.replace(/^0x/, "");
|
|
2908
|
-
const commitmentChars = BID_COMMITMENT_BYTES * 2;
|
|
2909
|
-
const end = commitmentChars + SOLVER_SIGNATURE_BYTES * 2;
|
|
2910
|
-
if (raw.length < end) return null;
|
|
2911
|
-
return {
|
|
2912
|
-
commitment: `0x${raw.slice(0, commitmentChars)}`,
|
|
2913
|
-
solverSignature: `0x${raw.slice(commitmentChars, end)}`
|
|
2914
|
-
};
|
|
2543
|
+
function hasPermit2Sponsorship(bytes) {
|
|
2544
|
+
return bytes.length >= PERMIT2_SPONSORSHIP_BYTES && bytes[PAYMASTER_DATA_OFFSET] === SIMPLEX_MODE_PERMIT2;
|
|
2915
2545
|
}
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
return
|
|
2922
|
-
}
|
|
2923
|
-
};
|
|
2924
|
-
var DELEGATION_INDICATOR_PREFIX = "0xef0100";
|
|
2925
|
-
async function isDelegatedToSolverAccount(evmRpcUrl, account, solverAccounts) {
|
|
2926
|
-
const response = await rpcCall(evmRpcUrl, {
|
|
2927
|
-
id: 1,
|
|
2928
|
-
jsonrpc: "2.0",
|
|
2929
|
-
method: "eth_getCode",
|
|
2930
|
-
params: [account, "latest"]
|
|
2931
|
-
});
|
|
2932
|
-
if (typeof response.result !== "string") {
|
|
2933
|
-
throw new PhantomRpcError(`eth_getCode returned no code for ${account} on ${evmRpcUrl}`);
|
|
2934
|
-
}
|
|
2935
|
-
const code = response.result.toLowerCase();
|
|
2936
|
-
if (!code.startsWith(DELEGATION_INDICATOR_PREFIX)) return false;
|
|
2937
|
-
const delegate = `0x${code.slice(DELEGATION_INDICATOR_PREFIX.length)}`;
|
|
2938
|
-
return solverAccounts.some((solverAccount) => solverAccount.toLowerCase() === delegate);
|
|
2939
|
-
}
|
|
2940
|
-
function memoizedDelegationCheck() {
|
|
2941
|
-
const cache = /* @__PURE__ */ new Map();
|
|
2942
|
-
return (evmRpcUrl, account, solverAccounts) => {
|
|
2943
|
-
const targets = solverAccounts.map((a) => a.toLowerCase()).sort().join(",");
|
|
2944
|
-
const key = `${evmRpcUrl}|${account.toLowerCase()}|${targets}`;
|
|
2945
|
-
let pending = cache.get(key);
|
|
2946
|
-
if (!pending) {
|
|
2947
|
-
pending = isDelegatedToSolverAccount(evmRpcUrl, account, solverAccounts).catch((err) => {
|
|
2948
|
-
cache.delete(key);
|
|
2949
|
-
throw err;
|
|
2950
|
-
});
|
|
2951
|
-
cache.set(key, pending);
|
|
2952
|
-
}
|
|
2953
|
-
return pending;
|
|
2546
|
+
function parseSponsorship(bytes) {
|
|
2547
|
+
let offset = 0;
|
|
2548
|
+
const take = (length) => {
|
|
2549
|
+
const slice = bytes.subarray(offset, offset + length);
|
|
2550
|
+
offset += length;
|
|
2551
|
+
return slice;
|
|
2954
2552
|
};
|
|
2553
|
+
const paymaster = bytesToAddress(take(PAYMASTER_ADDRESS_BYTES));
|
|
2554
|
+
take(2 * PAYMASTER_GAS_LIMIT_BYTES);
|
|
2555
|
+
take(1);
|
|
2556
|
+
const token = bytesToAddress(take(20));
|
|
2557
|
+
const permitAmount = bytesToBigInt2(take(32));
|
|
2558
|
+
const nonce = bytesToBigInt2(take(32));
|
|
2559
|
+
const deadline = bytesToBigInt2(take(32));
|
|
2560
|
+
return { paymaster, token, permitAmount, nonce, deadline };
|
|
2955
2561
|
}
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
solverAccounts,
|
|
2968
|
-
evmRpcUrl,
|
|
2969
|
-
recoverSigner,
|
|
2970
|
-
bidNonceKey,
|
|
2971
|
-
isDelegated,
|
|
2972
|
-
logger
|
|
2973
|
-
} = params;
|
|
2974
|
-
const solver = userOp.sender;
|
|
2975
|
-
const parsed = splitBidSignature(userOp.signature);
|
|
2976
|
-
if (!parsed) {
|
|
2977
|
-
logger?.warn({ solver, commitment }, "Rejecting phantom bid: malformed userOp signature");
|
|
2978
|
-
return false;
|
|
2979
|
-
}
|
|
2980
|
-
if (parsed.commitment.toLowerCase() !== commitment.toLowerCase()) {
|
|
2981
|
-
logger?.warn(
|
|
2982
|
-
{ solver, commitment, signedFor: parsed.commitment },
|
|
2983
|
-
"Rejecting phantom bid: signed for another order"
|
|
2984
|
-
);
|
|
2985
|
-
return false;
|
|
2986
|
-
}
|
|
2987
|
-
if (BigInt(userOp.nonce) >> 64n !== bidNonceKey(commitment, sessionKey)) {
|
|
2988
|
-
logger?.warn({ solver, commitment }, "Rejecting phantom bid: nonce does not bind order and session key");
|
|
2989
|
-
return false;
|
|
2990
|
-
}
|
|
2991
|
-
const signer = await recoverSigner(userOp, ENTRY_POINT_V08_ADDRESS, chainId, parsed.solverSignature);
|
|
2992
|
-
if (!signer || signer.toLowerCase() !== solver.toLowerCase()) {
|
|
2993
|
-
logger?.warn({ solver, commitment, signer }, "Rejecting phantom bid: signature does not recover to the sender");
|
|
2994
|
-
return false;
|
|
2995
|
-
}
|
|
2996
|
-
if (!await isDelegated(evmRpcUrl, solver, solverAccounts)) {
|
|
2997
|
-
logger?.warn({ solver, commitment, solverAccounts }, "Rejecting phantom bid: sender is not a delegated solver");
|
|
2998
|
-
return false;
|
|
2999
|
-
}
|
|
3000
|
-
return true;
|
|
3001
|
-
}
|
|
3002
|
-
async function fetchBidsForOrder(nodeUrl, commitment) {
|
|
3003
|
-
const data = await rpcCall(nodeUrl, {
|
|
3004
|
-
id: 1,
|
|
3005
|
-
jsonrpc: "2.0",
|
|
3006
|
-
method: "intents_getBidsForOrder",
|
|
3007
|
-
params: [commitment]
|
|
3008
|
-
});
|
|
3009
|
-
return Array.isArray(data.result) ? data.result : [];
|
|
3010
|
-
}
|
|
3011
|
-
async function ethCallUint(evmRpcUrl, to, data, blockTag = "latest") {
|
|
3012
|
-
const result = await rpcCall(evmRpcUrl, {
|
|
3013
|
-
id: 1,
|
|
3014
|
-
jsonrpc: "2.0",
|
|
3015
|
-
method: "eth_call",
|
|
3016
|
-
params: [{ to, data }, blockTag]
|
|
3017
|
-
});
|
|
3018
|
-
if (result.result === "0x") return 0n;
|
|
3019
|
-
if (typeof result.result !== "string") {
|
|
3020
|
-
throw new PhantomRpcError(`eth_call returned no result for ${to} on ${evmRpcUrl}`);
|
|
3021
|
-
}
|
|
3022
|
-
return BigInt(result.result);
|
|
2562
|
+
var absentDeclaration = () => ({ acceptedSources: null, uniswapV4Positions: [] });
|
|
2563
|
+
function decodePhantomBidPaymasterAndData(paymasterAndData) {
|
|
2564
|
+
const none = { mode: "none", declaration: absentDeclaration(), sponsorship: null };
|
|
2565
|
+
if (!paymasterAndData || !util.isHex(paymasterAndData)) return none;
|
|
2566
|
+
const bytes = util.hexToU8a(paymasterAndData);
|
|
2567
|
+
const bare = parseDeclaration(bytes, 0);
|
|
2568
|
+
if (bare) return { mode: "declaration", declaration: bare, sponsorship: null };
|
|
2569
|
+
if (!hasPermit2Sponsorship(bytes)) return none;
|
|
2570
|
+
const sponsorship = parseSponsorship(bytes);
|
|
2571
|
+
const tail = bytes.length > PERMIT2_SPONSORSHIP_BYTES ? parseDeclaration(bytes, PERMIT2_SPONSORSHIP_BYTES) : null;
|
|
2572
|
+
return { mode: "permit2", declaration: tail ?? absentDeclaration(), sponsorship };
|
|
3023
2573
|
}
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
const raw = await ethCallUint(evmRpcUrl, token, `0x70a08231${padded}`, blockTag);
|
|
3027
|
-
const vaults = yieldVaults[chain]?.[token.toLowerCase()] ?? [];
|
|
3028
|
-
const vaultBalances = await Promise.all(
|
|
3029
|
-
vaults.map((v) => ethCallUint(evmRpcUrl, v, `0xce96cb77${padded}`, blockTag))
|
|
3030
|
-
// maxWithdraw(address)
|
|
3031
|
-
);
|
|
3032
|
-
return vaultBalances.reduce((acc, b) => acc + b, raw);
|
|
2574
|
+
function decodePhantomBidDeclaration(paymasterAndData) {
|
|
2575
|
+
return decodePhantomBidPaymasterAndData(paymasterAndData).declaration;
|
|
3033
2576
|
}
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
id: 1,
|
|
3044
|
-
jsonrpc: "2.0",
|
|
3045
|
-
method: "eth_call",
|
|
3046
|
-
params: [{ to, data }, blockTag]
|
|
3047
|
-
});
|
|
3048
|
-
if (result.result === "0x") return null;
|
|
3049
|
-
if (typeof result.result !== "string") {
|
|
3050
|
-
throw new PhantomRpcError(`eth_call returned no result for ${to} on ${evmRpcUrl}`);
|
|
3051
|
-
}
|
|
3052
|
-
return result.result;
|
|
3053
|
-
};
|
|
3054
|
-
const arg = uint256Arg(tokenId);
|
|
3055
|
-
const [ownerData, infoData, liquidityData] = await Promise.all([
|
|
3056
|
-
call(contracts.positionManager, `${SELECTOR_OWNER_OF}${arg}`),
|
|
3057
|
-
call(contracts.positionManager, `${SELECTOR_POOL_AND_POSITION_INFO}${arg}`),
|
|
3058
|
-
call(contracts.positionManager, `${SELECTOR_POSITION_LIQUIDITY}${arg}`)
|
|
3059
|
-
]);
|
|
3060
|
-
if (!ownerData) return null;
|
|
3061
|
-
if (!infoData || !liquidityData) {
|
|
3062
|
-
logger?.warn(
|
|
3063
|
-
{ tokenId: tokenId.toString(), positionManager: contracts.positionManager },
|
|
3064
|
-
"Uniswap V4 position exists but its pool info or liquidity did not read back \u2014 check the configured PositionManager"
|
|
3065
|
-
);
|
|
3066
|
-
return null;
|
|
3067
|
-
}
|
|
3068
|
-
const info = decodePoolAndPositionInfo(infoData);
|
|
3069
|
-
const slot0Data = await call(contracts.stateView, `${SELECTOR_GET_SLOT0}${keccak(info.poolKeyEncoded).slice(2)}`);
|
|
3070
|
-
if (!slot0Data) {
|
|
3071
|
-
logger?.warn(
|
|
3072
|
-
{ tokenId: tokenId.toString(), stateView: contracts.stateView, evmRpcUrl },
|
|
3073
|
-
"Uniswap V4 slot0 read returned nothing for a live position \u2014 the configured StateView address is wrong"
|
|
2577
|
+
function encodePhantomBidPaymasterAndData(bid) {
|
|
2578
|
+
const declaration = encodePhantomBidDeclaration(bid);
|
|
2579
|
+
const sponsorship = bid.sponsorship;
|
|
2580
|
+
if (!sponsorship || sponsorship === "0x") return declaration;
|
|
2581
|
+
if (!util.isHex(sponsorship)) throw new Error("Phantom bid sponsorship is not hex");
|
|
2582
|
+
const bytes = util.hexToU8a(sponsorship);
|
|
2583
|
+
if (bytes.length !== PERMIT2_SPONSORSHIP_BYTES || !hasPermit2Sponsorship(bytes)) {
|
|
2584
|
+
throw new Error(
|
|
2585
|
+
`Phantom bid sponsorship must be a ${PERMIT2_SPONSORSHIP_BYTES}-byte Permit2-mode paymasterAndData, got ${bytes.length} bytes`
|
|
3074
2586
|
);
|
|
3075
|
-
return null;
|
|
3076
2587
|
}
|
|
3077
|
-
return {
|
|
3078
|
-
owner: `0x${ownerData.slice(-40)}`.toLowerCase(),
|
|
3079
|
-
info,
|
|
3080
|
-
liquidity: word(liquidityData, 0),
|
|
3081
|
-
sqrtPriceX96: word(slot0Data, 0)
|
|
3082
|
-
};
|
|
3083
|
-
}
|
|
3084
|
-
function memoizedV4Position(keccak, logger) {
|
|
3085
|
-
const cache = /* @__PURE__ */ new Map();
|
|
3086
|
-
return (evmRpcUrl, chain, contracts, tokenId) => {
|
|
3087
|
-
const key = `${chain}|${tokenId}`;
|
|
3088
|
-
let pending = cache.get(key);
|
|
3089
|
-
if (!pending) {
|
|
3090
|
-
pending = readV4Position({ evmRpcUrl, contracts, tokenId, keccak, logger }).catch((err) => {
|
|
3091
|
-
cache.delete(key);
|
|
3092
|
-
throw err;
|
|
3093
|
-
});
|
|
3094
|
-
cache.set(key, pending);
|
|
3095
|
-
}
|
|
3096
|
-
return pending;
|
|
3097
|
-
};
|
|
3098
|
-
}
|
|
3099
|
-
function memoizedSolverBalance(yieldVaults, blockTags = {}) {
|
|
3100
|
-
const cache = /* @__PURE__ */ new Map();
|
|
3101
|
-
return (evmRpcUrl, chain, token, solver) => {
|
|
3102
|
-
const key = `${chain}|${token.toLowerCase()}|${solver.toLowerCase()}`;
|
|
3103
|
-
let pending = cache.get(key);
|
|
3104
|
-
if (!pending) {
|
|
3105
|
-
pending = getTotalSolverBalance(evmRpcUrl, chain, token, solver, yieldVaults, blockTags[chain]).catch((err) => {
|
|
3106
|
-
cache.delete(key);
|
|
3107
|
-
throw err;
|
|
3108
|
-
});
|
|
3109
|
-
cache.set(key, pending);
|
|
3110
|
-
}
|
|
3111
|
-
return pending;
|
|
3112
|
-
};
|
|
2588
|
+
return `${sponsorship}${declaration.slice(2)}`;
|
|
3113
2589
|
}
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
for (const [chain, tokens] of Object.entries(yieldVaults)) {
|
|
3117
|
-
const url = evmRpcUrls[chain];
|
|
3118
|
-
if (!url) continue;
|
|
3119
|
-
for (const token of Object.keys(tokens)) {
|
|
3120
|
-
const balance = await getBalance(url, chain, token, solver);
|
|
3121
|
-
const uniswapV4Balance = chain === positions.chain ? positions.states.reduce(
|
|
3122
|
-
(total2, state) => total2 + positionAmountOfToken({
|
|
3123
|
-
info: state.info,
|
|
3124
|
-
liquidity: state.liquidity,
|
|
3125
|
-
sqrtPriceX96: state.sqrtPriceX96,
|
|
3126
|
-
outputToken: token
|
|
3127
|
-
}),
|
|
3128
|
-
0n
|
|
3129
|
-
) : 0n;
|
|
3130
|
-
const total = balance + uniswapV4Balance;
|
|
3131
|
-
if (total === 0n) continue;
|
|
3132
|
-
balances.push({ solver, chain, tokenAddress: token, balance: total });
|
|
3133
|
-
}
|
|
3134
|
-
}
|
|
3135
|
-
return balances;
|
|
3136
|
-
}
|
|
3137
|
-
function toAddress(token) {
|
|
3138
|
-
const hex = token.toLowerCase().replace(/^0x/, "");
|
|
3139
|
-
const addr = hex.length > 40 ? hex.slice(-40) : hex.padStart(40, "0");
|
|
3140
|
-
return `0x${addr}`;
|
|
3141
|
-
}
|
|
3142
|
-
async function aggregatePhantomBids(params) {
|
|
3143
|
-
const isDelegated = memoizedDelegationCheck();
|
|
3144
|
-
let lastErr;
|
|
3145
|
-
for (let attempt = 1; attempt <= AGGREGATION_ATTEMPTS; attempt++) {
|
|
3146
|
-
try {
|
|
3147
|
-
return await runAggregation(params, isDelegated);
|
|
3148
|
-
} catch (err) {
|
|
3149
|
-
lastErr = err;
|
|
3150
|
-
params.logger?.warn(
|
|
3151
|
-
{ err, commitment: params.commitment, chain: params.chain, attempt, of: AGGREGATION_ATTEMPTS },
|
|
3152
|
-
"Phantom aggregation attempt failed"
|
|
3153
|
-
);
|
|
3154
|
-
if (attempt < AGGREGATION_ATTEMPTS) await new Promise((resolve) => setTimeout(resolve, 250 * attempt));
|
|
3155
|
-
}
|
|
3156
|
-
}
|
|
3157
|
-
throw lastErr;
|
|
2590
|
+
function encodeAcceptedSourceChains(chains) {
|
|
2591
|
+
return encodePhantomBidDeclaration({ acceptedSourceChains: chains });
|
|
3158
2592
|
}
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
const { nodeUrl, evmRpcUrls, chain, gatewayAddress, commitment, yieldVaults, logger } = params;
|
|
3162
|
-
const solverAccounts = (Array.isArray(params.solverAccount) ? params.solverAccount : [params.solverAccount]).filter(
|
|
3163
|
-
(a) => typeof a === "string" && a.length > 0
|
|
3164
|
-
);
|
|
3165
|
-
const extractFill = params.extractFill ?? extractFillData;
|
|
3166
|
-
const recoverSigner = params.recoverSigner ?? recoverBidSignerViem;
|
|
3167
|
-
const bidNonceKey = params.bidNonceKey ?? CryptoUtils.bidNonceKey;
|
|
3168
|
-
const orderCommitment = params.orderCommitment ?? orderCommitmentFromDecoded;
|
|
3169
|
-
const destUrl = evmRpcUrls[chain];
|
|
3170
|
-
if (!destUrl) return null;
|
|
3171
|
-
const chainId = evmChainId(chain);
|
|
3172
|
-
if (solverAccounts.length === 0 || chainId === null) {
|
|
3173
|
-
logger?.warn({ chain, commitment }, "Cannot verify phantom bids: no SolverAccount or chain id for chain");
|
|
3174
|
-
return null;
|
|
3175
|
-
}
|
|
3176
|
-
const bids = await fetchBidsForOrder(nodeUrl, commitment);
|
|
3177
|
-
if (bids.length === 0) return null;
|
|
3178
|
-
const protocolFeeHaircutBps = await readProtocolFeeHaircutBps(destUrl, gatewayAddress);
|
|
3179
|
-
const v4Contracts = params.uniswapV4?.[chain];
|
|
3180
|
-
const readPosition = memoizedV4Position(params.keccak ?? viem.keccak256, logger);
|
|
3181
|
-
const getBalance = params.getBalance ?? memoizedSolverBalance(yieldVaults);
|
|
3182
|
-
const quotesByLeg = /* @__PURE__ */ new Map();
|
|
3183
|
-
const lpBalances = [];
|
|
3184
|
-
const verifiedPositions = [];
|
|
3185
|
-
const countedSolvers = /* @__PURE__ */ new Set();
|
|
3186
|
-
for (const bid of bids) {
|
|
3187
|
-
if (!bid.user_op) continue;
|
|
3188
|
-
try {
|
|
3189
|
-
const decoded = decodeUserOpScale(bid.user_op);
|
|
3190
|
-
const solver = decoded.sender;
|
|
3191
|
-
const fillData = extractFill(decoded.callData, gatewayAddress);
|
|
3192
|
-
if (!fillData) continue;
|
|
3193
|
-
const decodedCommitment = orderCommitment(fillData.order);
|
|
3194
|
-
if (!decodedCommitment || decodedCommitment.toLowerCase() !== commitment.toLowerCase()) {
|
|
3195
|
-
logger?.warn({ solver, commitment }, "Rejecting phantom bid: calldata order is not the indexed order");
|
|
3196
|
-
continue;
|
|
3197
|
-
}
|
|
3198
|
-
const sessionKey = fillData.order?.session;
|
|
3199
|
-
if (!sessionKey) {
|
|
3200
|
-
logger?.warn({ solver, commitment }, "Rejecting phantom bid: order carries no session key");
|
|
3201
|
-
continue;
|
|
3202
|
-
}
|
|
3203
|
-
const verified = await isVerifiedSolverBid({
|
|
3204
|
-
userOp: decoded,
|
|
3205
|
-
commitment,
|
|
3206
|
-
sessionKey,
|
|
3207
|
-
chainId,
|
|
3208
|
-
solverAccounts,
|
|
3209
|
-
evmRpcUrl: destUrl,
|
|
3210
|
-
recoverSigner,
|
|
3211
|
-
bidNonceKey,
|
|
3212
|
-
isDelegated,
|
|
3213
|
-
logger
|
|
3214
|
-
});
|
|
3215
|
-
if (!verified) continue;
|
|
3216
|
-
const normalizedSolver = solver.toLowerCase();
|
|
3217
|
-
if (countedSolvers.has(normalizedSolver)) {
|
|
3218
|
-
logger?.warn({ solver, commitment }, "Skipping phantom bid: solver already counted for this order");
|
|
3219
|
-
continue;
|
|
3220
|
-
}
|
|
3221
|
-
countedSolvers.add(normalizedSolver);
|
|
3222
|
-
const declaration = decodePhantomBidDeclaration(decoded.paymasterAndData);
|
|
3223
|
-
const acceptedSources = declaration.acceptedSources;
|
|
3224
|
-
const poolPriced = declaration.uniswapV4Positions.length > 0;
|
|
3225
|
-
const applyHaircut = (amount) => poolPriced ? applyUniswapQuoteHaircut(amount) : applyProtocolFeeHaircut(amount, protocolFeeHaircutBps);
|
|
3226
|
-
const quotedLegs = [...fillData.legs.entries()].map(([legIndex, leg]) => [
|
|
3227
|
-
legIndex,
|
|
3228
|
-
{ ...leg, solverAmount: applyHaircut(leg.solverAmount) }
|
|
3229
|
-
]).filter(([, leg]) => leg.solverAmount !== 0n);
|
|
3230
|
-
const declaredPositions = v4Contracts ? declaration.uniswapV4Positions : [];
|
|
3231
|
-
const ownedPositions = (await Promise.all(
|
|
3232
|
-
declaredPositions.map(async (tokenId) => ({
|
|
3233
|
-
tokenId,
|
|
3234
|
-
state: await readPosition(destUrl, chain, v4Contracts, tokenId)
|
|
3235
|
-
}))
|
|
3236
|
-
)).filter((entry) => {
|
|
3237
|
-
if (!entry.state) return false;
|
|
3238
|
-
if (entry.state.owner !== normalizedSolver) {
|
|
3239
|
-
logger?.warn(
|
|
3240
|
-
{ solver, commitment, tokenId: entry.tokenId.toString(), owner: entry.state.owner },
|
|
3241
|
-
"Ignoring declared Uniswap V4 position: not owned by the bidding solver"
|
|
3242
|
-
);
|
|
3243
|
-
return false;
|
|
3244
|
-
}
|
|
3245
|
-
return true;
|
|
3246
|
-
});
|
|
3247
|
-
const positions = ownedPositions.map((entry) => entry.state);
|
|
3248
|
-
for (const entry of ownedPositions) {
|
|
3249
|
-
verifiedPositions.push({ solver: normalizedSolver, chain, tokenId: entry.tokenId });
|
|
3250
|
-
}
|
|
3251
|
-
const weights = await Promise.all(
|
|
3252
|
-
// Price influence: the solver's liquidity in THIS leg's output token on the destination
|
|
3253
|
-
// chain, so a leg is weighted by the inventory that actually backs it.
|
|
3254
|
-
quotedLegs.map(async ([, leg]) => {
|
|
3255
|
-
const outputToken = toAddress(leg.outputToken);
|
|
3256
|
-
const balance = await getBalance(destUrl, chain, outputToken, solver);
|
|
3257
|
-
return positions.reduce(
|
|
3258
|
-
(total, state) => total + positionAmountOfToken({
|
|
3259
|
-
info: state.info,
|
|
3260
|
-
liquidity: state.liquidity,
|
|
3261
|
-
sqrtPriceX96: state.sqrtPriceX96,
|
|
3262
|
-
outputToken
|
|
3263
|
-
}),
|
|
3264
|
-
balance
|
|
3265
|
-
);
|
|
3266
|
-
})
|
|
3267
|
-
);
|
|
3268
|
-
for (const [position, [legIndex, leg]] of quotedLegs.entries()) {
|
|
3269
|
-
const weight = weights[position];
|
|
3270
|
-
const entry = quotesByLeg.get(legIndex) ?? { outputToken: leg.outputToken, quotes: [], bidders: [] };
|
|
3271
|
-
entry.quotes.push({ price: leg.solverAmount, weight });
|
|
3272
|
-
entry.bidders.push({ solver: normalizedSolver, weight, acceptedSources });
|
|
3273
|
-
quotesByLeg.set(legIndex, entry);
|
|
3274
|
-
}
|
|
3275
|
-
lpBalances.push(
|
|
3276
|
-
...await sweepSolverLiquidity(evmRpcUrls, yieldVaults, solver, getBalance, {
|
|
3277
|
-
chain,
|
|
3278
|
-
states: positions
|
|
3279
|
-
})
|
|
3280
|
-
);
|
|
3281
|
-
} catch (err) {
|
|
3282
|
-
if (err instanceof PhantomRpcError) throw err;
|
|
3283
|
-
logger?.warn({ err, filler: bid.filler }, "Failed to process bid for price snapshot");
|
|
3284
|
-
}
|
|
3285
|
-
}
|
|
3286
|
-
if (quotesByLeg.size === 0) return null;
|
|
3287
|
-
const legs = [...quotesByLeg.entries()].sort(([a], [b]) => a - b).flatMap(([legIndex, { outputToken, quotes, bidders }]) => {
|
|
3288
|
-
const backedQuotes = quotes.filter((quote) => quote.weight > 0n);
|
|
3289
|
-
const backedBidders = bidders.filter((bidder) => bidder.weight > 0n);
|
|
3290
|
-
if (backedQuotes.length === 0) {
|
|
3291
|
-
logger?.warn(
|
|
3292
|
-
{ commitment, chain, legIndex, outputToken, quotes: quotes.length },
|
|
3293
|
-
"Dropping phantom leg: no bidder holds the output token on this chain, so no quote is backed"
|
|
3294
|
-
);
|
|
3295
|
-
return [];
|
|
3296
|
-
}
|
|
3297
|
-
const medianPrice = weightedMedian(backedQuotes);
|
|
3298
|
-
return [
|
|
3299
|
-
{
|
|
3300
|
-
legIndex,
|
|
3301
|
-
outputToken,
|
|
3302
|
-
lowestPrice: medianPrice,
|
|
3303
|
-
highestPrice: medianPrice,
|
|
3304
|
-
medianPrice,
|
|
3305
|
-
bidCount: backedQuotes.length,
|
|
3306
|
-
bidders: backedBidders
|
|
3307
|
-
}
|
|
3308
|
-
];
|
|
3309
|
-
});
|
|
3310
|
-
return { legs, lpBalances, positions: verifiedPositions, solvers: [...countedSolvers] };
|
|
2593
|
+
function decodeAcceptedSourceChains(paymasterAndData) {
|
|
2594
|
+
return decodePhantomBidDeclaration(paymasterAndData).acceptedSources;
|
|
3311
2595
|
}
|
|
3312
2596
|
|
|
3313
|
-
exports.ENTRY_POINT_V08_ADDRESS = ENTRY_POINT_V08_ADDRESS;
|
|
3314
|
-
exports.FILL_ORDER_ABI = FILL_ORDER_ABI;
|
|
3315
|
-
exports.FILL_ORDER_V1_ABI = FILL_ORDER_V1_ABI;
|
|
3316
2597
|
exports.IntentGatewayV2 = IntentGatewayV2_default;
|
|
3317
|
-
exports.
|
|
3318
|
-
exports.
|
|
3319
|
-
exports.applyProtocolFeeHaircut = applyProtocolFeeHaircut;
|
|
3320
|
-
exports.applyUniswapQuoteHaircut = applyUniswapQuoteHaircut;
|
|
2598
|
+
exports.MAX_DECLARED_ENTRIES = MAX_DECLARED_ENTRIES;
|
|
2599
|
+
exports.PERMIT2_SPONSORSHIP_BYTES = PERMIT2_SPONSORSHIP_BYTES;
|
|
3321
2600
|
exports.decodeAcceptedSourceChains = decodeAcceptedSourceChains;
|
|
3322
2601
|
exports.decodeERC7821ExecuteBatch = decodeERC7821ExecuteBatch;
|
|
3323
2602
|
exports.decodePhantomBidDeclaration = decodePhantomBidDeclaration;
|
|
2603
|
+
exports.decodePhantomBidPaymasterAndData = decodePhantomBidPaymasterAndData;
|
|
3324
2604
|
exports.decodeUserOpScale = decodeUserOpScale;
|
|
3325
2605
|
exports.encodeAcceptedSourceChains = encodeAcceptedSourceChains;
|
|
3326
2606
|
exports.encodeERC7821ExecuteBatch = encodeERC7821ExecuteBatch;
|
|
3327
2607
|
exports.encodePhantomBidDeclaration = encodePhantomBidDeclaration;
|
|
2608
|
+
exports.encodePhantomBidPaymasterAndData = encodePhantomBidPaymasterAndData;
|
|
3328
2609
|
exports.encodeUserOpScale = encodeUserOpScale;
|
|
3329
|
-
exports.extractFillData = extractFillData;
|
|
3330
2610
|
exports.fetchBidsForOrder = fetchBidsForOrder;
|
|
3331
|
-
exports.getTotalSolverBalance = getTotalSolverBalance;
|
|
3332
|
-
exports.memoizedSolverBalance = memoizedSolverBalance;
|
|
3333
|
-
exports.orderCommitmentFromDecoded = orderCommitmentFromDecoded;
|
|
3334
2611
|
exports.poolSlug = poolSlug;
|
|
3335
|
-
exports.positionAmountOfToken = positionAmountOfToken;
|
|
3336
|
-
exports.readProtocolFeeHaircutBps = readProtocolFeeHaircutBps;
|
|
3337
|
-
exports.readV4Position = readV4Position;
|
|
3338
|
-
exports.recoverBidSignerViem = recoverBidSignerViem;
|
|
3339
2612
|
exports.setAggregationFetch = setAggregationFetch;
|
|
3340
2613
|
exports.sortPoolSymbols = sortPoolSymbols;
|
|
3341
|
-
exports.splitBidSignature = splitBidSignature;
|
|
3342
|
-
exports.weightedMedian = weightedMedian;
|
|
3343
|
-
exports.zipFillLegs = zipFillLegs;
|
|
3344
2614
|
//# sourceMappingURL=intents-helpers.cjs.map
|
|
3345
2615
|
//# sourceMappingURL=intents-helpers.cjs.map
|