ox 0.8.3 → 0.8.5

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.
@@ -1,9 +1,11 @@
1
1
  import * as AbiParameters from '../core/AbiParameters.js'
2
2
  import type * as Address from '../core/Address.js'
3
+ import type * as Authorization from '../core/Authorization.js'
3
4
  import type * as Errors from '../core/Errors.js'
4
5
  import * as Hash from '../core/Hash.js'
5
6
  import * as Hex from '../core/Hex.js'
6
7
  import * as Signature from '../core/Signature.js'
8
+ import * as TypedData from '../core/TypedData.js'
7
9
  import type { Assign, Compute, OneOf } from '../core/internal/types.js'
8
10
  import type * as EntryPoint from './EntryPoint.js'
9
11
 
@@ -12,9 +14,13 @@ export type UserOperation<
12
14
  entryPointVersion extends EntryPoint.Version = EntryPoint.Version,
13
15
  signed extends boolean = boolean,
14
16
  bigintType = bigint,
17
+ numberType = number,
15
18
  > = OneOf<
16
19
  | (entryPointVersion extends '0.6' ? V06<signed, bigintType> : never)
17
20
  | (entryPointVersion extends '0.7' ? V07<signed, bigintType> : never)
21
+ | (entryPointVersion extends '0.8'
22
+ ? V08<signed, bigintType, numberType>
23
+ : never)
18
24
  >
19
25
 
20
26
  /**
@@ -50,6 +56,7 @@ export type Rpc<
50
56
  > = OneOf<
51
57
  | (entryPointVersion extends '0.6' ? V06<signed, Hex.Hex> : never)
52
58
  | (entryPointVersion extends '0.7' ? V07<signed, Hex.Hex> : never)
59
+ | (entryPointVersion extends '0.8' ? V08<signed, Hex.Hex, Hex.Hex> : never)
53
60
  >
54
61
 
55
62
  /** Transaction Info. */
@@ -135,6 +142,53 @@ export type V07<signed extends boolean = boolean, bigintType = bigint> = {
135
142
  /** RPC User Operation on EntryPoint 0.7 */
136
143
  export type RpcV07<signed extends boolean = true> = V07<signed, Hex.Hex>
137
144
 
145
+ /** Type for User Operation on EntryPoint 0.8 */
146
+ export type V08<
147
+ signed extends boolean = boolean,
148
+ bigintType = bigint,
149
+ numberType = number,
150
+ > = {
151
+ /** Authorization data. */
152
+ authorization?: Authorization.Signed<bigintType, numberType> | undefined
153
+ /** The data to pass to the `sender` during the main execution call. */
154
+ callData: Hex.Hex
155
+ /** The amount of gas to allocate the main execution call */
156
+ callGasLimit: bigintType
157
+ /** Account factory. Only for new accounts. */
158
+ factory?: Address.Address | undefined
159
+ /** Data for account factory. */
160
+ factoryData?: Hex.Hex | undefined
161
+ /** Maximum fee per gas. */
162
+ maxFeePerGas: bigintType
163
+ /** Maximum priority fee per gas. */
164
+ maxPriorityFeePerGas: bigintType
165
+ /** Anti-replay parameter. */
166
+ nonce: bigintType
167
+ /** Address of paymaster contract. */
168
+ paymaster?: Address.Address | undefined
169
+ /** Data for paymaster. */
170
+ paymasterData?: Hex.Hex | undefined
171
+ /** The amount of gas to allocate for the paymaster post-operation code. */
172
+ paymasterPostOpGasLimit?: bigintType | undefined
173
+ /** The amount of gas to allocate for the paymaster validation code. */
174
+ paymasterVerificationGasLimit?: bigintType | undefined
175
+ /** Extra gas to pay the Bundler. */
176
+ preVerificationGas: bigintType
177
+ /** The account making the operation. */
178
+ sender: Address.Address
179
+ /** Data passed into the account to verify authorization. */
180
+ signature?: Hex.Hex | undefined
181
+ /** The amount of gas to allocate for the verification step. */
182
+ verificationGasLimit: bigintType
183
+ } & (signed extends true ? { signature: Hex.Hex } : {})
184
+
185
+ /** RPC User Operation on EntryPoint 0.8 */
186
+ export type RpcV08<signed extends boolean = true> = V08<
187
+ signed,
188
+ Hex.Hex,
189
+ Hex.Hex
190
+ >
191
+
138
192
  /**
139
193
  * Instantiates a {@link ox#UserOperation.UserOperation} from a provided input.
140
194
  *
@@ -370,6 +424,14 @@ export function hash<
370
424
  verificationGasLimit,
371
425
  } = userOperation as UserOperation
372
426
 
427
+ if (entryPointVersion === '0.8') {
428
+ const typedData = toTypedData(userOperation as UserOperation<'0.8', true>, {
429
+ chainId,
430
+ entryPointAddress,
431
+ })
432
+ return TypedData.getSignPayload(typedData)
433
+ }
434
+
373
435
  const packedUserOp = (() => {
374
436
  if (entryPointVersion === '0.6') {
375
437
  return AbiParameters.encode(
@@ -479,6 +541,52 @@ export declare namespace hash {
479
541
  | Errors.GlobalErrorType
480
542
  }
481
543
 
544
+ /**
545
+ * Converts a {@link ox#UserOperation.UserOperation} to `initCode`.
546
+ *
547
+ * @example
548
+ * ```ts twoslash
549
+ * import { Value } from 'ox'
550
+ * import { UserOperation } from 'ox/erc4337'
551
+ *
552
+ * const initCode = UserOperation.toInitCode({
553
+ * authorization: {
554
+ * address: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
555
+ * chainId: 1,
556
+ * nonce: 69n,
557
+ * yParity: 0,
558
+ * r: 1n,
559
+ * s: 2n,
560
+ * },
561
+ * callData: '0xdeadbeef',
562
+ * callGasLimit: 300_000n,
563
+ * factory: '0x7702',
564
+ * factoryData: '0xdeadbeef',
565
+ * maxFeePerGas: Value.fromGwei('20'),
566
+ * maxPriorityFeePerGas: Value.fromGwei('2'),
567
+ * nonce: 69n,
568
+ * preVerificationGas: 100_000n,
569
+ * sender: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
570
+ * })
571
+ * ```
572
+ *
573
+ * @param userOperation - The user operation to convert.
574
+ * @returns The init code.
575
+ */
576
+ export function toInitCode(userOperation: Partial<UserOperation>): Hex.Hex {
577
+ const { authorization, factory, factoryData } = userOperation
578
+ if (
579
+ factory === '0x7702' ||
580
+ factory === '0x7702000000000000000000000000000000000000'
581
+ ) {
582
+ if (!authorization) return '0x7702000000000000000000000000000000000000'
583
+ const delegation = authorization.address
584
+ return Hex.concat(delegation, factoryData ?? '0x')
585
+ }
586
+ if (!factory) return '0x'
587
+ return Hex.concat(factory, factoryData ?? '0x')
588
+ }
589
+
482
590
  /**
483
591
  * Transforms a User Operation into "packed" format.
484
592
  *
@@ -503,12 +611,12 @@ export declare namespace hash {
503
611
  * @param userOperation - The user operation to transform.
504
612
  * @returns The packed user operation.
505
613
  */
506
- export function toPacked(userOperation: UserOperation<'0.7', true>): Packed {
614
+ export function toPacked(
615
+ userOperation: UserOperation<'0.7' | '0.8', true>,
616
+ ): Packed {
507
617
  const {
508
618
  callGasLimit,
509
619
  callData,
510
- factory,
511
- factoryData,
512
620
  maxPriorityFeePerGas,
513
621
  maxFeePerGas,
514
622
  nonce,
@@ -525,8 +633,7 @@ export function toPacked(userOperation: UserOperation<'0.7', true>): Packed {
525
633
  Hex.padLeft(Hex.fromNumber(verificationGasLimit || 0n), 16),
526
634
  Hex.padLeft(Hex.fromNumber(callGasLimit || 0n), 16),
527
635
  )
528
- const initCode =
529
- factory && factoryData ? Hex.concat(factory, factoryData) : '0x'
636
+ const initCode = toInitCode(userOperation)
530
637
  const gasFees = Hex.concat(
531
638
  Hex.padLeft(Hex.fromNumber(maxPriorityFeePerGas || 0n), 16),
532
639
  Hex.padLeft(Hex.fromNumber(maxFeePerGas || 0n), 16),
@@ -615,3 +722,81 @@ export function toRpc(userOperation: UserOperation): Rpc {
615
722
  export declare namespace toRpc {
616
723
  export type ErrorType = Hex.fromNumber.ErrorType | Errors.GlobalErrorType
617
724
  }
725
+
726
+ /**
727
+ * Converts a signed {@link ox#UserOperation.UserOperation} to a {@link ox#TypedData.Definition}.
728
+ *
729
+ * @example
730
+ * ```ts twoslash
731
+ * import { Value } from 'ox'
732
+ * import { UserOperation } from 'ox/erc4337'
733
+ *
734
+ * const typedData = UserOperation.toTypedData({
735
+ * authorization: {
736
+ * chainId: 1,
737
+ * address: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
738
+ * nonce: 69n,
739
+ * yParity: 0,
740
+ * r: 1n,
741
+ * s: 2n,
742
+ * },
743
+ * callData: '0xdeadbeef',
744
+ * callGasLimit: 300_000n,
745
+ * maxFeePerGas: Value.fromGwei('20'),
746
+ * maxPriorityFeePerGas: Value.fromGwei('2'),
747
+ * nonce: 69n,
748
+ * preVerificationGas: 100_000n,
749
+ * sender: '0x9f1fdab6458c5fc642fa0f4c5af7473c46837357',
750
+ * signature: '0x...',
751
+ * verificationGasLimit: 100_000n,
752
+ * }, {
753
+ * chainId: 1,
754
+ * entryPointAddress: '0x1234567890123456789012345678901234567890',
755
+ * })
756
+ * ```
757
+ *
758
+ * @param userOperation - The user operation to convert.
759
+ * @returns A Typed Data definition.
760
+ */
761
+ export function toTypedData(
762
+ userOperation: UserOperation<'0.8', true>,
763
+ options: toTypedData.Options,
764
+ ): TypedData.Definition<typeof toTypedData.types, 'PackedUserOperation'> {
765
+ const { chainId, entryPointAddress } = options
766
+
767
+ const packedUserOp = toPacked(userOperation)
768
+
769
+ return {
770
+ domain: {
771
+ name: 'ERC4337',
772
+ version: '1',
773
+ chainId,
774
+ verifyingContract: entryPointAddress,
775
+ },
776
+ message: packedUserOp,
777
+ primaryType: 'PackedUserOperation',
778
+ types: toTypedData.types,
779
+ }
780
+ }
781
+
782
+ export namespace toTypedData {
783
+ export type Options = {
784
+ chainId: number
785
+ entryPointAddress: Address.Address
786
+ }
787
+
788
+ export type ErrorType = Errors.GlobalErrorType
789
+
790
+ export const types = {
791
+ PackedUserOperation: [
792
+ { type: 'address', name: 'sender' },
793
+ { type: 'uint256', name: 'nonce' },
794
+ { type: 'bytes', name: 'initCode' },
795
+ { type: 'bytes', name: 'callData' },
796
+ { type: 'bytes32', name: 'accountGasLimits' },
797
+ { type: 'uint256', name: 'preVerificationGas' },
798
+ { type: 'bytes32', name: 'gasFees' },
799
+ { type: 'bytes', name: 'paymasterAndData' },
800
+ ],
801
+ } as const
802
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ox",
3
3
  "description": "Ethereum Standard Library",
4
- "version": "0.8.3",
4
+ "version": "0.8.5",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",
7
7
  "types": "./_types/index.d.ts",
package/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** @internal */
2
- export const version = '0.8.3'
2
+ export const version = '0.8.5'