@safe-global/relay-kit 3.4.3 → 4.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/cjs/src/index.cjs +1497 -0
  2. package/dist/cjs/test-utils/index.cjs +1360 -0
  3. package/dist/esm/src/index.mjs +1487 -0
  4. package/dist/esm/test-utils/index.mjs +1348 -0
  5. package/dist/src/RelayKitBasePack.d.ts +1 -0
  6. package/dist/src/RelayKitBasePack.d.ts.map +1 -0
  7. package/dist/src/constants.d.ts +1 -0
  8. package/dist/src/constants.d.ts.map +1 -0
  9. package/dist/src/deprecated.d.ts +1 -0
  10. package/dist/src/deprecated.d.ts.map +1 -0
  11. package/dist/src/index.d.ts +6 -1
  12. package/dist/src/index.d.ts.map +1 -0
  13. package/dist/src/packs/gelato/GelatoRelayPack.d.ts +1 -0
  14. package/dist/src/packs/gelato/GelatoRelayPack.d.ts.map +1 -0
  15. package/dist/src/packs/gelato/types.d.ts +1 -0
  16. package/dist/src/packs/gelato/types.d.ts.map +1 -0
  17. package/dist/src/packs/safe-4337/BaseSafeOperation.d.ts +18 -0
  18. package/dist/src/packs/safe-4337/BaseSafeOperation.d.ts.map +1 -0
  19. package/dist/src/packs/safe-4337/Safe4337Pack.d.ts +17 -17
  20. package/dist/src/packs/safe-4337/Safe4337Pack.d.ts.map +1 -0
  21. package/dist/src/packs/safe-4337/SafeOperationFactory.d.ts +13 -0
  22. package/dist/src/packs/safe-4337/SafeOperationFactory.d.ts.map +1 -0
  23. package/dist/src/packs/safe-4337/SafeOperationV06.d.ts +16 -0
  24. package/dist/src/packs/safe-4337/SafeOperationV06.d.ts.map +1 -0
  25. package/dist/src/packs/safe-4337/SafeOperationV07.d.ts +16 -0
  26. package/dist/src/packs/safe-4337/SafeOperationV07.d.ts.map +1 -0
  27. package/dist/src/packs/safe-4337/constants.d.ts +11 -3
  28. package/dist/src/packs/safe-4337/constants.d.ts.map +1 -0
  29. package/dist/src/packs/safe-4337/estimators/index.d.ts +2 -1
  30. package/dist/src/packs/safe-4337/estimators/index.d.ts.map +1 -0
  31. package/dist/src/packs/safe-4337/estimators/pimlico/PimlicoFeeEstimator.d.ts +13 -0
  32. package/dist/src/packs/safe-4337/estimators/pimlico/PimlicoFeeEstimator.d.ts.map +1 -0
  33. package/dist/src/packs/safe-4337/estimators/pimlico/types.d.ts +48 -0
  34. package/dist/src/packs/safe-4337/estimators/pimlico/types.d.ts.map +1 -0
  35. package/dist/src/packs/safe-4337/types.d.ts +50 -44
  36. package/dist/src/packs/safe-4337/types.d.ts.map +1 -0
  37. package/dist/src/packs/safe-4337/utils/encodeNonce.d.ts +5 -0
  38. package/dist/src/packs/safe-4337/utils/encodeNonce.d.ts.map +1 -0
  39. package/dist/src/packs/safe-4337/utils/entrypoint.d.ts +4 -0
  40. package/dist/src/packs/safe-4337/utils/entrypoint.d.ts.map +1 -0
  41. package/dist/src/packs/safe-4337/utils/getRelayKitVersion.d.ts +1 -0
  42. package/dist/src/packs/safe-4337/utils/getRelayKitVersion.d.ts.map +1 -0
  43. package/dist/src/packs/safe-4337/utils/index.d.ts +22 -0
  44. package/dist/src/packs/safe-4337/utils/index.d.ts.map +1 -0
  45. package/dist/src/packs/safe-4337/utils/signing.d.ts +37 -0
  46. package/dist/src/packs/safe-4337/utils/signing.d.ts.map +1 -0
  47. package/dist/src/packs/safe-4337/utils/userOperations.d.ts +27 -0
  48. package/dist/src/packs/safe-4337/utils/userOperations.d.ts.map +1 -0
  49. package/dist/{src/packs/safe-4337/testing-utils → test-utils}/fixtures.d.ts +28 -5
  50. package/dist/test-utils/fixtures.d.ts.map +1 -0
  51. package/dist/{src/packs/safe-4337/testing-utils → test-utils}/helpers.d.ts +3 -2
  52. package/dist/test-utils/helpers.d.ts.map +1 -0
  53. package/dist/test-utils/index.d.ts +4 -0
  54. package/dist/test-utils/index.d.ts.map +1 -0
  55. package/dist/tsconfig.build.tsbuildinfo +1 -1
  56. package/package.json +22 -6
  57. package/dist/src/RelayKitBasePack.js +0 -26
  58. package/dist/src/RelayKitBasePack.js.map +0 -1
  59. package/dist/src/constants.js +0 -12
  60. package/dist/src/constants.js.map +0 -1
  61. package/dist/src/deprecated.js +0 -3
  62. package/dist/src/deprecated.js.map +0 -1
  63. package/dist/src/index.js +0 -30
  64. package/dist/src/index.js.map +0 -1
  65. package/dist/src/packs/gelato/GelatoRelayPack.js +0 -327
  66. package/dist/src/packs/gelato/GelatoRelayPack.js.map +0 -1
  67. package/dist/src/packs/gelato/types.js +0 -3
  68. package/dist/src/packs/gelato/types.js.map +0 -1
  69. package/dist/src/packs/safe-4337/Safe4337Pack.js +0 -644
  70. package/dist/src/packs/safe-4337/Safe4337Pack.js.map +0 -1
  71. package/dist/src/packs/safe-4337/SafeOperation.d.ts +0 -22
  72. package/dist/src/packs/safe-4337/SafeOperation.js +0 -68
  73. package/dist/src/packs/safe-4337/SafeOperation.js.map +0 -1
  74. package/dist/src/packs/safe-4337/constants.js +0 -55
  75. package/dist/src/packs/safe-4337/constants.js.map +0 -1
  76. package/dist/src/packs/safe-4337/estimators/PimlicoFeeEstimator.d.ts +0 -8
  77. package/dist/src/packs/safe-4337/estimators/PimlicoFeeEstimator.js +0 -49
  78. package/dist/src/packs/safe-4337/estimators/PimlicoFeeEstimator.js.map +0 -1
  79. package/dist/src/packs/safe-4337/estimators/index.js +0 -6
  80. package/dist/src/packs/safe-4337/estimators/index.js.map +0 -1
  81. package/dist/src/packs/safe-4337/testing-utils/fixtures.js +0 -128
  82. package/dist/src/packs/safe-4337/testing-utils/fixtures.js.map +0 -1
  83. package/dist/src/packs/safe-4337/testing-utils/helpers.js +0 -58
  84. package/dist/src/packs/safe-4337/testing-utils/helpers.js.map +0 -1
  85. package/dist/src/packs/safe-4337/types.js +0 -3
  86. package/dist/src/packs/safe-4337/types.js.map +0 -1
  87. package/dist/src/packs/safe-4337/utils/entrypoint.js +0 -23
  88. package/dist/src/packs/safe-4337/utils/entrypoint.js.map +0 -1
  89. package/dist/src/packs/safe-4337/utils/getRelayKitVersion.js +0 -6
  90. package/dist/src/packs/safe-4337/utils/getRelayKitVersion.js.map +0 -1
  91. package/dist/src/packs/safe-4337/utils.d.ts +0 -91
  92. package/dist/src/packs/safe-4337/utils.js +0 -190
  93. package/dist/src/packs/safe-4337/utils.js.map +0 -1
@@ -0,0 +1,1487 @@
1
+ // src/packs/gelato/GelatoRelayPack.ts
2
+ import {
3
+ GelatoRelay as GelatoNetworkRelay
4
+ } from "@gelatonetwork/relay-sdk";
5
+ import {
6
+ estimateTxBaseGas,
7
+ estimateSafeTxGas,
8
+ estimateSafeDeploymentGas,
9
+ createERC20TokenTransferTransaction,
10
+ isGasTokenCompatibleWithHandlePayment
11
+ } from "@safe-global/protocol-kit";
12
+
13
+ // src/RelayKitBasePack.ts
14
+ var RelayKitBasePack = class {
15
+ /**
16
+ * Creates a new RelayKitBasePack instance.
17
+ * The packs implemented using our SDK should extend this class and therefore provide a Safe SDK instance
18
+ * @param {Safe} protocolKit - The Safe SDK instance
19
+ */
20
+ constructor(protocolKit) {
21
+ this.protocolKit = protocolKit;
22
+ }
23
+ };
24
+
25
+ // src/constants.ts
26
+ var GELATO_NATIVE_TOKEN_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
27
+ var GELATO_FEE_COLLECTOR = "0x3AC05161b76a35c1c28dC99Aa01BEd7B24cEA3bf";
28
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
29
+ var GELATO_GAS_EXECUTION_OVERHEAD = 15e4;
30
+ var GELATO_TRANSFER_GAS_COST = 15e3;
31
+
32
+ // src/packs/gelato/GelatoRelayPack.ts
33
+ var GelatoRelayPack = class extends RelayKitBasePack {
34
+ #gelatoRelay;
35
+ #apiKey;
36
+ constructor({ apiKey, protocolKit }) {
37
+ super(protocolKit);
38
+ this.#gelatoRelay = new GelatoNetworkRelay();
39
+ this.#apiKey = apiKey;
40
+ }
41
+ _getFeeToken(gasToken) {
42
+ return !gasToken || gasToken === ZERO_ADDRESS ? GELATO_NATIVE_TOKEN_ADDRESS : gasToken;
43
+ }
44
+ getFeeCollector() {
45
+ return GELATO_FEE_COLLECTOR;
46
+ }
47
+ async getEstimateFee(propsOrChainId, inputGasLimit, inputGasToken) {
48
+ let chainId;
49
+ let gasLimit;
50
+ let gasToken;
51
+ if (typeof propsOrChainId === "object") {
52
+ ;
53
+ ({ chainId, gasLimit, gasToken } = propsOrChainId);
54
+ } else {
55
+ chainId = propsOrChainId;
56
+ gasLimit = inputGasLimit;
57
+ gasToken = inputGasToken;
58
+ }
59
+ const feeToken = this._getFeeToken(gasToken);
60
+ const estimation = await this.#gelatoRelay.getEstimatedFee(
61
+ chainId,
62
+ feeToken,
63
+ BigInt(gasLimit),
64
+ false
65
+ );
66
+ return estimation.toString();
67
+ }
68
+ async getTaskStatus(taskId) {
69
+ return this.#gelatoRelay.getTaskStatus(taskId);
70
+ }
71
+ /**
72
+ * Creates a payment transaction to Gelato
73
+ *
74
+ * @private
75
+ * @async
76
+ * @function
77
+ * @param {string} gas - The gas amount for the payment.
78
+ * @param {MetaTransactionOptions} options - Options for the meta transaction.
79
+ * @returns {Promise<Transaction>} Promise object representing the created payment transaction.
80
+ *
81
+ */
82
+ async createPaymentToGelato(gas, options) {
83
+ const chainId = await this.protocolKit.getChainId();
84
+ const gelatoAddress = this.getFeeCollector();
85
+ const gasToken = options.gasToken ?? ZERO_ADDRESS;
86
+ const paymentToGelato = await this.getEstimateFee({ chainId, gasLimit: gas, gasToken });
87
+ const transferToGelato = createERC20TokenTransferTransaction(
88
+ gasToken,
89
+ gelatoAddress,
90
+ paymentToGelato
91
+ );
92
+ return transferToGelato;
93
+ }
94
+ /**
95
+ * @deprecated Use createTransaction instead
96
+ */
97
+ async createRelayedTransaction({
98
+ transactions,
99
+ onlyCalls = false,
100
+ options = {}
101
+ }) {
102
+ return this.createTransaction({ transactions, onlyCalls, options });
103
+ }
104
+ /**
105
+ * Creates a Safe transaction designed to be executed using the Gelato Relayer.
106
+ *
107
+ * @param {GelatoCreateTransactionProps} options - Options for Gelato.
108
+ * @param {MetaTransactionData[]} [options.transactions] - The transactions batch.
109
+ * @param {boolean} [options.onlyCalls=false] - If true, MultiSendCallOnly contract should be used. Remember to not use delegate calls in the batch.
110
+ * @param {MetaTransactionOptions} [options.options={}] - Gas Options for the transaction batch.
111
+ * @returns {Promise<SafeTransaction>} Returns a Promise that resolves with a SafeTransaction object.
112
+ */
113
+ async createTransaction({
114
+ transactions,
115
+ onlyCalls = false,
116
+ options = {}
117
+ }) {
118
+ const { isSponsored = false } = options;
119
+ if (isSponsored) {
120
+ const nonce = await this.protocolKit.getNonce();
121
+ const sponsoredTransaction = await this.protocolKit.createTransaction({
122
+ transactions,
123
+ onlyCalls,
124
+ options: {
125
+ nonce
126
+ }
127
+ });
128
+ return sponsoredTransaction;
129
+ }
130
+ const gasToken = options.gasToken ?? ZERO_ADDRESS;
131
+ const isGasTokenCompatible = await isGasTokenCompatibleWithHandlePayment(
132
+ gasToken,
133
+ this.protocolKit
134
+ );
135
+ if (!isGasTokenCompatible) {
136
+ return this.createTransactionWithTransfer({ transactions, onlyCalls, options });
137
+ }
138
+ return this.createTransactionWithHandlePayment({ transactions, onlyCalls, options });
139
+ }
140
+ /**
141
+ * Creates a Safe transaction designed to be executed using the Gelato Relayer and
142
+ * uses the handlePayment function defined in the Safe contract to pay the fees
143
+ * to the Gelato relayer.
144
+ *
145
+ * @async
146
+ * @function createTransactionWithHandlePayment
147
+ * @param {GelatoCreateTransactionProps} options - Options for Gelato.
148
+ * @param {MetaTransactionData[]} [options.transactions] - The transactions batch.
149
+ * @param {boolean} [options.onlyCalls=false] - If true, MultiSendCallOnly contract should be used. Remember to not use delegate calls in the batch.
150
+ * @param {MetaTransactionOptions} [options.options={}] - Gas Options for the transaction batch.
151
+ * @returns {Promise<SafeTransaction>} Returns a promise that resolves to the created SafeTransaction.
152
+ * @private
153
+ */
154
+ async createTransactionWithHandlePayment({
155
+ transactions,
156
+ onlyCalls = false,
157
+ options = {}
158
+ }) {
159
+ const { gasLimit } = options;
160
+ const nonce = await this.protocolKit.getNonce();
161
+ const transactionToEstimateGas = await this.protocolKit.createTransaction({
162
+ transactions,
163
+ onlyCalls,
164
+ options: {
165
+ nonce
166
+ }
167
+ });
168
+ const gasPrice = "1";
169
+ const safeTxGas = await estimateSafeTxGas(this.protocolKit, transactionToEstimateGas);
170
+ const gasToken = options.gasToken ?? ZERO_ADDRESS;
171
+ const refundReceiver = this.getFeeCollector();
172
+ const chainId = await this.protocolKit.getChainId();
173
+ if (gasLimit) {
174
+ const paymentToGelato2 = await this.getEstimateFee({ chainId, gasLimit, gasToken });
175
+ const syncTransaction2 = await this.protocolKit.createTransaction({
176
+ transactions,
177
+ onlyCalls,
178
+ options: {
179
+ baseGas: paymentToGelato2,
180
+ gasPrice,
181
+ safeTxGas,
182
+ gasToken,
183
+ refundReceiver,
184
+ nonce
185
+ }
186
+ });
187
+ return syncTransaction2;
188
+ }
189
+ const baseGas = await estimateTxBaseGas(this.protocolKit, transactionToEstimateGas);
190
+ const safeDeploymentGasCost = await estimateSafeDeploymentGas(this.protocolKit);
191
+ const totalGas = Number(baseGas) + // baseGas
192
+ Number(safeTxGas) + // safeTxGas
193
+ Number(safeDeploymentGasCost) + // Safe deploymet gas cost if it is required
194
+ GELATO_GAS_EXECUTION_OVERHEAD;
195
+ const paymentToGelato = await this.getEstimateFee({
196
+ chainId,
197
+ gasLimit: String(totalGas),
198
+ gasToken
199
+ });
200
+ const syncTransaction = await this.protocolKit.createTransaction({
201
+ transactions,
202
+ onlyCalls,
203
+ options: {
204
+ baseGas: paymentToGelato,
205
+ // payment to Gelato
206
+ gasPrice,
207
+ safeTxGas,
208
+ gasToken,
209
+ refundReceiver,
210
+ nonce
211
+ }
212
+ });
213
+ return syncTransaction;
214
+ }
215
+ /**
216
+ * Creates a Safe transaction designed to be executed using the Gelato Relayer and
217
+ * uses a separate ERC20 transfer to pay the fees to the Gelato relayer.
218
+ *
219
+ * @async
220
+ * @function createTransactionWithTransfer
221
+ * @param {GelatoCreateTransactionProps} options - Options for Gelato.
222
+ * @param {MetaTransactionData[]} [options.transactions] - The transactions batch.
223
+ * @param {boolean} [options.onlyCalls=false] - If true, MultiSendCallOnly contract should be used. Remember to not use delegate calls in the batch.
224
+ * @param {MetaTransactionOptions} [options.options={}] - Gas Options for the transaction batch.
225
+ * @returns {Promise<SafeTransaction>} Returns a promise that resolves to the created SafeTransaction.
226
+ * @private
227
+ */
228
+ async createTransactionWithTransfer({
229
+ transactions,
230
+ onlyCalls = false,
231
+ options = {}
232
+ }) {
233
+ const { gasLimit } = options;
234
+ const nonce = await this.protocolKit.getNonce();
235
+ const gasToken = options.gasToken ?? ZERO_ADDRESS;
236
+ if (gasLimit) {
237
+ const transferToGelato2 = await this.createPaymentToGelato(gasLimit, options);
238
+ const syncTransaction2 = await this.protocolKit.createTransaction({
239
+ transactions: [...transactions, transferToGelato2],
240
+ onlyCalls,
241
+ options: {
242
+ nonce,
243
+ gasToken
244
+ }
245
+ });
246
+ return syncTransaction2;
247
+ }
248
+ const transactionToEstimateGas = await this.protocolKit.createTransaction({
249
+ transactions,
250
+ onlyCalls,
251
+ options: {
252
+ nonce
253
+ }
254
+ });
255
+ const safeTxGas = await estimateSafeTxGas(this.protocolKit, transactionToEstimateGas);
256
+ const baseGas = await estimateTxBaseGas(this.protocolKit, transactionToEstimateGas);
257
+ const safeDeploymentGasCost = await estimateSafeDeploymentGas(this.protocolKit);
258
+ const totalGas = Number(baseGas) + // baseGas
259
+ Number(safeTxGas) + // safeTxGas without Gelato payment transfer
260
+ Number(safeDeploymentGasCost) + // Safe deploymet gas cost if it is required
261
+ GELATO_TRANSFER_GAS_COST + // Gelato payment transfer
262
+ GELATO_GAS_EXECUTION_OVERHEAD;
263
+ const transferToGelato = await this.createPaymentToGelato(String(totalGas), options);
264
+ const syncTransaction = await this.protocolKit.createTransaction({
265
+ transactions: [...transactions, transferToGelato],
266
+ onlyCalls,
267
+ options: {
268
+ nonce,
269
+ gasToken
270
+ }
271
+ });
272
+ return syncTransaction;
273
+ }
274
+ async sendSponsorTransaction(target, encodedTransaction, chainId) {
275
+ if (!this.#apiKey) {
276
+ throw new Error("API key not defined");
277
+ }
278
+ const request = {
279
+ chainId,
280
+ target,
281
+ data: encodedTransaction
282
+ };
283
+ const response = await this.#gelatoRelay.sponsoredCall(request, this.#apiKey);
284
+ return response;
285
+ }
286
+ async sendSyncTransaction(target, encodedTransaction, chainId, options) {
287
+ const { gasLimit, gasToken } = options;
288
+ const feeToken = this._getFeeToken(gasToken);
289
+ const request = {
290
+ chainId,
291
+ target,
292
+ data: encodedTransaction,
293
+ feeToken,
294
+ isRelayContext: false
295
+ };
296
+ const relayRequestOptions = {
297
+ gasLimit: gasLimit ? BigInt(gasLimit) : void 0
298
+ };
299
+ const response = await this.#gelatoRelay.callWithSyncFee(request, relayRequestOptions);
300
+ return response;
301
+ }
302
+ async relayTransaction({
303
+ target,
304
+ encodedTransaction,
305
+ chainId,
306
+ options = {}
307
+ }) {
308
+ const response = options.isSponsored ? this.sendSponsorTransaction(target, encodedTransaction, chainId) : this.sendSyncTransaction(target, encodedTransaction, chainId, options);
309
+ return response;
310
+ }
311
+ /**
312
+ * @deprecated Use executeTransaction instead
313
+ */
314
+ async executeRelayTransaction(safeTransaction, options) {
315
+ return this.executeTransaction({ executable: safeTransaction, options });
316
+ }
317
+ /**
318
+ * Sends the Safe transaction to the Gelato Relayer for execution.
319
+ * If the Safe is not deployed, it creates a batch of transactions including the Safe deployment transaction.
320
+ *
321
+ * @param {GelatoExecuteTransactionProps} props - Execution props
322
+ * @param {SafeTransaction} props.executable - The Safe transaction to be executed.
323
+ * @param {MetaTransactionOptions} props.options - Options for the transaction.
324
+ * @returns {Promise<RelayResponse>} Returns a Promise that resolves with a RelayResponse object.
325
+ */
326
+ async executeTransaction({
327
+ executable: safeTransaction,
328
+ options
329
+ }) {
330
+ const isSafeDeployed = await this.protocolKit.isSafeDeployed();
331
+ const chainId = await this.protocolKit.getChainId();
332
+ const safeAddress = await this.protocolKit.getAddress();
333
+ const safeTransactionEncodedData = await this.protocolKit.getEncodedTransaction(safeTransaction);
334
+ const gasToken = options?.gasToken || safeTransaction.data.gasToken;
335
+ if (isSafeDeployed) {
336
+ const relayTransaction2 = {
337
+ target: safeAddress,
338
+ encodedTransaction: safeTransactionEncodedData,
339
+ chainId,
340
+ options: {
341
+ ...options,
342
+ gasToken
343
+ }
344
+ };
345
+ return this.relayTransaction(relayTransaction2);
346
+ }
347
+ const safeDeploymentBatch = await this.protocolKit.wrapSafeTransactionIntoDeploymentBatch(safeTransaction);
348
+ const relayTransaction = {
349
+ target: safeDeploymentBatch.to,
350
+ // multiSend Contract address
351
+ encodedTransaction: safeDeploymentBatch.data,
352
+ chainId,
353
+ options: {
354
+ ...options,
355
+ gasToken
356
+ }
357
+ };
358
+ return this.relayTransaction(relayTransaction);
359
+ }
360
+ };
361
+
362
+ // src/packs/safe-4337/Safe4337Pack.ts
363
+ import { getAddress as getAddress2, toHex as toHex5 } from "viem";
364
+ import semverSatisfies from "semver/functions/satisfies.js";
365
+ import Safe, {
366
+ EthSafeSignature as EthSafeSignature2,
367
+ encodeMultiSendData as encodeMultiSendData2,
368
+ getMultiSendContract,
369
+ SafeProvider,
370
+ generateOnChainIdentifier
371
+ } from "@safe-global/protocol-kit";
372
+ import {
373
+ OperationType as OperationType3,
374
+ SigningMethod
375
+ } from "@safe-global/types-kit";
376
+ import {
377
+ getSafeModuleSetupDeployment,
378
+ getSafe4337ModuleDeployment,
379
+ getSafeWebAuthnShareSignerDeployment
380
+ } from "@safe-global/safe-modules-deployments";
381
+ import { encodeFunctionData as encodeFunctionData3, zeroAddress, concat as concat2 } from "viem";
382
+
383
+ // src/packs/safe-4337/BaseSafeOperation.ts
384
+ import { encodePacked, hashTypedData } from "viem";
385
+ import { buildSignatureBytes } from "@safe-global/protocol-kit";
386
+ var BaseSafeOperation = class {
387
+ constructor(userOperation, options) {
388
+ this.signatures = /* @__PURE__ */ new Map();
389
+ this.userOperation = userOperation;
390
+ this.options = options;
391
+ }
392
+ getSignature(signer) {
393
+ return this.signatures.get(signer.toLowerCase());
394
+ }
395
+ addSignature(signature) {
396
+ this.signatures.set(signature.signer.toLowerCase(), signature);
397
+ }
398
+ encodedSignatures() {
399
+ return buildSignatureBytes(Array.from(this.signatures.values()));
400
+ }
401
+ getUserOperation() {
402
+ return {
403
+ ...this.userOperation,
404
+ signature: encodePacked(
405
+ ["uint48", "uint48", "bytes"],
406
+ [
407
+ this.options.validAfter || 0,
408
+ this.options.validUntil || 0,
409
+ this.encodedSignatures()
410
+ ]
411
+ )
412
+ };
413
+ }
414
+ getHash() {
415
+ return hashTypedData({
416
+ domain: {
417
+ chainId: Number(this.options.chainId),
418
+ verifyingContract: this.options.moduleAddress
419
+ },
420
+ types: this.getEIP712Type(),
421
+ primaryType: "SafeOp",
422
+ message: this.getSafeOperation()
423
+ });
424
+ }
425
+ };
426
+ var BaseSafeOperation_default = BaseSafeOperation;
427
+
428
+ // src/packs/safe-4337/constants.ts
429
+ import { parseAbi } from "viem";
430
+ var DEFAULT_SAFE_VERSION = "1.4.1";
431
+ var DEFAULT_SAFE_MODULES_VERSION = "0.3.0";
432
+ var EIP712_SAFE_OPERATION_TYPE_V06 = {
433
+ SafeOp: [
434
+ { type: "address", name: "safe" },
435
+ { type: "uint256", name: "nonce" },
436
+ { type: "bytes", name: "initCode" },
437
+ { type: "bytes", name: "callData" },
438
+ { type: "uint256", name: "callGasLimit" },
439
+ { type: "uint256", name: "verificationGasLimit" },
440
+ { type: "uint256", name: "preVerificationGas" },
441
+ { type: "uint256", name: "maxFeePerGas" },
442
+ { type: "uint256", name: "maxPriorityFeePerGas" },
443
+ { type: "bytes", name: "paymasterAndData" },
444
+ { type: "uint48", name: "validAfter" },
445
+ { type: "uint48", name: "validUntil" },
446
+ { type: "address", name: "entryPoint" }
447
+ ]
448
+ };
449
+ var EIP712_SAFE_OPERATION_TYPE_V07 = {
450
+ SafeOp: [
451
+ { type: "address", name: "safe" },
452
+ { type: "uint256", name: "nonce" },
453
+ { type: "bytes", name: "initCode" },
454
+ { type: "bytes", name: "callData" },
455
+ { type: "uint128", name: "verificationGasLimit" },
456
+ { type: "uint128", name: "callGasLimit" },
457
+ { type: "uint256", name: "preVerificationGas" },
458
+ { type: "uint128", name: "maxPriorityFeePerGas" },
459
+ { type: "uint128", name: "maxFeePerGas" },
460
+ { type: "bytes", name: "paymasterAndData" },
461
+ { type: "uint48", name: "validAfter" },
462
+ { type: "uint48", name: "validUntil" },
463
+ { type: "address", name: "entryPoint" }
464
+ ]
465
+ };
466
+ var ABI = parseAbi([
467
+ "function enableModules(address[])",
468
+ "function multiSend(bytes memory transactions) public payable",
469
+ "function executeUserOp(address to, uint256 value, bytes data, uint8 operation)",
470
+ "function approve(address _spender, uint256 _value)",
471
+ "function configure((uint256 x, uint256 y, uint176 verifiers) signer)"
472
+ ]);
473
+ var ENTRYPOINT_ABI = [
474
+ {
475
+ inputs: [
476
+ { name: "sender", type: "address" },
477
+ { name: "key", type: "uint192" }
478
+ ],
479
+ name: "getNonce",
480
+ outputs: [{ name: "nonce", type: "uint256" }],
481
+ stateMutability: "view",
482
+ type: "function"
483
+ }
484
+ ];
485
+ var ENTRYPOINT_ADDRESS_V06 = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789";
486
+ var ENTRYPOINT_ADDRESS_V07 = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
487
+
488
+ // src/packs/safe-4337/SafeOperationV06.ts
489
+ var SafeOperationV06 = class extends BaseSafeOperation_default {
490
+ constructor(userOperation, options) {
491
+ super(userOperation, options);
492
+ }
493
+ addEstimations(estimations) {
494
+ this.userOperation.maxFeePerGas = BigInt(
495
+ estimations.maxFeePerGas || this.userOperation.maxFeePerGas
496
+ );
497
+ this.userOperation.maxPriorityFeePerGas = BigInt(
498
+ estimations.maxPriorityFeePerGas || this.userOperation.maxPriorityFeePerGas
499
+ );
500
+ this.userOperation.verificationGasLimit = BigInt(
501
+ estimations.verificationGasLimit || this.userOperation.verificationGasLimit
502
+ );
503
+ this.userOperation.preVerificationGas = BigInt(
504
+ estimations.preVerificationGas || this.userOperation.preVerificationGas
505
+ );
506
+ this.userOperation.callGasLimit = BigInt(
507
+ estimations.callGasLimit || this.userOperation.callGasLimit
508
+ );
509
+ this.userOperation.paymasterAndData = estimations.paymasterAndData || this.userOperation.paymasterAndData;
510
+ }
511
+ getSafeOperation() {
512
+ return {
513
+ safe: this.userOperation.sender,
514
+ nonce: this.userOperation.nonce,
515
+ initCode: this.userOperation.initCode,
516
+ callData: this.userOperation.callData,
517
+ callGasLimit: this.userOperation.callGasLimit,
518
+ verificationGasLimit: this.userOperation.verificationGasLimit,
519
+ preVerificationGas: this.userOperation.preVerificationGas,
520
+ maxFeePerGas: this.userOperation.maxFeePerGas,
521
+ maxPriorityFeePerGas: this.userOperation.maxPriorityFeePerGas,
522
+ paymasterAndData: this.userOperation.paymasterAndData,
523
+ validAfter: this.options.validAfter || 0,
524
+ validUntil: this.options.validUntil || 0,
525
+ entryPoint: this.options.entryPoint
526
+ };
527
+ }
528
+ getEIP712Type() {
529
+ return EIP712_SAFE_OPERATION_TYPE_V06;
530
+ }
531
+ };
532
+ var SafeOperationV06_default = SafeOperationV06;
533
+
534
+ // src/packs/safe-4337/SafeOperationV07.ts
535
+ import { concat, isAddress, pad, toHex } from "viem";
536
+ var SafeOperationV07 = class extends BaseSafeOperation_default {
537
+ constructor(userOperation, options) {
538
+ super(userOperation, options);
539
+ }
540
+ addEstimations(estimations) {
541
+ this.userOperation.maxFeePerGas = BigInt(
542
+ estimations.maxFeePerGas || this.userOperation.maxFeePerGas
543
+ );
544
+ this.userOperation.maxPriorityFeePerGas = BigInt(
545
+ estimations.maxPriorityFeePerGas || this.userOperation.maxPriorityFeePerGas
546
+ );
547
+ this.userOperation.verificationGasLimit = BigInt(
548
+ estimations.verificationGasLimit || this.userOperation.verificationGasLimit
549
+ );
550
+ this.userOperation.preVerificationGas = BigInt(
551
+ estimations.preVerificationGas || this.userOperation.preVerificationGas
552
+ );
553
+ this.userOperation.callGasLimit = BigInt(
554
+ estimations.callGasLimit || this.userOperation.callGasLimit
555
+ );
556
+ this.userOperation.paymasterPostOpGasLimit = estimations.paymasterPostOpGasLimit ? BigInt(estimations.paymasterPostOpGasLimit) : this.userOperation.paymasterPostOpGasLimit;
557
+ this.userOperation.paymasterVerificationGasLimit = estimations.paymasterVerificationGasLimit ? BigInt(estimations.paymasterVerificationGasLimit) : this.userOperation.paymasterVerificationGasLimit;
558
+ this.userOperation.paymaster = estimations.paymaster || this.userOperation.paymaster;
559
+ this.userOperation.paymasterData = estimations.paymasterData || this.userOperation.paymasterData;
560
+ }
561
+ getSafeOperation() {
562
+ const initCode = this.userOperation.factory ? concat([
563
+ this.userOperation.factory,
564
+ this.userOperation.factoryData || "0x"
565
+ ]) : "0x";
566
+ const paymasterAndData = isAddress(this.userOperation.paymaster || "") ? concat([
567
+ this.userOperation.paymaster,
568
+ pad(toHex(this.userOperation.paymasterVerificationGasLimit || 0n), {
569
+ size: 16
570
+ }),
571
+ pad(toHex(this.userOperation.paymasterPostOpGasLimit || 0n), {
572
+ size: 16
573
+ }),
574
+ this.userOperation.paymasterData || "0x"
575
+ ]) : "0x";
576
+ return {
577
+ safe: this.userOperation.sender,
578
+ nonce: this.userOperation.nonce,
579
+ initCode,
580
+ callData: this.userOperation.callData,
581
+ callGasLimit: this.userOperation.callGasLimit,
582
+ verificationGasLimit: this.userOperation.verificationGasLimit,
583
+ preVerificationGas: this.userOperation.preVerificationGas,
584
+ maxFeePerGas: this.userOperation.maxFeePerGas,
585
+ maxPriorityFeePerGas: this.userOperation.maxPriorityFeePerGas,
586
+ paymasterAndData,
587
+ validAfter: this.options.validAfter || 0,
588
+ validUntil: this.options.validUntil || 0,
589
+ entryPoint: this.options.entryPoint
590
+ };
591
+ }
592
+ getEIP712Type() {
593
+ return EIP712_SAFE_OPERATION_TYPE_V07;
594
+ }
595
+ };
596
+ var SafeOperationV07_default = SafeOperationV07;
597
+
598
+ // src/packs/safe-4337/utils/index.ts
599
+ import { createPublicClient, encodeFunctionData as encodeFunctionData2, http, rpcSchema } from "viem";
600
+ import { OperationType as OperationType2 } from "@safe-global/types-kit";
601
+ import { encodeMultiSendData } from "@safe-global/protocol-kit";
602
+
603
+ // src/packs/safe-4337/utils/entrypoint.ts
604
+ var EQ_0_2_0 = "0.2.0";
605
+ var EQ_OR_GT_0_3_0 = ">=0.3.0";
606
+ function sameString(str1, str2) {
607
+ return str1.toLowerCase() === str2.toLowerCase();
608
+ }
609
+ function entryPointToSafeModules(entryPoint) {
610
+ const moduleVersionToEntryPoint = {
611
+ [ENTRYPOINT_ADDRESS_V06]: EQ_0_2_0,
612
+ [ENTRYPOINT_ADDRESS_V07]: EQ_OR_GT_0_3_0
613
+ };
614
+ return moduleVersionToEntryPoint[entryPoint];
615
+ }
616
+ function isEntryPointV6(address) {
617
+ return sameString(address, ENTRYPOINT_ADDRESS_V06);
618
+ }
619
+ function isEntryPointV7(address) {
620
+ return sameString(address, ENTRYPOINT_ADDRESS_V07);
621
+ }
622
+ async function getSafeNonceFromEntrypoint(protocolKit, safeAddress, entryPointAddress) {
623
+ const safeProvider = protocolKit.getSafeProvider();
624
+ const newNonce = await safeProvider.readContract({
625
+ address: entryPointAddress || "0x",
626
+ abi: ENTRYPOINT_ABI,
627
+ functionName: "getNonce",
628
+ args: [safeAddress, 0n]
629
+ });
630
+ return newNonce;
631
+ }
632
+
633
+ // src/packs/safe-4337/utils/signing.ts
634
+ import { encodePacked as encodePacked2, toHex as toHex2 } from "viem";
635
+ import { EthSafeSignature, buildSignatureBytes as buildSignatureBytes2 } from "@safe-global/protocol-kit";
636
+ var DUMMY_CLIENT_DATA_FIELDS = [
637
+ `"origin":"https://safe.global"`,
638
+ `"padding":"This pads the clientDataJSON so that we can leave room for additional implementation specific fields for a more accurate 'preVerificationGas' estimate."`
639
+ ].join(",");
640
+ var DUMMY_AUTHENTICATOR_DATA = new Uint8Array(37);
641
+ DUMMY_AUTHENTICATOR_DATA.fill(254);
642
+ DUMMY_AUTHENTICATOR_DATA[32] = 4;
643
+ function getDummySignature(signer, threshold) {
644
+ const signatures = [];
645
+ for (let i = 0; i < threshold; i++) {
646
+ const isContractSignature = true;
647
+ const passkeySignature = getSignatureBytes({
648
+ authenticatorData: DUMMY_AUTHENTICATOR_DATA,
649
+ clientDataFields: DUMMY_CLIENT_DATA_FIELDS,
650
+ r: BigInt(`0x${"ec".repeat(32)}`),
651
+ s: BigInt(`0x${"d5a".repeat(21)}f`)
652
+ });
653
+ signatures.push(new EthSafeSignature(signer, passkeySignature, isContractSignature));
654
+ }
655
+ return encodePacked2(["uint48", "uint48", "bytes"], [0, 0, buildSignatureBytes2(signatures)]);
656
+ }
657
+ function getSignatureBytes({
658
+ authenticatorData,
659
+ clientDataFields,
660
+ r,
661
+ s
662
+ }) {
663
+ const encodeUint256 = (x) => x.toString(16).padStart(64, "0");
664
+ const byteSize = (data) => 32 * (Math.ceil(data.length / 32) + 1);
665
+ const encodeBytes = (data) => `${encodeUint256(data.length)}${toHex2(data).slice(2)}`.padEnd(byteSize(data) * 2, "0");
666
+ const authenticatorDataOffset = 32 * 4;
667
+ const clientDataFieldsOffset = authenticatorDataOffset + byteSize(authenticatorData);
668
+ return "0x" + encodeUint256(authenticatorDataOffset) + encodeUint256(clientDataFieldsOffset) + encodeUint256(r) + encodeUint256(s) + encodeBytes(authenticatorData) + encodeBytes(new TextEncoder().encode(clientDataFields));
669
+ }
670
+
671
+ // src/packs/safe-4337/utils/userOperations.ts
672
+ import { encodeFunctionData, getAddress, hexToBytes, sliceHex, toHex as toHex3 } from "viem";
673
+ import {
674
+ OperationType
675
+ } from "@safe-global/types-kit";
676
+ function encodeExecuteUserOpCallData(transaction) {
677
+ return encodeFunctionData({
678
+ abi: ABI,
679
+ functionName: "executeUserOp",
680
+ args: [
681
+ transaction.to,
682
+ BigInt(transaction.value),
683
+ transaction.data,
684
+ transaction.operation || OperationType.Call
685
+ ]
686
+ });
687
+ }
688
+ async function getCallData(protocolKit, transactions, paymasterOptions, amountToApprove) {
689
+ if (amountToApprove) {
690
+ const approveToPaymasterTransaction = {
691
+ to: paymasterOptions.paymasterTokenAddress,
692
+ data: encodeFunctionData({
693
+ abi: ABI,
694
+ functionName: "approve",
695
+ args: [paymasterOptions.paymasterAddress, amountToApprove]
696
+ }),
697
+ value: "0",
698
+ operation: OperationType.Call
699
+ // Call for approve
700
+ };
701
+ transactions.push(approveToPaymasterTransaction);
702
+ }
703
+ const isBatch = transactions.length > 1;
704
+ const multiSendAddress = protocolKit.getMultiSendAddress();
705
+ const callData = isBatch ? encodeExecuteUserOpCallData({
706
+ to: multiSendAddress,
707
+ value: "0",
708
+ data: encodeMultiSendCallData(transactions),
709
+ operation: OperationType.DelegateCall
710
+ }) : encodeExecuteUserOpCallData(transactions[0]);
711
+ return callData;
712
+ }
713
+ function unpackInitCode(initCode) {
714
+ const initCodeBytes = hexToBytes(initCode);
715
+ return initCodeBytes.length > 0 ? {
716
+ factory: getAddress(sliceHex(initCode, 0, 20)),
717
+ factoryData: sliceHex(initCode, 20)
718
+ } : {};
719
+ }
720
+ async function createUserOperation(protocolKit, transactions, {
721
+ amountToApprove,
722
+ entryPoint,
723
+ paymasterOptions,
724
+ customNonce
725
+ }) {
726
+ const safeAddress = await protocolKit.getAddress();
727
+ const nonce = customNonce || await getSafeNonceFromEntrypoint(protocolKit, safeAddress, entryPoint);
728
+ const isSafeDeployed = await protocolKit.isSafeDeployed();
729
+ const paymasterAndData = paymasterOptions && "paymasterAddress" in paymasterOptions ? paymasterOptions.paymasterAddress : "0x";
730
+ const callData = await getCallData(
731
+ protocolKit,
732
+ transactions,
733
+ paymasterOptions,
734
+ amountToApprove
735
+ );
736
+ const initCode = isSafeDeployed ? "0x" : await protocolKit.getInitCode();
737
+ if (isEntryPointV6(entryPoint)) {
738
+ return {
739
+ sender: safeAddress,
740
+ nonce: nonce.toString(),
741
+ initCode,
742
+ callData,
743
+ callGasLimit: 1n,
744
+ verificationGasLimit: 1n,
745
+ preVerificationGas: 1n,
746
+ maxFeePerGas: 1n,
747
+ maxPriorityFeePerGas: 1n,
748
+ paymasterAndData,
749
+ signature: "0x"
750
+ };
751
+ }
752
+ return {
753
+ sender: safeAddress,
754
+ nonce: nonce.toString(),
755
+ ...unpackInitCode(initCode),
756
+ callData,
757
+ callGasLimit: 1n,
758
+ verificationGasLimit: 1n,
759
+ preVerificationGas: 1n,
760
+ maxFeePerGas: 1n,
761
+ maxPriorityFeePerGas: 1n,
762
+ paymaster: paymasterAndData,
763
+ paymasterData: "0x",
764
+ paymasterVerificationGasLimit: void 0,
765
+ paymasterPostOpGasLimit: void 0,
766
+ signature: "0x"
767
+ };
768
+ }
769
+ function userOperationToHexValues(userOperation, entryPointAddress) {
770
+ const userOpV07 = userOperation;
771
+ const userOperationWithHexValues = {
772
+ ...userOperation,
773
+ nonce: toHex3(BigInt(userOperation.nonce)),
774
+ callGasLimit: toHex3(userOperation.callGasLimit),
775
+ verificationGasLimit: toHex3(userOperation.verificationGasLimit),
776
+ preVerificationGas: toHex3(userOperation.preVerificationGas),
777
+ maxFeePerGas: toHex3(userOperation.maxFeePerGas),
778
+ maxPriorityFeePerGas: toHex3(userOperation.maxPriorityFeePerGas),
779
+ ...isEntryPointV7(entryPointAddress) ? {
780
+ paymaster: userOpV07.paymaster !== "0x" ? userOpV07.paymaster : null,
781
+ paymasterData: userOpV07.paymasterData !== "0x" ? userOpV07.paymasterData : null,
782
+ paymasterVerificationGasLimit: userOpV07.paymasterVerificationGasLimit ? toHex3(userOpV07.paymasterVerificationGasLimit) : null,
783
+ paymasterPostOpGasLimit: userOpV07.paymasterPostOpGasLimit ? toHex3(userOpV07.paymasterPostOpGasLimit) : null
784
+ } : {}
785
+ };
786
+ return userOperationWithHexValues;
787
+ }
788
+
789
+ // src/packs/safe-4337/utils/getRelayKitVersion.ts
790
+ var getRelayKitVersion = () => "4.0.0";
791
+
792
+ // src/packs/safe-4337/utils/encodeNonce.ts
793
+ import { toHex as toHex4 } from "viem";
794
+ function encodeNonce(args) {
795
+ const key = BigInt(toHex4(args.key, { size: 24 }));
796
+ const sequence = BigInt(toHex4(args.sequence, { size: 8 }));
797
+ return (key << BigInt(64)) + sequence;
798
+ }
799
+
800
+ // src/packs/safe-4337/utils/index.ts
801
+ function createBundlerClient(bundlerUrl) {
802
+ const provider = createPublicClient({
803
+ transport: http(bundlerUrl),
804
+ rpcSchema: rpcSchema()
805
+ });
806
+ return provider;
807
+ }
808
+ function encodeMultiSendCallData(transactions) {
809
+ return encodeFunctionData2({
810
+ abi: ABI,
811
+ functionName: "multiSend",
812
+ args: [
813
+ encodeMultiSendData(
814
+ transactions.map((tx) => ({ ...tx, operation: tx.operation ?? OperationType2.Call }))
815
+ )
816
+ ]
817
+ });
818
+ }
819
+
820
+ // src/packs/safe-4337/SafeOperationFactory.ts
821
+ var SafeOperationFactory = class {
822
+ /**
823
+ * Creates a new SafeOperation with proper validation
824
+ * @param userOperation - The base user operation
825
+ * @param options - Configuration options
826
+ * @returns Validated SafeOperation instance
827
+ */
828
+ static createSafeOperation(userOperation, options) {
829
+ if (isEntryPointV6(options.entryPoint)) {
830
+ return new SafeOperationV06_default(userOperation, options);
831
+ }
832
+ return new SafeOperationV07_default(userOperation, options);
833
+ }
834
+ };
835
+ var SafeOperationFactory_default = SafeOperationFactory;
836
+
837
+ // src/packs/safe-4337/estimators/pimlico/PimlicoFeeEstimator.ts
838
+ var PimlicoFeeEstimator = class {
839
+ async preEstimateUserOperationGas({
840
+ bundlerUrl,
841
+ userOperation,
842
+ entryPoint,
843
+ paymasterOptions
844
+ }) {
845
+ const bundlerClient = createBundlerClient(bundlerUrl);
846
+ const feeData = await this.#getUserOperationGasPrices(bundlerClient);
847
+ const chainId = await this.#getChainId(bundlerClient);
848
+ let paymasterStubData = {};
849
+ if (paymasterOptions) {
850
+ const paymasterClient = createBundlerClient(
851
+ paymasterOptions.paymasterUrl
852
+ );
853
+ const context = "paymasterTokenAddress" in paymasterOptions ? {
854
+ token: paymasterOptions.paymasterTokenAddress
855
+ } : void 0;
856
+ paymasterStubData = await paymasterClient.request({
857
+ method: "pm_getPaymasterStubData" /* GET_PAYMASTER_STUB_DATA */,
858
+ params: [userOperationToHexValues(userOperation, entryPoint), entryPoint, chainId, context]
859
+ });
860
+ }
861
+ return {
862
+ ...feeData,
863
+ ...paymasterStubData
864
+ };
865
+ }
866
+ async postEstimateUserOperationGas({
867
+ userOperation,
868
+ entryPoint,
869
+ paymasterOptions
870
+ }) {
871
+ if (!paymasterOptions) return {};
872
+ const paymasterClient = createBundlerClient(
873
+ paymasterOptions.paymasterUrl
874
+ );
875
+ if (paymasterOptions.isSponsored) {
876
+ const params = [
877
+ userOperationToHexValues(userOperation, entryPoint),
878
+ entryPoint
879
+ ];
880
+ if (paymasterOptions.sponsorshipPolicyId) {
881
+ params.push({
882
+ sponsorshipPolicyId: paymasterOptions.sponsorshipPolicyId
883
+ });
884
+ }
885
+ const sponsoredData = await paymasterClient.request({
886
+ method: "pm_sponsorUserOperation" /* SPONSOR_USER_OPERATION */,
887
+ params
888
+ });
889
+ return sponsoredData;
890
+ }
891
+ const chainId = await this.#getChainId(paymasterClient);
892
+ const erc20PaymasterData = await paymasterClient.request({
893
+ method: "pm_getPaymasterData" /* GET_PAYMASTER_DATA */,
894
+ params: [
895
+ userOperationToHexValues(userOperation, entryPoint),
896
+ entryPoint,
897
+ chainId,
898
+ { token: paymasterOptions.paymasterTokenAddress }
899
+ ]
900
+ });
901
+ return erc20PaymasterData;
902
+ }
903
+ async #getUserOperationGasPrices(client) {
904
+ const feeData = await client.request({
905
+ method: "pimlico_getUserOperationGasPrice" /* GET_USER_OPERATION_GAS_PRICE */
906
+ });
907
+ const {
908
+ fast: { maxFeePerGas, maxPriorityFeePerGas }
909
+ } = feeData;
910
+ return {
911
+ maxFeePerGas,
912
+ maxPriorityFeePerGas
913
+ };
914
+ }
915
+ async #getChainId(client) {
916
+ const chainId = await client.request({ method: "eth_chainId" });
917
+ return chainId;
918
+ }
919
+ };
920
+
921
+ // src/packs/safe-4337/Safe4337Pack.ts
922
+ var MAX_ERC20_AMOUNT_TO_APPROVE = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn;
923
+ var EQ_OR_GT_1_4_1 = ">=1.4.1";
924
+ var Safe4337Pack = class _Safe4337Pack extends RelayKitBasePack {
925
+ #BUNDLER_URL;
926
+ #ENTRYPOINT_ADDRESS;
927
+ #SAFE_4337_MODULE_ADDRESS = "0x";
928
+ #SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS = "0x";
929
+ #bundlerClient;
930
+ #chainId;
931
+ #paymasterOptions;
932
+ #onchainIdentifier = "";
933
+ /**
934
+ * Creates an instance of the Safe4337Pack.
935
+ *
936
+ * @param {Safe4337Options} options - The initialization parameters.
937
+ */
938
+ constructor({
939
+ protocolKit,
940
+ bundlerClient,
941
+ bundlerUrl,
942
+ chainId,
943
+ paymasterOptions,
944
+ entryPointAddress,
945
+ safe4337ModuleAddress,
946
+ safeWebAuthnSharedSignerAddress,
947
+ onchainAnalytics
948
+ }) {
949
+ super(protocolKit);
950
+ this.#BUNDLER_URL = bundlerUrl;
951
+ this.#bundlerClient = bundlerClient;
952
+ this.#chainId = chainId;
953
+ this.#paymasterOptions = paymasterOptions;
954
+ this.#ENTRYPOINT_ADDRESS = entryPointAddress;
955
+ this.#SAFE_4337_MODULE_ADDRESS = safe4337ModuleAddress;
956
+ this.#SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS = safeWebAuthnSharedSignerAddress || "0x";
957
+ if (onchainAnalytics?.project) {
958
+ const { project, platform } = onchainAnalytics;
959
+ this.#onchainIdentifier = generateOnChainIdentifier({
960
+ project,
961
+ platform,
962
+ tool: "relay-kit",
963
+ toolVersion: getRelayKitVersion()
964
+ });
965
+ }
966
+ }
967
+ /**
968
+ * Initializes a Safe4337Pack class.
969
+ * This method creates the protocolKit instance based on the input parameters.
970
+ * When the Safe address is provided, it will use the existing Safe.
971
+ * When the Safe address is not provided, it will use the predictedSafe feature with the provided owners and threshold.
972
+ * It will use the correct contract addresses for the fallbackHandler and the module and will add the data to enable the 4337 module.
973
+ *
974
+ * @param {Safe4337InitOptions} initOptions - The initialization parameters.
975
+ * @return {Promise<Safe4337Pack>} The Promise object that will be resolved into an instance of Safe4337Pack.
976
+ */
977
+ static async init(initOptions) {
978
+ const {
979
+ provider,
980
+ signer,
981
+ options,
982
+ bundlerUrl,
983
+ customContracts,
984
+ paymasterOptions,
985
+ onchainAnalytics
986
+ } = initOptions;
987
+ let protocolKit;
988
+ const bundlerClient = createBundlerClient(bundlerUrl);
989
+ const chainId = await bundlerClient.request({ method: "eth_chainId" /* CHAIN_ID */ });
990
+ let safeModulesSetupAddress = customContracts?.safeModulesSetupAddress;
991
+ const network = parseInt(chainId, 16).toString();
992
+ const safeModulesVersion = initOptions.safeModulesVersion || DEFAULT_SAFE_MODULES_VERSION;
993
+ if (!safeModulesSetupAddress) {
994
+ const safeModuleSetupDeployment = getSafeModuleSetupDeployment({
995
+ released: true,
996
+ version: safeModulesVersion,
997
+ network
998
+ });
999
+ safeModulesSetupAddress = safeModuleSetupDeployment?.networkAddresses[network];
1000
+ }
1001
+ let safe4337ModuleAddress = customContracts?.safe4337ModuleAddress;
1002
+ if (!safe4337ModuleAddress) {
1003
+ const safe4337ModuleDeployment = getSafe4337ModuleDeployment({
1004
+ released: true,
1005
+ version: safeModulesVersion,
1006
+ network
1007
+ });
1008
+ safe4337ModuleAddress = safe4337ModuleDeployment?.networkAddresses[network];
1009
+ }
1010
+ if (!safeModulesSetupAddress || !safe4337ModuleAddress) {
1011
+ throw new Error(
1012
+ `Safe4337Module and/or SafeModuleSetup not available for chain ${network} and modules version ${safeModulesVersion}`
1013
+ );
1014
+ }
1015
+ let safeWebAuthnSharedSignerAddress = customContracts?.safeWebAuthnSharedSignerAddress;
1016
+ if ("safeAddress" in options) {
1017
+ protocolKit = await Safe.init({
1018
+ provider,
1019
+ signer,
1020
+ safeAddress: options.safeAddress
1021
+ });
1022
+ const safeVersion = protocolKit.getContractVersion();
1023
+ const isSafeVersion4337Compatible = semverSatisfies(safeVersion, EQ_OR_GT_1_4_1);
1024
+ if (!isSafeVersion4337Compatible) {
1025
+ throw new Error(
1026
+ `Incompatibility detected: The current Safe Account version (${safeVersion}) is not supported. EIP-4337 requires the Safe to use at least v1.4.1.`
1027
+ );
1028
+ }
1029
+ const safeModules = await protocolKit.getModules();
1030
+ const is4337ModulePresent = safeModules.some((module) => module === safe4337ModuleAddress);
1031
+ if (!is4337ModulePresent) {
1032
+ throw new Error(
1033
+ `Incompatibility detected: The EIP-4337 module is not enabled in the provided Safe Account. Enable this module (address: ${safe4337ModuleAddress}) to add compatibility.`
1034
+ );
1035
+ }
1036
+ const safeFallbackhandler = await protocolKit.getFallbackHandler();
1037
+ const is4337FallbackhandlerPresent = safeFallbackhandler === safe4337ModuleAddress;
1038
+ if (!is4337FallbackhandlerPresent) {
1039
+ throw new Error(
1040
+ `Incompatibility detected: The EIP-4337 fallbackhandler is not attached to the Safe Account. Attach this fallbackhandler (address: ${safe4337ModuleAddress}) to ensure compatibility.`
1041
+ );
1042
+ }
1043
+ } else {
1044
+ if (!options.owners || !options.threshold) {
1045
+ throw new Error("Owners and threshold are required to deploy a new Safe");
1046
+ }
1047
+ const safeVersion = options.safeVersion || DEFAULT_SAFE_VERSION;
1048
+ const enable4337ModuleTransaction = {
1049
+ to: safeModulesSetupAddress,
1050
+ value: "0",
1051
+ data: encodeFunctionData3({
1052
+ abi: ABI,
1053
+ functionName: "enableModules",
1054
+ args: [[safe4337ModuleAddress]]
1055
+ }),
1056
+ operation: OperationType3.DelegateCall
1057
+ // DelegateCall required for enabling the 4337 module
1058
+ };
1059
+ const setupTransactions = [enable4337ModuleTransaction];
1060
+ const isApproveTransactionRequired = !!paymasterOptions && !paymasterOptions.isSponsored && !!paymasterOptions.paymasterTokenAddress;
1061
+ if (isApproveTransactionRequired) {
1062
+ const { paymasterAddress, amountToApprove = MAX_ERC20_AMOUNT_TO_APPROVE } = paymasterOptions;
1063
+ const approveToPaymasterTransaction = {
1064
+ to: paymasterOptions.paymasterTokenAddress,
1065
+ data: encodeFunctionData3({
1066
+ abi: ABI,
1067
+ functionName: "approve",
1068
+ args: [paymasterAddress, amountToApprove]
1069
+ }),
1070
+ value: "0",
1071
+ operation: OperationType3.Call
1072
+ // Call for approve
1073
+ };
1074
+ setupTransactions.push(approveToPaymasterTransaction);
1075
+ }
1076
+ const safeProvider = await SafeProvider.init({ provider, signer, safeVersion });
1077
+ const isPasskeySigner = await safeProvider.isPasskeySigner();
1078
+ if (isPasskeySigner) {
1079
+ if (!safeWebAuthnSharedSignerAddress) {
1080
+ const safeWebAuthnSharedSignerDeployment = getSafeWebAuthnShareSignerDeployment({
1081
+ released: true,
1082
+ version: "0.2.1",
1083
+ network
1084
+ });
1085
+ safeWebAuthnSharedSignerAddress = safeWebAuthnSharedSignerDeployment?.networkAddresses[network];
1086
+ }
1087
+ if (!safeWebAuthnSharedSignerAddress) {
1088
+ throw new Error(`safeWebAuthnSharedSignerAddress not available for chain ${network}`);
1089
+ }
1090
+ const passkeySigner = await safeProvider.getExternalSigner();
1091
+ const checkSummedOwners = options.owners.map((owner) => getAddress2(owner));
1092
+ const checkSummedSignerAddress = getAddress2(safeWebAuthnSharedSignerAddress);
1093
+ if (!checkSummedOwners.includes(checkSummedSignerAddress)) {
1094
+ options.owners.push(checkSummedSignerAddress);
1095
+ }
1096
+ const sharedSignerTransaction = {
1097
+ to: safeWebAuthnSharedSignerAddress,
1098
+ value: "0",
1099
+ data: passkeySigner.encodeConfigure(),
1100
+ operation: OperationType3.DelegateCall
1101
+ // DelegateCall required into the SafeWebAuthnSharedSigner instance in order for it to set its configuration.
1102
+ };
1103
+ setupTransactions.push(sharedSignerTransaction);
1104
+ }
1105
+ let deploymentTo;
1106
+ let deploymentData;
1107
+ const isBatch = setupTransactions.length > 1;
1108
+ if (isBatch) {
1109
+ const multiSendContract = await getMultiSendContract({
1110
+ safeProvider,
1111
+ safeVersion,
1112
+ deploymentType: options.deploymentType || void 0
1113
+ });
1114
+ const batchData = encodeFunctionData3({
1115
+ abi: ABI,
1116
+ functionName: "multiSend",
1117
+ args: [encodeMultiSendData2(setupTransactions)]
1118
+ });
1119
+ deploymentTo = multiSendContract.getAddress();
1120
+ deploymentData = batchData;
1121
+ } else {
1122
+ deploymentTo = enable4337ModuleTransaction.to;
1123
+ deploymentData = enable4337ModuleTransaction.data;
1124
+ }
1125
+ protocolKit = await Safe.init({
1126
+ provider,
1127
+ signer,
1128
+ predictedSafe: {
1129
+ safeDeploymentConfig: {
1130
+ safeVersion,
1131
+ saltNonce: options.saltNonce || void 0,
1132
+ deploymentType: options.deploymentType || void 0
1133
+ },
1134
+ safeAccountConfig: {
1135
+ owners: options.owners,
1136
+ threshold: options.threshold,
1137
+ to: deploymentTo,
1138
+ data: deploymentData,
1139
+ fallbackHandler: safe4337ModuleAddress,
1140
+ paymentToken: zeroAddress,
1141
+ payment: 0,
1142
+ paymentReceiver: zeroAddress
1143
+ }
1144
+ },
1145
+ onchainAnalytics
1146
+ });
1147
+ }
1148
+ let selectedEntryPoint;
1149
+ if (customContracts?.entryPointAddress) {
1150
+ const requiredSafeModulesVersion = entryPointToSafeModules(customContracts?.entryPointAddress);
1151
+ if (!semverSatisfies(safeModulesVersion, requiredSafeModulesVersion))
1152
+ throw new Error(
1153
+ `The selected entrypoint ${customContracts?.entryPointAddress} is not compatible with version ${safeModulesVersion} of Safe modules`
1154
+ );
1155
+ selectedEntryPoint = customContracts?.entryPointAddress;
1156
+ } else {
1157
+ const supportedEntryPoints = await bundlerClient.request({
1158
+ method: "eth_supportedEntryPoints" /* SUPPORTED_ENTRY_POINTS */
1159
+ });
1160
+ if (!supportedEntryPoints.length) {
1161
+ throw new Error("No entrypoint provided or available through the bundler");
1162
+ }
1163
+ selectedEntryPoint = supportedEntryPoints.find((entryPoint) => {
1164
+ const requiredSafeModulesVersion = entryPointToSafeModules(entryPoint);
1165
+ return semverSatisfies(safeModulesVersion, requiredSafeModulesVersion);
1166
+ });
1167
+ if (!selectedEntryPoint) {
1168
+ throw new Error(
1169
+ `Incompatibility detected: None of the entrypoints provided by the bundler is compatible with the Safe modules version ${safeModulesVersion}`
1170
+ );
1171
+ }
1172
+ }
1173
+ return new _Safe4337Pack({
1174
+ chainId: BigInt(chainId),
1175
+ protocolKit,
1176
+ bundlerClient,
1177
+ paymasterOptions,
1178
+ bundlerUrl,
1179
+ entryPointAddress: selectedEntryPoint,
1180
+ safe4337ModuleAddress,
1181
+ safeWebAuthnSharedSignerAddress,
1182
+ onchainAnalytics
1183
+ });
1184
+ }
1185
+ /**
1186
+ * Estimates gas for the SafeOperation.
1187
+ *
1188
+ * @param {EstimateFeeProps} props - The parameters for the gas estimation.
1189
+ * @param {BaseSafeOperation} props.safeOperation - The SafeOperation to estimate the gas.
1190
+ * @param {IFeeEstimator} props.feeEstimator - The function to estimate the gas.
1191
+ * @return {Promise<BaseSafeOperation>} The Promise object that will be resolved into the gas estimation.
1192
+ */
1193
+ async getEstimateFee({
1194
+ safeOperation,
1195
+ feeEstimator = new PimlicoFeeEstimator()
1196
+ }) {
1197
+ const threshold = await this.protocolKit.getThreshold();
1198
+ const preEstimationData = await feeEstimator?.preEstimateUserOperationGas?.({
1199
+ bundlerUrl: this.#BUNDLER_URL,
1200
+ entryPoint: this.#ENTRYPOINT_ADDRESS,
1201
+ userOperation: safeOperation.getUserOperation(),
1202
+ paymasterOptions: this.#paymasterOptions
1203
+ });
1204
+ if (preEstimationData) {
1205
+ safeOperation.addEstimations(preEstimationData);
1206
+ }
1207
+ const estimateUserOperationGas = await this.#bundlerClient.request({
1208
+ method: "eth_estimateUserOperationGas" /* ESTIMATE_USER_OPERATION_GAS */,
1209
+ params: [
1210
+ {
1211
+ ...userOperationToHexValues(safeOperation.getUserOperation(), this.#ENTRYPOINT_ADDRESS),
1212
+ signature: getDummySignature(this.#SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS, threshold)
1213
+ },
1214
+ this.#ENTRYPOINT_ADDRESS
1215
+ ]
1216
+ });
1217
+ if (estimateUserOperationGas) {
1218
+ safeOperation.addEstimations(estimateUserOperationGas);
1219
+ }
1220
+ const postEstimationData = await feeEstimator?.postEstimateUserOperationGas?.({
1221
+ bundlerUrl: this.#BUNDLER_URL,
1222
+ entryPoint: this.#ENTRYPOINT_ADDRESS,
1223
+ userOperation: {
1224
+ ...safeOperation.getUserOperation(),
1225
+ signature: getDummySignature(this.#SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS, threshold)
1226
+ },
1227
+ paymasterOptions: this.#paymasterOptions
1228
+ });
1229
+ if (postEstimationData) {
1230
+ safeOperation.addEstimations(postEstimationData);
1231
+ }
1232
+ return safeOperation;
1233
+ }
1234
+ /**
1235
+ * Creates a relayed transaction based on the provided parameters.
1236
+ *
1237
+ * @param {MetaTransactionData[]} transactions - The transactions to batch in a SafeOperation.
1238
+ * @param options - Optional configuration options for the transaction creation.
1239
+ * @return {Promise<BaseSafeOperation>} The Promise object will resolve a SafeOperation.
1240
+ */
1241
+ async createTransaction({
1242
+ transactions,
1243
+ options = {}
1244
+ }) {
1245
+ const { amountToApprove, validUntil, validAfter, feeEstimator, customNonce } = options;
1246
+ const userOperation = await createUserOperation(this.protocolKit, transactions, {
1247
+ entryPoint: this.#ENTRYPOINT_ADDRESS,
1248
+ paymasterOptions: this.#paymasterOptions,
1249
+ amountToApprove,
1250
+ customNonce
1251
+ });
1252
+ if (this.#onchainIdentifier) {
1253
+ userOperation.callData += this.#onchainIdentifier;
1254
+ }
1255
+ const safeOperation = SafeOperationFactory_default.createSafeOperation(userOperation, {
1256
+ chainId: this.#chainId,
1257
+ moduleAddress: this.#SAFE_4337_MODULE_ADDRESS,
1258
+ entryPoint: this.#ENTRYPOINT_ADDRESS,
1259
+ validUntil,
1260
+ validAfter
1261
+ });
1262
+ return await this.getEstimateFee({
1263
+ safeOperation,
1264
+ feeEstimator
1265
+ });
1266
+ }
1267
+ /**
1268
+ * Converts a SafeOperationResponse to an SafeOperation.
1269
+ *
1270
+ * @param {SafeOperationResponse} safeOperationResponse - The SafeOperationResponse to convert to SafeOperation
1271
+ * @returns {BaseSafeOperation} - The SafeOperation object
1272
+ */
1273
+ #toSafeOperation(safeOperationResponse) {
1274
+ const { validUntil, validAfter, userOperation } = safeOperationResponse;
1275
+ const paymaster = userOperation?.paymaster || "0x";
1276
+ const paymasterData = userOperation?.paymasterData || "0x";
1277
+ const safeOperation = SafeOperationFactory_default.createSafeOperation(
1278
+ {
1279
+ sender: userOperation?.sender || "0x",
1280
+ nonce: userOperation?.nonce || "0",
1281
+ initCode: userOperation?.initCode || "",
1282
+ callData: userOperation?.callData || "",
1283
+ callGasLimit: BigInt(userOperation?.callGasLimit || 0n),
1284
+ verificationGasLimit: BigInt(userOperation?.verificationGasLimit || 0),
1285
+ preVerificationGas: BigInt(userOperation?.preVerificationGas || 0),
1286
+ maxFeePerGas: BigInt(userOperation?.maxFeePerGas || 0),
1287
+ maxPriorityFeePerGas: BigInt(userOperation?.maxPriorityFeePerGas || 0),
1288
+ paymasterAndData: concat2([paymaster, paymasterData]),
1289
+ signature: safeOperationResponse.preparedSignature || "0x"
1290
+ },
1291
+ {
1292
+ chainId: this.#chainId,
1293
+ moduleAddress: this.#SAFE_4337_MODULE_ADDRESS,
1294
+ entryPoint: userOperation?.entryPoint || this.#ENTRYPOINT_ADDRESS,
1295
+ validAfter: this.#timestamp(validAfter),
1296
+ validUntil: this.#timestamp(validUntil)
1297
+ }
1298
+ );
1299
+ if (safeOperationResponse.confirmations) {
1300
+ safeOperationResponse.confirmations.forEach((confirmation) => {
1301
+ safeOperation.addSignature(new EthSafeSignature2(confirmation.owner, confirmation.signature));
1302
+ });
1303
+ }
1304
+ return safeOperation;
1305
+ }
1306
+ /**
1307
+ *
1308
+ * @param date An ISO string date
1309
+ * @returns The timestamp in seconds to send to the bundler
1310
+ */
1311
+ #timestamp(date) {
1312
+ return date ? new Date(date).getTime() / 1e3 : void 0;
1313
+ }
1314
+ /**
1315
+ * Signs a safe operation.
1316
+ *
1317
+ * @param {BaseSafeOperation | SafeOperationResponse} safeOperation - The SafeOperation to sign. It can be:
1318
+ * - A response from the API (Tx Service)
1319
+ * - An instance of SafeOperation
1320
+ * @param {SigningMethod} signingMethod - The signing method to use.
1321
+ * @return {Promise<BaseSafeOperation>} The Promise object will resolve to the signed SafeOperation.
1322
+ */
1323
+ async signSafeOperation(safeOperation, signingMethod = SigningMethod.ETH_SIGN_TYPED_DATA_V4) {
1324
+ let safeOp;
1325
+ if (safeOperation instanceof BaseSafeOperation_default) {
1326
+ safeOp = safeOperation;
1327
+ } else {
1328
+ safeOp = this.#toSafeOperation(safeOperation);
1329
+ }
1330
+ const safeProvider = this.protocolKit.getSafeProvider();
1331
+ const signerAddress = await safeProvider.getSignerAddress();
1332
+ const isPasskeySigner = await safeProvider.isPasskeySigner();
1333
+ if (!signerAddress) {
1334
+ throw new Error("There is no signer address available to sign the SafeOperation");
1335
+ }
1336
+ const isOwner = await this.protocolKit.isOwner(signerAddress);
1337
+ const isSafeDeployed = await this.protocolKit.isSafeDeployed();
1338
+ if (!isOwner && isSafeDeployed || !isSafeDeployed && !isPasskeySigner && !isOwner) {
1339
+ throw new Error("UserOperations can only be signed by Safe owners");
1340
+ }
1341
+ let safeSignature;
1342
+ if (isPasskeySigner) {
1343
+ const safeOpHash = safeOp.getHash();
1344
+ if (!isSafeDeployed) {
1345
+ const passkeySignature = await this.protocolKit.signHash(safeOpHash);
1346
+ safeSignature = new EthSafeSignature2(
1347
+ this.#SAFE_WEBAUTHN_SHARED_SIGNER_ADDRESS,
1348
+ passkeySignature.data,
1349
+ true
1350
+ );
1351
+ } else {
1352
+ safeSignature = await this.protocolKit.signHash(safeOpHash);
1353
+ }
1354
+ } else {
1355
+ if ([
1356
+ SigningMethod.ETH_SIGN_TYPED_DATA_V4,
1357
+ SigningMethod.ETH_SIGN_TYPED_DATA_V3,
1358
+ SigningMethod.ETH_SIGN_TYPED_DATA
1359
+ ].includes(signingMethod)) {
1360
+ const signer = await safeProvider.getExternalSigner();
1361
+ if (!signer) {
1362
+ throw new Error("No signer found");
1363
+ }
1364
+ const signerAddress2 = signer.account.address;
1365
+ const safeOperation2 = safeOp.getSafeOperation();
1366
+ const signature = await signer.signTypedData({
1367
+ domain: {
1368
+ chainId: Number(this.#chainId),
1369
+ verifyingContract: this.#SAFE_4337_MODULE_ADDRESS
1370
+ },
1371
+ types: safeOp.getEIP712Type(),
1372
+ message: {
1373
+ ...safeOperation2,
1374
+ nonce: BigInt(safeOperation2.nonce),
1375
+ validAfter: toHex5(safeOperation2.validAfter),
1376
+ validUntil: toHex5(safeOperation2.validUntil),
1377
+ maxFeePerGas: toHex5(safeOperation2.maxFeePerGas),
1378
+ maxPriorityFeePerGas: toHex5(safeOperation2.maxPriorityFeePerGas)
1379
+ },
1380
+ primaryType: "SafeOp"
1381
+ });
1382
+ safeSignature = new EthSafeSignature2(signerAddress2, signature);
1383
+ } else {
1384
+ const safeOpHash = safeOp.getHash();
1385
+ safeSignature = await this.protocolKit.signHash(safeOpHash);
1386
+ }
1387
+ }
1388
+ safeOp.addSignature(safeSignature);
1389
+ return safeOp;
1390
+ }
1391
+ /**
1392
+ * Executes the relay transaction.
1393
+ *
1394
+ * @param {Safe4337ExecutableProps} props - The parameters for the transaction execution.
1395
+ * @param {BaseSafeOperation | SafeOperationResponse} props.executable - The SafeOperation to execute. It can be:
1396
+ * - A response from the API (Tx Service)
1397
+ * - An instance of SafeOperation
1398
+ * @return {Promise<string>} The user operation hash.
1399
+ */
1400
+ async executeTransaction({ executable }) {
1401
+ let safeOperation;
1402
+ if (executable instanceof BaseSafeOperation_default) {
1403
+ safeOperation = executable;
1404
+ } else {
1405
+ safeOperation = this.#toSafeOperation(executable);
1406
+ }
1407
+ return this.#bundlerClient.request({
1408
+ method: "eth_sendUserOperation" /* SEND_USER_OPERATION */,
1409
+ params: [
1410
+ userOperationToHexValues(safeOperation.getUserOperation(), this.#ENTRYPOINT_ADDRESS),
1411
+ this.#ENTRYPOINT_ADDRESS
1412
+ ]
1413
+ });
1414
+ }
1415
+ /**
1416
+ * Return a UserOperation based on a hash (userOpHash) returned by eth_sendUserOperation
1417
+ *
1418
+ * @param {string} userOpHash - The hash of the user operation to fetch. Returned from the #sendUserOperation method
1419
+ * @returns {UserOperation} - null in case the UserOperation is not yet included in a block, or a full UserOperation, with the addition of entryPoint, blockNumber, blockHash and transactionHash
1420
+ */
1421
+ async getUserOperationByHash(userOpHash) {
1422
+ return this.#bundlerClient.request({
1423
+ method: "eth_getUserOperationByHash" /* GET_USER_OPERATION_BY_HASH */,
1424
+ params: [userOpHash]
1425
+ });
1426
+ }
1427
+ /**
1428
+ * Return a UserOperation receipt based on a hash (userOpHash) returned by eth_sendUserOperation
1429
+ *
1430
+ * @param {string} userOpHash - The hash of the user operation to fetch. Returned from the #sendUserOperation method
1431
+ * @returns {UserOperationReceipt} - null in case the UserOperation is not yet included in a block, or UserOperationReceipt object
1432
+ */
1433
+ async getUserOperationReceipt(userOpHash) {
1434
+ return this.#bundlerClient.request({
1435
+ method: "eth_getUserOperationReceipt" /* GET_USER_OPERATION_RECEIPT */,
1436
+ params: [userOpHash]
1437
+ });
1438
+ }
1439
+ /**
1440
+ * Returns an array of the entryPoint addresses supported by the client.
1441
+ * The first element of the array SHOULD be the entryPoint addressed preferred by the client.
1442
+ *
1443
+ * @returns {string[]} - The supported entry points.
1444
+ */
1445
+ async getSupportedEntryPoints() {
1446
+ return this.#bundlerClient.request({
1447
+ method: "eth_supportedEntryPoints" /* SUPPORTED_ENTRY_POINTS */
1448
+ });
1449
+ }
1450
+ /**
1451
+ * Returns EIP-155 Chain ID.
1452
+ *
1453
+ * @returns {string} - The chain id.
1454
+ */
1455
+ async getChainId() {
1456
+ return this.#bundlerClient.request({ method: "eth_chainId" /* CHAIN_ID */ });
1457
+ }
1458
+ getOnchainIdentifier() {
1459
+ return this.#onchainIdentifier;
1460
+ }
1461
+ };
1462
+ export {
1463
+ BaseSafeOperation_default as BaseSafeOperation,
1464
+ DUMMY_AUTHENTICATOR_DATA,
1465
+ DUMMY_CLIENT_DATA_FIELDS,
1466
+ EQ_OR_GT_0_3_0,
1467
+ GelatoRelayPack,
1468
+ PimlicoFeeEstimator,
1469
+ RelayKitBasePack,
1470
+ Safe4337Pack,
1471
+ SafeOperationFactory_default as SafeOperationFactory,
1472
+ SafeOperationV06_default as SafeOperationV06,
1473
+ SafeOperationV07_default as SafeOperationV07,
1474
+ createBundlerClient,
1475
+ createUserOperation,
1476
+ encodeMultiSendCallData,
1477
+ encodeNonce,
1478
+ entryPointToSafeModules,
1479
+ getDummySignature,
1480
+ getRelayKitVersion,
1481
+ getSafeNonceFromEntrypoint,
1482
+ getSignatureBytes,
1483
+ isEntryPointV6,
1484
+ isEntryPointV7,
1485
+ sameString,
1486
+ userOperationToHexValues
1487
+ };