abstractionkit 0.3.4 → 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";
@@ -3189,7 +3218,7 @@ var abstractionkit = (function(exports, ethers) {
3189
3218
  */
3190
3219
  static createAccountAddressAndFactoryAddressAndData(owners, overrides, safe4337ModuleAddress, safeModuleSetupAddress) {
3191
3220
  if (owners.length < 1) throw new RangeError("There should be at least one owner");
3192
- 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);
3193
3222
  let safeAccountFactory;
3194
3223
  if (overrides.safeAccountFactoryAddress != null) safeAccountFactory = new SafeAccountFactory(overrides.safeAccountFactoryAddress);
3195
3224
  else safeAccountFactory = new SafeAccountFactory();
@@ -3211,7 +3240,7 @@ var abstractionkit = (function(exports, ethers) {
3211
3240
  factoryGeneratorFunctionCallData
3212
3241
  ];
3213
3242
  }
3214
- 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) {
3215
3244
  if (owners.length < 1) throw new RangeError("There should be at least one owner");
3216
3245
  if (threshold < 1) throw new RangeError("threshold should be at least one");
3217
3246
  if (threshold > owners.length) throw new RangeError("threshold can't be larger than number of owners");
@@ -3287,7 +3316,7 @@ var abstractionkit = (function(exports, ethers) {
3287
3316
  if (threshold < 1) throw new RangeError("threshold should be at least one");
3288
3317
  if (threshold > owners.length) throw new RangeError("threshold can't be larger than number of owners");
3289
3318
  if (c2Nonce < 0n) throw new RangeError("c2Nonce can't be negative");
3290
- 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);
3291
3320
  let safeAccountFactory;
3292
3321
  if (overrides.safeAccountFactoryAddress != null) safeAccountFactory = new SafeAccountFactory(overrides.safeAccountFactoryAddress);
3293
3322
  else safeAccountFactory = new SafeAccountFactory();
@@ -3349,9 +3378,7 @@ var abstractionkit = (function(exports, ethers) {
3349
3378
  eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier,
3350
3379
  webAuthnSignerFactory: overrides.webAuthnSignerFactory,
3351
3380
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton,
3352
- webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode,
3353
- validAfter,
3354
- validUntil
3381
+ webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode
3355
3382
  });
3356
3383
  userOperation.signature = SafeAccount.formatSignaturesToUseroperationSignature(dummySignerSignaturePairs, {
3357
3384
  validAfter,
@@ -3418,7 +3445,7 @@ var abstractionkit = (function(exports, ethers) {
3418
3445
  maxFeePerGas = overrides.maxFeePerGas ?? maxFeePerGas * BigInt((overrides.maxFeePerGasPercentageMultiplier ?? 0) + 100) / 100n;
3419
3446
  maxPriorityFeePerGas = overrides.maxPriorityFeePerGas ?? maxPriorityFeePerGas * BigInt((overrides.maxPriorityFeePerGasPercentageMultiplier ?? 0) + 100) / 100n;
3420
3447
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3421
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3448
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3422
3449
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3423
3450
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3424
3451
  const webAuthnSignerProxyCreationCode = overrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -3493,16 +3520,14 @@ var abstractionkit = (function(exports, ethers) {
3493
3520
  eip7212WebAuthnContractVerifier,
3494
3521
  webAuthnSignerFactory,
3495
3522
  webAuthnSignerSingleton,
3496
- webAuthnSignerProxyCreationCode,
3497
- validAfter,
3498
- validUntil
3523
+ webAuthnSignerProxyCreationCode
3499
3524
  });
3500
3525
  }
3501
3526
  userOperation.signature = SafeAccount.formatSignaturesToUseroperationSignature(dummySignerSignaturePairs, {
3502
3527
  validAfter,
3503
3528
  validUntil,
3504
- webAuthnSharedSigner,
3505
- isMultiChainSignature: overrides.isMultiChainSignature
3529
+ isMultiChainSignature: overrides.isMultiChainSignature,
3530
+ webAuthnSharedSigner
3506
3531
  });
3507
3532
  if (!(overrides.skipGasEstimation ?? false) && (overrides.preVerificationGas == null || overrides.verificationGasLimit == null || overrides.callGasLimit == null)) if (bundlerRpc != null) {
3508
3533
  userOperation.callGasLimit = 0n;
@@ -3569,14 +3594,15 @@ var abstractionkit = (function(exports, ethers) {
3569
3594
  * @param useroperation - useroperation to sign
3570
3595
  * @param privateKeys - for the signers
3571
3596
  * @param chainId - target chain id
3572
- * @param overrides - overrides for the default values
3573
- * @param overrides.validAfter - timestamp the signature will be valid after
3574
- * @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}
3575
3600
  * @returns signature
3576
3601
  */
3577
- static baseSignSingleUserOperation(useroperation, privateKeys, chainId, entrypointAddress, safe4337ModuleAddress, overrides = {}) {
3578
- const validAfter = overrides.validAfter ?? 0n;
3579
- 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;
3580
3606
  if (privateKeys.length < 1) throw new RangeError("There should be at least one privateKey");
3581
3607
  if (chainId < 0n) throw new RangeError("chainId can't be negative");
3582
3608
  if (validAfter < 0n) throw new RangeError("validAfter can't be negative");
@@ -3585,7 +3611,7 @@ var abstractionkit = (function(exports, ethers) {
3585
3611
  validAfter,
3586
3612
  validUntil,
3587
3613
  entrypointAddress,
3588
- safe4337ModuleAddress
3614
+ safe4337ModuleAddress: moduleAddress
3589
3615
  });
3590
3616
  const signerSignaturePairs = [];
3591
3617
  for (const privateKey of privateKeys) {
@@ -3597,9 +3623,9 @@ var abstractionkit = (function(exports, ethers) {
3597
3623
  });
3598
3624
  }
3599
3625
  return SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
3626
+ ...options,
3600
3627
  validAfter,
3601
- validUntil,
3602
- isMultiChainSignature: overrides.isMultiChainSignature
3628
+ validUntil
3603
3629
  });
3604
3630
  }
3605
3631
  /**
@@ -3622,20 +3648,24 @@ var abstractionkit = (function(exports, ethers) {
3622
3648
  * @param useroperation - UserOperation to sign
3623
3649
  * @param signers - Signer instances (`fromViem(account)`, `fromEthersWallet(wallet)`, etc.)
3624
3650
  * @param chainId - target chain id
3625
- * @param entrypointAddress - target EntryPoint
3626
- * @param safe4337ModuleAddress - Safe 4337 module
3627
- * @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}.
3628
3656
  * @returns formatted signature
3629
3657
  */
3630
- static async baseSignUserOperationWithSigners(useroperation, signers, chainId, entrypointAddress, safe4337ModuleAddress, context, overrides = {}) {
3631
- const validAfter = overrides.validAfter ?? 0n;
3632
- 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;
3633
3663
  if (signers.length < 1) throw new RangeError("There should be at least one signer");
3634
3664
  const typedDataRaw = SafeAccount.getUserOperationEip712Data(useroperation, chainId, {
3635
3665
  validAfter,
3636
3666
  validUntil,
3637
3667
  entrypointAddress,
3638
- safe4337ModuleAddress
3668
+ safe4337ModuleAddress: moduleAddress
3639
3669
  });
3640
3670
  const userOpHash = ethers.TypedDataEncoder.hash(typedDataRaw.domain, typedDataRaw.types, typedDataRaw.messageValue);
3641
3671
  const { EIP712Domain: _drop, ...primaryTypes } = typedDataRaw.types;
@@ -3656,12 +3686,13 @@ var abstractionkit = (function(exports, ethers) {
3656
3686
  context
3657
3687
  })))).map((signature, i) => ({
3658
3688
  signer: normalizedAddresses[i],
3659
- signature
3689
+ signature,
3690
+ isContractSignature: signers[i].type === "contract"
3660
3691
  }));
3661
3692
  return SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
3693
+ ...options,
3662
3694
  validAfter,
3663
- validUntil,
3664
- isMultiChainSignature: overrides.isMultiChainSignature
3695
+ validUntil
3665
3696
  });
3666
3697
  }
3667
3698
  /**
@@ -3674,7 +3705,7 @@ var abstractionkit = (function(exports, ethers) {
3674
3705
  */
3675
3706
  static createWebAuthnSignerVerifierAddress(x, y, overrides = {}) {
3676
3707
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3677
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3708
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3678
3709
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3679
3710
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3680
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____");
@@ -3705,15 +3736,15 @@ var abstractionkit = (function(exports, ethers) {
3705
3736
  /**
3706
3737
  * format a list of eip712 signatures to a useroperation signature
3707
3738
  * @param signerSignaturePairs - a list of a pair of a signer and it's signature
3708
- * @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.
3709
3740
  * @returns signature
3710
3741
  */
3711
- static formatSignaturesToUseroperationSignature(signerSignaturePairs, overrides = {}) {
3712
- const validAfter = overrides.validAfter ?? 0n;
3713
- const validUntil = overrides.validUntil ?? 0n;
3714
- const signature = SafeAccount.buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, overrides);
3715
- if (overrides.isMultiChainSignature) if (overrides.multiChainMerkleProof != null) {
3716
- 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;
3717
3748
  if (merkleProofLength < 128 || merkleProofLength % 64 !== 0) throw new RangeError("invalid multiChainMerkleProof length.");
3718
3749
  let merkleTreeDepthHex = (merkleProofLength / 64 - 1).toString(16);
3719
3750
  if (merkleTreeDepthHex.length % 2 === 0) merkleTreeDepthHex = `0x${merkleTreeDepthHex}`;
@@ -3727,7 +3758,7 @@ var abstractionkit = (function(exports, ethers) {
3727
3758
  merkleTreeDepthHex,
3728
3759
  validAfter,
3729
3760
  validUntil,
3730
- overrides.multiChainMerkleProof + signature.slice(2)
3761
+ options.multiChainMerkleProof + signature.slice(2)
3731
3762
  ]);
3732
3763
  } else return (0, ethers.solidityPacked)([
3733
3764
  "bytes1",
@@ -3760,7 +3791,7 @@ var abstractionkit = (function(exports, ethers) {
3760
3791
  if (typeof signer === "string") return signer.toLowerCase();
3761
3792
  else {
3762
3793
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3763
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3794
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3764
3795
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3765
3796
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3766
3797
  const webAuthnSignerProxyCreationCode = overrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -3786,7 +3817,7 @@ var abstractionkit = (function(exports, ethers) {
3786
3817
  /**
3787
3818
  * format a list of eip712 signatures to a safe signature (without the time range)
3788
3819
  * @param signerSignaturePairs - a list of a pair of a signer and it's signature
3789
- * @param overrides - overrides for the default values
3820
+ * @param webAuthnSignatureOverrides - WebAuthn-only configuration (verifier addresses, init flag)
3790
3821
  * @returns signature
3791
3822
  */
3792
3823
  static buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, webAuthnSignatureOverrides = {}) {
@@ -3800,7 +3831,7 @@ var abstractionkit = (function(exports, ethers) {
3800
3831
  if (webAuthnSignatureOverrides.isInit) signer = webAuthnSignatureOverrides.webAuthnSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER;
3801
3832
  else {
3802
3833
  const eip7212WebAuthnPrecompileVerifier = webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3803
- const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3834
+ const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3804
3835
  const webAuthnSignerFactory = webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3805
3836
  const webAuthnSignerSingleton = webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3806
3837
  const webAuthnSignerProxyCreationCode = webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -4071,7 +4102,7 @@ var abstractionkit = (function(exports, ethers) {
4071
4102
  */
4072
4103
  static createDeployWebAuthnVerifierMetaTransaction(x, y, overrides = {}) {
4073
4104
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4074
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4105
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4075
4106
  return {
4076
4107
  to: overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
4077
4108
  value: 0n,
@@ -4173,7 +4204,7 @@ var abstractionkit = (function(exports, ethers) {
4173
4204
  signerSignaturePair.signer = webauthnsharedsigner;
4174
4205
  } else {
4175
4206
  const eip7212WebAuthnPrecompileVerifier = webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4176
- const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4207
+ const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4177
4208
  const webAuthnSignerFactory = webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
4178
4209
  const webAuthnSignerSingleton = webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
4179
4210
  const webAuthnSignerProxyCreationCode = webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -4207,7 +4238,7 @@ var abstractionkit = (function(exports, ethers) {
4207
4238
  static async verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, overrides = {}) {
4208
4239
  if (messageHash.length !== 66 || messageHash.slice(0, 2) !== "0x") throw new RangeError("Invalid messageHash, must be a 0x-prefixed keccak256 hash.");
4209
4240
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4210
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4241
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4211
4242
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
4212
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____");
4213
4244
  const callData = createCallData("0x1626ba7e", ["bytes32", "bytes"], [messageHash, signature]);
@@ -4337,7 +4368,7 @@ var abstractionkit = (function(exports, ethers) {
4337
4368
  * @param toolVersion - tool version; defaults to the current abstractionkit version
4338
4369
  * @returns the on-chain identifier as a hex string (not 0x prefixed)
4339
4370
  */
4340
- function generateOnChainIdentifier(project, platform = "Web", tool = "abstractionkit", toolVersion = "0.3.4") {
4371
+ function generateOnChainIdentifier(project, platform = "Web", tool = "abstractionkit", toolVersion = "0.3.5") {
4341
4372
  const identifierPrefix = "5afe";
4342
4373
  const identifierVersion = "00";
4343
4374
  const projectHash = (0, ethers.keccak256)(`0x${Buffer.from(project, "utf8").toString("hex")}`).slice(-20);
@@ -5341,15 +5372,15 @@ var abstractionkit = (function(exports, ethers) {
5341
5372
  * @param useroperation - The UserOperation to sign
5342
5373
  * @param privateKeys - Array of private keys for the signers
5343
5374
  * @param chainId - The target chain ID
5344
- * @param overrides - Override validAfter and validUntil timestamps
5375
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5345
5376
  * @returns The formatted signature string ready to set on the UserOperation
5346
5377
  *
5347
5378
  * @example
5348
5379
  * const signature = smartAccount.signUserOperation(userOp, [privateKey], 1n);
5349
5380
  * userOp.signature = signature;
5350
5381
  */
5351
- signUserOperation(useroperation, privateKeys, chainId, overrides = {}) {
5352
- 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);
5353
5384
  }
5354
5385
  /**
5355
5386
  * Sign a UserOperation with one or more {@link ExternalSigner} instances
@@ -5371,16 +5402,21 @@ var abstractionkit = (function(exports, ethers) {
5371
5402
  * @param useroperation - UserOperation to sign
5372
5403
  * @param signers - one ExternalSigner per owner (any order)
5373
5404
  * @param chainId - target chain ID
5374
- * @param overrides - optional validAfter / validUntil / multi-chain flag
5405
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5375
5406
  * @returns Promise resolving to the formatted signature string
5376
5407
  */
5377
- signUserOperationWithSigners(useroperation, signers, chainId, overrides = {}) {
5408
+ signUserOperationWithSigners(useroperation, signers, chainId, options = {}) {
5378
5409
  const context = {
5379
5410
  userOperation: useroperation,
5380
5411
  chainId,
5381
5412
  entryPoint: this.entrypointAddress
5382
5413
  };
5383
- 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
+ });
5384
5420
  }
5385
5421
  };
5386
5422
  //#endregion
@@ -5623,28 +5659,39 @@ var abstractionkit = (function(exports, ethers) {
5623
5659
  * @param useroperation - The UserOperation to sign
5624
5660
  * @param privateKeys - Array of private keys for the signers
5625
5661
  * @param chainId - The target chain ID
5626
- * @param overrides - Override validAfter and validUntil timestamps
5662
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5627
5663
  * @returns The formatted signature string ready to set on the UserOperation
5628
5664
  *
5629
5665
  * @example
5630
5666
  * const signature = smartAccount.signUserOperation(userOp, [privateKey], 1n);
5631
5667
  * userOp.signature = signature;
5632
5668
  */
5633
- signUserOperation(useroperation, privateKeys, chainId, overrides = {}) {
5634
- 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);
5635
5671
  }
5636
5672
  /**
5637
5673
  * Sign a UserOperation using one or more {@link AkSigner} instances.
5638
5674
  * See {@link SafeAccountV0_3_0.signUserOperationWithSigners} for full
5639
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
5640
5682
  */
5641
- signUserOperationWithSigners(useroperation, signers, chainId, overrides = {}) {
5683
+ signUserOperationWithSigners(useroperation, signers, chainId, options = {}) {
5642
5684
  const context = {
5643
5685
  userOperation: useroperation,
5644
5686
  chainId,
5645
5687
  entryPoint: this.entrypointAddress
5646
5688
  };
5647
- 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
+ });
5648
5695
  }
5649
5696
  };
5650
5697
  //#endregion
@@ -5663,6 +5710,7 @@ var abstractionkit = (function(exports, ethers) {
5663
5710
  var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAccountV0_3_0 {
5664
5711
  static DEFAULT_WEB_AUTHN_PRECOMPILE = "0x0000000000000000000000000000000000000100";
5665
5712
  static DEFAULT_WEB_AUTHN_DAIMO_VERIFIER = "0xc2b78104907F722DABAc4C69f826a522B2754De4";
5713
+ static DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER = "0xc2b78104907F722DABAc4C69f826a522B2754De4";
5666
5714
  /**
5667
5715
  * Create a SafeAccountV1_5_0_M_0_3_0 instance for an existing deployed account.
5668
5716
  * For new (undeployed) accounts, use the static `initializeNewAccount` method instead.
@@ -5711,7 +5759,7 @@ var abstractionkit = (function(exports, ethers) {
5711
5759
  ...overrides,
5712
5760
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5713
5761
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5714
- 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
5715
5763
  };
5716
5764
  return SafeAccountV0_3_0.initializeNewAccount(owners, modOverrides);
5717
5765
  }
@@ -5728,7 +5776,7 @@ var abstractionkit = (function(exports, ethers) {
5728
5776
  ...overrides,
5729
5777
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5730
5778
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5731
- 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
5732
5780
  };
5733
5781
  return SafeAccountV0_3_0.createAccountAddress(owners, modOverrides);
5734
5782
  }
@@ -5745,7 +5793,7 @@ var abstractionkit = (function(exports, ethers) {
5745
5793
  ...overrides,
5746
5794
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5747
5795
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5748
- 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
5749
5797
  };
5750
5798
  return SafeAccountV0_3_0.createFactoryAddressAndData(owners, modOverrides);
5751
5799
  }
@@ -5763,7 +5811,7 @@ var abstractionkit = (function(exports, ethers) {
5763
5811
  return super.createUserOperation(transactions, providerRpc, bundlerRpc, {
5764
5812
  ...overrides,
5765
5813
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5766
- 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
5767
5815
  });
5768
5816
  }
5769
5817
  /**
@@ -5778,7 +5826,7 @@ var abstractionkit = (function(exports, ethers) {
5778
5826
  return super.estimateUserOperationGas(userOperation, bundlerRpc, {
5779
5827
  ...overrides,
5780
5828
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5781
- 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
5782
5830
  });
5783
5831
  }
5784
5832
  /**
@@ -5794,7 +5842,7 @@ var abstractionkit = (function(exports, ethers) {
5794
5842
  return SafeAccount.createWebAuthnSignerVerifierAddress(x, y, {
5795
5843
  ...overrides,
5796
5844
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5797
- 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
5798
5846
  });
5799
5847
  }
5800
5848
  /**
@@ -5810,7 +5858,7 @@ var abstractionkit = (function(exports, ethers) {
5810
5858
  return SafeAccount.createDeployWebAuthnVerifierMetaTransaction(x, y, {
5811
5859
  ...overrides,
5812
5860
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5813
- 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
5814
5862
  });
5815
5863
  }
5816
5864
  /**
@@ -5824,7 +5872,7 @@ var abstractionkit = (function(exports, ethers) {
5824
5872
  return SafeAccount.createDummySignerSignaturePairForExpectedSigners(expectedSigners, {
5825
5873
  ...webAuthnSignatureOverrides,
5826
5874
  eip7212WebAuthnPrecompileVerifier: webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5827
- 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
5828
5876
  });
5829
5877
  }
5830
5878
  /**
@@ -5842,7 +5890,7 @@ var abstractionkit = (function(exports, ethers) {
5842
5890
  return SafeAccount.verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, {
5843
5891
  ...overrides,
5844
5892
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5845
- 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
5846
5894
  });
5847
5895
  }
5848
5896
  };
@@ -5936,6 +5984,7 @@ var abstractionkit = (function(exports, ethers) {
5936
5984
  static DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE = DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE_V_0_2_1;
5937
5985
  static DEFAULT_WEB_AUTHN_PRECOMPILE = DEFAULT_WEB_AUTHN_PRECOMPILE_RIP_7951;
5938
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;
5939
5988
  /**
5940
5989
  * Create a SafeMultiChainSigAccount instance for an existing or new account.
5941
5990
  * @param accountAddress - the Safe account address
@@ -5961,7 +6010,7 @@ var abstractionkit = (function(exports, ethers) {
5961
6010
  ...overrides,
5962
6011
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
5963
6012
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
5964
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6013
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5965
6014
  };
5966
6015
  const [accountAddress, ,] = SafeAccount.createAccountAddressAndFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
5967
6016
  return accountAddress;
@@ -5991,7 +6040,7 @@ var abstractionkit = (function(exports, ethers) {
5991
6040
  ...overrides,
5992
6041
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
5993
6042
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
5994
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6043
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5995
6044
  };
5996
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);
5997
6046
  const safe = new SafeMultiChainSigAccountV1(accountAddress, {
@@ -6068,7 +6117,7 @@ var abstractionkit = (function(exports, ethers) {
6068
6117
  static createInitializerCallData(owners, threshold, overrides = {}) {
6069
6118
  const safe4337ModuleAddress = overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS;
6070
6119
  const safeModuleSetupAddress = overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS;
6071
- 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);
6072
6121
  }
6073
6122
  /**
6074
6123
  * create account factory address and factory data
@@ -6081,7 +6130,7 @@ var abstractionkit = (function(exports, ethers) {
6081
6130
  ...overrides,
6082
6131
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
6083
6132
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6084
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6133
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
6085
6134
  };
6086
6135
  return SafeAccount.createFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
6087
6136
  }
@@ -6103,7 +6152,7 @@ var abstractionkit = (function(exports, ethers) {
6103
6152
  isMultiChainSignature: true,
6104
6153
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
6105
6154
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6106
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6155
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6107
6156
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6108
6157
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6109
6158
  webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE
@@ -6131,14 +6180,13 @@ var abstractionkit = (function(exports, ethers) {
6131
6180
  * @param useroperation - useroperation to sign
6132
6181
  * @param privateKeys - for the signers
6133
6182
  * @param chainId - target chain id
6134
- * @param overrides - overrides for the default values
6135
- * @param overrides.validAfter - timestamp the signature will be valid after
6136
- * @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.
6137
6184
  * @returns signature
6138
6185
  */
6139
- 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");
6140
6188
  return SafeAccount.baseSignSingleUserOperation(userOperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, {
6141
- ...overrides,
6189
+ ...options,
6142
6190
  isMultiChainSignature: true
6143
6191
  });
6144
6192
  }
@@ -6147,16 +6195,28 @@ var abstractionkit = (function(exports, ethers) {
6147
6195
  * {@link AkSigner} instances. See
6148
6196
  * {@link SafeAccountV0_3_0.signUserOperationWithSigners} for the full
6149
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
6150
6204
  */
6151
- 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");
6152
6207
  const context = {
6153
6208
  userOperation,
6154
6209
  chainId,
6155
6210
  entryPoint: this.entrypointAddress
6156
6211
  };
6157
- return SafeAccount.baseSignUserOperationWithSigners(userOperation, signers, chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, {
6158
- ...overrides,
6159
- 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
+ }
6160
6220
  });
6161
6221
  }
6162
6222
  /**
@@ -6277,10 +6337,15 @@ var abstractionkit = (function(exports, ethers) {
6277
6337
  return userOpSignatures;
6278
6338
  } else {
6279
6339
  const u = userOperationsToSign[0];
6280
- return [await SafeAccount.baseSignUserOperationWithSigners(u.userOperation, signers, u.chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, {
6281
- validAfter: u.validAfter,
6282
- validUntil: u.validUntil,
6283
- 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
+ }
6284
6349
  })];
6285
6350
  }
6286
6351
  }
@@ -6330,28 +6395,34 @@ var abstractionkit = (function(exports, ethers) {
6330
6395
  */
6331
6396
  static formatSignaturesToUseroperationsSignatures(userOperationsToSign, signerSignaturePairs) {
6332
6397
  if (userOperationsToSign.length < 1) throw new RangeError("There should be at least one userOperationsToSign");
6333
- const defaultOverrides = {
6398
+ const defaultWebAuthnOverrides = {
6334
6399
  eip7212WebAuthnPrecompileVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6335
- eip7212WebAuthnContractVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6400
+ eip7212WebAuthnContractVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6336
6401
  webAuthnSignerFactory: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6337
6402
  webAuthnSignerSingleton: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6338
6403
  webAuthnSignerProxyCreationCode: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
6339
- safe4337ModuleAddress: SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS,
6340
6404
  webAuthnSharedSigner: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER
6341
6405
  };
6406
+ const defaultOptions = { safe4337ModuleAddress: SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS };
6342
6407
  if (userOperationsToSign.length === 1) return [SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
6343
- ...defaultOverrides,
6344
- ...userOperationsToSign[0].overrides,
6408
+ ...defaultOptions,
6409
+ ...defaultWebAuthnOverrides,
6410
+ ...userOperationsToSign[0].options,
6411
+ ...userOperationsToSign[0].webAuthnSignatureOverrides,
6345
6412
  validAfter: userOperationsToSign[0].validAfter,
6346
6413
  validUntil: userOperationsToSign[0].validUntil,
6347
6414
  isMultiChainSignature: true
6348
6415
  })];
6349
6416
  const userOperationsHashes = [];
6350
- 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) => {
6351
6422
  const userOperationHash = SafeAccount.getUserOperationEip712Hash_V9(userOperationToSign.userOperation, userOperationToSign.chainId, {
6352
- validAfter: userOperationToSign.validAfter,
6353
- validUntil: userOperationToSign.validUntil,
6354
- safe4337ModuleAddress: userOperationToSign.overrides?.safe4337ModuleAddress ?? defaultOverrides.safe4337ModuleAddress
6423
+ validAfter: resolvedValidity[index].validAfter,
6424
+ validUntil: resolvedValidity[index].validUntil,
6425
+ safe4337ModuleAddress: userOperationToSign.options?.safe4337ModuleAddress ?? defaultOptions.safe4337ModuleAddress
6355
6426
  });
6356
6427
  userOperationsHashes.push(userOperationHash);
6357
6428
  });
@@ -6359,8 +6430,12 @@ var abstractionkit = (function(exports, ethers) {
6359
6430
  const userOpSignatures = [];
6360
6431
  userOperationsToSign.forEach((userOperationToSign, index) => {
6361
6432
  userOpSignatures.push(SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
6362
- ...defaultOverrides,
6363
- ...userOperationToSign.overrides,
6433
+ ...defaultOptions,
6434
+ ...defaultWebAuthnOverrides,
6435
+ ...userOperationToSign.options,
6436
+ ...userOperationToSign.webAuthnSignatureOverrides,
6437
+ validAfter: resolvedValidity[index].validAfter,
6438
+ validUntil: resolvedValidity[index].validUntil,
6364
6439
  isMultiChainSignature: true,
6365
6440
  multiChainMerkleProof: proofs[index]
6366
6441
  }));
@@ -6371,7 +6446,7 @@ var abstractionkit = (function(exports, ethers) {
6371
6446
  return SafeAccount.createWebAuthnSignerVerifierAddress(x, y, {
6372
6447
  ...overrides,
6373
6448
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6374
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6449
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6375
6450
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6376
6451
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6377
6452
  webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE
@@ -6381,7 +6456,7 @@ var abstractionkit = (function(exports, ethers) {
6381
6456
  return SafeAccount.createDeployWebAuthnVerifierMetaTransaction(x, y, {
6382
6457
  ...overrides,
6383
6458
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6384
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6459
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6385
6460
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY
6386
6461
  });
6387
6462
  }
@@ -6389,7 +6464,7 @@ var abstractionkit = (function(exports, ethers) {
6389
6464
  return SafeAccount.createDummySignerSignaturePairForExpectedSigners(expectedSigners, {
6390
6465
  ...webAuthnSignatureOverrides,
6391
6466
  eip7212WebAuthnPrecompileVerifier: webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6392
- eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6467
+ eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6393
6468
  webAuthnSignerFactory: webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6394
6469
  webAuthnSignerSingleton: webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6395
6470
  webAuthnSignerProxyCreationCode: webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
@@ -6400,7 +6475,7 @@ var abstractionkit = (function(exports, ethers) {
6400
6475
  return SafeAccount.verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, {
6401
6476
  ...overrides,
6402
6477
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6403
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6478
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6404
6479
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON
6405
6480
  });
6406
6481
  }
@@ -6738,27 +6813,139 @@ var abstractionkit = (function(exports, ethers) {
6738
6813
  return new ethers.Wallet(privateKey).signingKey.sign(userOperationHash).serialized;
6739
6814
  }
6740
6815
  /**
6741
- * Schemes Simple7702 accepts from a Signer. Only raw-hash ECDSA, since
6742
- * 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.
6743
6828
  */
6744
- static ACCEPTED_SIGNING_SCHEMES = ["hash"];
6829
+ static ACCEPTED_SIGNING_SCHEMES = ["typedData", "hash"];
6745
6830
  /**
6746
- * Sign a UserOperation with an {@link AkSigner}. Signer must implement
6747
- * `signHash`, since Simple7702 only verifies raw ECDSA over the userOp
6748
- * hash. JSON-RPC wallets and anything that only provides `signTypedData`
6749
- * 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.
6750
6933
  */
6751
6934
  async baseSignUserOperationWithSigner(useroperation, signer, chainId) {
6752
- return invokeSigner(signer, pickScheme(signer, BaseSimple7702Account.ACCEPTED_SIGNING_SCHEMES, {
6753
- 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)",
6754
6937
  signerIndex: 0
6755
- }), {
6756
- hash: createUserOperationHash(useroperation, this.entrypointAddress, chainId),
6757
- context: {
6758
- userOperation: useroperation,
6759
- chainId,
6760
- entryPoint: this.entrypointAddress
6761
- }
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
6762
6949
  });
6763
6950
  }
6764
6951
  /**
@@ -6872,13 +7059,34 @@ var abstractionkit = (function(exports, ethers) {
6872
7059
  return this.baseSignUserOperation(useroperation, privateKey, chainId);
6873
7060
  }
6874
7061
  /**
6875
- * Sign a {@link UserOperationV8} using an {@link ExternalSigner}.
6876
- * Simple7702 only accepts raw-hash ECDSA; signers without `signHash`
6877
- * 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
+ * ```
6878
7081
  *
6879
7082
  * For signing with a raw private-key string, use the sync
6880
7083
  * {@link signUserOperation} method, or wrap explicitly with
6881
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).
6882
7090
  */
6883
7091
  async signUserOperationWithSigner(useroperation, signer, chainId) {
6884
7092
  return this.baseSignUserOperationWithSigner(useroperation, signer, chainId);
@@ -6949,10 +7157,33 @@ var abstractionkit = (function(exports, ethers) {
6949
7157
  return this.baseSignUserOperation(useroperation, privateKey, chainId);
6950
7158
  }
6951
7159
  /**
6952
- * Sign a {@link UserOperationV9} using an {@link ExternalSigner}.
6953
- * Simple7702 only accepts raw-hash ECDSA; signers without `signHash`
6954
- * fail offline with an actionable error. For a raw pk string, use the
6955
- * 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.
6956
7187
  */
6957
7188
  async signUserOperationWithSigner(useroperation, signer, chainId) {
6958
7189
  return this.baseSignUserOperationWithSigner(useroperation, signer, chainId);
@@ -7963,6 +8194,280 @@ var abstractionkit = (function(exports, ethers) {
7963
8194
  ]));
7964
8195
  }
7965
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
7966
8471
  //#region src/signer/adapters.ts
7967
8472
  /**
7968
8473
  * Build a Signer from a raw private-key hex string. Supports both raw-hash
@@ -8101,6 +8606,7 @@ var abstractionkit = (function(exports, ethers) {
8101
8606
  fetchGasPrice: () => fetchGasPrice,
8102
8607
  fromEthersWallet: () => fromEthersWallet,
8103
8608
  fromPrivateKey: () => fromPrivateKey,
8609
+ fromSafeWebauthn: () => fromSafeWebauthn,
8104
8610
  fromViem: () => fromViem,
8105
8611
  fromViemWalletClient: () => fromViemWalletClient,
8106
8612
  getBalanceOf: () => getBalanceOf,
@@ -8108,6 +8614,8 @@ var abstractionkit = (function(exports, ethers) {
8108
8614
  getDepositInfo: () => getDepositInfo,
8109
8615
  getFunctionSelector: () => getFunctionSelector,
8110
8616
  getSafeMessageEip712Data: () => getSafeMessageEip712Data,
8617
+ pubkeyCoordinatesFromJson: () => pubkeyCoordinatesFromJson,
8618
+ pubkeyCoordinatesToJson: () => pubkeyCoordinatesToJson,
8111
8619
  sendJsonRpcRequest: () => sendJsonRpcRequest,
8112
8620
  shareTenderlySimulationAndCreateLink: () => shareTenderlySimulationAndCreateLink,
8113
8621
  signHash: () => signHash,
@@ -8116,7 +8624,8 @@ var abstractionkit = (function(exports, ethers) {
8116
8624
  simulateUserOperationCallDataWithTenderly: () => simulateUserOperationCallDataWithTenderly,
8117
8625
  simulateUserOperationCallDataWithTenderlyAndCreateShareLink: () => simulateUserOperationCallDataWithTenderlyAndCreateShareLink,
8118
8626
  simulateUserOperationWithTenderly: () => simulateUserOperationWithTenderly,
8119
- simulateUserOperationWithTenderlyAndCreateShareLink: () => simulateUserOperationWithTenderlyAndCreateShareLink
8627
+ simulateUserOperationWithTenderlyAndCreateShareLink: () => simulateUserOperationWithTenderlyAndCreateShareLink,
8628
+ webauthnSignatureFromAssertion: () => webauthnSignatureFromAssertion
8120
8629
  });
8121
8630
  //#endregion
8122
8631
  exports.ALLOWANCE_MODULE_V0_1_0_ADDRESS = ALLOWANCE_MODULE_V0_1_0_ADDRESS;
@@ -8185,6 +8694,7 @@ var abstractionkit = (function(exports, ethers) {
8185
8694
  exports.fetchGasPrice = fetchGasPrice;
8186
8695
  exports.fromEthersWallet = fromEthersWallet;
8187
8696
  exports.fromPrivateKey = fromPrivateKey;
8697
+ exports.fromSafeWebauthn = fromSafeWebauthn;
8188
8698
  exports.fromViem = fromViem;
8189
8699
  exports.fromViemWalletClient = fromViemWalletClient;
8190
8700
  exports.getBalanceOf = getBalanceOf;
@@ -8192,6 +8702,8 @@ var abstractionkit = (function(exports, ethers) {
8192
8702
  exports.getDepositInfo = getDepositInfo;
8193
8703
  exports.getFunctionSelector = getFunctionSelector;
8194
8704
  exports.getSafeMessageEip712Data = getSafeMessageEip712Data;
8705
+ exports.pubkeyCoordinatesFromJson = pubkeyCoordinatesFromJson;
8706
+ exports.pubkeyCoordinatesToJson = pubkeyCoordinatesToJson;
8195
8707
  exports.sendJsonRpcRequest = sendJsonRpcRequest;
8196
8708
  exports.shareTenderlySimulationAndCreateLink = shareTenderlySimulationAndCreateLink;
8197
8709
  exports.signHash = signHash;
@@ -8201,5 +8713,6 @@ var abstractionkit = (function(exports, ethers) {
8201
8713
  exports.simulateUserOperationCallDataWithTenderlyAndCreateShareLink = simulateUserOperationCallDataWithTenderlyAndCreateShareLink;
8202
8714
  exports.simulateUserOperationWithTenderly = simulateUserOperationWithTenderly;
8203
8715
  exports.simulateUserOperationWithTenderlyAndCreateShareLink = simulateUserOperationWithTenderlyAndCreateShareLink;
8716
+ exports.webauthnSignatureFromAssertion = webauthnSignatureFromAssertion;
8204
8717
  return exports;
8205
8718
  })({}, ethers);