abstractionkit 0.3.3 → 0.3.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.
@@ -331,6 +331,61 @@ var abstractionkit = (function(exports, ethers) {
331
331
  return userOperationHash;
332
332
  }
333
333
  /**
334
+ * @internal
335
+ * Reconstruct the packed `initCode` field for an EntryPoint v0.8/v0.9
336
+ * UserOperation. When `eip7702Auth.address` is set, the EIP-7702 delegatee
337
+ * address replaces the factory address in initCode (only `factoryData` is
338
+ * concatenated). Otherwise, behaves like v0.7 (`factory + factoryData`).
339
+ *
340
+ * Shared by {@link createPackedUserOperationV8} /
341
+ * {@link createPackedUserOperationV9} and Simple7702Account's typed-data
342
+ * builder. Not part of the public API; only `export`ed for cross-module
343
+ * use within the package and not re-exported from `src/abstractionkit.ts`.
344
+ *
345
+ * @param useroperation - V8 or V9 UserOperation to read fields from
346
+ * @returns Hex-encoded initCode
347
+ */
348
+ function buildPackedInitCodeV8V9(useroperation) {
349
+ if (useroperation.factory == null) return "0x";
350
+ const eip7702Auth = useroperation.eip7702Auth;
351
+ return (eip7702Auth != null && eip7702Auth.address != null ? eip7702Auth.address : useroperation.factory) + (useroperation.factoryData != null ? useroperation.factoryData.slice(2) : "");
352
+ }
353
+ /**
354
+ * @internal
355
+ * Reconstruct the packed `paymasterAndData` field from a UserOperation's
356
+ * separate paymaster fields. Returns `0x` when no paymaster is set.
357
+ *
358
+ * For EntryPoint v0.9, when `paymasterData` ends with the parallel-paymaster
359
+ * signature magic suffix (`0x22e325a297439656`), the embedded signature is
360
+ * stripped so the userOpHash does not commit to the paymaster's signature
361
+ * over itself. Pass `stripV9PaymasterSig=false` to preserve the wire format.
362
+ *
363
+ * Shared by v7/v8/v9 packers and Simple7702Account's typed-data builder.
364
+ * Not part of the public API; only `export`ed for cross-module use within
365
+ * the package and not re-exported from `src/abstractionkit.ts`.
366
+ *
367
+ * @param useroperation - V7/V8/V9 UserOperation to read fields from
368
+ * @param stripV9PaymasterSig - Whether to strip the v0.9 paymaster signature suffix
369
+ * @returns Hex-encoded paymasterAndData
370
+ */
371
+ function buildPaymasterAndData(useroperation, stripV9PaymasterSig = false) {
372
+ if (useroperation.paymaster == null) return "0x";
373
+ const abiCoder = ethers.AbiCoder.defaultAbiCoder();
374
+ let paymasterAndData = useroperation.paymaster;
375
+ if (useroperation.paymasterVerificationGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterVerificationGasLimit]).slice(34);
376
+ if (useroperation.paymasterPostOpGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterPostOpGasLimit]).slice(34);
377
+ if (useroperation.paymasterData != null) {
378
+ const PAYMASTER_SIG_MAGIC = "22e325a297439656";
379
+ if (stripV9PaymasterSig && useroperation.paymasterData.toLowerCase().endsWith(PAYMASTER_SIG_MAGIC)) {
380
+ const sigLenHex = useroperation.paymasterData.slice(useroperation.paymasterData.length - 16 - 4, useroperation.paymasterData.length - 16);
381
+ const sigLen = parseInt(sigLenHex, 16);
382
+ const prefixEnd = useroperation.paymasterData.length - 16 - 4 - sigLen * 2;
383
+ paymasterAndData += useroperation.paymasterData.slice(0, prefixEnd).replaceAll("0x", "") + PAYMASTER_SIG_MAGIC;
384
+ } else paymasterAndData += useroperation.paymasterData.slice(2);
385
+ }
386
+ return paymasterAndData;
387
+ }
388
+ /**
334
389
  * ABI-encode and pack a UserOperation for hashing (EntryPoint v0.6 format).
335
390
  * Bytes fields (initCode, callData, paymasterAndData) are keccak256-hashed before packing.
336
391
  *
@@ -379,13 +434,7 @@ var abstractionkit = (function(exports, ethers) {
379
434
  }
380
435
  const accountGasLimits = "0x" + abiCoder.encode(["uint128"], [useroperation.verificationGasLimit]).slice(34) + abiCoder.encode(["uint128"], [useroperation.callGasLimit]).slice(34);
381
436
  const gasFees = "0x" + abiCoder.encode(["uint128"], [useroperation.maxPriorityFeePerGas]).slice(34) + abiCoder.encode(["uint128"], [useroperation.maxFeePerGas]).slice(34);
382
- let paymasterAndData = "0x";
383
- if (useroperation.paymaster != null) {
384
- paymasterAndData = useroperation.paymaster;
385
- if (useroperation.paymasterVerificationGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterVerificationGasLimit]).slice(34);
386
- if (useroperation.paymasterPostOpGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterPostOpGasLimit]).slice(34);
387
- if (useroperation.paymasterData != null) paymasterAndData += useroperation.paymasterData.slice(2);
388
- }
437
+ const paymasterAndData = buildPaymasterAndData(useroperation);
389
438
  const useroperationValuesArrayWithHashedByteValues = [
390
439
  useroperation.sender,
391
440
  useroperation.nonce,
@@ -433,30 +482,10 @@ var abstractionkit = (function(exports, ethers) {
433
482
  */
434
483
  function baseCreatePackedUserOperationV8V9(useroperation, is_v9) {
435
484
  const abiCoder = ethers.AbiCoder.defaultAbiCoder();
436
- let initCode = "0x";
437
- if (useroperation.factory != null) {
438
- const eip7702Auth = useroperation.eip7702Auth;
439
- if (eip7702Auth != null && eip7702Auth.address != null) initCode = eip7702Auth.address;
440
- else initCode = useroperation.factory;
441
- if (useroperation.factoryData != null) initCode += useroperation.factoryData.slice(2);
442
- }
485
+ const initCode = buildPackedInitCodeV8V9(useroperation);
443
486
  const accountGasLimits = "0x" + abiCoder.encode(["uint128"], [useroperation.verificationGasLimit]).slice(34) + abiCoder.encode(["uint128"], [useroperation.callGasLimit]).slice(34);
444
487
  const gasFees = "0x" + abiCoder.encode(["uint128"], [useroperation.maxPriorityFeePerGas]).slice(34) + abiCoder.encode(["uint128"], [useroperation.maxFeePerGas]).slice(34);
445
- let paymasterAndData = "0x";
446
- if (useroperation.paymaster != null) {
447
- paymasterAndData = useroperation.paymaster;
448
- if (useroperation.paymasterVerificationGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterVerificationGasLimit]).slice(34);
449
- if (useroperation.paymasterPostOpGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterPostOpGasLimit]).slice(34);
450
- if (useroperation.paymasterData != null) {
451
- const PAYMASTER_SIG_MAGIC = "22e325a297439656";
452
- if (is_v9 && useroperation.paymasterData.toLowerCase().endsWith(PAYMASTER_SIG_MAGIC)) {
453
- const sigLenHex = useroperation.paymasterData.slice(useroperation.paymasterData.length - 16 - 4, useroperation.paymasterData.length - 16);
454
- const sigLen = parseInt(sigLenHex, 16);
455
- const prefixEnd = useroperation.paymasterData.length - 16 - 4 - sigLen * 2;
456
- paymasterAndData += useroperation.paymasterData.slice(0, prefixEnd).replaceAll("0x", "") + PAYMASTER_SIG_MAGIC;
457
- } else paymasterAndData += useroperation.paymasterData.slice(2);
458
- }
459
- }
488
+ const paymasterAndData = buildPaymasterAndData(useroperation, is_v9);
460
489
  const useroperationValuesArrayWithHashedByteValues = [
461
490
  "0x29a0bca4af4be3421398da00295e58e6d7de38cb492214754cb6a47507dd6f8e",
462
491
  useroperation.sender,
@@ -2678,7 +2707,7 @@ var abstractionkit = (function(exports, ethers) {
2678
2707
  static DEFAULT_WEB_AUTHN_SHARED_SIGNER = "0xfD90FAd33ee8b58f32c00aceEad1358e4AFC23f9";
2679
2708
  static DEFAULT_WEB_AUTHN_SIGNER_SINGLETON = "0x270D7E4a57E6322f336261f3EaE2BADe72E68d72";
2680
2709
  static DEFAULT_WEB_AUTHN_SIGNER_FACTORY = "0xF7488fFbe67327ac9f37D5F722d83Fc900852Fbf";
2681
- static DEFAULT_WEB_AUTHN_FCLP256_VERIFIER = "0x445a0683e494ea0c5AF3E83c5159fBE47Cf9e765";
2710
+ static DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER = "0x445a0683e494ea0c5AF3E83c5159fBE47Cf9e765";
2682
2711
  static DEFAULT_WEB_AUTHN_PRECOMPILE = "0x0000000000000000000000000000000000000000";
2683
2712
  static DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE = "0x61010060405234801561001157600080fd5b506040516101ee3803806101ee83398101604081905261003091610058565b6001600160a01b0390931660805260a09190915260c0526001600160b01b031660e0526100bc565b6000806000806080858703121561006e57600080fd5b84516001600160a01b038116811461008557600080fd5b60208601516040870151606088015192965090945092506001600160b01b03811681146100b157600080fd5b939692955090935050565b60805160a05160c05160e05160ff6100ef60003960006008015260006031015260006059015260006080015260ff6000f3fe608060408190527f00000000000000000000000000000000000000000000000000000000000000003660b681018290527f000000000000000000000000000000000000000000000000000000000000000060a082018190527f00000000000000000000000000000000000000000000000000000000000000008285018190527f00000000000000000000000000000000000000000000000000000000000000009490939192600082376000806056360183885af490503d6000803e8060c3573d6000fd5b503d6000f3fea2646970667358221220ddd9bb059ba7a6497d560ca97aadf4dbf0476f578378554a50d41c6bb654beae64736f6c63430008180033";
2684
2713
  static DEFAULT_MULTISEND_CONTRACT_ADDRESS = "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526";
@@ -2766,6 +2795,33 @@ var abstractionkit = (function(exports, ethers) {
2766
2795
  ]).slice(-40)}`);
2767
2796
  }
2768
2797
  /**
2798
+ * Check whether a Safe account is already deployed at the given address.
2799
+ *
2800
+ * Use this to decide between connecting to an existing account
2801
+ * (`new SafeAccountV0_3_0(address)`) and initializing a new one
2802
+ * (`SafeAccountV0_3_0.initializeNewAccount(owners)`). Once an account is
2803
+ * deployed, the factory data carried by `initializeNewAccount` is no
2804
+ * longer needed and including it would waste gas.
2805
+ *
2806
+ * Note: this only checks whether bytecode exists at `accountAddress`, not
2807
+ * whether the deployed code is actually a Safe or whether its on-chain
2808
+ * configuration matches a given set of owners.
2809
+ *
2810
+ * @param accountAddress - the Safe account address to check
2811
+ * @param nodeRpcUrl - Ethereum JSON-RPC node URL
2812
+ * @returns `true` if bytecode is deployed at `accountAddress`, `false` otherwise
2813
+ *
2814
+ * @example
2815
+ * ```ts
2816
+ * const account = (await SafeAccountV0_3_0.isDeployed(addr, rpc))
2817
+ * ? new SafeAccountV0_3_0(addr)
2818
+ * : SafeAccountV0_3_0.initializeNewAccount(owners);
2819
+ * ```
2820
+ */
2821
+ static async isDeployed(accountAddress, nodeRpcUrl) {
2822
+ return (await sendEthGetCodeRequest(nodeRpcUrl, accountAddress, "latest")).length > 2;
2823
+ }
2824
+ /**
2769
2825
  * encode calldata for a single MetaTransaction to be executed by Safe account
2770
2826
  * @param metaTransaction - metaTransaction to create calldata for
2771
2827
  * @param overrides - overrides for the default values
@@ -3162,7 +3218,7 @@ var abstractionkit = (function(exports, ethers) {
3162
3218
  */
3163
3219
  static createAccountAddressAndFactoryAddressAndData(owners, overrides, safe4337ModuleAddress, safeModuleSetupAddress) {
3164
3220
  if (owners.length < 1) throw new RangeError("There should be at least one owner");
3165
- const initializerCallData = SafeAccount.createBaseInitializerCallData(owners, overrides.threshold ?? 1, safe4337ModuleAddress, safeModuleSetupAddress, overrides.multisendContractAddress ?? SafeAccount.DEFAULT_MULTISEND_CONTRACT_ADDRESS, overrides.webAuthnSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER, overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE, overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER);
3221
+ const initializerCallData = SafeAccount.createBaseInitializerCallData(owners, overrides.threshold ?? 1, safe4337ModuleAddress, safeModuleSetupAddress, overrides.multisendContractAddress ?? SafeAccount.DEFAULT_MULTISEND_CONTRACT_ADDRESS, overrides.webAuthnSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER, overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE, overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER);
3166
3222
  let safeAccountFactory;
3167
3223
  if (overrides.safeAccountFactoryAddress != null) safeAccountFactory = new SafeAccountFactory(overrides.safeAccountFactoryAddress);
3168
3224
  else safeAccountFactory = new SafeAccountFactory();
@@ -3184,7 +3240,7 @@ var abstractionkit = (function(exports, ethers) {
3184
3240
  factoryGeneratorFunctionCallData
3185
3241
  ];
3186
3242
  }
3187
- static createBaseInitializerCallData(owners, threshold, safe4337ModuleAddress, safeModuleSetupAddress, multisendContractAddress = SafeAccount.DEFAULT_MULTISEND_CONTRACT_ADDRESS, webAuthnSharedSigner = SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER, eip7212WebAuthnPrecompileVerifierForSharedSigner = SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE, eip7212WebAuthnContractVerifierForSharedSigner = SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER) {
3243
+ static createBaseInitializerCallData(owners, threshold, safe4337ModuleAddress, safeModuleSetupAddress, multisendContractAddress = SafeAccount.DEFAULT_MULTISEND_CONTRACT_ADDRESS, webAuthnSharedSigner = SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER, eip7212WebAuthnPrecompileVerifierForSharedSigner = SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE, eip7212WebAuthnContractVerifierForSharedSigner = SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER) {
3188
3244
  if (owners.length < 1) throw new RangeError("There should be at least one owner");
3189
3245
  if (threshold < 1) throw new RangeError("threshold should be at least one");
3190
3246
  if (threshold > owners.length) throw new RangeError("threshold can't be larger than number of owners");
@@ -3260,7 +3316,7 @@ var abstractionkit = (function(exports, ethers) {
3260
3316
  if (threshold < 1) throw new RangeError("threshold should be at least one");
3261
3317
  if (threshold > owners.length) throw new RangeError("threshold can't be larger than number of owners");
3262
3318
  if (c2Nonce < 0n) throw new RangeError("c2Nonce can't be negative");
3263
- const initializerCallData = SafeAccount.createBaseInitializerCallData(owners, overrides.threshold ?? 1, safe4337ModuleAddress, safeModuleSetupAddress, overrides.multisendContractAddress ?? SafeAccount.DEFAULT_MULTISEND_CONTRACT_ADDRESS, overrides.webAuthnSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER, overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE, overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER);
3319
+ const initializerCallData = SafeAccount.createBaseInitializerCallData(owners, overrides.threshold ?? 1, safe4337ModuleAddress, safeModuleSetupAddress, overrides.multisendContractAddress ?? SafeAccount.DEFAULT_MULTISEND_CONTRACT_ADDRESS, overrides.webAuthnSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER, overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE, overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER);
3264
3320
  let safeAccountFactory;
3265
3321
  if (overrides.safeAccountFactoryAddress != null) safeAccountFactory = new SafeAccountFactory(overrides.safeAccountFactoryAddress);
3266
3322
  else safeAccountFactory = new SafeAccountFactory();
@@ -3322,9 +3378,7 @@ var abstractionkit = (function(exports, ethers) {
3322
3378
  eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier,
3323
3379
  webAuthnSignerFactory: overrides.webAuthnSignerFactory,
3324
3380
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton,
3325
- webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode,
3326
- validAfter,
3327
- validUntil
3381
+ webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode
3328
3382
  });
3329
3383
  userOperation.signature = SafeAccount.formatSignaturesToUseroperationSignature(dummySignerSignaturePairs, {
3330
3384
  validAfter,
@@ -3391,7 +3445,7 @@ var abstractionkit = (function(exports, ethers) {
3391
3445
  maxFeePerGas = overrides.maxFeePerGas ?? maxFeePerGas * BigInt((overrides.maxFeePerGasPercentageMultiplier ?? 0) + 100) / 100n;
3392
3446
  maxPriorityFeePerGas = overrides.maxPriorityFeePerGas ?? maxPriorityFeePerGas * BigInt((overrides.maxPriorityFeePerGasPercentageMultiplier ?? 0) + 100) / 100n;
3393
3447
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3394
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3448
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3395
3449
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3396
3450
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3397
3451
  const webAuthnSignerProxyCreationCode = overrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -3466,16 +3520,14 @@ var abstractionkit = (function(exports, ethers) {
3466
3520
  eip7212WebAuthnContractVerifier,
3467
3521
  webAuthnSignerFactory,
3468
3522
  webAuthnSignerSingleton,
3469
- webAuthnSignerProxyCreationCode,
3470
- validAfter,
3471
- validUntil
3523
+ webAuthnSignerProxyCreationCode
3472
3524
  });
3473
3525
  }
3474
3526
  userOperation.signature = SafeAccount.formatSignaturesToUseroperationSignature(dummySignerSignaturePairs, {
3475
3527
  validAfter,
3476
3528
  validUntil,
3477
- webAuthnSharedSigner,
3478
- isMultiChainSignature: overrides.isMultiChainSignature
3529
+ isMultiChainSignature: overrides.isMultiChainSignature,
3530
+ webAuthnSharedSigner
3479
3531
  });
3480
3532
  if (!(overrides.skipGasEstimation ?? false) && (overrides.preVerificationGas == null || overrides.verificationGasLimit == null || overrides.callGasLimit == null)) if (bundlerRpc != null) {
3481
3533
  userOperation.callGasLimit = 0n;
@@ -3542,14 +3594,15 @@ var abstractionkit = (function(exports, ethers) {
3542
3594
  * @param useroperation - useroperation to sign
3543
3595
  * @param privateKeys - for the signers
3544
3596
  * @param chainId - target chain id
3545
- * @param overrides - overrides for the default values
3546
- * @param overrides.validAfter - timestamp the signature will be valid after
3547
- * @param overrides.validUntil - timestamp the signature will be valid until
3597
+ * @param entrypointAddress - target EntryPoint
3598
+ * @param safe4337ModuleAddress - Safe 4337 module
3599
+ * @param options - per-call signing options (timing, multi-chain encoding, module address) — passed through to {@link formatSignaturesToUseroperationSignature}
3548
3600
  * @returns signature
3549
3601
  */
3550
- static baseSignSingleUserOperation(useroperation, privateKeys, chainId, entrypointAddress, safe4337ModuleAddress, overrides = {}) {
3551
- const validAfter = overrides.validAfter ?? 0n;
3552
- const validUntil = overrides.validUntil ?? 0n;
3602
+ static baseSignSingleUserOperation(useroperation, privateKeys, chainId, entrypointAddress, safe4337ModuleAddress, options = {}) {
3603
+ const validAfter = options.validAfter ?? 0n;
3604
+ const validUntil = options.validUntil ?? 0n;
3605
+ const moduleAddress = options.safe4337ModuleAddress ?? safe4337ModuleAddress;
3553
3606
  if (privateKeys.length < 1) throw new RangeError("There should be at least one privateKey");
3554
3607
  if (chainId < 0n) throw new RangeError("chainId can't be negative");
3555
3608
  if (validAfter < 0n) throw new RangeError("validAfter can't be negative");
@@ -3558,7 +3611,7 @@ var abstractionkit = (function(exports, ethers) {
3558
3611
  validAfter,
3559
3612
  validUntil,
3560
3613
  entrypointAddress,
3561
- safe4337ModuleAddress
3614
+ safe4337ModuleAddress: moduleAddress
3562
3615
  });
3563
3616
  const signerSignaturePairs = [];
3564
3617
  for (const privateKey of privateKeys) {
@@ -3570,9 +3623,9 @@ var abstractionkit = (function(exports, ethers) {
3570
3623
  });
3571
3624
  }
3572
3625
  return SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
3626
+ ...options,
3573
3627
  validAfter,
3574
- validUntil,
3575
- isMultiChainSignature: overrides.isMultiChainSignature
3628
+ validUntil
3576
3629
  });
3577
3630
  }
3578
3631
  /**
@@ -3595,20 +3648,24 @@ var abstractionkit = (function(exports, ethers) {
3595
3648
  * @param useroperation - UserOperation to sign
3596
3649
  * @param signers - Signer instances (`fromViem(account)`, `fromEthersWallet(wallet)`, etc.)
3597
3650
  * @param chainId - target chain id
3598
- * @param entrypointAddress - target EntryPoint
3599
- * @param safe4337ModuleAddress - Safe 4337 module
3600
- * @param overrides - optional validAfter / validUntil / multi-chain flag
3651
+ * @param params - bag combining required wiring (`entrypointAddress`,
3652
+ * `safe4337ModuleAddress`, `context`) with optional `options`
3653
+ * ({@link SafeSignatureOptions}: timing, multi-chain encoding,
3654
+ * module address).
3655
+ * Both flow through to {@link formatSignaturesToUseroperationSignature}.
3601
3656
  * @returns formatted signature
3602
3657
  */
3603
- static async baseSignUserOperationWithSigners(useroperation, signers, chainId, entrypointAddress, safe4337ModuleAddress, context, overrides = {}) {
3604
- const validAfter = overrides.validAfter ?? 0n;
3605
- const validUntil = overrides.validUntil ?? 0n;
3658
+ static async baseSignUserOperationWithSigners(useroperation, signers, chainId, params) {
3659
+ const { entrypointAddress, safe4337ModuleAddress, context, options = {} } = params;
3660
+ const validAfter = options.validAfter ?? 0n;
3661
+ const validUntil = options.validUntil ?? 0n;
3662
+ const moduleAddress = options.safe4337ModuleAddress ?? safe4337ModuleAddress;
3606
3663
  if (signers.length < 1) throw new RangeError("There should be at least one signer");
3607
3664
  const typedDataRaw = SafeAccount.getUserOperationEip712Data(useroperation, chainId, {
3608
3665
  validAfter,
3609
3666
  validUntil,
3610
3667
  entrypointAddress,
3611
- safe4337ModuleAddress
3668
+ safe4337ModuleAddress: moduleAddress
3612
3669
  });
3613
3670
  const userOpHash = ethers.TypedDataEncoder.hash(typedDataRaw.domain, typedDataRaw.types, typedDataRaw.messageValue);
3614
3671
  const { EIP712Domain: _drop, ...primaryTypes } = typedDataRaw.types;
@@ -3629,12 +3686,13 @@ var abstractionkit = (function(exports, ethers) {
3629
3686
  context
3630
3687
  })))).map((signature, i) => ({
3631
3688
  signer: normalizedAddresses[i],
3632
- signature
3689
+ signature,
3690
+ isContractSignature: signers[i].type === "contract"
3633
3691
  }));
3634
3692
  return SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
3693
+ ...options,
3635
3694
  validAfter,
3636
- validUntil,
3637
- isMultiChainSignature: overrides.isMultiChainSignature
3695
+ validUntil
3638
3696
  });
3639
3697
  }
3640
3698
  /**
@@ -3647,7 +3705,7 @@ var abstractionkit = (function(exports, ethers) {
3647
3705
  */
3648
3706
  static createWebAuthnSignerVerifierAddress(x, y, overrides = {}) {
3649
3707
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3650
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3708
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3651
3709
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3652
3710
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3653
3711
  if (eip7212WebAuthnPrecompileVerifier.length !== 42 || eip7212WebAuthnPrecompileVerifier.slice(0, 38) !== "0x0000000000000000000000000000000000000000".slice(0, 38)) throw new RangeError("Invalid precompile address. It should have the format 0x000000000000000000000000000000000000____");
@@ -3678,15 +3736,15 @@ var abstractionkit = (function(exports, ethers) {
3678
3736
  /**
3679
3737
  * format a list of eip712 signatures to a useroperation signature
3680
3738
  * @param signerSignaturePairs - a list of a pair of a signer and it's signature
3681
- * @param overrides - overrides for the default values
3739
+ * @param options - merged bag of {@link SafeSignatureOptions} (timing, multi-chain encoding, module address) and {@link WebAuthnSignatureOverrides} (verifier addresses, init flag). Single param for back-compat with the pre-split shape — callers may pass any combination of fields from either type.
3682
3740
  * @returns signature
3683
3741
  */
3684
- static formatSignaturesToUseroperationSignature(signerSignaturePairs, overrides = {}) {
3685
- const validAfter = overrides.validAfter ?? 0n;
3686
- const validUntil = overrides.validUntil ?? 0n;
3687
- const signature = SafeAccount.buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, overrides);
3688
- if (overrides.isMultiChainSignature) if (overrides.multiChainMerkleProof != null) {
3689
- const merkleProofLength = overrides.multiChainMerkleProof.slice(2).length;
3742
+ static formatSignaturesToUseroperationSignature(signerSignaturePairs, options = {}) {
3743
+ const validAfter = options.validAfter ?? 0n;
3744
+ const validUntil = options.validUntil ?? 0n;
3745
+ const signature = SafeAccount.buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, options);
3746
+ if (options.isMultiChainSignature) if (options.multiChainMerkleProof != null) {
3747
+ const merkleProofLength = options.multiChainMerkleProof.slice(2).length;
3690
3748
  if (merkleProofLength < 128 || merkleProofLength % 64 !== 0) throw new RangeError("invalid multiChainMerkleProof length.");
3691
3749
  let merkleTreeDepthHex = (merkleProofLength / 64 - 1).toString(16);
3692
3750
  if (merkleTreeDepthHex.length % 2 === 0) merkleTreeDepthHex = `0x${merkleTreeDepthHex}`;
@@ -3700,7 +3758,7 @@ var abstractionkit = (function(exports, ethers) {
3700
3758
  merkleTreeDepthHex,
3701
3759
  validAfter,
3702
3760
  validUntil,
3703
- overrides.multiChainMerkleProof + signature.slice(2)
3761
+ options.multiChainMerkleProof + signature.slice(2)
3704
3762
  ]);
3705
3763
  } else return (0, ethers.solidityPacked)([
3706
3764
  "bytes1",
@@ -3733,7 +3791,7 @@ var abstractionkit = (function(exports, ethers) {
3733
3791
  if (typeof signer === "string") return signer.toLowerCase();
3734
3792
  else {
3735
3793
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3736
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3794
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3737
3795
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3738
3796
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3739
3797
  const webAuthnSignerProxyCreationCode = overrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -3759,7 +3817,7 @@ var abstractionkit = (function(exports, ethers) {
3759
3817
  /**
3760
3818
  * format a list of eip712 signatures to a safe signature (without the time range)
3761
3819
  * @param signerSignaturePairs - a list of a pair of a signer and it's signature
3762
- * @param overrides - overrides for the default values
3820
+ * @param webAuthnSignatureOverrides - WebAuthn-only configuration (verifier addresses, init flag)
3763
3821
  * @returns signature
3764
3822
  */
3765
3823
  static buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, webAuthnSignatureOverrides = {}) {
@@ -3773,7 +3831,7 @@ var abstractionkit = (function(exports, ethers) {
3773
3831
  if (webAuthnSignatureOverrides.isInit) signer = webAuthnSignatureOverrides.webAuthnSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER;
3774
3832
  else {
3775
3833
  const eip7212WebAuthnPrecompileVerifier = webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3776
- const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3834
+ const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3777
3835
  const webAuthnSignerFactory = webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3778
3836
  const webAuthnSignerSingleton = webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3779
3837
  const webAuthnSignerProxyCreationCode = webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -4044,7 +4102,7 @@ var abstractionkit = (function(exports, ethers) {
4044
4102
  */
4045
4103
  static createDeployWebAuthnVerifierMetaTransaction(x, y, overrides = {}) {
4046
4104
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4047
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4105
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4048
4106
  return {
4049
4107
  to: overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
4050
4108
  value: 0n,
@@ -4146,7 +4204,7 @@ var abstractionkit = (function(exports, ethers) {
4146
4204
  signerSignaturePair.signer = webauthnsharedsigner;
4147
4205
  } else {
4148
4206
  const eip7212WebAuthnPrecompileVerifier = webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4149
- const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4207
+ const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4150
4208
  const webAuthnSignerFactory = webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
4151
4209
  const webAuthnSignerSingleton = webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
4152
4210
  const webAuthnSignerProxyCreationCode = webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -4180,7 +4238,7 @@ var abstractionkit = (function(exports, ethers) {
4180
4238
  static async verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, overrides = {}) {
4181
4239
  if (messageHash.length !== 66 || messageHash.slice(0, 2) !== "0x") throw new RangeError("Invalid messageHash, must be a 0x-prefixed keccak256 hash.");
4182
4240
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4183
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4241
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4184
4242
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
4185
4243
  if (eip7212WebAuthnPrecompileVerifier.length !== 42 || eip7212WebAuthnPrecompileVerifier.slice(0, 38) !== "0x0000000000000000000000000000000000000000".slice(0, 38)) throw new RangeError("Invalid precompile address. It should have the format 0x000000000000000000000000000000000000____");
4186
4244
  const callData = createCallData("0x1626ba7e", ["bytes32", "bytes"], [messageHash, signature]);
@@ -4310,7 +4368,7 @@ var abstractionkit = (function(exports, ethers) {
4310
4368
  * @param toolVersion - tool version; defaults to the current abstractionkit version
4311
4369
  * @returns the on-chain identifier as a hex string (not 0x prefixed)
4312
4370
  */
4313
- function generateOnChainIdentifier(project, platform = "Web", tool = "abstractionkit", toolVersion = "0.3.3") {
4371
+ function generateOnChainIdentifier(project, platform = "Web", tool = "abstractionkit", toolVersion = "0.3.5") {
4314
4372
  const identifierPrefix = "5afe";
4315
4373
  const identifierVersion = "00";
4316
4374
  const projectHash = (0, ethers.keccak256)(`0x${Buffer.from(project, "utf8").toString("hex")}`).slice(-20);
@@ -5314,15 +5372,15 @@ var abstractionkit = (function(exports, ethers) {
5314
5372
  * @param useroperation - The UserOperation to sign
5315
5373
  * @param privateKeys - Array of private keys for the signers
5316
5374
  * @param chainId - The target chain ID
5317
- * @param overrides - Override validAfter and validUntil timestamps
5375
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5318
5376
  * @returns The formatted signature string ready to set on the UserOperation
5319
5377
  *
5320
5378
  * @example
5321
5379
  * const signature = smartAccount.signUserOperation(userOp, [privateKey], 1n);
5322
5380
  * userOp.signature = signature;
5323
5381
  */
5324
- signUserOperation(useroperation, privateKeys, chainId, overrides = {}) {
5325
- return SafeAccount.baseSignSingleUserOperation(useroperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, overrides);
5382
+ signUserOperation(useroperation, privateKeys, chainId, options = {}) {
5383
+ return SafeAccount.baseSignSingleUserOperation(useroperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, options);
5326
5384
  }
5327
5385
  /**
5328
5386
  * Sign a UserOperation with one or more {@link ExternalSigner} instances
@@ -5344,16 +5402,21 @@ var abstractionkit = (function(exports, ethers) {
5344
5402
  * @param useroperation - UserOperation to sign
5345
5403
  * @param signers - one ExternalSigner per owner (any order)
5346
5404
  * @param chainId - target chain ID
5347
- * @param overrides - optional validAfter / validUntil / multi-chain flag
5405
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5348
5406
  * @returns Promise resolving to the formatted signature string
5349
5407
  */
5350
- signUserOperationWithSigners(useroperation, signers, chainId, overrides = {}) {
5408
+ signUserOperationWithSigners(useroperation, signers, chainId, options = {}) {
5351
5409
  const context = {
5352
5410
  userOperation: useroperation,
5353
5411
  chainId,
5354
5412
  entryPoint: this.entrypointAddress
5355
5413
  };
5356
- return SafeAccount.baseSignUserOperationWithSigners(useroperation, signers, chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, overrides);
5414
+ return SafeAccount.baseSignUserOperationWithSigners(useroperation, signers, chainId, {
5415
+ entrypointAddress: this.entrypointAddress,
5416
+ safe4337ModuleAddress: this.safe4337ModuleAddress,
5417
+ context,
5418
+ options
5419
+ });
5357
5420
  }
5358
5421
  };
5359
5422
  //#endregion
@@ -5596,28 +5659,39 @@ var abstractionkit = (function(exports, ethers) {
5596
5659
  * @param useroperation - The UserOperation to sign
5597
5660
  * @param privateKeys - Array of private keys for the signers
5598
5661
  * @param chainId - The target chain ID
5599
- * @param overrides - Override validAfter and validUntil timestamps
5662
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5600
5663
  * @returns The formatted signature string ready to set on the UserOperation
5601
5664
  *
5602
5665
  * @example
5603
5666
  * const signature = smartAccount.signUserOperation(userOp, [privateKey], 1n);
5604
5667
  * userOp.signature = signature;
5605
5668
  */
5606
- signUserOperation(useroperation, privateKeys, chainId, overrides = {}) {
5607
- return SafeAccount.baseSignSingleUserOperation(useroperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, overrides);
5669
+ signUserOperation(useroperation, privateKeys, chainId, options = {}) {
5670
+ return SafeAccount.baseSignSingleUserOperation(useroperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, options);
5608
5671
  }
5609
5672
  /**
5610
5673
  * Sign a UserOperation using one or more {@link AkSigner} instances.
5611
5674
  * See {@link SafeAccountV0_3_0.signUserOperationWithSigners} for full
5612
5675
  * design rationale and examples.
5676
+ *
5677
+ * @param useroperation - The UserOperation to sign
5678
+ * @param signers - one ExternalSigner per owner (any order)
5679
+ * @param chainId - The target chain ID
5680
+ * @param options - {@link SafeSignatureOptions} — timing, multi-chain encoding, module address
5681
+ * @returns Promise resolving to the formatted signature string
5613
5682
  */
5614
- signUserOperationWithSigners(useroperation, signers, chainId, overrides = {}) {
5683
+ signUserOperationWithSigners(useroperation, signers, chainId, options = {}) {
5615
5684
  const context = {
5616
5685
  userOperation: useroperation,
5617
5686
  chainId,
5618
5687
  entryPoint: this.entrypointAddress
5619
5688
  };
5620
- return SafeAccount.baseSignUserOperationWithSigners(useroperation, signers, chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, overrides);
5689
+ return SafeAccount.baseSignUserOperationWithSigners(useroperation, signers, chainId, {
5690
+ entrypointAddress: this.entrypointAddress,
5691
+ safe4337ModuleAddress: this.safe4337ModuleAddress,
5692
+ context,
5693
+ options
5694
+ });
5621
5695
  }
5622
5696
  };
5623
5697
  //#endregion
@@ -5636,6 +5710,7 @@ var abstractionkit = (function(exports, ethers) {
5636
5710
  var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAccountV0_3_0 {
5637
5711
  static DEFAULT_WEB_AUTHN_PRECOMPILE = "0x0000000000000000000000000000000000000100";
5638
5712
  static DEFAULT_WEB_AUTHN_DAIMO_VERIFIER = "0xc2b78104907F722DABAc4C69f826a522B2754De4";
5713
+ static DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER = "0xc2b78104907F722DABAc4C69f826a522B2754De4";
5639
5714
  /**
5640
5715
  * Create a SafeAccountV1_5_0_M_0_3_0 instance for an existing deployed account.
5641
5716
  * For new (undeployed) accounts, use the static `initializeNewAccount` method instead.
@@ -5684,7 +5759,7 @@ var abstractionkit = (function(exports, ethers) {
5684
5759
  ...overrides,
5685
5760
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5686
5761
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5687
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5762
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5688
5763
  };
5689
5764
  return SafeAccountV0_3_0.initializeNewAccount(owners, modOverrides);
5690
5765
  }
@@ -5701,7 +5776,7 @@ var abstractionkit = (function(exports, ethers) {
5701
5776
  ...overrides,
5702
5777
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5703
5778
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5704
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5779
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5705
5780
  };
5706
5781
  return SafeAccountV0_3_0.createAccountAddress(owners, modOverrides);
5707
5782
  }
@@ -5718,7 +5793,7 @@ var abstractionkit = (function(exports, ethers) {
5718
5793
  ...overrides,
5719
5794
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5720
5795
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5721
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5796
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5722
5797
  };
5723
5798
  return SafeAccountV0_3_0.createFactoryAddressAndData(owners, modOverrides);
5724
5799
  }
@@ -5736,7 +5811,7 @@ var abstractionkit = (function(exports, ethers) {
5736
5811
  return super.createUserOperation(transactions, providerRpc, bundlerRpc, {
5737
5812
  ...overrides,
5738
5813
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5739
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5814
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5740
5815
  });
5741
5816
  }
5742
5817
  /**
@@ -5751,7 +5826,7 @@ var abstractionkit = (function(exports, ethers) {
5751
5826
  return super.estimateUserOperationGas(userOperation, bundlerRpc, {
5752
5827
  ...overrides,
5753
5828
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5754
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5829
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5755
5830
  });
5756
5831
  }
5757
5832
  /**
@@ -5767,7 +5842,7 @@ var abstractionkit = (function(exports, ethers) {
5767
5842
  return SafeAccount.createWebAuthnSignerVerifierAddress(x, y, {
5768
5843
  ...overrides,
5769
5844
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5770
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5845
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5771
5846
  });
5772
5847
  }
5773
5848
  /**
@@ -5783,7 +5858,7 @@ var abstractionkit = (function(exports, ethers) {
5783
5858
  return SafeAccount.createDeployWebAuthnVerifierMetaTransaction(x, y, {
5784
5859
  ...overrides,
5785
5860
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5786
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5861
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5787
5862
  });
5788
5863
  }
5789
5864
  /**
@@ -5797,7 +5872,7 @@ var abstractionkit = (function(exports, ethers) {
5797
5872
  return SafeAccount.createDummySignerSignaturePairForExpectedSigners(expectedSigners, {
5798
5873
  ...webAuthnSignatureOverrides,
5799
5874
  eip7212WebAuthnPrecompileVerifier: webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5800
- eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5875
+ eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5801
5876
  });
5802
5877
  }
5803
5878
  /**
@@ -5815,7 +5890,7 @@ var abstractionkit = (function(exports, ethers) {
5815
5890
  return SafeAccount.verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, {
5816
5891
  ...overrides,
5817
5892
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5818
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5893
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5819
5894
  });
5820
5895
  }
5821
5896
  };
@@ -5909,6 +5984,7 @@ var abstractionkit = (function(exports, ethers) {
5909
5984
  static DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE = DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE_V_0_2_1;
5910
5985
  static DEFAULT_WEB_AUTHN_PRECOMPILE = DEFAULT_WEB_AUTHN_PRECOMPILE_RIP_7951;
5911
5986
  static DEFAULT_WEB_AUTHN_DAIMO_VERIFIER = DEFAULT_WEB_AUTHN_DAIMO_VERIFIER_V_0_2_1;
5987
+ static DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER = DEFAULT_WEB_AUTHN_DAIMO_VERIFIER_V_0_2_1;
5912
5988
  /**
5913
5989
  * Create a SafeMultiChainSigAccount instance for an existing or new account.
5914
5990
  * @param accountAddress - the Safe account address
@@ -5934,7 +6010,7 @@ var abstractionkit = (function(exports, ethers) {
5934
6010
  ...overrides,
5935
6011
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
5936
6012
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
5937
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6013
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5938
6014
  };
5939
6015
  const [accountAddress, ,] = SafeAccount.createAccountAddressAndFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
5940
6016
  return accountAddress;
@@ -5964,7 +6040,7 @@ var abstractionkit = (function(exports, ethers) {
5964
6040
  ...overrides,
5965
6041
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
5966
6042
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
5967
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6043
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5968
6044
  };
5969
6045
  const [accountAddress, factoryAddress, factoryData] = SafeAccount.createAccountAddressAndFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
5970
6046
  const safe = new SafeMultiChainSigAccountV1(accountAddress, {
@@ -6041,7 +6117,7 @@ var abstractionkit = (function(exports, ethers) {
6041
6117
  static createInitializerCallData(owners, threshold, overrides = {}) {
6042
6118
  const safe4337ModuleAddress = overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS;
6043
6119
  const safeModuleSetupAddress = overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS;
6044
- return SafeAccount.createBaseInitializerCallData(owners, threshold, safe4337ModuleAddress, safeModuleSetupAddress, overrides.multisendContractAddress, overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER, overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE, overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER);
6120
+ return SafeAccount.createBaseInitializerCallData(owners, threshold, safe4337ModuleAddress, safeModuleSetupAddress, overrides.multisendContractAddress, overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER, overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE, overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER);
6045
6121
  }
6046
6122
  /**
6047
6123
  * create account factory address and factory data
@@ -6054,7 +6130,7 @@ var abstractionkit = (function(exports, ethers) {
6054
6130
  ...overrides,
6055
6131
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
6056
6132
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6057
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6133
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
6058
6134
  };
6059
6135
  return SafeAccount.createFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
6060
6136
  }
@@ -6076,7 +6152,7 @@ var abstractionkit = (function(exports, ethers) {
6076
6152
  isMultiChainSignature: true,
6077
6153
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
6078
6154
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6079
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6155
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6080
6156
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6081
6157
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6082
6158
  webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE
@@ -6104,14 +6180,13 @@ var abstractionkit = (function(exports, ethers) {
6104
6180
  * @param useroperation - useroperation to sign
6105
6181
  * @param privateKeys - for the signers
6106
6182
  * @param chainId - target chain id
6107
- * @param overrides - overrides for the default values
6108
- * @param overrides.validAfter - timestamp the signature will be valid after
6109
- * @param overrides.validUntil - timestamp the signature will be valid until
6183
+ * @param options - {@link SafeSignatureOptions} — timing, multiChainMerkleProof, module address. The multi-chain flag is force-set true and overrides any caller value.
6110
6184
  * @returns signature
6111
6185
  */
6112
- signUserOperation(userOperation, privateKeys, chainId, overrides = {}) {
6186
+ signUserOperation(userOperation, privateKeys, chainId, options = {}) {
6187
+ if (options.multiChainMerkleProof != null && options.multiChainMerkleProof.length > 0) throw new RangeError("signUserOperation does not accept multiChainMerkleProof; use signUserOperations for multi-op Merkle signatures");
6113
6188
  return SafeAccount.baseSignSingleUserOperation(userOperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, {
6114
- ...overrides,
6189
+ ...options,
6115
6190
  isMultiChainSignature: true
6116
6191
  });
6117
6192
  }
@@ -6120,16 +6195,28 @@ var abstractionkit = (function(exports, ethers) {
6120
6195
  * {@link AkSigner} instances. See
6121
6196
  * {@link SafeAccountV0_3_0.signUserOperationWithSigners} for the full
6122
6197
  * design rationale. Sets the multi-chain flag automatically.
6198
+ *
6199
+ * @param userOperation - UserOperation to sign
6200
+ * @param signers - one ExternalSigner per owner (any order)
6201
+ * @param chainId - target chain id
6202
+ * @param options - {@link SafeSignatureOptions} — timing, multiChainMerkleProof, module address. The multi-chain flag is force-set true and overrides any caller value.
6203
+ * @returns Promise resolving to the formatted signature string
6123
6204
  */
6124
- signUserOperationWithSigners(userOperation, signers, chainId, overrides = {}) {
6205
+ signUserOperationWithSigners(userOperation, signers, chainId, options = {}) {
6206
+ if (options.multiChainMerkleProof != null && options.multiChainMerkleProof.length > 0) throw new RangeError("signUserOperationWithSigners does not accept multiChainMerkleProof; use signUserOperationsWithSigners for multi-op Merkle signatures");
6125
6207
  const context = {
6126
6208
  userOperation,
6127
6209
  chainId,
6128
6210
  entryPoint: this.entrypointAddress
6129
6211
  };
6130
- return SafeAccount.baseSignUserOperationWithSigners(userOperation, signers, chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, {
6131
- ...overrides,
6132
- isMultiChainSignature: true
6212
+ return SafeAccount.baseSignUserOperationWithSigners(userOperation, signers, chainId, {
6213
+ entrypointAddress: this.entrypointAddress,
6214
+ safe4337ModuleAddress: this.safe4337ModuleAddress,
6215
+ context,
6216
+ options: {
6217
+ ...options,
6218
+ isMultiChainSignature: true
6219
+ }
6133
6220
  });
6134
6221
  }
6135
6222
  /**
@@ -6250,10 +6337,15 @@ var abstractionkit = (function(exports, ethers) {
6250
6337
  return userOpSignatures;
6251
6338
  } else {
6252
6339
  const u = userOperationsToSign[0];
6253
- return [await SafeAccount.baseSignUserOperationWithSigners(u.userOperation, signers, u.chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, {
6254
- validAfter: u.validAfter,
6255
- validUntil: u.validUntil,
6256
- isMultiChainSignature: true
6340
+ return [await SafeAccount.baseSignUserOperationWithSigners(u.userOperation, signers, u.chainId, {
6341
+ entrypointAddress: this.entrypointAddress,
6342
+ safe4337ModuleAddress: this.safe4337ModuleAddress,
6343
+ context,
6344
+ options: {
6345
+ validAfter: u.validAfter,
6346
+ validUntil: u.validUntil,
6347
+ isMultiChainSignature: true
6348
+ }
6257
6349
  })];
6258
6350
  }
6259
6351
  }
@@ -6303,28 +6395,34 @@ var abstractionkit = (function(exports, ethers) {
6303
6395
  */
6304
6396
  static formatSignaturesToUseroperationsSignatures(userOperationsToSign, signerSignaturePairs) {
6305
6397
  if (userOperationsToSign.length < 1) throw new RangeError("There should be at least one userOperationsToSign");
6306
- const defaultOverrides = {
6398
+ const defaultWebAuthnOverrides = {
6307
6399
  eip7212WebAuthnPrecompileVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6308
- eip7212WebAuthnContractVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6400
+ eip7212WebAuthnContractVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6309
6401
  webAuthnSignerFactory: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6310
6402
  webAuthnSignerSingleton: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6311
6403
  webAuthnSignerProxyCreationCode: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
6312
- safe4337ModuleAddress: SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS,
6313
6404
  webAuthnSharedSigner: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER
6314
6405
  };
6406
+ const defaultOptions = { safe4337ModuleAddress: SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS };
6315
6407
  if (userOperationsToSign.length === 1) return [SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
6316
- ...defaultOverrides,
6317
- ...userOperationsToSign[0].overrides,
6408
+ ...defaultOptions,
6409
+ ...defaultWebAuthnOverrides,
6410
+ ...userOperationsToSign[0].options,
6411
+ ...userOperationsToSign[0].webAuthnSignatureOverrides,
6318
6412
  validAfter: userOperationsToSign[0].validAfter,
6319
6413
  validUntil: userOperationsToSign[0].validUntil,
6320
6414
  isMultiChainSignature: true
6321
6415
  })];
6322
6416
  const userOperationsHashes = [];
6323
- userOperationsToSign.forEach((userOperationToSign, _index) => {
6417
+ const resolvedValidity = userOperationsToSign.map((userOperationToSign) => ({
6418
+ validAfter: userOperationToSign.options?.validAfter ?? userOperationToSign.validAfter,
6419
+ validUntil: userOperationToSign.options?.validUntil ?? userOperationToSign.validUntil
6420
+ }));
6421
+ userOperationsToSign.forEach((userOperationToSign, index) => {
6324
6422
  const userOperationHash = SafeAccount.getUserOperationEip712Hash_V9(userOperationToSign.userOperation, userOperationToSign.chainId, {
6325
- validAfter: userOperationToSign.validAfter,
6326
- validUntil: userOperationToSign.validUntil,
6327
- safe4337ModuleAddress: userOperationToSign.overrides?.safe4337ModuleAddress ?? defaultOverrides.safe4337ModuleAddress
6423
+ validAfter: resolvedValidity[index].validAfter,
6424
+ validUntil: resolvedValidity[index].validUntil,
6425
+ safe4337ModuleAddress: userOperationToSign.options?.safe4337ModuleAddress ?? defaultOptions.safe4337ModuleAddress
6328
6426
  });
6329
6427
  userOperationsHashes.push(userOperationHash);
6330
6428
  });
@@ -6332,8 +6430,12 @@ var abstractionkit = (function(exports, ethers) {
6332
6430
  const userOpSignatures = [];
6333
6431
  userOperationsToSign.forEach((userOperationToSign, index) => {
6334
6432
  userOpSignatures.push(SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
6335
- ...defaultOverrides,
6336
- ...userOperationToSign.overrides,
6433
+ ...defaultOptions,
6434
+ ...defaultWebAuthnOverrides,
6435
+ ...userOperationToSign.options,
6436
+ ...userOperationToSign.webAuthnSignatureOverrides,
6437
+ validAfter: resolvedValidity[index].validAfter,
6438
+ validUntil: resolvedValidity[index].validUntil,
6337
6439
  isMultiChainSignature: true,
6338
6440
  multiChainMerkleProof: proofs[index]
6339
6441
  }));
@@ -6344,7 +6446,7 @@ var abstractionkit = (function(exports, ethers) {
6344
6446
  return SafeAccount.createWebAuthnSignerVerifierAddress(x, y, {
6345
6447
  ...overrides,
6346
6448
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6347
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6449
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6348
6450
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6349
6451
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6350
6452
  webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE
@@ -6354,7 +6456,7 @@ var abstractionkit = (function(exports, ethers) {
6354
6456
  return SafeAccount.createDeployWebAuthnVerifierMetaTransaction(x, y, {
6355
6457
  ...overrides,
6356
6458
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6357
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6459
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6358
6460
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY
6359
6461
  });
6360
6462
  }
@@ -6362,7 +6464,7 @@ var abstractionkit = (function(exports, ethers) {
6362
6464
  return SafeAccount.createDummySignerSignaturePairForExpectedSigners(expectedSigners, {
6363
6465
  ...webAuthnSignatureOverrides,
6364
6466
  eip7212WebAuthnPrecompileVerifier: webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6365
- eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6467
+ eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6366
6468
  webAuthnSignerFactory: webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6367
6469
  webAuthnSignerSingleton: webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6368
6470
  webAuthnSignerProxyCreationCode: webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
@@ -6373,7 +6475,7 @@ var abstractionkit = (function(exports, ethers) {
6373
6475
  return SafeAccount.verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, {
6374
6476
  ...overrides,
6375
6477
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6376
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6478
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6377
6479
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON
6378
6480
  });
6379
6481
  }
@@ -6711,27 +6813,139 @@ var abstractionkit = (function(exports, ethers) {
6711
6813
  return new ethers.Wallet(privateKey).signingKey.sign(userOperationHash).serialized;
6712
6814
  }
6713
6815
  /**
6714
- * Schemes Simple7702 accepts from a Signer. Only raw-hash ECDSA, since
6715
- * the delegatee verifies a plain signature over the userOp hash.
6816
+ * Schemes Simple7702 accepts from a Signer. EntryPoint v0.8/v0.9 introduced
6817
+ * an EIP-712 domain at the EntryPoint contract, and the userOpHash IS the
6818
+ * EIP-712 digest of the PackedUserOperation under that domain — so signing
6819
+ * the typed data and signing the raw hash produce signatures that verify
6820
+ * against the same `userOpHash` (and recover to the same signer address).
6821
+ * Deterministic-ECDSA signers (ethers, viem, MetaMask) yield byte-identical
6822
+ * bytes; signers that differ in `s` / `v` normalization still validate the
6823
+ * same on-chain.
6824
+ *
6825
+ * `typedData` is listed first so JSON-RPC wallets that can only sign typed
6826
+ * data work without a separate code path; `hash` remains a valid fallback
6827
+ * for local-key signers.
6716
6828
  */
6717
- static ACCEPTED_SIGNING_SCHEMES = ["hash"];
6829
+ static ACCEPTED_SIGNING_SCHEMES = ["typedData", "hash"];
6718
6830
  /**
6719
- * Sign a UserOperation with an {@link AkSigner}. Signer must implement
6720
- * `signHash`, since Simple7702 only verifies raw ECDSA over the userOp
6721
- * hash. JSON-RPC wallets and anything that only provides `signTypedData`
6722
- * fail offline with a specific error.
6831
+ * Build the EIP-712 typed data payload for a UserOperation under the
6832
+ * EntryPoint v0.8 / v0.9 domain. Lower-level escape hatch for integrators
6833
+ * driving `signTypedData` themselves with their own signing primitive
6834
+ * (HSM, MPC, custom wallet abstraction). Most callers should pass an
6835
+ * {@link AkSigner} to {@link signUserOperationWithSigner} instead, which
6836
+ * builds this internally.
6837
+ *
6838
+ * The digest of the returned payload equals the UserOperation hash from
6839
+ * {@link createUserOperationHash}, so a wallet calling
6840
+ * `signTypedData(domain, types, message)` produces a signature that
6841
+ * verifies against the same `userOpHash` as raw ECDSA over that hash.
6842
+ * Deterministic-ECDSA signers yield byte-identical signatures; signers
6843
+ * that differ in `s` / `v` normalization still validate the same on-chain.
6844
+ *
6845
+ * Common use cases beyond direct signing:
6846
+ * - Inspect / log the typed data the wallet will display.
6847
+ * - Render a custom confirmation UI before delegating to a wallet's
6848
+ * `signTypedData`.
6849
+ * - Drive non-`ExternalSigner`-shaped signers (HSM, MPC service,
6850
+ * backend signing pipelines).
6851
+ *
6852
+ * @param userOperation - Unsigned UserOperation to wrap
6853
+ * @param chainId - Target chain ID (must match the chain that will validate
6854
+ * the signature)
6855
+ * @returns EIP-712 {@link TypedData} payload ready for `signTypedData`
6856
+ * @throws {AbstractionKitError} if this account targets an EntryPoint
6857
+ * version other than v0.8 / v0.9. Earlier EntryPoints define the
6858
+ * userOpHash differently and require raw-hash signing.
6859
+ */
6860
+ getUserOperationEip712TypedData(userOperation, chainId) {
6861
+ const ep = this.entrypointAddress.toLowerCase();
6862
+ const isV9 = ep === ENTRYPOINT_V9.toLowerCase();
6863
+ if (ep !== "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108".toLowerCase() && !isV9) throw new AbstractionKitError("BAD_DATA", `getUserOperationEip712TypedData supports EntryPoint v0.8 / v0.9 only; this account targets ${this.entrypointAddress}. Use signUserOperation (raw-hash ECDSA) for earlier EntryPoint versions.`);
6864
+ const abiCoder = ethers.AbiCoder.defaultAbiCoder();
6865
+ const initCode = buildPackedInitCodeV8V9(userOperation);
6866
+ const accountGasLimits = "0x" + abiCoder.encode(["uint128"], [userOperation.verificationGasLimit]).slice(34) + abiCoder.encode(["uint128"], [userOperation.callGasLimit]).slice(34);
6867
+ const gasFees = "0x" + abiCoder.encode(["uint128"], [userOperation.maxPriorityFeePerGas]).slice(34) + abiCoder.encode(["uint128"], [userOperation.maxFeePerGas]).slice(34);
6868
+ const paymasterAndData = buildPaymasterAndData(userOperation, isV9);
6869
+ return {
6870
+ domain: {
6871
+ name: "ERC4337",
6872
+ version: "1",
6873
+ chainId,
6874
+ verifyingContract: this.entrypointAddress
6875
+ },
6876
+ types: { PackedUserOperation: [
6877
+ {
6878
+ name: "sender",
6879
+ type: "address"
6880
+ },
6881
+ {
6882
+ name: "nonce",
6883
+ type: "uint256"
6884
+ },
6885
+ {
6886
+ name: "initCode",
6887
+ type: "bytes"
6888
+ },
6889
+ {
6890
+ name: "callData",
6891
+ type: "bytes"
6892
+ },
6893
+ {
6894
+ name: "accountGasLimits",
6895
+ type: "bytes32"
6896
+ },
6897
+ {
6898
+ name: "preVerificationGas",
6899
+ type: "uint256"
6900
+ },
6901
+ {
6902
+ name: "gasFees",
6903
+ type: "bytes32"
6904
+ },
6905
+ {
6906
+ name: "paymasterAndData",
6907
+ type: "bytes"
6908
+ }
6909
+ ] },
6910
+ primaryType: "PackedUserOperation",
6911
+ message: {
6912
+ sender: userOperation.sender,
6913
+ nonce: userOperation.nonce,
6914
+ initCode,
6915
+ callData: userOperation.callData,
6916
+ accountGasLimits,
6917
+ preVerificationGas: userOperation.preVerificationGas,
6918
+ gasFees,
6919
+ paymasterAndData
6920
+ }
6921
+ };
6922
+ }
6923
+ /**
6924
+ * Sign a UserOperation with an {@link AkSigner}. The signer can implement
6925
+ * either `signTypedData` (preferred — JSON-RPC wallets, viem `WalletClient`)
6926
+ * or `signHash` (local keys, hardware wallets). Both schemes produce
6927
+ * signatures that validate against the same `userOpHash` because the
6928
+ * v0.8 / v0.9 userOpHash IS the EIP-712 digest of the PackedUserOperation
6929
+ * (deterministic-ECDSA signers yield byte-identical bytes).
6930
+ *
6931
+ * Signers that implement neither method fail offline with an actionable
6932
+ * error.
6723
6933
  */
6724
6934
  async baseSignUserOperationWithSigner(useroperation, signer, chainId) {
6725
- return invokeSigner(signer, pickScheme(signer, BaseSimple7702Account.ACCEPTED_SIGNING_SCHEMES, {
6726
- accountName: "Simple7702 (raw ECDSA over userOpHash)",
6935
+ const scheme = pickScheme(signer, BaseSimple7702Account.ACCEPTED_SIGNING_SCHEMES, {
6936
+ accountName: "Simple7702 (EIP-712 typed data or raw ECDSA over userOpHash)",
6727
6937
  signerIndex: 0
6728
- }), {
6729
- hash: createUserOperationHash(useroperation, this.entrypointAddress, chainId),
6730
- context: {
6731
- userOperation: useroperation,
6732
- chainId,
6733
- entryPoint: this.entrypointAddress
6734
- }
6938
+ });
6939
+ const hash = createUserOperationHash(useroperation, this.entrypointAddress, chainId);
6940
+ const context = {
6941
+ userOperation: useroperation,
6942
+ chainId,
6943
+ entryPoint: this.entrypointAddress
6944
+ };
6945
+ return invokeSigner(signer, scheme, {
6946
+ hash,
6947
+ typedData: scheme === "typedData" ? this.getUserOperationEip712TypedData(useroperation, chainId) : void 0,
6948
+ context
6735
6949
  });
6736
6950
  }
6737
6951
  /**
@@ -6845,13 +7059,34 @@ var abstractionkit = (function(exports, ethers) {
6845
7059
  return this.baseSignUserOperation(useroperation, privateKey, chainId);
6846
7060
  }
6847
7061
  /**
6848
- * Sign a {@link UserOperationV8} using an {@link ExternalSigner}.
6849
- * Simple7702 only accepts raw-hash ECDSA; signers without `signHash`
6850
- * fail offline with an actionable error.
7062
+ * Sign a {@link UserOperationV8} using an {@link ExternalSigner}. This is
7063
+ * the recommended entry point for any non-private-key signer.
7064
+ *
7065
+ * Accepts signers that implement `signTypedData` (JSON-RPC wallets, viem
7066
+ * `WalletClient`, browser wallets), `signHash` (local keys, hardware
7067
+ * wallets), or both. The v0.8 userOpHash IS the EIP-712 digest of the
7068
+ * PackedUserOperation under the EntryPoint domain, so both schemes
7069
+ * produce signatures that validate against the same `userOpHash`.
7070
+ *
7071
+ * Wrapping a custom signing primitive is just an object literal; no
7072
+ * adapter function required:
7073
+ *
7074
+ * ```ts
7075
+ * const signer: ExternalSigner = {
7076
+ * address: ownerAddress,
7077
+ * signTypedData: async (td) => myWallet.signTypedData(td),
7078
+ * }
7079
+ * userOp.signature = await account.signUserOperationWithSigner(userOp, signer, chainId)
7080
+ * ```
6851
7081
  *
6852
7082
  * For signing with a raw private-key string, use the sync
6853
7083
  * {@link signUserOperation} method, or wrap explicitly with
6854
7084
  * `fromPrivateKey(pk)`.
7085
+ *
7086
+ * @see {@link BaseSimple7702Account.getUserOperationEip712TypedData} for
7087
+ * the lower-level escape hatch when you need the typed data outside the
7088
+ * dispatcher (e.g., to render a custom confirmation UI or feed an HSM
7089
+ * that doesn't fit the {@link ExternalSigner} shape).
6855
7090
  */
6856
7091
  async signUserOperationWithSigner(useroperation, signer, chainId) {
6857
7092
  return this.baseSignUserOperationWithSigner(useroperation, signer, chainId);
@@ -6922,10 +7157,33 @@ var abstractionkit = (function(exports, ethers) {
6922
7157
  return this.baseSignUserOperation(useroperation, privateKey, chainId);
6923
7158
  }
6924
7159
  /**
6925
- * Sign a {@link UserOperationV9} using an {@link ExternalSigner}.
6926
- * Simple7702 only accepts raw-hash ECDSA; signers without `signHash`
6927
- * fail offline with an actionable error. For a raw pk string, use the
6928
- * sync {@link signUserOperation} method or wrap with `fromPrivateKey`.
7160
+ * Sign a {@link UserOperationV9} using an {@link ExternalSigner}. This is
7161
+ * the recommended entry point for any non-private-key signer.
7162
+ *
7163
+ * Accepts signers that implement `signTypedData` (JSON-RPC wallets, viem
7164
+ * `WalletClient`, browser wallets), `signHash` (local keys, hardware
7165
+ * wallets), or both. The v0.9 userOpHash IS the EIP-712 digest of the
7166
+ * PackedUserOperation under the EntryPoint domain, so both schemes
7167
+ * produce signatures that validate against the same `userOpHash`.
7168
+ *
7169
+ * Wrapping a custom signing primitive is just an object literal; no
7170
+ * adapter function required:
7171
+ *
7172
+ * ```ts
7173
+ * const signer: ExternalSigner = {
7174
+ * address: ownerAddress,
7175
+ * signTypedData: async (td) => myWallet.signTypedData(td),
7176
+ * }
7177
+ * userOp.signature = await account.signUserOperationWithSigner(userOp, signer, chainId)
7178
+ * ```
7179
+ *
7180
+ * For signing with a raw private-key string, use the sync
7181
+ * {@link signUserOperation} method, or wrap explicitly with
7182
+ * `fromPrivateKey(pk)`.
7183
+ *
7184
+ * @see {@link BaseSimple7702Account.getUserOperationEip712TypedData} for
7185
+ * the lower-level escape hatch when you need the typed data outside the
7186
+ * dispatcher.
6929
7187
  */
6930
7188
  async signUserOperationWithSigner(useroperation, signer, chainId) {
6931
7189
  return this.baseSignUserOperationWithSigner(useroperation, signer, chainId);
@@ -7936,6 +8194,280 @@ var abstractionkit = (function(exports, ethers) {
7936
8194
  ]));
7937
8195
  }
7938
8196
  //#endregion
8197
+ //#region src/account/Safe/adapters.ts
8198
+ /**
8199
+ * Adapt a WebAuthn credential to a Signer for `signUserOperationWithSigners`
8200
+ * on Safe accounts. Safe-specific (uses Safe's WebAuthn shared signer /
8201
+ * verifier proxy / signature encoding) — for non-Safe accounts, use the
8202
+ * account's own WebAuthn adapter.
8203
+ *
8204
+ * Hides the address routing (shared signer for the init UserOp, per-owner
8205
+ * verifier proxy after that), the `type: "contract"` tag, and the
8206
+ * Safe-specific signature encoding. The caller supplies a
8207
+ * {@link FromSafeWebauthnParams.getAssertion} callback that runs the
8208
+ * actual WebAuthn ceremony — this is where you call
8209
+ * `navigator.credentials.get(...)` (browser) or an equivalent native
8210
+ * bridge, since the SDK doesn't import `navigator` itself.
8211
+ *
8212
+ * Only `signHash` is exposed: WebAuthn signs a flat challenge, so a typed-data
8213
+ * preview would never reach the authenticator anyway.
8214
+ *
8215
+ * **Override consistency.** Pass the same `accountClass` you passed to
8216
+ * `initializeNewAccount` so the adapter sources the right Safe Passkey
8217
+ * module defaults — v0.2.0 / FCL P256 for `SafeAccount` / `SafeAccountV0_2_0`
8218
+ * / `SafeAccountV0_3_0`, v0.2.1 / Daimo P256 + RIP-7951 for
8219
+ * `SafeMultiChainSigAccountV1`. Every individual WebAuthn override
8220
+ * (`webAuthnSharedSigner`, `webAuthnSignerFactory`, `webAuthnSignerSingleton`,
8221
+ * `webAuthnSignerProxyCreationCode`, `eip7212WebAuthnPrecompileVerifier`,
8222
+ * `eip7212WebAuthnContractVerifier`) must likewise match what was passed to
8223
+ * `InitCodeOverrides` at init time — only set them when you've also
8224
+ * overridden them at init. The on-chain owner set is locked to whatever was
8225
+ * used at init: `webAuthnSharedSigner` for `isInit=true`, the deterministic
8226
+ * verifier proxy derived from the other five for `isInit=false`. A mismatch
8227
+ * produces a signature pointing at an address that isn't an owner; on-chain
8228
+ * `checkSignatures` reverts with `GS026` and the bundler surfaces it as a
8229
+ * generic "Invalid UserOp signature" with no offline diagnostic.
8230
+ *
8231
+ * @example
8232
+ * import { fromSafeWebauthn, SafeAccountV0_3_0 } from "abstractionkit";
8233
+ *
8234
+ * // Pass `expectedSigners: [{ x, y }]` so createUserOperation picks the
8235
+ * // WebAuthn dummy signature for gas estimation. Without it, the
8236
+ * // bundler sizes verification gas against the EOA dummy and the
8237
+ * // real signed UserOp gets rejected (or under-budgeted on-chain) at submit.
8238
+ * let userOperation = await safe.createUserOperation(
8239
+ * transactions, nodeUrl, bundlerUrl,
8240
+ * { expectedSigners: [{ x, y }] },
8241
+ * );
8242
+ *
8243
+ * const signer = fromSafeWebauthn({
8244
+ * publicKey: { x, y },
8245
+ * isInit: userOperation.nonce === 0n,
8246
+ * accountClass: SafeAccountV0_3_0, // SafeMultiChainSigAccountV1 for multi-chain
8247
+ * getAssertion: async (challenge) => {
8248
+ * const assertion = await navigator.credentials.get({
8249
+ * publicKey: { challenge, rpId, allowCredentials, userVerification },
8250
+ * });
8251
+ * return {
8252
+ * authenticatorData: assertion.response.authenticatorData,
8253
+ * clientDataFields: extractClientDataFields(assertion.response),
8254
+ * rs: extractSignature(assertion.response),
8255
+ * };
8256
+ * },
8257
+ * });
8258
+ * userOperation.signature = await safe.signUserOperationWithSigners(
8259
+ * userOperation, [signer], chainId,
8260
+ * );
8261
+ */
8262
+ function fromSafeWebauthn(params) {
8263
+ const { publicKey, isInit, getAssertion, accountClass, webAuthnSharedSigner, webAuthnSignerFactory, webAuthnSignerSingleton, webAuthnSignerProxyCreationCode, eip7212WebAuthnPrecompileVerifier, eip7212WebAuthnContractVerifier } = params;
8264
+ if (typeof publicKey?.x !== "bigint" || typeof publicKey?.y !== "bigint") throw new TypeError("fromSafeWebauthn: publicKey.x and publicKey.y must be bigint. If they round-tripped through JSON.parse, hydrate them back to bigint first (e.g. BigInt(value) for decimal strings, or use a JSON reviver).");
8265
+ return {
8266
+ address: isInit ? webAuthnSharedSigner ?? accountClass.DEFAULT_WEB_AUTHN_SHARED_SIGNER : SafeAccount.createWebAuthnSignerVerifierAddress(publicKey.x, publicKey.y, {
8267
+ webAuthnSignerFactory: webAuthnSignerFactory ?? accountClass.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
8268
+ webAuthnSignerSingleton: webAuthnSignerSingleton ?? accountClass.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
8269
+ webAuthnSignerProxyCreationCode: webAuthnSignerProxyCreationCode ?? accountClass.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
8270
+ eip7212WebAuthnPrecompileVerifier: eip7212WebAuthnPrecompileVerifier ?? accountClass.DEFAULT_WEB_AUTHN_PRECOMPILE,
8271
+ eip7212WebAuthnContractVerifier: eip7212WebAuthnContractVerifier ?? accountClass.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
8272
+ }),
8273
+ type: "contract",
8274
+ signHash: async (hash) => {
8275
+ const assertion = await getAssertion((0, ethers.getBytes)(hash));
8276
+ return SafeAccount.createWebAuthnSignature(assertion);
8277
+ }
8278
+ };
8279
+ }
8280
+ /**
8281
+ * Coerce a `{ x, y }` pair where each coord may be `bigint`, hex string
8282
+ * (`"0x..."`), decimal string, or a safe-integer number into a canonical
8283
+ * {@link WebauthnPublicKey} with bigint coords. Used internally by
8284
+ * {@link pubkeyCoordinatesFromJson} — for non-JSON inputs (URL params,
8285
+ * RPC responses), pass the pre-parsed object straight to that helper.
8286
+ *
8287
+ * @throws if either coordinate is missing, the wrong type, or an
8288
+ * unparseable string.
8289
+ */
8290
+ function toBigintPubkey(pubkey) {
8291
+ if (!pubkey || pubkey.x == null || pubkey.y == null) throw new Error("toBigintPubkey: pubkey must be `{ x, y }` with both coords set");
8292
+ return {
8293
+ x: coerceBigint(pubkey.x, "x"),
8294
+ y: coerceBigint(pubkey.y, "y")
8295
+ };
8296
+ }
8297
+ function coerceBigint(v, field) {
8298
+ let coerced;
8299
+ if (typeof v === "bigint") coerced = v;
8300
+ else if (typeof v === "string") try {
8301
+ coerced = BigInt(v);
8302
+ } catch {
8303
+ throw new Error(`toBigintPubkey: pubkey.${field} ("${v}") is not a valid bigint string. Accepted: non-negative bigint, decimal string, or 0x-prefixed hex string.`);
8304
+ }
8305
+ else if (typeof v === "number") {
8306
+ if (!Number.isSafeInteger(v)) throw new Error(`toBigintPubkey: pubkey.${field} is a Number but not a safe integer. Pass as bigint or hex string to avoid precision loss.`);
8307
+ coerced = BigInt(v);
8308
+ } else throw new Error(`toBigintPubkey: pubkey.${field} must be bigint, string, or number (got ${typeof v})`);
8309
+ if (coerced < 0n) throw new Error(`toBigintPubkey: pubkey.${field} must be non-negative (got ${coerced.toString()}). P-256 coordinates are non-negative field elements; negative values aren't valid and would break canonical JSON round-trip serialization.`);
8310
+ return coerced;
8311
+ }
8312
+ /**
8313
+ * Serialize a WebAuthn pubkey to a JSON string with hex-encoded
8314
+ * coordinates. Inverse of {@link pubkeyCoordinatesFromJson}.
8315
+ *
8316
+ * Any JSON-string persistence — localStorage, backend indexes, query
8317
+ * strings, IPC payloads — eventually needs a custom replacer for
8318
+ * `bigint` (which `JSON.stringify` can't serialize on its own). This
8319
+ * helper ships the canonical version so the round-trip is consistent
8320
+ * across call sites.
8321
+ *
8322
+ * @example
8323
+ * ```ts
8324
+ * localStorage.setItem("passkey", pubkeyCoordinatesToJson({ x: 0x7a..., y: 0x2e... }));
8325
+ * // Stored as: {"x":"0x7a...","y":"0x2e..."}
8326
+ * ```
8327
+ */
8328
+ function pubkeyCoordinatesToJson(pubkey) {
8329
+ return JSON.stringify({
8330
+ x: "0x" + pubkey.x.toString(16),
8331
+ y: "0x" + pubkey.y.toString(16)
8332
+ });
8333
+ }
8334
+ /**
8335
+ * Parse a JSON string produced by {@link pubkeyCoordinatesToJson} (or
8336
+ * any JSON object with `x` / `y` fields as bigint-compatible values)
8337
+ * back into a {@link WebauthnPublicKey} with bigint coords.
8338
+ *
8339
+ * Lenient about input shape: accepts a JSON string, a pre-parsed object
8340
+ * (skip `JSON.parse` if you already ran it), and either hex (`"0x..."`)
8341
+ * or decimal-string coords. Same one-line cost regardless of where the
8342
+ * string came from — localStorage, backend response, query parameter.
8343
+ *
8344
+ * @example
8345
+ * ```ts
8346
+ * const raw = localStorage.getItem("passkey");
8347
+ * if (raw) {
8348
+ * const pubkey = pubkeyCoordinatesFromJson(raw);
8349
+ * // pubkey: { x: bigint, y: bigint }
8350
+ * }
8351
+ * ```
8352
+ */
8353
+ function pubkeyCoordinatesFromJson(input) {
8354
+ return toBigintPubkey(typeof input === "string" ? JSON.parse(input) : input);
8355
+ }
8356
+ /**
8357
+ * Turn a structural {@link AuthenticatorAssertionLike} into
8358
+ * {@link WebauthnSignatureData}, ready to feed straight into
8359
+ * `SafeAccount.createWebAuthnSignature` or the `getAssertion` callback
8360
+ * of `fromSafeWebauthn`.
8361
+ *
8362
+ * Replaces the ~13-line manual pipeline every Safe-passkeys consumer
8363
+ * has been writing — `JSON.parse` of `clientDataJSON`, destructure +
8364
+ * re-serialize the non-`type` / non-`challenge` fields, hex-encode,
8365
+ * normalize `authenticatorData`, parse DER signature → `(r, s)` —
8366
+ * with a single call.
8367
+ *
8368
+ * @example Browser:
8369
+ * ```ts
8370
+ * const assertion = await navigator.credentials.get({...});
8371
+ * return webauthnSignatureFromAssertion(assertion.response);
8372
+ * ```
8373
+ *
8374
+ * @example `ox/WebAuthnP256`:
8375
+ * ```ts
8376
+ * const { metadata, signature } = await sign({ challenge, credentialId });
8377
+ * return webauthnSignatureFromAssertion({
8378
+ * authenticatorData: metadata.authenticatorData, // hex string from ox
8379
+ * clientDataJSON: metadata.clientDataJSON, // string from ox
8380
+ * signature, // { r, s } from ox
8381
+ * });
8382
+ * ```
8383
+ */
8384
+ function webauthnSignatureFromAssertion(response) {
8385
+ const authenticatorData = toArrayBuffer(response.authenticatorData);
8386
+ const clientDataJSON = toUtf8String(response.clientDataJSON);
8387
+ const rs = toRSPair(response.signature);
8388
+ return {
8389
+ authenticatorData,
8390
+ clientDataFields: extractClientDataFieldsHex(clientDataJSON),
8391
+ rs: [rs.r, rs.s]
8392
+ };
8393
+ }
8394
+ function toArrayBuffer(input) {
8395
+ if (input instanceof ArrayBuffer) return input;
8396
+ const bytes = (0, ethers.getBytes)(input);
8397
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
8398
+ }
8399
+ function toUtf8String(input) {
8400
+ if (typeof input === "string") return input;
8401
+ const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
8402
+ return new TextDecoder("utf-8").decode(bytes);
8403
+ }
8404
+ function toRSPair(input) {
8405
+ if (input !== null && typeof input === "object" && "r" in input && "s" in input && typeof input.r === "bigint" && typeof input.s === "bigint") return {
8406
+ r: input.r,
8407
+ s: input.s
8408
+ };
8409
+ return parseDerP256Signature(input instanceof Uint8Array ? input : new Uint8Array(input));
8410
+ }
8411
+ /**
8412
+ * Re-serialize every clientDataJSON field except `type` and `challenge`.
8413
+ * Robust to authenticators adding or reordering keys (e.g. Safari's
8414
+ * `crossOrigin`, future WebAuthn L3 fields) — parses JSON instead of
8415
+ * using a regex, validates the shape is a plain object, and emits hex
8416
+ * via `TextEncoder` (browser-safe; `Buffer` isn't defined in Vite /
8417
+ * Rollup / esbuild bundles without a polyfill).
8418
+ */
8419
+ function extractClientDataFieldsHex(clientDataJSON) {
8420
+ let parsed;
8421
+ try {
8422
+ parsed = JSON.parse(clientDataJSON);
8423
+ } catch (err) {
8424
+ throw new Error(`webauthnSignatureFromAssertion: clientDataJSON is not valid JSON (${err.message})`);
8425
+ }
8426
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) throw new Error(`webauthnSignatureFromAssertion: clientDataJSON must parse to a plain object (got ${parsed === null ? "null" : Array.isArray(parsed) ? "array" : typeof parsed})`);
8427
+ const { type: _type, challenge: _challenge, ...rest } = parsed;
8428
+ const fields = Object.entries(rest).map(([key, value]) => `"${key}":${JSON.stringify(value)}`).join(",");
8429
+ return (0, ethers.hexlify)(new TextEncoder().encode(fields));
8430
+ }
8431
+ /**
8432
+ * Parse a DER-encoded ECDSA P-256 signature into `(r, s)` bigints with
8433
+ * low-S normalization. Defends against truncated / malformed DER: every
8434
+ * length and tag is bounds-checked against the buffer before slicing,
8435
+ * because `Uint8Array.subarray` silently clamps OOB indices and would
8436
+ * otherwise produce attacker-controlled-length r/s.
8437
+ *
8438
+ * DER layout:
8439
+ * 0x30 | total-len | 0x02 | r-len | r-bytes | 0x02 | s-len | s-bytes
8440
+ */
8441
+ function parseDerP256Signature(der) {
8442
+ const malformed = () => /* @__PURE__ */ new Error("webauthnSignatureFromAssertion: malformed DER signature");
8443
+ if (der.length < 8 || der[0] !== 48) throw malformed();
8444
+ const headerLen = der[1] === 129 ? 3 : 2;
8445
+ const outerLen = der[1] === 129 ? der[2] : der[1];
8446
+ if (der.length !== headerLen + outerLen) throw malformed();
8447
+ let offset = headerLen;
8448
+ if (offset + 2 > der.length) throw malformed();
8449
+ if (der[offset] !== 2) throw malformed();
8450
+ const rLen = der[offset + 1];
8451
+ if (rLen <= 0 || offset + 2 + rLen > der.length) throw malformed();
8452
+ const rBytes = der.subarray(offset + 2, offset + 2 + rLen);
8453
+ offset += 2 + rLen;
8454
+ if (offset + 2 > der.length) throw malformed();
8455
+ if (der[offset] !== 2) throw malformed();
8456
+ const sLen = der[offset + 1];
8457
+ if (sLen <= 0 || offset + 2 + sLen > der.length) throw malformed();
8458
+ const sBytes = der.subarray(offset + 2, offset + 2 + sLen);
8459
+ if (offset + 2 + sLen !== der.length) throw malformed();
8460
+ const r = rBytes.length === 0 ? 0n : BigInt((0, ethers.hexlify)(rBytes));
8461
+ let s = sBytes.length === 0 ? 0n : BigInt((0, ethers.hexlify)(sBytes));
8462
+ const P256_N = 115792089210356248762697446949407573529996955224135760342422259061068512044369n;
8463
+ const P256_N_HALF = P256_N >> 1n;
8464
+ if (s > P256_N_HALF) s = P256_N - s;
8465
+ return {
8466
+ r,
8467
+ s
8468
+ };
8469
+ }
8470
+ //#endregion
7939
8471
  //#region src/signer/adapters.ts
7940
8472
  /**
7941
8473
  * Build a Signer from a raw private-key hex string. Supports both raw-hash
@@ -8074,6 +8606,7 @@ var abstractionkit = (function(exports, ethers) {
8074
8606
  fetchGasPrice: () => fetchGasPrice,
8075
8607
  fromEthersWallet: () => fromEthersWallet,
8076
8608
  fromPrivateKey: () => fromPrivateKey,
8609
+ fromSafeWebauthn: () => fromSafeWebauthn,
8077
8610
  fromViem: () => fromViem,
8078
8611
  fromViemWalletClient: () => fromViemWalletClient,
8079
8612
  getBalanceOf: () => getBalanceOf,
@@ -8081,6 +8614,8 @@ var abstractionkit = (function(exports, ethers) {
8081
8614
  getDepositInfo: () => getDepositInfo,
8082
8615
  getFunctionSelector: () => getFunctionSelector,
8083
8616
  getSafeMessageEip712Data: () => getSafeMessageEip712Data,
8617
+ pubkeyCoordinatesFromJson: () => pubkeyCoordinatesFromJson,
8618
+ pubkeyCoordinatesToJson: () => pubkeyCoordinatesToJson,
8084
8619
  sendJsonRpcRequest: () => sendJsonRpcRequest,
8085
8620
  shareTenderlySimulationAndCreateLink: () => shareTenderlySimulationAndCreateLink,
8086
8621
  signHash: () => signHash,
@@ -8089,7 +8624,8 @@ var abstractionkit = (function(exports, ethers) {
8089
8624
  simulateUserOperationCallDataWithTenderly: () => simulateUserOperationCallDataWithTenderly,
8090
8625
  simulateUserOperationCallDataWithTenderlyAndCreateShareLink: () => simulateUserOperationCallDataWithTenderlyAndCreateShareLink,
8091
8626
  simulateUserOperationWithTenderly: () => simulateUserOperationWithTenderly,
8092
- simulateUserOperationWithTenderlyAndCreateShareLink: () => simulateUserOperationWithTenderlyAndCreateShareLink
8627
+ simulateUserOperationWithTenderlyAndCreateShareLink: () => simulateUserOperationWithTenderlyAndCreateShareLink,
8628
+ webauthnSignatureFromAssertion: () => webauthnSignatureFromAssertion
8093
8629
  });
8094
8630
  //#endregion
8095
8631
  exports.ALLOWANCE_MODULE_V0_1_0_ADDRESS = ALLOWANCE_MODULE_V0_1_0_ADDRESS;
@@ -8158,6 +8694,7 @@ var abstractionkit = (function(exports, ethers) {
8158
8694
  exports.fetchGasPrice = fetchGasPrice;
8159
8695
  exports.fromEthersWallet = fromEthersWallet;
8160
8696
  exports.fromPrivateKey = fromPrivateKey;
8697
+ exports.fromSafeWebauthn = fromSafeWebauthn;
8161
8698
  exports.fromViem = fromViem;
8162
8699
  exports.fromViemWalletClient = fromViemWalletClient;
8163
8700
  exports.getBalanceOf = getBalanceOf;
@@ -8165,6 +8702,8 @@ var abstractionkit = (function(exports, ethers) {
8165
8702
  exports.getDepositInfo = getDepositInfo;
8166
8703
  exports.getFunctionSelector = getFunctionSelector;
8167
8704
  exports.getSafeMessageEip712Data = getSafeMessageEip712Data;
8705
+ exports.pubkeyCoordinatesFromJson = pubkeyCoordinatesFromJson;
8706
+ exports.pubkeyCoordinatesToJson = pubkeyCoordinatesToJson;
8168
8707
  exports.sendJsonRpcRequest = sendJsonRpcRequest;
8169
8708
  exports.shareTenderlySimulationAndCreateLink = shareTenderlySimulationAndCreateLink;
8170
8709
  exports.signHash = signHash;
@@ -8174,5 +8713,6 @@ var abstractionkit = (function(exports, ethers) {
8174
8713
  exports.simulateUserOperationCallDataWithTenderlyAndCreateShareLink = simulateUserOperationCallDataWithTenderlyAndCreateShareLink;
8175
8714
  exports.simulateUserOperationWithTenderly = simulateUserOperationWithTenderly;
8176
8715
  exports.simulateUserOperationWithTenderlyAndCreateShareLink = simulateUserOperationWithTenderlyAndCreateShareLink;
8716
+ exports.webauthnSignatureFromAssertion = webauthnSignatureFromAssertion;
8177
8717
  return exports;
8178
8718
  })({}, ethers);