ox 0.4.3 → 0.5.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 (66) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/_cjs/core/Siwe.js +1 -1
  3. package/_cjs/core/Siwe.js.map +1 -1
  4. package/_cjs/erc4337/EntryPoint.js +1320 -0
  5. package/_cjs/erc4337/EntryPoint.js.map +1 -0
  6. package/_cjs/erc4337/RpcSchema.js +3 -0
  7. package/_cjs/erc4337/RpcSchema.js.map +1 -0
  8. package/_cjs/erc4337/UserOperation.js +152 -0
  9. package/_cjs/erc4337/UserOperation.js.map +1 -0
  10. package/_cjs/erc4337/UserOperationGas.js +31 -0
  11. package/_cjs/erc4337/UserOperationGas.js.map +1 -0
  12. package/_cjs/erc4337/UserOperationReceipt.js +35 -0
  13. package/_cjs/erc4337/UserOperationReceipt.js.map +1 -0
  14. package/_cjs/erc4337/index.js +9 -0
  15. package/_cjs/erc4337/index.js.map +1 -0
  16. package/_cjs/index.docs.js +1 -0
  17. package/_cjs/index.docs.js.map +1 -1
  18. package/_cjs/version.js +1 -1
  19. package/_esm/core/Siwe.js +1 -1
  20. package/_esm/core/Siwe.js.map +1 -1
  21. package/_esm/erc4337/EntryPoint.js +1321 -0
  22. package/_esm/erc4337/EntryPoint.js.map +1 -0
  23. package/_esm/erc4337/RpcSchema.js +2 -0
  24. package/_esm/erc4337/RpcSchema.js.map +1 -0
  25. package/_esm/erc4337/UserOperation.js +324 -0
  26. package/_esm/erc4337/UserOperation.js.map +1 -0
  27. package/_esm/erc4337/UserOperationGas.js +61 -0
  28. package/_esm/erc4337/UserOperationGas.js.map +1 -0
  29. package/_esm/erc4337/UserOperationReceipt.js +79 -0
  30. package/_esm/erc4337/UserOperationReceipt.js.map +1 -0
  31. package/_esm/erc4337/index.js +31 -0
  32. package/_esm/erc4337/index.js.map +1 -0
  33. package/_esm/index.docs.js +1 -0
  34. package/_esm/index.docs.js.map +1 -1
  35. package/_esm/version.js +1 -1
  36. package/_types/erc4337/EntryPoint.d.ts +1480 -0
  37. package/_types/erc4337/EntryPoint.d.ts.map +1 -0
  38. package/_types/erc4337/RpcSchema.d.ts +159 -0
  39. package/_types/erc4337/RpcSchema.d.ts.map +1 -0
  40. package/_types/erc4337/UserOperation.d.ts +330 -0
  41. package/_types/erc4337/UserOperation.d.ts.map +1 -0
  42. package/_types/erc4337/UserOperationGas.d.ts +62 -0
  43. package/_types/erc4337/UserOperationGas.d.ts.map +1 -0
  44. package/_types/erc4337/UserOperationReceipt.d.ts +87 -0
  45. package/_types/erc4337/UserOperationReceipt.d.ts.map +1 -0
  46. package/_types/erc4337/index.d.ts +33 -0
  47. package/_types/erc4337/index.d.ts.map +1 -0
  48. package/_types/index.docs.d.ts +1 -0
  49. package/_types/index.docs.d.ts.map +1 -1
  50. package/_types/version.d.ts +1 -1
  51. package/core/Siwe.ts +1 -1
  52. package/erc4337/EntryPoint/package.json +6 -0
  53. package/erc4337/EntryPoint.ts +1419 -0
  54. package/erc4337/RpcSchema/package.json +6 -0
  55. package/erc4337/RpcSchema.ts +179 -0
  56. package/erc4337/UserOperation/package.json +6 -0
  57. package/erc4337/UserOperation.ts +617 -0
  58. package/erc4337/UserOperationGas/package.json +6 -0
  59. package/erc4337/UserOperationGas.ts +109 -0
  60. package/erc4337/UserOperationReceipt/package.json +6 -0
  61. package/erc4337/UserOperationReceipt.ts +139 -0
  62. package/erc4337/index.ts +38 -0
  63. package/erc4337/package.json +6 -0
  64. package/index.docs.ts +1 -0
  65. package/package.json +31 -1
  66. package/version.ts +1 -1
@@ -0,0 +1,617 @@
1
+ import * as AbiParameters from '../core/AbiParameters.js'
2
+ import type * as Address from '../core/Address.js'
3
+ import type * as Errors from '../core/Errors.js'
4
+ import * as Hash from '../core/Hash.js'
5
+ import * as Hex from '../core/Hex.js'
6
+ import * as Signature from '../core/Signature.js'
7
+ import type { Assign, Compute, OneOf } from '../core/internal/types.js'
8
+ import type * as EntryPoint from './EntryPoint.js'
9
+
10
+ /** User Operation. */
11
+ export type UserOperation<
12
+ entryPointVersion extends EntryPoint.Version = EntryPoint.Version,
13
+ signed extends boolean = boolean,
14
+ bigintType = bigint,
15
+ > = OneOf<
16
+ | (entryPointVersion extends '0.6' ? V06<signed, bigintType> : never)
17
+ | (entryPointVersion extends '0.7' ? V07<signed, bigintType> : never)
18
+ >
19
+
20
+ /**
21
+ * Packed User Operation.
22
+ *
23
+ * @see https://eips.ethereum.org/EIPS/eip-4337#entrypoint-definition
24
+ */
25
+ export type Packed = {
26
+ /** Concatenation of `verificationGasLimit` (16 bytes) and `callGasLimit` (16 bytes) */
27
+ accountGasLimits: Hex.Hex
28
+ /** The data to pass to the `sender` during the main execution call. */
29
+ callData: Hex.Hex
30
+ /** Concatenation of `factory` and `factoryData`. */
31
+ initCode: Hex.Hex
32
+ /** Concatenation of `maxPriorityFee` (16 bytes) and `maxFeePerGas` (16 bytes) */
33
+ gasFees: Hex.Hex
34
+ /** Anti-replay parameter. */
35
+ nonce: bigint
36
+ /** Concatenation of paymaster fields (or empty). */
37
+ paymasterAndData: Hex.Hex
38
+ /** Extra gas to pay the Bundler. */
39
+ preVerificationGas: bigint
40
+ /** The account making the operation. */
41
+ sender: Address.Address
42
+ /** Data passed into the account to verify authorization. */
43
+ signature: Hex.Hex
44
+ }
45
+
46
+ /** RPC User Operation type. */
47
+ export type Rpc<
48
+ entryPointVersion extends EntryPoint.Version = EntryPoint.Version,
49
+ signed extends boolean = true,
50
+ > = OneOf<
51
+ | (entryPointVersion extends '0.6' ? V06<signed, Hex.Hex> : never)
52
+ | (entryPointVersion extends '0.7' ? V07<signed, Hex.Hex> : never)
53
+ >
54
+
55
+ /** Transaction Info. */
56
+ export type TransactionInfo<
57
+ entryPointVersion extends EntryPoint.Version = EntryPoint.Version,
58
+ bigintType = bigint,
59
+ > = {
60
+ blockHash: Hex.Hex
61
+ blockNumber: bigintType
62
+ entryPoint: Address.Address
63
+ transactionHash: Hex.Hex
64
+ userOperation: UserOperation<entryPointVersion, true, bigintType>
65
+ }
66
+
67
+ /** RPC Transaction Info. */
68
+ export type RpcTransactionInfo<
69
+ entryPointVersion extends EntryPoint.Version = EntryPoint.Version,
70
+ > = TransactionInfo<entryPointVersion, Hex.Hex>
71
+
72
+ /** Type for User Operation on EntryPoint 0.6 */
73
+ export type V06<signed extends boolean = boolean, bigintType = bigint> = {
74
+ /** The data to pass to the `sender` during the main execution call. */
75
+ callData: Hex.Hex
76
+ /** The amount of gas to allocate the main execution call */
77
+ callGasLimit: bigintType
78
+ /** Account init code. Only for new accounts. */
79
+ initCode?: Hex.Hex | undefined
80
+ /** Maximum fee per gas. */
81
+ maxFeePerGas: bigintType
82
+ /** Maximum priority fee per gas. */
83
+ maxPriorityFeePerGas: bigintType
84
+ /** Anti-replay parameter. */
85
+ nonce: bigintType
86
+ /** Paymaster address with calldata. */
87
+ paymasterAndData?: Hex.Hex | undefined
88
+ /** Extra gas to pay the Bundler. */
89
+ preVerificationGas: bigintType
90
+ /** The account making the operation. */
91
+ sender: Address.Address
92
+ /** Data passed into the account to verify authorization. */
93
+ signature?: Hex.Hex | undefined
94
+ /** The amount of gas to allocate for the verification step. */
95
+ verificationGasLimit: bigintType
96
+ } & (signed extends true ? { signature: Hex.Hex } : {})
97
+
98
+ /** RPC User Operation on EntryPoint 0.6 */
99
+ export type RpcV06<signed extends boolean = true> = V06<signed, Hex.Hex>
100
+
101
+ /** Type for User Operation on EntryPoint 0.7 */
102
+ export type V07<signed extends boolean = boolean, bigintType = bigint> = {
103
+ /** The data to pass to the `sender` during the main execution call. */
104
+ callData: Hex.Hex
105
+ /** The amount of gas to allocate the main execution call */
106
+ callGasLimit: bigintType
107
+ /** Account factory. Only for new accounts. */
108
+ factory?: Address.Address | undefined
109
+ /** Data for account factory. */
110
+ factoryData?: Hex.Hex | undefined
111
+ /** Maximum fee per gas. */
112
+ maxFeePerGas: bigintType
113
+ /** Maximum priority fee per gas. */
114
+ maxPriorityFeePerGas: bigintType
115
+ /** Anti-replay parameter. */
116
+ nonce: bigintType
117
+ /** Address of paymaster contract. */
118
+ paymaster?: Address.Address | undefined
119
+ /** Data for paymaster. */
120
+ paymasterData?: Hex.Hex | undefined
121
+ /** The amount of gas to allocate for the paymaster post-operation code. */
122
+ paymasterPostOpGasLimit?: bigintType | undefined
123
+ /** The amount of gas to allocate for the paymaster validation code. */
124
+ paymasterVerificationGasLimit?: bigintType | undefined
125
+ /** Extra gas to pay the Bundler. */
126
+ preVerificationGas: bigintType
127
+ /** The account making the operation. */
128
+ sender: Address.Address
129
+ /** Data passed into the account to verify authorization. */
130
+ signature?: Hex.Hex | undefined
131
+ /** The amount of gas to allocate for the verification step. */
132
+ verificationGasLimit: bigintType
133
+ } & (signed extends true ? { signature: Hex.Hex } : {})
134
+
135
+ /** RPC User Operation on EntryPoint 0.7 */
136
+ export type RpcV07<signed extends boolean = true> = V07<signed, Hex.Hex>
137
+
138
+ /**
139
+ * Instantiates a {@link ox#UserOperation.UserOperation} from a provided input.
140
+ *
141
+ * @example
142
+ * ```ts twoslash
143
+ * import { Value } from 'ox'
144
+ * import { UserOperation } from 'ox/erc4337'
145
+ *
146
+ * const userOperation = UserOperation.from({
147
+ * callData: '0xdeadbeef',
148
+ * callGasLimit: 300_000n,
149
+ * maxFeePerGas: Value.fromGwei('20'),
150
+ * maxPriorityFeePerGas: Value.fromGwei('2'),
151
+ * nonce: 69n,
152
+ * preVerificationGas: 100_000n,
153
+ * sender: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
154
+ * verificationGasLimit: 100_000n,
155
+ * })
156
+ * ```
157
+ *
158
+ * @example
159
+ * ### Attaching Signatures
160
+ *
161
+ * ```ts twoslash
162
+ * import { Secp256k1, Value } from 'ox'
163
+ * import { UserOperation } from 'ox/erc4337'
164
+ *
165
+ * const userOperation = UserOperation.from({
166
+ * callData: '0xdeadbeef',
167
+ * callGasLimit: 300_000n,
168
+ * maxFeePerGas: Value.fromGwei('20'),
169
+ * maxPriorityFeePerGas: Value.fromGwei('2'),
170
+ * nonce: 69n,
171
+ * preVerificationGas: 100_000n,
172
+ * sender: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
173
+ * verificationGasLimit: 100_000n,
174
+ * })
175
+ *
176
+ * const payload = UserOperation.getSignPayload(userOperation, {
177
+ * chainId: 1,
178
+ * entryPointAddress: '0x1234567890123456789012345678901234567890',
179
+ * entryPointVersion: '0.7',
180
+ * })
181
+ *
182
+ * const signature = Secp256k1.sign({ payload, privateKey: '0x...' })
183
+ *
184
+ * const userOperation_signed = UserOperation.from(userOperation, { signature }) // [!code focus]
185
+ * ```
186
+ *
187
+ * @param userOperation - The user operation to instantiate.
188
+ * @returns User Operation.
189
+ */
190
+ export function from<
191
+ const userOperation extends UserOperation,
192
+ const signature extends Hex.Hex | undefined = undefined,
193
+ >(
194
+ userOperation: userOperation | UserOperation,
195
+ options: from.Options<signature> = {},
196
+ ): from.ReturnType<userOperation, signature> {
197
+ const signature = (() => {
198
+ if (!options.signature) return undefined
199
+ if (typeof options.signature === 'string') return options.signature
200
+ return Signature.toHex(options.signature)
201
+ })()
202
+ return { ...userOperation, signature } as never
203
+ }
204
+
205
+ export declare namespace from {
206
+ export type Options<
207
+ signature extends Signature.Signature | Hex.Hex | undefined = undefined,
208
+ > = {
209
+ signature?: signature | Signature.Signature | Hex.Hex | undefined
210
+ }
211
+
212
+ export type ReturnType<
213
+ userOperation extends UserOperation = UserOperation,
214
+ signature extends Signature.Signature | Hex.Hex | undefined = undefined,
215
+ > = Compute<
216
+ Assign<
217
+ userOperation,
218
+ signature extends Signature.Signature | Hex.Hex
219
+ ? Readonly<{ signature: Hex.Hex }>
220
+ : {}
221
+ >
222
+ >
223
+
224
+ export type ErrorType = Errors.GlobalErrorType
225
+ }
226
+
227
+ /**
228
+ * Converts an {@link ox#UserOperation.Rpc} to an {@link ox#UserOperation.UserOperation}.
229
+ *
230
+ * @example
231
+ * ```ts twoslash
232
+ * import { UserOperation } from 'ox/erc4337'
233
+ *
234
+ * const userOperation = UserOperation.fromRpc({
235
+ * callData: '0xdeadbeef',
236
+ * callGasLimit: '0x69420',
237
+ * maxFeePerGas: '0x2ca6ae494',
238
+ * maxPriorityFeePerGas: '0x41cc3c0',
239
+ * nonce: '0x357',
240
+ * preVerificationGas: '0x69420',
241
+ * signature: '0x',
242
+ * sender: '0x1234567890123456789012345678901234567890',
243
+ * verificationGasLimit: '0x69420',
244
+ * })
245
+ * ```
246
+ *
247
+ * @param rpc - The RPC user operation to convert.
248
+ * @returns An instantiated {@link ox#UserOperation.UserOperation}.
249
+ */
250
+ export function fromRpc(rpc: Rpc): UserOperation {
251
+ return {
252
+ ...rpc,
253
+ callGasLimit: BigInt(rpc.callGasLimit),
254
+ maxFeePerGas: BigInt(rpc.maxFeePerGas),
255
+ maxPriorityFeePerGas: BigInt(rpc.maxPriorityFeePerGas),
256
+ nonce: BigInt(rpc.nonce),
257
+ preVerificationGas: BigInt(rpc.preVerificationGas),
258
+ verificationGasLimit: BigInt(rpc.verificationGasLimit),
259
+ ...(rpc.paymasterPostOpGasLimit && {
260
+ paymasterPostOpGasLimit: BigInt(rpc.paymasterPostOpGasLimit),
261
+ }),
262
+ ...(rpc.paymasterVerificationGasLimit && {
263
+ paymasterVerificationGasLimit: BigInt(rpc.paymasterVerificationGasLimit),
264
+ }),
265
+ } as UserOperation
266
+ }
267
+
268
+ export declare namespace fromRpc {
269
+ type ErrorType = Errors.GlobalErrorType
270
+ }
271
+
272
+ /**
273
+ * Obtains the signing payload for a {@link ox#UserOperation.UserOperation}.
274
+ *
275
+ * @example
276
+ * ```ts twoslash
277
+ * import { Secp256k1, Value } from 'ox'
278
+ * import { UserOperation } from 'ox/erc4337'
279
+ *
280
+ * const userOperation = UserOperation.from({
281
+ * callData: '0xdeadbeef',
282
+ * callGasLimit: 300_000n,
283
+ * maxFeePerGas: Value.fromGwei('20'),
284
+ * maxPriorityFeePerGas: Value.fromGwei('2'),
285
+ * nonce: 69n,
286
+ * preVerificationGas: 100_000n,
287
+ * sender: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
288
+ * verificationGasLimit: 100_000n,
289
+ * })
290
+ *
291
+ * const payload = UserOperation.getSignPayload(userOperation, { // [!code focus]
292
+ * chainId: 1, // [!code focus]
293
+ * entryPointAddress: '0x1234567890123456789012345678901234567890', // [!code focus]
294
+ * entryPointVersion: '0.6', // [!code focus]
295
+ * }) // [!code focus]
296
+ *
297
+ * const signature = Secp256k1.sign({ payload, privateKey: '0x...' })
298
+ * ```
299
+ *
300
+ * @param userOperation - The user operation to get the sign payload for.
301
+ * @returns The signing payload for the user operation.
302
+ */
303
+ export function getSignPayload<
304
+ entrypointVersion extends EntryPoint.Version = EntryPoint.Version,
305
+ >(
306
+ userOperation: UserOperation<entrypointVersion>,
307
+ options: getSignPayload.Options<entrypointVersion>,
308
+ ): Hex.Hex {
309
+ return hash(userOperation, options)
310
+ }
311
+
312
+ export declare namespace getSignPayload {
313
+ type Options<
314
+ entrypointVersion extends EntryPoint.Version = EntryPoint.Version,
315
+ > = hash.Options<entrypointVersion>
316
+
317
+ type ErrorType = hash.ErrorType | Errors.GlobalErrorType
318
+ }
319
+
320
+ /**
321
+ * Hashes a {@link ox#UserOperation.UserOperation}. This is the "user operation hash".
322
+ *
323
+ * @example
324
+ * ```ts twoslash
325
+ * import { Value } from 'ox'
326
+ * import { UserOperation } from 'ox/erc4337'
327
+ *
328
+ * const userOperation = UserOperation.hash({
329
+ * callData: '0xdeadbeef',
330
+ * callGasLimit: 300_000n,
331
+ * maxFeePerGas: Value.fromGwei('20'),
332
+ * maxPriorityFeePerGas: Value.fromGwei('2'),
333
+ * nonce: 69n,
334
+ * preVerificationGas: 100_000n,
335
+ * sender: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
336
+ * verificationGasLimit: 100_000n,
337
+ * }, {
338
+ * chainId: 1,
339
+ * entryPointAddress: '0x1234567890123456789012345678901234567890',
340
+ * entryPointVersion: '0.6',
341
+ * })
342
+ * ```
343
+ *
344
+ * @param userOperation - The user operation to hash.
345
+ * @returns The hash of the user operation.
346
+ */
347
+ export function hash<
348
+ entrypointVersion extends EntryPoint.Version = EntryPoint.Version,
349
+ >(
350
+ userOperation: UserOperation<entrypointVersion>,
351
+ options: hash.Options<entrypointVersion>,
352
+ ): Hex.Hex {
353
+ const { chainId, entryPointAddress, entryPointVersion } = options
354
+ const {
355
+ callData,
356
+ callGasLimit,
357
+ initCode,
358
+ factory,
359
+ factoryData,
360
+ maxFeePerGas,
361
+ maxPriorityFeePerGas,
362
+ nonce,
363
+ paymaster,
364
+ paymasterAndData,
365
+ paymasterData,
366
+ paymasterPostOpGasLimit,
367
+ paymasterVerificationGasLimit,
368
+ preVerificationGas,
369
+ sender,
370
+ verificationGasLimit,
371
+ } = userOperation as UserOperation
372
+
373
+ const packedUserOp = (() => {
374
+ if (entryPointVersion === '0.6') {
375
+ return AbiParameters.encode(
376
+ [
377
+ { type: 'address' },
378
+ { type: 'uint256' },
379
+ { type: 'bytes32' },
380
+ { type: 'bytes32' },
381
+ { type: 'uint256' },
382
+ { type: 'uint256' },
383
+ { type: 'uint256' },
384
+ { type: 'uint256' },
385
+ { type: 'uint256' },
386
+ { type: 'bytes32' },
387
+ ],
388
+ [
389
+ sender,
390
+ nonce,
391
+ Hash.keccak256(initCode ?? '0x'),
392
+ Hash.keccak256(callData),
393
+ callGasLimit,
394
+ verificationGasLimit,
395
+ preVerificationGas,
396
+ maxFeePerGas,
397
+ maxPriorityFeePerGas,
398
+ Hash.keccak256(paymasterAndData ?? '0x'),
399
+ ],
400
+ )
401
+ }
402
+
403
+ if (entryPointVersion === '0.7') {
404
+ const accountGasLimits = Hex.concat(
405
+ Hex.padLeft(Hex.fromNumber(verificationGasLimit), 16),
406
+ Hex.padLeft(Hex.fromNumber(callGasLimit), 16),
407
+ )
408
+ const gasFees = Hex.concat(
409
+ Hex.padLeft(Hex.fromNumber(maxPriorityFeePerGas), 16),
410
+ Hex.padLeft(Hex.fromNumber(maxFeePerGas), 16),
411
+ )
412
+ const initCode_hashed = Hash.keccak256(
413
+ factory && factoryData ? Hex.concat(factory, factoryData) : '0x',
414
+ )
415
+ const paymasterAndData_hashed = Hash.keccak256(
416
+ paymaster
417
+ ? Hex.concat(
418
+ paymaster,
419
+ Hex.padLeft(
420
+ Hex.fromNumber(paymasterVerificationGasLimit || 0),
421
+ 16,
422
+ ),
423
+ Hex.padLeft(Hex.fromNumber(paymasterPostOpGasLimit || 0), 16),
424
+ paymasterData || '0x',
425
+ )
426
+ : '0x',
427
+ )
428
+
429
+ return AbiParameters.encode(
430
+ [
431
+ { type: 'address' },
432
+ { type: 'uint256' },
433
+ { type: 'bytes32' },
434
+ { type: 'bytes32' },
435
+ { type: 'bytes32' },
436
+ { type: 'uint256' },
437
+ { type: 'bytes32' },
438
+ { type: 'bytes32' },
439
+ ],
440
+ [
441
+ sender,
442
+ nonce,
443
+ initCode_hashed,
444
+ Hash.keccak256(callData),
445
+ accountGasLimits,
446
+ preVerificationGas,
447
+ gasFees,
448
+ paymasterAndData_hashed,
449
+ ],
450
+ )
451
+ }
452
+
453
+ throw new Error(`entryPointVersion "${entryPointVersion}" not supported.`)
454
+ })()
455
+
456
+ return Hash.keccak256(
457
+ AbiParameters.encode(
458
+ [{ type: 'bytes32' }, { type: 'address' }, { type: 'uint256' }],
459
+ [Hash.keccak256(packedUserOp), entryPointAddress, BigInt(chainId)],
460
+ ),
461
+ )
462
+ }
463
+
464
+ export declare namespace hash {
465
+ type Options<
466
+ entrypointVersion extends EntryPoint.Version = EntryPoint.Version,
467
+ > = {
468
+ chainId: number
469
+ entryPointAddress: Address.Address
470
+ entryPointVersion: entrypointVersion | EntryPoint.Version
471
+ }
472
+
473
+ type ErrorType =
474
+ | AbiParameters.encode.ErrorType
475
+ | Hash.keccak256.ErrorType
476
+ | Hex.concat.ErrorType
477
+ | Hex.fromNumber.ErrorType
478
+ | Hex.padLeft.ErrorType
479
+ | Errors.GlobalErrorType
480
+ }
481
+
482
+ /**
483
+ * Transforms a User Operation into "packed" format.
484
+ *
485
+ * @example
486
+ * ```ts twoslash
487
+ * import { Value } from 'ox'
488
+ * import { UserOperation } from 'ox/erc4337'
489
+ *
490
+ * const packed = UserOperation.toPacked({
491
+ * callData: '0xdeadbeef',
492
+ * callGasLimit: 300_000n,
493
+ * maxFeePerGas: Value.fromGwei('20'),
494
+ * maxPriorityFeePerGas: Value.fromGwei('2'),
495
+ * nonce: 69n,
496
+ * preVerificationGas: 100_000n,
497
+ * sender: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
498
+ * signature: '0x...',
499
+ * verificationGasLimit: 100_000n,
500
+ * })
501
+ * ```
502
+ *
503
+ * @param userOperation - The user operation to transform.
504
+ * @returns The packed user operation.
505
+ */
506
+ export function toPacked(userOperation: UserOperation<'0.7', true>): Packed {
507
+ const {
508
+ callGasLimit,
509
+ callData,
510
+ factory,
511
+ factoryData,
512
+ maxPriorityFeePerGas,
513
+ maxFeePerGas,
514
+ nonce,
515
+ paymaster,
516
+ paymasterData,
517
+ paymasterPostOpGasLimit,
518
+ paymasterVerificationGasLimit,
519
+ sender,
520
+ signature,
521
+ verificationGasLimit,
522
+ } = userOperation
523
+
524
+ const accountGasLimits = Hex.concat(
525
+ Hex.padLeft(Hex.fromNumber(verificationGasLimit || 0n), 16),
526
+ Hex.padLeft(Hex.fromNumber(callGasLimit || 0n), 16),
527
+ )
528
+ const initCode =
529
+ factory && factoryData ? Hex.concat(factory, factoryData) : '0x'
530
+ const gasFees = Hex.concat(
531
+ Hex.padLeft(Hex.fromNumber(maxPriorityFeePerGas || 0n), 16),
532
+ Hex.padLeft(Hex.fromNumber(maxFeePerGas || 0n), 16),
533
+ )
534
+ const paymasterAndData = paymaster
535
+ ? Hex.concat(
536
+ paymaster,
537
+ Hex.padLeft(Hex.fromNumber(paymasterVerificationGasLimit || 0n), 16),
538
+ Hex.padLeft(Hex.fromNumber(paymasterPostOpGasLimit || 0n), 16),
539
+ paymasterData || '0x',
540
+ )
541
+ : '0x'
542
+ const preVerificationGas = userOperation.preVerificationGas ?? 0n
543
+
544
+ return {
545
+ accountGasLimits,
546
+ callData,
547
+ initCode,
548
+ gasFees,
549
+ nonce,
550
+ paymasterAndData,
551
+ preVerificationGas,
552
+ sender,
553
+ signature,
554
+ }
555
+ }
556
+
557
+ export declare namespace toPacked {
558
+ export type ErrorType = Errors.GlobalErrorType
559
+ }
560
+
561
+ /**
562
+ * Converts a {@link ox#UserOperation.UserOperation} to a {@link ox#UserOperation.Rpc}.
563
+ *
564
+ * @example
565
+ * ```ts twoslash
566
+ * import { Value } from 'ox'
567
+ * import { UserOperation } from 'ox/erc4337'
568
+ *
569
+ * const userOperation = UserOperation.toRpc({
570
+ * callData: '0xdeadbeef',
571
+ * callGasLimit: 300_000n,
572
+ * maxFeePerGas: Value.fromGwei('20'),
573
+ * maxPriorityFeePerGas: Value.fromGwei('2'),
574
+ * nonce: 69n,
575
+ * preVerificationGas: 100_000n,
576
+ * sender: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
577
+ * verificationGasLimit: 100_000n,
578
+ * })
579
+ * ```
580
+ *
581
+ * @param userOperation - The user operation to convert.
582
+ * @returns An RPC-formatted user operation.
583
+ */
584
+ export function toRpc(userOperation: UserOperation): Rpc {
585
+ const rpc = {} as Rpc
586
+
587
+ rpc.callData = userOperation.callData
588
+ rpc.callGasLimit = Hex.fromNumber(userOperation.callGasLimit)
589
+ rpc.maxFeePerGas = Hex.fromNumber(userOperation.maxFeePerGas)
590
+ rpc.maxPriorityFeePerGas = Hex.fromNumber(userOperation.maxPriorityFeePerGas)
591
+ rpc.nonce = Hex.fromNumber(userOperation.nonce)
592
+ rpc.preVerificationGas = Hex.fromNumber(userOperation.preVerificationGas)
593
+ rpc.sender = userOperation.sender
594
+ rpc.verificationGasLimit = Hex.fromNumber(userOperation.verificationGasLimit)
595
+
596
+ if (userOperation.factory) rpc.factory = userOperation.factory
597
+ if (userOperation.factoryData) rpc.factoryData = userOperation.factoryData
598
+ if (userOperation.initCode) rpc.initCode = userOperation.initCode
599
+ if (userOperation.paymaster) rpc.paymaster = userOperation.paymaster
600
+ if (userOperation.paymasterData)
601
+ rpc.paymasterData = userOperation.paymasterData
602
+ if (typeof userOperation.paymasterPostOpGasLimit === 'bigint')
603
+ rpc.paymasterPostOpGasLimit = Hex.fromNumber(
604
+ userOperation.paymasterPostOpGasLimit,
605
+ )
606
+ if (typeof userOperation.paymasterVerificationGasLimit === 'bigint')
607
+ rpc.paymasterVerificationGasLimit = Hex.fromNumber(
608
+ userOperation.paymasterVerificationGasLimit,
609
+ )
610
+ if (userOperation.signature) rpc.signature = userOperation.signature
611
+
612
+ return rpc
613
+ }
614
+
615
+ export declare namespace toRpc {
616
+ export type ErrorType = Hex.fromNumber.ErrorType | Errors.GlobalErrorType
617
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "module",
3
+ "types": "../../_types/erc4337/UserOperationGas.d.ts",
4
+ "main": "../../_cjs/erc4337/UserOperationGas.js",
5
+ "module": "../../_esm/erc4337/UserOperationGas.js"
6
+ }