@gelatocloud/gasless 0.0.1 → 0.0.3

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 (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +417 -0
  3. package/_dist/account/actions/sendTransactionSync.d.ts +2 -2
  4. package/_dist/account/actions/sendTransactionSync.d.ts.map +1 -1
  5. package/_dist/account/actions/sendTransactionSync.js.map +1 -1
  6. package/_dist/account/index.d.ts +3 -3
  7. package/_dist/account/index.d.ts.map +1 -1
  8. package/_dist/account/index.js +1 -0
  9. package/_dist/account/index.js.map +1 -1
  10. package/_dist/relayer/evm/actions/getStatus.d.ts +77 -0
  11. package/_dist/relayer/evm/actions/getStatus.d.ts.map +1 -1
  12. package/_dist/relayer/evm/actions/getStatus.js +7 -1
  13. package/_dist/relayer/evm/actions/getStatus.js.map +1 -1
  14. package/_dist/relayer/evm/actions/handleTerminalStatus.d.ts +3 -0
  15. package/_dist/relayer/evm/actions/handleTerminalStatus.d.ts.map +1 -0
  16. package/_dist/relayer/evm/actions/handleTerminalStatus.js +29 -0
  17. package/_dist/relayer/evm/actions/handleTerminalStatus.js.map +1 -0
  18. package/_dist/relayer/evm/actions/index.d.ts +1 -0
  19. package/_dist/relayer/evm/actions/index.d.ts.map +1 -1
  20. package/_dist/relayer/evm/actions/index.js +1 -0
  21. package/_dist/relayer/evm/actions/index.js.map +1 -1
  22. package/_dist/relayer/evm/actions/sendTransactionSync.d.ts +2 -2
  23. package/_dist/relayer/evm/actions/sendTransactionSync.d.ts.map +1 -1
  24. package/_dist/relayer/evm/actions/sendTransactionSync.js +3 -1
  25. package/_dist/relayer/evm/actions/sendTransactionSync.js.map +1 -1
  26. package/_dist/relayer/evm/actions/waitForInclusion.d.ts +4 -0
  27. package/_dist/relayer/evm/actions/waitForInclusion.d.ts.map +1 -0
  28. package/_dist/relayer/evm/actions/waitForInclusion.js +11 -0
  29. package/_dist/relayer/evm/actions/waitForInclusion.js.map +1 -0
  30. package/_dist/relayer/evm/errors/index.d.ts +36 -0
  31. package/_dist/relayer/evm/errors/index.d.ts.map +1 -0
  32. package/_dist/relayer/evm/errors/index.js +62 -0
  33. package/_dist/relayer/evm/errors/index.js.map +1 -0
  34. package/_dist/relayer/evm/index.d.ts +3 -2
  35. package/_dist/relayer/evm/index.d.ts.map +1 -1
  36. package/_dist/relayer/evm/index.js +1 -0
  37. package/_dist/relayer/evm/index.js.map +1 -1
  38. package/_dist/tsconfig.build.tsbuildinfo +1 -1
  39. package/package.json +6 -1
  40. package/CHANGELOG.md +0 -9
  41. package/account/actions/getFeeQuote.ts +0 -34
  42. package/account/actions/index.ts +0 -3
  43. package/account/actions/sendTransaction.ts +0 -61
  44. package/account/actions/sendTransactionSync.ts +0 -51
  45. package/account/adapters/gelato/abi.ts +0 -13
  46. package/account/adapters/gelato/constants.ts +0 -13
  47. package/account/adapters/gelato/index.ts +0 -216
  48. package/account/adapters/index.ts +0 -1
  49. package/account/adapters/types/index.ts +0 -36
  50. package/account/index.ts +0 -60
  51. package/account/utils/delegation.ts +0 -9
  52. package/account/utils/estimation.ts +0 -29
  53. package/account/utils/index.ts +0 -2
  54. package/bundler/actions/estimateUserOperationGas.ts +0 -63
  55. package/bundler/actions/getUserOperationGasPrice.ts +0 -25
  56. package/bundler/actions/getUserOperationQuote.ts +0 -83
  57. package/bundler/actions/index.ts +0 -6
  58. package/bundler/actions/prepareUserOperation.ts +0 -437
  59. package/bundler/actions/sendUserOperation.ts +0 -64
  60. package/bundler/actions/sendUserOperationSync.ts +0 -71
  61. package/bundler/index.ts +0 -98
  62. package/constants/index.ts +0 -2
  63. package/index.ts +0 -4
  64. package/relayer/evm/actions/getCapabilities.ts +0 -22
  65. package/relayer/evm/actions/getFeeData.ts +0 -36
  66. package/relayer/evm/actions/getFeeQuote.ts +0 -39
  67. package/relayer/evm/actions/getGelatoStatus.ts +0 -99
  68. package/relayer/evm/actions/getStatus.ts +0 -92
  69. package/relayer/evm/actions/index.ts +0 -9
  70. package/relayer/evm/actions/sendTransaction.ts +0 -33
  71. package/relayer/evm/actions/sendTransactionSync.ts +0 -30
  72. package/relayer/evm/actions/waitForGelatoStatus.ts +0 -28
  73. package/relayer/evm/actions/waitForStatus.ts +0 -24
  74. package/relayer/evm/index.ts +0 -77
  75. package/relayer/index.ts +0 -1
  76. package/tsconfig.build.json +0 -19
  77. package/tsconfig.json +0 -8
  78. package/types/error.ts +0 -38
  79. package/types/index.ts +0 -3
  80. package/types/payment.ts +0 -23
  81. package/types/schema.ts +0 -28
  82. package/utils/index.ts +0 -2
  83. package/utils/payment.ts +0 -20
  84. package/utils/serialize.ts +0 -91
@@ -1,25 +0,0 @@
1
- import type { Client, EstimateFeesPerGasReturnType } from 'viem';
2
- import type { Payment } from '../../types/index.js';
3
-
4
- export type GetUserOperationGasPriceReturnType = EstimateFeesPerGasReturnType<'eip1559'>;
5
-
6
- export const getUserOperationGasPrice = async (
7
- client: Client,
8
- payment?: Payment
9
- ): Promise<GetUserOperationGasPriceReturnType> => {
10
- if (payment) {
11
- return {
12
- maxFeePerGas: 0n,
13
- maxPriorityFeePerGas: 0n
14
- };
15
- }
16
-
17
- const { maxFeePerGas, maxPriorityFeePerGas } = await client.request({
18
- method: 'gelato_getUserOperationGasPrice'
19
- } as never);
20
-
21
- return {
22
- maxFeePerGas: BigInt(maxFeePerGas),
23
- maxPriorityFeePerGas: BigInt(maxPriorityFeePerGas)
24
- };
25
- };
@@ -1,83 +0,0 @@
1
- import type { BaseError, Client, Transport } from 'viem';
2
- import {
3
- type EstimateUserOperationGasParameters,
4
- type EstimateUserOperationGasReturnType,
5
- formatUserOperationRequest,
6
- getUserOperationError,
7
- type PrepareUserOperationParameters,
8
- type SmartAccount,
9
- type UserOperation
10
- } from 'viem/account-abstraction';
11
- import { parseAccount } from 'viem/accounts';
12
- import type { Chain } from 'viem/chains';
13
- import type { CapabilitiesByChain } from '../../relayer/evm/actions/index.js';
14
- import { AccountNotFoundError, type Payment } from '../../types/index.js';
15
- import { serializeStateOverride } from '../../utils/index.js';
16
- import { prepareUserOperation } from './prepareUserOperation.js';
17
-
18
- export type GetUserOperationQuoteParameters = Omit<
19
- EstimateUserOperationGasParameters,
20
- 'paymaster' | 'paymasterContext'
21
- >;
22
-
23
- export type GetUserOperationQuoteReturnType = EstimateUserOperationGasReturnType & {
24
- fee: bigint;
25
- gas: bigint;
26
- l1Fee?: bigint;
27
- };
28
-
29
- export const getUserOperationQuote = async <account extends SmartAccount | undefined>(
30
- client: Client<Transport, Chain | undefined, account>,
31
- parameters: GetUserOperationQuoteParameters,
32
- capabilities: CapabilitiesByChain,
33
- payment?: Payment
34
- ): Promise<GetUserOperationQuoteReturnType> => {
35
- const { account: account_ = client.account, entryPointAddress, stateOverride } = parameters;
36
-
37
- if (!account_ && !parameters.sender) throw new AccountNotFoundError();
38
- const account = account_ ? parseAccount(account_) : undefined;
39
-
40
- const rpcStateOverride = serializeStateOverride(stateOverride);
41
-
42
- const request = account
43
- ? await prepareUserOperation(
44
- client,
45
- {
46
- ...parameters,
47
- parameters: ['authorization', 'factory', 'nonce', 'signature']
48
- } as unknown as PrepareUserOperationParameters,
49
- capabilities,
50
- payment
51
- )
52
- : parameters;
53
-
54
- try {
55
- const params = [
56
- formatUserOperationRequest(request as UserOperation),
57
- // biome-ignore lint/style/noNonNullAssertion: copied from viem
58
- (entryPointAddress ?? account?.entryPoint?.address)!
59
- ] as const;
60
-
61
- const { fee, gas, l1Fee, preVerificationGas, verificationGasLimit, callGasLimit } =
62
- await client.request({
63
- method: 'gelato_getUserOperationQuote',
64
- params: rpcStateOverride ? [...params, rpcStateOverride] : [...params]
65
- } as never);
66
-
67
- return {
68
- callGasLimit: BigInt(callGasLimit),
69
- fee: BigInt(fee),
70
- gas: BigInt(gas),
71
- l1Fee: l1Fee ? BigInt(l1Fee) : undefined,
72
- preVerificationGas: BigInt(preVerificationGas),
73
- verificationGasLimit: BigInt(verificationGasLimit)
74
- };
75
- } catch (error) {
76
- // biome-ignore lint/suspicious/noExplicitAny: copied from viem
77
- const calls = (parameters as any).calls;
78
- throw getUserOperationError(error as BaseError, {
79
- ...(request as UserOperation),
80
- ...(calls ? { calls } : {})
81
- });
82
- }
83
- };
@@ -1,6 +0,0 @@
1
- export * from './estimateUserOperationGas.js';
2
- export * from './getUserOperationGasPrice.js';
3
- export * from './getUserOperationQuote.js';
4
- export * from './prepareUserOperation.js';
5
- export * from './sendUserOperation.js';
6
- export * from './sendUserOperationSync.js';
@@ -1,437 +0,0 @@
1
- import type { Call, Chain, Client, SignedAuthorization, Transport } from 'viem';
2
- import {
3
- type EstimateUserOperationGasParameters,
4
- getPaymasterData as getPaymasterData_,
5
- getPaymasterStubData as getPaymasterStubData_,
6
- type PrepareUserOperationParameters,
7
- type PrepareUserOperationRequest,
8
- type PrepareUserOperationReturnType,
9
- type SmartAccount,
10
- type UserOperation
11
- } from 'viem/account-abstraction';
12
- import { parseAccount } from 'viem/accounts';
13
- import { getChainId as getChainId_, prepareAuthorization } from 'viem/actions';
14
- import { concat, encodeFunctionData, getAction } from 'viem/utils';
15
- import type { CapabilitiesByChain } from '../../relayer/evm/actions/index.js';
16
- import { AccountNotFoundError, type Payment, PaymentType } from '../../types/index.js';
17
- import { appendPayment } from '../../utils/payment.js';
18
- import type { GelatoBundlerClient } from '..';
19
- import { estimateUserOperationGas } from './estimateUserOperationGas.js';
20
- import { getUserOperationGasPrice } from './getUserOperationGasPrice.js';
21
- import { getUserOperationQuote } from './getUserOperationQuote.js';
22
-
23
- const defaultParameters = [
24
- 'factory',
25
- 'fees',
26
- 'gas',
27
- 'paymaster',
28
- 'nonce',
29
- 'signature',
30
- 'authorization'
31
- ] as const;
32
-
33
- export const prepareUserOperation = async <
34
- account extends SmartAccount | undefined,
35
- const calls extends readonly unknown[],
36
- const request extends PrepareUserOperationRequest<account, accountOverride, calls>,
37
- accountOverride extends SmartAccount | undefined = undefined
38
- >(
39
- client: Client<Transport, Chain | undefined, account>,
40
- parameters_: PrepareUserOperationParameters<account, accountOverride, calls, request>,
41
- capabilities: CapabilitiesByChain,
42
- payment?: Payment,
43
- quote: boolean = false
44
- ): Promise<PrepareUserOperationReturnType<account, accountOverride, calls, request>> => {
45
- const parameters = parameters_ as PrepareUserOperationParameters;
46
- const {
47
- account: account_ = client.account,
48
- parameters: properties = defaultParameters,
49
- stateOverride
50
- } = parameters;
51
-
52
- ////////////////////////////////////////////////////////////////////////////////
53
- // Assert that an Account is defined.
54
- ////////////////////////////////////////////////////////////////////////////////
55
-
56
- if (!account_) throw new AccountNotFoundError();
57
- const account = parseAccount(account_);
58
-
59
- ////////////////////////////////////////////////////////////////////////////////
60
- // Declare typed Bundler Client.
61
- ////////////////////////////////////////////////////////////////////////////////
62
-
63
- const bundlerClient = client as unknown as GelatoBundlerClient;
64
-
65
- ////////////////////////////////////////////////////////////////////////////////
66
- // Declare Paymaster properties.
67
- ////////////////////////////////////////////////////////////////////////////////
68
-
69
- const paymaster = parameters.paymaster ?? bundlerClient?.paymaster;
70
- const paymasterAddress = typeof paymaster === 'string' ? paymaster : undefined;
71
- const { getPaymasterStubData, getPaymasterData } = (() => {
72
- // If `paymaster: true`, we will assume the Bundler Client supports Paymaster Actions.
73
- if (paymaster === true)
74
- return {
75
- // biome-ignore lint/suspicious/noExplicitAny: copied from viem
76
- getPaymasterData: (parameters: any) =>
77
- getAction(bundlerClient, getPaymasterData_, 'getPaymasterData')(parameters),
78
- // biome-ignore lint/suspicious/noExplicitAny: copied from viem
79
- getPaymasterStubData: (parameters: any) =>
80
- getAction(bundlerClient, getPaymasterStubData_, 'getPaymasterStubData')(parameters)
81
- };
82
-
83
- // If Actions are passed to `paymaster` (via Paymaster Client or directly), we will use them.
84
- if (typeof paymaster === 'object') {
85
- const { getPaymasterStubData, getPaymasterData } = paymaster;
86
- return {
87
- getPaymasterData: getPaymasterData && getPaymasterStubData ? getPaymasterData : undefined,
88
- getPaymasterStubData: (getPaymasterData && getPaymasterStubData
89
- ? getPaymasterStubData
90
- : getPaymasterData) as typeof getPaymasterStubData
91
- };
92
- }
93
-
94
- // No Paymaster functions.
95
- return {
96
- getPaymasterData: undefined,
97
- getPaymasterStubData: undefined
98
- };
99
- })();
100
- const paymasterContext = parameters.paymasterContext
101
- ? parameters.paymasterContext
102
- : bundlerClient?.paymasterContext;
103
-
104
- ////////////////////////////////////////////////////////////////////////////////
105
- // Set up the User Operation request.
106
- ////////////////////////////////////////////////////////////////////////////////
107
-
108
- let request = {
109
- ...parameters,
110
- paymaster: paymasterAddress,
111
- sender: account.address
112
- } as PrepareUserOperationRequest;
113
-
114
- ////////////////////////////////////////////////////////////////////////////////
115
- // Concurrently prepare properties required to fill the User Operation.
116
- ////////////////////////////////////////////////////////////////////////////////
117
-
118
- const [{ callsWithoutPayment, callData }, factory, fees, nonce, authorization] =
119
- await Promise.all([
120
- (async () => {
121
- if (parameters.calls) {
122
- const callsWithoutPayment = parameters.calls.map((call_) => {
123
- const call = call_ as Call;
124
- if (call.abi)
125
- return {
126
- data: encodeFunctionData(call),
127
- to: call.to,
128
- value: call.value
129
- } as Call;
130
- return call as Call;
131
- });
132
-
133
- const calls =
134
- payment?.type === PaymentType.Token
135
- ? appendPayment(callsWithoutPayment, payment.address, capabilities.feeCollector, 1n)
136
- : callsWithoutPayment;
137
-
138
- const callData = await account.encodeCalls(calls);
139
-
140
- return {
141
- callData,
142
- callsWithoutPayment
143
- };
144
- }
145
-
146
- if (payment?.type !== PaymentType.Token) {
147
- return {
148
- callData: parameters.callData,
149
- callsWithoutPayment: undefined
150
- };
151
- }
152
-
153
- if (!account.decodeCalls) {
154
- throw new Error(
155
- 'Account must be able to decodeCalls in order to append token payments if raw callData is specified'
156
- );
157
- }
158
-
159
- const callsWithoutPayment = (await account.decodeCalls(parameters.callData)) as Call[];
160
-
161
- const calls = appendPayment(
162
- callsWithoutPayment,
163
- payment.address,
164
- capabilities.feeCollector,
165
- 1n
166
- );
167
-
168
- const callData = await account.encodeCalls(calls);
169
-
170
- return {
171
- callData,
172
- callsWithoutPayment
173
- };
174
- })(),
175
- (async () => {
176
- if (!properties.includes('factory')) return undefined;
177
- if (parameters.initCode) return { initCode: parameters.initCode };
178
- if (parameters.factory && parameters.factoryData) {
179
- return {
180
- factory: parameters.factory,
181
- factoryData: parameters.factoryData
182
- };
183
- }
184
-
185
- const { factory, factoryData } = await account.getFactoryArgs();
186
-
187
- if (account.entryPoint.version === '0.6')
188
- return {
189
- initCode: factory && factoryData ? concat([factory, factoryData]) : undefined
190
- };
191
- return {
192
- factory,
193
- factoryData
194
- };
195
- })(),
196
- (async () => {
197
- if (!properties.includes('fees')) return undefined;
198
-
199
- // If we have sufficient properties for fees, return them.
200
- if (
201
- typeof parameters.maxFeePerGas === 'bigint' &&
202
- typeof parameters.maxPriorityFeePerGas === 'bigint'
203
- )
204
- return request;
205
-
206
- const fees = await getUserOperationGasPrice(bundlerClient, payment);
207
-
208
- return {
209
- ...request,
210
- ...fees
211
- };
212
- })(),
213
- (async () => {
214
- if (!properties.includes('nonce')) return undefined;
215
- if (typeof parameters.nonce === 'bigint') return parameters.nonce;
216
- return account.getNonce();
217
- })(),
218
- (async () => {
219
- if (!properties.includes('authorization')) return undefined;
220
- if (typeof parameters.authorization === 'object') return parameters.authorization;
221
- if (account.authorization && !(await account.isDeployed())) {
222
- const authorization = await prepareAuthorization(account.client, account.authorization);
223
- return {
224
- ...authorization,
225
- r: '0xfffffffffffffffffffffffffffffff000000000000000000000000000000000',
226
- s: '0x7aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
227
- yParity: 1
228
- } satisfies SignedAuthorization;
229
- }
230
- return undefined;
231
- })()
232
- ]);
233
-
234
- ////////////////////////////////////////////////////////////////////////////////
235
- // Fill User Operation with the prepared properties from above.
236
- ////////////////////////////////////////////////////////////////////////////////
237
-
238
- if (typeof callData !== 'undefined') request.callData = callData;
239
- // biome-ignore lint/suspicious/noExplicitAny: copied from viem
240
- if (typeof factory !== 'undefined') request = { ...request, ...(factory as any) };
241
- // biome-ignore lint/suspicious/noExplicitAny: copied from viem
242
- if (typeof fees !== 'undefined') request = { ...request, ...(fees as any) };
243
- if (typeof nonce !== 'undefined') request.nonce = nonce;
244
- if (typeof authorization !== 'undefined') request.authorization = authorization;
245
-
246
- ////////////////////////////////////////////////////////////////////////////////
247
- // Fill User Operation with the `signature` property.
248
- ////////////////////////////////////////////////////////////////////////////////
249
-
250
- if (properties.includes('signature')) {
251
- if (typeof parameters.signature !== 'undefined') request.signature = parameters.signature;
252
- else request.signature = await account.getStubSignature(request as UserOperation);
253
- }
254
-
255
- ////////////////////////////////////////////////////////////////////////////////
256
- // `initCode` is required to be filled with EntryPoint 0.6.
257
- ////////////////////////////////////////////////////////////////////////////////
258
-
259
- // If no `initCode` is provided, we use an empty bytes string.
260
- if (account.entryPoint.version === '0.6' && !request.initCode) request.initCode = '0x';
261
-
262
- ////////////////////////////////////////////////////////////////////////////////
263
- // Fill User Operation with paymaster-related properties for **gas estimation**.
264
- ////////////////////////////////////////////////////////////////////////////////
265
-
266
- let chainId: number | undefined;
267
- async function getChainId(): Promise<number> {
268
- if (chainId) return chainId;
269
- if (client.chain) return client.chain.id;
270
- const chainId_ = await getAction(client, getChainId_, 'getChainId')({});
271
- chainId = chainId_;
272
- return chainId;
273
- }
274
-
275
- // If the User Operation is intended to be sponsored, we will need to fill the paymaster-related
276
- // User Operation properties required to estimate the User Operation gas.
277
- let isPaymasterPopulated = false;
278
- if (
279
- properties.includes('paymaster') &&
280
- getPaymasterStubData &&
281
- !paymasterAddress &&
282
- !parameters.paymasterAndData
283
- ) {
284
- const {
285
- isFinal = false,
286
- sponsor: _,
287
- ...paymasterArgs
288
- } = await getPaymasterStubData({
289
- chainId: await getChainId(),
290
- context: paymasterContext,
291
- entryPointAddress: account.entryPoint.address,
292
- ...(request as UserOperation)
293
- });
294
- isPaymasterPopulated = isFinal;
295
- request = {
296
- ...request,
297
- ...paymasterArgs
298
- } as PrepareUserOperationRequest;
299
- }
300
-
301
- ////////////////////////////////////////////////////////////////////////////////
302
- // `paymasterAndData` is required to be filled with EntryPoint 0.6.
303
- ////////////////////////////////////////////////////////////////////////////////
304
-
305
- // If no `paymasterAndData` is provided, we use an empty bytes string.
306
- if (account.entryPoint.version === '0.6' && !request.paymasterAndData)
307
- request.paymasterAndData = '0x';
308
-
309
- ////////////////////////////////////////////////////////////////////////////////
310
- // Fill User Operation with gas-related properties.
311
- ////////////////////////////////////////////////////////////////////////////////
312
-
313
- if (quote && callsWithoutPayment && payment?.type === PaymentType.Token) {
314
- const quote = await getUserOperationQuote(
315
- bundlerClient,
316
- {
317
- account,
318
- stateOverride,
319
- ...request
320
- },
321
- capabilities,
322
- payment
323
- );
324
-
325
- const calls = appendPayment(
326
- callsWithoutPayment,
327
- payment.address,
328
- capabilities.feeCollector,
329
- quote.fee
330
- );
331
-
332
- const callData = await account.encodeCalls(calls);
333
-
334
- request = {
335
- ...request,
336
- callData,
337
- callGasLimit: request.callGasLimit ?? quote.callGasLimit,
338
- preVerificationGas: request.preVerificationGas ?? quote.preVerificationGas,
339
- verificationGasLimit: request.verificationGasLimit ?? quote.verificationGasLimit
340
- } as PrepareUserOperationRequest;
341
- } else if (properties.includes('gas')) {
342
- // If the Account has opinionated gas estimation logic, run the `estimateGas` hook and
343
- // fill the request with the prepared gas properties.
344
- if (account.userOperation?.estimateGas) {
345
- const gas = await account.userOperation.estimateGas(request as UserOperation);
346
- request = {
347
- ...request,
348
- ...gas
349
- } as PrepareUserOperationRequest;
350
- }
351
-
352
- // If not all the gas properties are already populated, we will need to estimate the gas
353
- // to fill the gas properties.
354
- if (
355
- typeof request.callGasLimit === 'undefined' ||
356
- typeof request.preVerificationGas === 'undefined' ||
357
- typeof request.verificationGasLimit === 'undefined' ||
358
- (request.paymaster && typeof request.paymasterPostOpGasLimit === 'undefined') ||
359
- (request.paymaster && typeof request.paymasterVerificationGasLimit === 'undefined')
360
- ) {
361
- const gas = await estimateUserOperationGas(
362
- bundlerClient,
363
- {
364
- account,
365
- // Some Bundlers fail if nullish gas values are provided for gas estimation :') –
366
- // so we will need to set a default zeroish value.
367
- callGasLimit: 0n,
368
- preVerificationGas: 0n,
369
- stateOverride,
370
- verificationGasLimit: 0n,
371
- ...(request.paymaster
372
- ? {
373
- paymasterPostOpGasLimit: 0n,
374
- paymasterVerificationGasLimit: 0n
375
- }
376
- : {}),
377
- ...request
378
- } as EstimateUserOperationGasParameters,
379
- capabilities,
380
- payment
381
- );
382
- request = {
383
- ...request,
384
- callGasLimit: request.callGasLimit ?? gas.callGasLimit,
385
- paymasterPostOpGasLimit: request.paymasterPostOpGasLimit ?? gas.paymasterPostOpGasLimit,
386
- paymasterVerificationGasLimit:
387
- request.paymasterVerificationGasLimit ?? gas.paymasterVerificationGasLimit,
388
- preVerificationGas: request.preVerificationGas ?? gas.preVerificationGas,
389
- verificationGasLimit: request.verificationGasLimit ?? gas.verificationGasLimit
390
- } as PrepareUserOperationRequest;
391
- }
392
- }
393
-
394
- ////////////////////////////////////////////////////////////////////////////////
395
- // Fill User Operation with paymaster-related properties for **sending** the User Operation.
396
- ////////////////////////////////////////////////////////////////////////////////
397
-
398
- // If the User Operation is intended to be sponsored, we will need to fill the paymaster-related
399
- // User Operation properties required to send the User Operation.
400
- if (
401
- properties.includes('paymaster') &&
402
- getPaymasterData &&
403
- !paymasterAddress &&
404
- !parameters.paymasterAndData &&
405
- !isPaymasterPopulated
406
- ) {
407
- // Retrieve paymaster-related User Operation properties to be used for **sending** the User Operation.
408
- const paymaster = await getPaymasterData({
409
- chainId: await getChainId(),
410
- context: paymasterContext,
411
- entryPointAddress: account.entryPoint.address,
412
- ...(request as UserOperation)
413
- });
414
- request = {
415
- ...request,
416
- ...paymaster
417
- } as PrepareUserOperationRequest;
418
- }
419
-
420
- ////////////////////////////////////////////////////////////////////////////////
421
- // Remove redundant properties that do not conform to the User Operation schema.
422
- ////////////////////////////////////////////////////////////////////////////////
423
-
424
- delete request.calls;
425
- delete request.parameters;
426
- delete request.paymasterContext;
427
- if (typeof request.paymaster !== 'string') delete request.paymaster;
428
-
429
- ////////////////////////////////////////////////////////////////////////////////
430
-
431
- return request as unknown as PrepareUserOperationReturnType<
432
- account,
433
- accountOverride,
434
- calls,
435
- request
436
- >;
437
- };
@@ -1,64 +0,0 @@
1
- import type { BaseError, Chain, Client, Transport } from 'viem';
2
- import {
3
- formatUserOperationRequest,
4
- getUserOperationError,
5
- type PrepareUserOperationParameters,
6
- type SendUserOperationParameters,
7
- type SendUserOperationReturnType,
8
- type SmartAccount,
9
- type UserOperation
10
- } from 'viem/account-abstraction';
11
- import { parseAccount } from 'viem/accounts';
12
- import type { CapabilitiesByChain } from '../../relayer/evm/actions/index.js';
13
- import { AccountNotFoundError, type Payment } from '../../types/index.js';
14
- import { prepareUserOperation } from './prepareUserOperation.js';
15
-
16
- export const sendUserOperation = async <account extends SmartAccount | undefined>(
17
- client: Client<Transport, Chain | undefined, account>,
18
- parameters: SendUserOperationParameters,
19
- capabilities: CapabilitiesByChain,
20
- payment?: Payment
21
- ): Promise<SendUserOperationReturnType> => {
22
- const { account: account_ = client.account, entryPointAddress } = parameters;
23
-
24
- if (!account_ && !parameters.sender) throw new AccountNotFoundError();
25
- const account = account_ ? parseAccount(account_) : undefined;
26
-
27
- const request = account
28
- ? await prepareUserOperation(
29
- client,
30
- parameters as unknown as PrepareUserOperationParameters,
31
- capabilities,
32
- payment,
33
- true
34
- )
35
- : parameters;
36
-
37
- // biome-ignore lint/style/noNonNullAssertion: copied from viem
38
- const signature = (parameters.signature ||
39
- (await account?.signUserOperation?.(request as UserOperation)))!;
40
-
41
- const rpcParameters = formatUserOperationRequest({
42
- ...request,
43
- signature
44
- } as UserOperation);
45
-
46
- try {
47
- return await client.request(
48
- {
49
- method: 'eth_sendUserOperation',
50
- // biome-ignore lint/style/noNonNullAssertion: copied from viem
51
- params: [rpcParameters, (entryPointAddress ?? account?.entryPoint?.address)!]
52
- },
53
- { retryCount: 0 }
54
- );
55
- } catch (error) {
56
- // biome-ignore lint/suspicious/noExplicitAny: copied from viem
57
- const calls = (parameters as any).calls;
58
- throw getUserOperationError(error as BaseError, {
59
- ...(request as UserOperation),
60
- ...(calls ? { calls } : {}),
61
- signature
62
- });
63
- }
64
- };