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.
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
- import { AbiCoder, JsonRpcProvider, TypedDataEncoder, Wallet, encodeRlp, ethers, getAddress, getBytes, hashMessage, id, isAddress, keccak256, solidityPacked, solidityPackedKeccak256, toBeArray } from "ethers";
2
+ import { AbiCoder, JsonRpcProvider, TypedDataEncoder, Wallet, encodeRlp, ethers, getAddress, getBytes, hashMessage, hexlify, id, isAddress, keccak256, solidityPacked, solidityPackedKeccak256, toBeArray } from "ethers";
3
3
  //#region src/errors.ts
4
4
  /**
5
5
  * Maps JSON-RPC numeric error codes to human-readable {@link BundlerErrorCode} values.
@@ -319,6 +319,61 @@ function createUserOperationHash(useroperation, entrypointAddress, chainId) {
319
319
  return userOperationHash;
320
320
  }
321
321
  /**
322
+ * @internal
323
+ * Reconstruct the packed `initCode` field for an EntryPoint v0.8/v0.9
324
+ * UserOperation. When `eip7702Auth.address` is set, the EIP-7702 delegatee
325
+ * address replaces the factory address in initCode (only `factoryData` is
326
+ * concatenated). Otherwise, behaves like v0.7 (`factory + factoryData`).
327
+ *
328
+ * Shared by {@link createPackedUserOperationV8} /
329
+ * {@link createPackedUserOperationV9} and Simple7702Account's typed-data
330
+ * builder. Not part of the public API; only `export`ed for cross-module
331
+ * use within the package and not re-exported from `src/abstractionkit.ts`.
332
+ *
333
+ * @param useroperation - V8 or V9 UserOperation to read fields from
334
+ * @returns Hex-encoded initCode
335
+ */
336
+ function buildPackedInitCodeV8V9(useroperation) {
337
+ if (useroperation.factory == null) return "0x";
338
+ const eip7702Auth = useroperation.eip7702Auth;
339
+ return (eip7702Auth != null && eip7702Auth.address != null ? eip7702Auth.address : useroperation.factory) + (useroperation.factoryData != null ? useroperation.factoryData.slice(2) : "");
340
+ }
341
+ /**
342
+ * @internal
343
+ * Reconstruct the packed `paymasterAndData` field from a UserOperation's
344
+ * separate paymaster fields. Returns `0x` when no paymaster is set.
345
+ *
346
+ * For EntryPoint v0.9, when `paymasterData` ends with the parallel-paymaster
347
+ * signature magic suffix (`0x22e325a297439656`), the embedded signature is
348
+ * stripped so the userOpHash does not commit to the paymaster's signature
349
+ * over itself. Pass `stripV9PaymasterSig=false` to preserve the wire format.
350
+ *
351
+ * Shared by v7/v8/v9 packers and Simple7702Account's typed-data builder.
352
+ * Not part of the public API; only `export`ed for cross-module use within
353
+ * the package and not re-exported from `src/abstractionkit.ts`.
354
+ *
355
+ * @param useroperation - V7/V8/V9 UserOperation to read fields from
356
+ * @param stripV9PaymasterSig - Whether to strip the v0.9 paymaster signature suffix
357
+ * @returns Hex-encoded paymasterAndData
358
+ */
359
+ function buildPaymasterAndData(useroperation, stripV9PaymasterSig = false) {
360
+ if (useroperation.paymaster == null) return "0x";
361
+ const abiCoder = AbiCoder.defaultAbiCoder();
362
+ let paymasterAndData = useroperation.paymaster;
363
+ if (useroperation.paymasterVerificationGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterVerificationGasLimit]).slice(34);
364
+ if (useroperation.paymasterPostOpGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterPostOpGasLimit]).slice(34);
365
+ if (useroperation.paymasterData != null) {
366
+ const PAYMASTER_SIG_MAGIC = "22e325a297439656";
367
+ if (stripV9PaymasterSig && useroperation.paymasterData.toLowerCase().endsWith(PAYMASTER_SIG_MAGIC)) {
368
+ const sigLenHex = useroperation.paymasterData.slice(useroperation.paymasterData.length - 16 - 4, useroperation.paymasterData.length - 16);
369
+ const sigLen = parseInt(sigLenHex, 16);
370
+ const prefixEnd = useroperation.paymasterData.length - 16 - 4 - sigLen * 2;
371
+ paymasterAndData += useroperation.paymasterData.slice(0, prefixEnd).replaceAll("0x", "") + PAYMASTER_SIG_MAGIC;
372
+ } else paymasterAndData += useroperation.paymasterData.slice(2);
373
+ }
374
+ return paymasterAndData;
375
+ }
376
+ /**
322
377
  * ABI-encode and pack a UserOperation for hashing (EntryPoint v0.6 format).
323
378
  * Bytes fields (initCode, callData, paymasterAndData) are keccak256-hashed before packing.
324
379
  *
@@ -367,13 +422,7 @@ function createPackedUserOperationV7(useroperation) {
367
422
  }
368
423
  const accountGasLimits = "0x" + abiCoder.encode(["uint128"], [useroperation.verificationGasLimit]).slice(34) + abiCoder.encode(["uint128"], [useroperation.callGasLimit]).slice(34);
369
424
  const gasFees = "0x" + abiCoder.encode(["uint128"], [useroperation.maxPriorityFeePerGas]).slice(34) + abiCoder.encode(["uint128"], [useroperation.maxFeePerGas]).slice(34);
370
- let paymasterAndData = "0x";
371
- if (useroperation.paymaster != null) {
372
- paymasterAndData = useroperation.paymaster;
373
- if (useroperation.paymasterVerificationGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterVerificationGasLimit]).slice(34);
374
- if (useroperation.paymasterPostOpGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterPostOpGasLimit]).slice(34);
375
- if (useroperation.paymasterData != null) paymasterAndData += useroperation.paymasterData.slice(2);
376
- }
425
+ const paymasterAndData = buildPaymasterAndData(useroperation);
377
426
  const useroperationValuesArrayWithHashedByteValues = [
378
427
  useroperation.sender,
379
428
  useroperation.nonce,
@@ -421,30 +470,10 @@ function createPackedUserOperationV8(useroperation) {
421
470
  */
422
471
  function baseCreatePackedUserOperationV8V9(useroperation, is_v9) {
423
472
  const abiCoder = AbiCoder.defaultAbiCoder();
424
- let initCode = "0x";
425
- if (useroperation.factory != null) {
426
- const eip7702Auth = useroperation.eip7702Auth;
427
- if (eip7702Auth != null && eip7702Auth.address != null) initCode = eip7702Auth.address;
428
- else initCode = useroperation.factory;
429
- if (useroperation.factoryData != null) initCode += useroperation.factoryData.slice(2);
430
- }
473
+ const initCode = buildPackedInitCodeV8V9(useroperation);
431
474
  const accountGasLimits = "0x" + abiCoder.encode(["uint128"], [useroperation.verificationGasLimit]).slice(34) + abiCoder.encode(["uint128"], [useroperation.callGasLimit]).slice(34);
432
475
  const gasFees = "0x" + abiCoder.encode(["uint128"], [useroperation.maxPriorityFeePerGas]).slice(34) + abiCoder.encode(["uint128"], [useroperation.maxFeePerGas]).slice(34);
433
- let paymasterAndData = "0x";
434
- if (useroperation.paymaster != null) {
435
- paymasterAndData = useroperation.paymaster;
436
- if (useroperation.paymasterVerificationGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterVerificationGasLimit]).slice(34);
437
- if (useroperation.paymasterPostOpGasLimit != null) paymasterAndData += abiCoder.encode(["uint128"], [useroperation.paymasterPostOpGasLimit]).slice(34);
438
- if (useroperation.paymasterData != null) {
439
- const PAYMASTER_SIG_MAGIC = "22e325a297439656";
440
- if (is_v9 && useroperation.paymasterData.toLowerCase().endsWith(PAYMASTER_SIG_MAGIC)) {
441
- const sigLenHex = useroperation.paymasterData.slice(useroperation.paymasterData.length - 16 - 4, useroperation.paymasterData.length - 16);
442
- const sigLen = parseInt(sigLenHex, 16);
443
- const prefixEnd = useroperation.paymasterData.length - 16 - 4 - sigLen * 2;
444
- paymasterAndData += useroperation.paymasterData.slice(0, prefixEnd).replaceAll("0x", "") + PAYMASTER_SIG_MAGIC;
445
- } else paymasterAndData += useroperation.paymasterData.slice(2);
446
- }
447
- }
476
+ const paymasterAndData = buildPaymasterAndData(useroperation, is_v9);
448
477
  const useroperationValuesArrayWithHashedByteValues = [
449
478
  "0x29a0bca4af4be3421398da00295e58e6d7de38cb492214754cb6a47507dd6f8e",
450
479
  useroperation.sender,
@@ -2666,7 +2695,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
2666
2695
  static DEFAULT_WEB_AUTHN_SHARED_SIGNER = "0xfD90FAd33ee8b58f32c00aceEad1358e4AFC23f9";
2667
2696
  static DEFAULT_WEB_AUTHN_SIGNER_SINGLETON = "0x270D7E4a57E6322f336261f3EaE2BADe72E68d72";
2668
2697
  static DEFAULT_WEB_AUTHN_SIGNER_FACTORY = "0xF7488fFbe67327ac9f37D5F722d83Fc900852Fbf";
2669
- static DEFAULT_WEB_AUTHN_FCLP256_VERIFIER = "0x445a0683e494ea0c5AF3E83c5159fBE47Cf9e765";
2698
+ static DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER = "0x445a0683e494ea0c5AF3E83c5159fBE47Cf9e765";
2670
2699
  static DEFAULT_WEB_AUTHN_PRECOMPILE = "0x0000000000000000000000000000000000000000";
2671
2700
  static DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE = "0x61010060405234801561001157600080fd5b506040516101ee3803806101ee83398101604081905261003091610058565b6001600160a01b0390931660805260a09190915260c0526001600160b01b031660e0526100bc565b6000806000806080858703121561006e57600080fd5b84516001600160a01b038116811461008557600080fd5b60208601516040870151606088015192965090945092506001600160b01b03811681146100b157600080fd5b939692955090935050565b60805160a05160c05160e05160ff6100ef60003960006008015260006031015260006059015260006080015260ff6000f3fe608060408190527f00000000000000000000000000000000000000000000000000000000000000003660b681018290527f000000000000000000000000000000000000000000000000000000000000000060a082018190527f00000000000000000000000000000000000000000000000000000000000000008285018190527f00000000000000000000000000000000000000000000000000000000000000009490939192600082376000806056360183885af490503d6000803e8060c3573d6000fd5b503d6000f3fea2646970667358221220ddd9bb059ba7a6497d560ca97aadf4dbf0476f578378554a50d41c6bb654beae64736f6c63430008180033";
2672
2701
  static DEFAULT_MULTISEND_CONTRACT_ADDRESS = "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526";
@@ -3177,7 +3206,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3177
3206
  */
3178
3207
  static createAccountAddressAndFactoryAddressAndData(owners, overrides, safe4337ModuleAddress, safeModuleSetupAddress) {
3179
3208
  if (owners.length < 1) throw new RangeError("There should be at least one owner");
3180
- 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);
3209
+ 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);
3181
3210
  let safeAccountFactory;
3182
3211
  if (overrides.safeAccountFactoryAddress != null) safeAccountFactory = new SafeAccountFactory(overrides.safeAccountFactoryAddress);
3183
3212
  else safeAccountFactory = new SafeAccountFactory();
@@ -3199,7 +3228,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3199
3228
  factoryGeneratorFunctionCallData
3200
3229
  ];
3201
3230
  }
3202
- 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) {
3231
+ 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) {
3203
3232
  if (owners.length < 1) throw new RangeError("There should be at least one owner");
3204
3233
  if (threshold < 1) throw new RangeError("threshold should be at least one");
3205
3234
  if (threshold > owners.length) throw new RangeError("threshold can't be larger than number of owners");
@@ -3275,7 +3304,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3275
3304
  if (threshold < 1) throw new RangeError("threshold should be at least one");
3276
3305
  if (threshold > owners.length) throw new RangeError("threshold can't be larger than number of owners");
3277
3306
  if (c2Nonce < 0n) throw new RangeError("c2Nonce can't be negative");
3278
- 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);
3307
+ 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);
3279
3308
  let safeAccountFactory;
3280
3309
  if (overrides.safeAccountFactoryAddress != null) safeAccountFactory = new SafeAccountFactory(overrides.safeAccountFactoryAddress);
3281
3310
  else safeAccountFactory = new SafeAccountFactory();
@@ -3337,9 +3366,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3337
3366
  eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier,
3338
3367
  webAuthnSignerFactory: overrides.webAuthnSignerFactory,
3339
3368
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton,
3340
- webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode,
3341
- validAfter,
3342
- validUntil
3369
+ webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode
3343
3370
  });
3344
3371
  userOperation.signature = SafeAccount.formatSignaturesToUseroperationSignature(dummySignerSignaturePairs, {
3345
3372
  validAfter,
@@ -3406,7 +3433,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3406
3433
  maxFeePerGas = overrides.maxFeePerGas ?? maxFeePerGas * BigInt((overrides.maxFeePerGasPercentageMultiplier ?? 0) + 100) / 100n;
3407
3434
  maxPriorityFeePerGas = overrides.maxPriorityFeePerGas ?? maxPriorityFeePerGas * BigInt((overrides.maxPriorityFeePerGasPercentageMultiplier ?? 0) + 100) / 100n;
3408
3435
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3409
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3436
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3410
3437
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3411
3438
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3412
3439
  const webAuthnSignerProxyCreationCode = overrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -3481,16 +3508,14 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3481
3508
  eip7212WebAuthnContractVerifier,
3482
3509
  webAuthnSignerFactory,
3483
3510
  webAuthnSignerSingleton,
3484
- webAuthnSignerProxyCreationCode,
3485
- validAfter,
3486
- validUntil
3511
+ webAuthnSignerProxyCreationCode
3487
3512
  });
3488
3513
  }
3489
3514
  userOperation.signature = SafeAccount.formatSignaturesToUseroperationSignature(dummySignerSignaturePairs, {
3490
3515
  validAfter,
3491
3516
  validUntil,
3492
- webAuthnSharedSigner,
3493
- isMultiChainSignature: overrides.isMultiChainSignature
3517
+ isMultiChainSignature: overrides.isMultiChainSignature,
3518
+ webAuthnSharedSigner
3494
3519
  });
3495
3520
  if (!(overrides.skipGasEstimation ?? false) && (overrides.preVerificationGas == null || overrides.verificationGasLimit == null || overrides.callGasLimit == null)) if (bundlerRpc != null) {
3496
3521
  userOperation.callGasLimit = 0n;
@@ -3557,14 +3582,15 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3557
3582
  * @param useroperation - useroperation to sign
3558
3583
  * @param privateKeys - for the signers
3559
3584
  * @param chainId - target chain id
3560
- * @param overrides - overrides for the default values
3561
- * @param overrides.validAfter - timestamp the signature will be valid after
3562
- * @param overrides.validUntil - timestamp the signature will be valid until
3585
+ * @param entrypointAddress - target EntryPoint
3586
+ * @param safe4337ModuleAddress - Safe 4337 module
3587
+ * @param options - per-call signing options (timing, multi-chain encoding, module address) — passed through to {@link formatSignaturesToUseroperationSignature}
3563
3588
  * @returns signature
3564
3589
  */
3565
- static baseSignSingleUserOperation(useroperation, privateKeys, chainId, entrypointAddress, safe4337ModuleAddress, overrides = {}) {
3566
- const validAfter = overrides.validAfter ?? 0n;
3567
- const validUntil = overrides.validUntil ?? 0n;
3590
+ static baseSignSingleUserOperation(useroperation, privateKeys, chainId, entrypointAddress, safe4337ModuleAddress, options = {}) {
3591
+ const validAfter = options.validAfter ?? 0n;
3592
+ const validUntil = options.validUntil ?? 0n;
3593
+ const moduleAddress = options.safe4337ModuleAddress ?? safe4337ModuleAddress;
3568
3594
  if (privateKeys.length < 1) throw new RangeError("There should be at least one privateKey");
3569
3595
  if (chainId < 0n) throw new RangeError("chainId can't be negative");
3570
3596
  if (validAfter < 0n) throw new RangeError("validAfter can't be negative");
@@ -3573,7 +3599,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3573
3599
  validAfter,
3574
3600
  validUntil,
3575
3601
  entrypointAddress,
3576
- safe4337ModuleAddress
3602
+ safe4337ModuleAddress: moduleAddress
3577
3603
  });
3578
3604
  const signerSignaturePairs = [];
3579
3605
  for (const privateKey of privateKeys) {
@@ -3585,9 +3611,9 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3585
3611
  });
3586
3612
  }
3587
3613
  return SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
3614
+ ...options,
3588
3615
  validAfter,
3589
- validUntil,
3590
- isMultiChainSignature: overrides.isMultiChainSignature
3616
+ validUntil
3591
3617
  });
3592
3618
  }
3593
3619
  /**
@@ -3610,20 +3636,24 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3610
3636
  * @param useroperation - UserOperation to sign
3611
3637
  * @param signers - Signer instances (`fromViem(account)`, `fromEthersWallet(wallet)`, etc.)
3612
3638
  * @param chainId - target chain id
3613
- * @param entrypointAddress - target EntryPoint
3614
- * @param safe4337ModuleAddress - Safe 4337 module
3615
- * @param overrides - optional validAfter / validUntil / multi-chain flag
3639
+ * @param params - bag combining required wiring (`entrypointAddress`,
3640
+ * `safe4337ModuleAddress`, `context`) with optional `options`
3641
+ * ({@link SafeSignatureOptions}: timing, multi-chain encoding,
3642
+ * module address).
3643
+ * Both flow through to {@link formatSignaturesToUseroperationSignature}.
3616
3644
  * @returns formatted signature
3617
3645
  */
3618
- static async baseSignUserOperationWithSigners(useroperation, signers, chainId, entrypointAddress, safe4337ModuleAddress, context, overrides = {}) {
3619
- const validAfter = overrides.validAfter ?? 0n;
3620
- const validUntil = overrides.validUntil ?? 0n;
3646
+ static async baseSignUserOperationWithSigners(useroperation, signers, chainId, params) {
3647
+ const { entrypointAddress, safe4337ModuleAddress, context, options = {} } = params;
3648
+ const validAfter = options.validAfter ?? 0n;
3649
+ const validUntil = options.validUntil ?? 0n;
3650
+ const moduleAddress = options.safe4337ModuleAddress ?? safe4337ModuleAddress;
3621
3651
  if (signers.length < 1) throw new RangeError("There should be at least one signer");
3622
3652
  const typedDataRaw = SafeAccount.getUserOperationEip712Data(useroperation, chainId, {
3623
3653
  validAfter,
3624
3654
  validUntil,
3625
3655
  entrypointAddress,
3626
- safe4337ModuleAddress
3656
+ safe4337ModuleAddress: moduleAddress
3627
3657
  });
3628
3658
  const userOpHash = TypedDataEncoder.hash(typedDataRaw.domain, typedDataRaw.types, typedDataRaw.messageValue);
3629
3659
  const { EIP712Domain: _drop, ...primaryTypes } = typedDataRaw.types;
@@ -3644,12 +3674,13 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3644
3674
  context
3645
3675
  })))).map((signature, i) => ({
3646
3676
  signer: normalizedAddresses[i],
3647
- signature
3677
+ signature,
3678
+ isContractSignature: signers[i].type === "contract"
3648
3679
  }));
3649
3680
  return SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
3681
+ ...options,
3650
3682
  validAfter,
3651
- validUntil,
3652
- isMultiChainSignature: overrides.isMultiChainSignature
3683
+ validUntil
3653
3684
  });
3654
3685
  }
3655
3686
  /**
@@ -3662,7 +3693,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3662
3693
  */
3663
3694
  static createWebAuthnSignerVerifierAddress(x, y, overrides = {}) {
3664
3695
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3665
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3696
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3666
3697
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3667
3698
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3668
3699
  if (eip7212WebAuthnPrecompileVerifier.length !== 42 || eip7212WebAuthnPrecompileVerifier.slice(0, 38) !== "0x0000000000000000000000000000000000000000".slice(0, 38)) throw new RangeError("Invalid precompile address. It should have the format 0x000000000000000000000000000000000000____");
@@ -3693,15 +3724,15 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3693
3724
  /**
3694
3725
  * format a list of eip712 signatures to a useroperation signature
3695
3726
  * @param signerSignaturePairs - a list of a pair of a signer and it's signature
3696
- * @param overrides - overrides for the default values
3727
+ * @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.
3697
3728
  * @returns signature
3698
3729
  */
3699
- static formatSignaturesToUseroperationSignature(signerSignaturePairs, overrides = {}) {
3700
- const validAfter = overrides.validAfter ?? 0n;
3701
- const validUntil = overrides.validUntil ?? 0n;
3702
- const signature = SafeAccount.buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, overrides);
3703
- if (overrides.isMultiChainSignature) if (overrides.multiChainMerkleProof != null) {
3704
- const merkleProofLength = overrides.multiChainMerkleProof.slice(2).length;
3730
+ static formatSignaturesToUseroperationSignature(signerSignaturePairs, options = {}) {
3731
+ const validAfter = options.validAfter ?? 0n;
3732
+ const validUntil = options.validUntil ?? 0n;
3733
+ const signature = SafeAccount.buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, options);
3734
+ if (options.isMultiChainSignature) if (options.multiChainMerkleProof != null) {
3735
+ const merkleProofLength = options.multiChainMerkleProof.slice(2).length;
3705
3736
  if (merkleProofLength < 128 || merkleProofLength % 64 !== 0) throw new RangeError("invalid multiChainMerkleProof length.");
3706
3737
  let merkleTreeDepthHex = (merkleProofLength / 64 - 1).toString(16);
3707
3738
  if (merkleTreeDepthHex.length % 2 === 0) merkleTreeDepthHex = `0x${merkleTreeDepthHex}`;
@@ -3715,7 +3746,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3715
3746
  merkleTreeDepthHex,
3716
3747
  validAfter,
3717
3748
  validUntil,
3718
- overrides.multiChainMerkleProof + signature.slice(2)
3749
+ options.multiChainMerkleProof + signature.slice(2)
3719
3750
  ]);
3720
3751
  } else return solidityPacked([
3721
3752
  "bytes1",
@@ -3748,7 +3779,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3748
3779
  if (typeof signer === "string") return signer.toLowerCase();
3749
3780
  else {
3750
3781
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3751
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3782
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3752
3783
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3753
3784
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3754
3785
  const webAuthnSignerProxyCreationCode = overrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -3774,7 +3805,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3774
3805
  /**
3775
3806
  * format a list of eip712 signatures to a safe signature (without the time range)
3776
3807
  * @param signerSignaturePairs - a list of a pair of a signer and it's signature
3777
- * @param overrides - overrides for the default values
3808
+ * @param webAuthnSignatureOverrides - WebAuthn-only configuration (verifier addresses, init flag)
3778
3809
  * @returns signature
3779
3810
  */
3780
3811
  static buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, webAuthnSignatureOverrides = {}) {
@@ -3788,7 +3819,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3788
3819
  if (webAuthnSignatureOverrides.isInit) signer = webAuthnSignatureOverrides.webAuthnSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER;
3789
3820
  else {
3790
3821
  const eip7212WebAuthnPrecompileVerifier = webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3791
- const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3822
+ const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3792
3823
  const webAuthnSignerFactory = webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3793
3824
  const webAuthnSignerSingleton = webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3794
3825
  const webAuthnSignerProxyCreationCode = webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -4059,7 +4090,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
4059
4090
  */
4060
4091
  static createDeployWebAuthnVerifierMetaTransaction(x, y, overrides = {}) {
4061
4092
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4062
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4093
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4063
4094
  return {
4064
4095
  to: overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
4065
4096
  value: 0n,
@@ -4161,7 +4192,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
4161
4192
  signerSignaturePair.signer = webauthnsharedsigner;
4162
4193
  } else {
4163
4194
  const eip7212WebAuthnPrecompileVerifier = webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4164
- const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4195
+ const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4165
4196
  const webAuthnSignerFactory = webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
4166
4197
  const webAuthnSignerSingleton = webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
4167
4198
  const webAuthnSignerProxyCreationCode = webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -4195,7 +4226,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
4195
4226
  static async verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, overrides = {}) {
4196
4227
  if (messageHash.length !== 66 || messageHash.slice(0, 2) !== "0x") throw new RangeError("Invalid messageHash, must be a 0x-prefixed keccak256 hash.");
4197
4228
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4198
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4229
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4199
4230
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
4200
4231
  if (eip7212WebAuthnPrecompileVerifier.length !== 42 || eip7212WebAuthnPrecompileVerifier.slice(0, 38) !== "0x0000000000000000000000000000000000000000".slice(0, 38)) throw new RangeError("Invalid precompile address. It should have the format 0x000000000000000000000000000000000000____");
4201
4232
  const callData = createCallData("0x1626ba7e", ["bytes32", "bytes"], [messageHash, signature]);
@@ -4325,7 +4356,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
4325
4356
  * @param toolVersion - tool version; defaults to the current abstractionkit version
4326
4357
  * @returns the on-chain identifier as a hex string (not 0x prefixed)
4327
4358
  */
4328
- function generateOnChainIdentifier(project, platform = "Web", tool = "abstractionkit", toolVersion = "0.3.4") {
4359
+ function generateOnChainIdentifier(project, platform = "Web", tool = "abstractionkit", toolVersion = "0.3.5") {
4329
4360
  const identifierPrefix = "5afe";
4330
4361
  const identifierVersion = "00";
4331
4362
  const projectHash = keccak256(`0x${Buffer.from(project, "utf8").toString("hex")}`).slice(-20);
@@ -5329,15 +5360,15 @@ var SafeAccountV0_3_0 = class SafeAccountV0_3_0 extends SafeAccount {
5329
5360
  * @param useroperation - The UserOperation to sign
5330
5361
  * @param privateKeys - Array of private keys for the signers
5331
5362
  * @param chainId - The target chain ID
5332
- * @param overrides - Override validAfter and validUntil timestamps
5363
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5333
5364
  * @returns The formatted signature string ready to set on the UserOperation
5334
5365
  *
5335
5366
  * @example
5336
5367
  * const signature = smartAccount.signUserOperation(userOp, [privateKey], 1n);
5337
5368
  * userOp.signature = signature;
5338
5369
  */
5339
- signUserOperation(useroperation, privateKeys, chainId, overrides = {}) {
5340
- return SafeAccount.baseSignSingleUserOperation(useroperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, overrides);
5370
+ signUserOperation(useroperation, privateKeys, chainId, options = {}) {
5371
+ return SafeAccount.baseSignSingleUserOperation(useroperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, options);
5341
5372
  }
5342
5373
  /**
5343
5374
  * Sign a UserOperation with one or more {@link ExternalSigner} instances
@@ -5359,16 +5390,21 @@ var SafeAccountV0_3_0 = class SafeAccountV0_3_0 extends SafeAccount {
5359
5390
  * @param useroperation - UserOperation to sign
5360
5391
  * @param signers - one ExternalSigner per owner (any order)
5361
5392
  * @param chainId - target chain ID
5362
- * @param overrides - optional validAfter / validUntil / multi-chain flag
5393
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5363
5394
  * @returns Promise resolving to the formatted signature string
5364
5395
  */
5365
- signUserOperationWithSigners(useroperation, signers, chainId, overrides = {}) {
5396
+ signUserOperationWithSigners(useroperation, signers, chainId, options = {}) {
5366
5397
  const context = {
5367
5398
  userOperation: useroperation,
5368
5399
  chainId,
5369
5400
  entryPoint: this.entrypointAddress
5370
5401
  };
5371
- return SafeAccount.baseSignUserOperationWithSigners(useroperation, signers, chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, overrides);
5402
+ return SafeAccount.baseSignUserOperationWithSigners(useroperation, signers, chainId, {
5403
+ entrypointAddress: this.entrypointAddress,
5404
+ safe4337ModuleAddress: this.safe4337ModuleAddress,
5405
+ context,
5406
+ options
5407
+ });
5372
5408
  }
5373
5409
  };
5374
5410
  //#endregion
@@ -5611,28 +5647,39 @@ var SafeAccountV0_2_0 = class SafeAccountV0_2_0 extends SafeAccount {
5611
5647
  * @param useroperation - The UserOperation to sign
5612
5648
  * @param privateKeys - Array of private keys for the signers
5613
5649
  * @param chainId - The target chain ID
5614
- * @param overrides - Override validAfter and validUntil timestamps
5650
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5615
5651
  * @returns The formatted signature string ready to set on the UserOperation
5616
5652
  *
5617
5653
  * @example
5618
5654
  * const signature = smartAccount.signUserOperation(userOp, [privateKey], 1n);
5619
5655
  * userOp.signature = signature;
5620
5656
  */
5621
- signUserOperation(useroperation, privateKeys, chainId, overrides = {}) {
5622
- return SafeAccount.baseSignSingleUserOperation(useroperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, overrides);
5657
+ signUserOperation(useroperation, privateKeys, chainId, options = {}) {
5658
+ return SafeAccount.baseSignSingleUserOperation(useroperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, options);
5623
5659
  }
5624
5660
  /**
5625
5661
  * Sign a UserOperation using one or more {@link AkSigner} instances.
5626
5662
  * See {@link SafeAccountV0_3_0.signUserOperationWithSigners} for full
5627
5663
  * design rationale and examples.
5664
+ *
5665
+ * @param useroperation - The UserOperation to sign
5666
+ * @param signers - one ExternalSigner per owner (any order)
5667
+ * @param chainId - The target chain ID
5668
+ * @param options - {@link SafeSignatureOptions} — timing, multi-chain encoding, module address
5669
+ * @returns Promise resolving to the formatted signature string
5628
5670
  */
5629
- signUserOperationWithSigners(useroperation, signers, chainId, overrides = {}) {
5671
+ signUserOperationWithSigners(useroperation, signers, chainId, options = {}) {
5630
5672
  const context = {
5631
5673
  userOperation: useroperation,
5632
5674
  chainId,
5633
5675
  entryPoint: this.entrypointAddress
5634
5676
  };
5635
- return SafeAccount.baseSignUserOperationWithSigners(useroperation, signers, chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, overrides);
5677
+ return SafeAccount.baseSignUserOperationWithSigners(useroperation, signers, chainId, {
5678
+ entrypointAddress: this.entrypointAddress,
5679
+ safe4337ModuleAddress: this.safe4337ModuleAddress,
5680
+ context,
5681
+ options
5682
+ });
5636
5683
  }
5637
5684
  };
5638
5685
  //#endregion
@@ -5651,6 +5698,7 @@ var SafeAccountV0_2_0 = class SafeAccountV0_2_0 extends SafeAccount {
5651
5698
  var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAccountV0_3_0 {
5652
5699
  static DEFAULT_WEB_AUTHN_PRECOMPILE = "0x0000000000000000000000000000000000000100";
5653
5700
  static DEFAULT_WEB_AUTHN_DAIMO_VERIFIER = "0xc2b78104907F722DABAc4C69f826a522B2754De4";
5701
+ static DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER = "0xc2b78104907F722DABAc4C69f826a522B2754De4";
5654
5702
  /**
5655
5703
  * Create a SafeAccountV1_5_0_M_0_3_0 instance for an existing deployed account.
5656
5704
  * For new (undeployed) accounts, use the static `initializeNewAccount` method instead.
@@ -5699,7 +5747,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5699
5747
  ...overrides,
5700
5748
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5701
5749
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5702
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5750
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5703
5751
  };
5704
5752
  return SafeAccountV0_3_0.initializeNewAccount(owners, modOverrides);
5705
5753
  }
@@ -5716,7 +5764,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5716
5764
  ...overrides,
5717
5765
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5718
5766
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5719
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5767
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5720
5768
  };
5721
5769
  return SafeAccountV0_3_0.createAccountAddress(owners, modOverrides);
5722
5770
  }
@@ -5733,7 +5781,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5733
5781
  ...overrides,
5734
5782
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5735
5783
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5736
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5784
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5737
5785
  };
5738
5786
  return SafeAccountV0_3_0.createFactoryAddressAndData(owners, modOverrides);
5739
5787
  }
@@ -5751,7 +5799,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5751
5799
  return super.createUserOperation(transactions, providerRpc, bundlerRpc, {
5752
5800
  ...overrides,
5753
5801
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5754
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5802
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5755
5803
  });
5756
5804
  }
5757
5805
  /**
@@ -5766,7 +5814,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5766
5814
  return super.estimateUserOperationGas(userOperation, bundlerRpc, {
5767
5815
  ...overrides,
5768
5816
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5769
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5817
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5770
5818
  });
5771
5819
  }
5772
5820
  /**
@@ -5782,7 +5830,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5782
5830
  return SafeAccount.createWebAuthnSignerVerifierAddress(x, y, {
5783
5831
  ...overrides,
5784
5832
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5785
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5833
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5786
5834
  });
5787
5835
  }
5788
5836
  /**
@@ -5798,7 +5846,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5798
5846
  return SafeAccount.createDeployWebAuthnVerifierMetaTransaction(x, y, {
5799
5847
  ...overrides,
5800
5848
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5801
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5849
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5802
5850
  });
5803
5851
  }
5804
5852
  /**
@@ -5812,7 +5860,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5812
5860
  return SafeAccount.createDummySignerSignaturePairForExpectedSigners(expectedSigners, {
5813
5861
  ...webAuthnSignatureOverrides,
5814
5862
  eip7212WebAuthnPrecompileVerifier: webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5815
- eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5863
+ eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5816
5864
  });
5817
5865
  }
5818
5866
  /**
@@ -5830,7 +5878,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5830
5878
  return SafeAccount.verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, {
5831
5879
  ...overrides,
5832
5880
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5833
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
5881
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5834
5882
  });
5835
5883
  }
5836
5884
  };
@@ -5924,6 +5972,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
5924
5972
  static DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE = DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE_V_0_2_1;
5925
5973
  static DEFAULT_WEB_AUTHN_PRECOMPILE = DEFAULT_WEB_AUTHN_PRECOMPILE_RIP_7951;
5926
5974
  static DEFAULT_WEB_AUTHN_DAIMO_VERIFIER = DEFAULT_WEB_AUTHN_DAIMO_VERIFIER_V_0_2_1;
5975
+ static DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER = DEFAULT_WEB_AUTHN_DAIMO_VERIFIER_V_0_2_1;
5927
5976
  /**
5928
5977
  * Create a SafeMultiChainSigAccount instance for an existing or new account.
5929
5978
  * @param accountAddress - the Safe account address
@@ -5949,7 +5998,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
5949
5998
  ...overrides,
5950
5999
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
5951
6000
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
5952
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6001
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5953
6002
  };
5954
6003
  const [accountAddress, ,] = SafeAccount.createAccountAddressAndFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
5955
6004
  return accountAddress;
@@ -5979,7 +6028,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
5979
6028
  ...overrides,
5980
6029
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
5981
6030
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
5982
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6031
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5983
6032
  };
5984
6033
  const [accountAddress, factoryAddress, factoryData] = SafeAccount.createAccountAddressAndFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
5985
6034
  const safe = new SafeMultiChainSigAccountV1(accountAddress, {
@@ -6056,7 +6105,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6056
6105
  static createInitializerCallData(owners, threshold, overrides = {}) {
6057
6106
  const safe4337ModuleAddress = overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS;
6058
6107
  const safeModuleSetupAddress = overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS;
6059
- 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);
6108
+ 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);
6060
6109
  }
6061
6110
  /**
6062
6111
  * create account factory address and factory data
@@ -6069,7 +6118,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6069
6118
  ...overrides,
6070
6119
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
6071
6120
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6072
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6121
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
6073
6122
  };
6074
6123
  return SafeAccount.createFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
6075
6124
  }
@@ -6091,7 +6140,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6091
6140
  isMultiChainSignature: true,
6092
6141
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
6093
6142
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6094
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6143
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6095
6144
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6096
6145
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6097
6146
  webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE
@@ -6119,14 +6168,13 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6119
6168
  * @param useroperation - useroperation to sign
6120
6169
  * @param privateKeys - for the signers
6121
6170
  * @param chainId - target chain id
6122
- * @param overrides - overrides for the default values
6123
- * @param overrides.validAfter - timestamp the signature will be valid after
6124
- * @param overrides.validUntil - timestamp the signature will be valid until
6171
+ * @param options - {@link SafeSignatureOptions} — timing, multiChainMerkleProof, module address. The multi-chain flag is force-set true and overrides any caller value.
6125
6172
  * @returns signature
6126
6173
  */
6127
- signUserOperation(userOperation, privateKeys, chainId, overrides = {}) {
6174
+ signUserOperation(userOperation, privateKeys, chainId, options = {}) {
6175
+ if (options.multiChainMerkleProof != null && options.multiChainMerkleProof.length > 0) throw new RangeError("signUserOperation does not accept multiChainMerkleProof; use signUserOperations for multi-op Merkle signatures");
6128
6176
  return SafeAccount.baseSignSingleUserOperation(userOperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, {
6129
- ...overrides,
6177
+ ...options,
6130
6178
  isMultiChainSignature: true
6131
6179
  });
6132
6180
  }
@@ -6135,16 +6183,28 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6135
6183
  * {@link AkSigner} instances. See
6136
6184
  * {@link SafeAccountV0_3_0.signUserOperationWithSigners} for the full
6137
6185
  * design rationale. Sets the multi-chain flag automatically.
6186
+ *
6187
+ * @param userOperation - UserOperation to sign
6188
+ * @param signers - one ExternalSigner per owner (any order)
6189
+ * @param chainId - target chain id
6190
+ * @param options - {@link SafeSignatureOptions} — timing, multiChainMerkleProof, module address. The multi-chain flag is force-set true and overrides any caller value.
6191
+ * @returns Promise resolving to the formatted signature string
6138
6192
  */
6139
- signUserOperationWithSigners(userOperation, signers, chainId, overrides = {}) {
6193
+ signUserOperationWithSigners(userOperation, signers, chainId, options = {}) {
6194
+ if (options.multiChainMerkleProof != null && options.multiChainMerkleProof.length > 0) throw new RangeError("signUserOperationWithSigners does not accept multiChainMerkleProof; use signUserOperationsWithSigners for multi-op Merkle signatures");
6140
6195
  const context = {
6141
6196
  userOperation,
6142
6197
  chainId,
6143
6198
  entryPoint: this.entrypointAddress
6144
6199
  };
6145
- return SafeAccount.baseSignUserOperationWithSigners(userOperation, signers, chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, {
6146
- ...overrides,
6147
- isMultiChainSignature: true
6200
+ return SafeAccount.baseSignUserOperationWithSigners(userOperation, signers, chainId, {
6201
+ entrypointAddress: this.entrypointAddress,
6202
+ safe4337ModuleAddress: this.safe4337ModuleAddress,
6203
+ context,
6204
+ options: {
6205
+ ...options,
6206
+ isMultiChainSignature: true
6207
+ }
6148
6208
  });
6149
6209
  }
6150
6210
  /**
@@ -6265,10 +6325,15 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6265
6325
  return userOpSignatures;
6266
6326
  } else {
6267
6327
  const u = userOperationsToSign[0];
6268
- return [await SafeAccount.baseSignUserOperationWithSigners(u.userOperation, signers, u.chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, {
6269
- validAfter: u.validAfter,
6270
- validUntil: u.validUntil,
6271
- isMultiChainSignature: true
6328
+ return [await SafeAccount.baseSignUserOperationWithSigners(u.userOperation, signers, u.chainId, {
6329
+ entrypointAddress: this.entrypointAddress,
6330
+ safe4337ModuleAddress: this.safe4337ModuleAddress,
6331
+ context,
6332
+ options: {
6333
+ validAfter: u.validAfter,
6334
+ validUntil: u.validUntil,
6335
+ isMultiChainSignature: true
6336
+ }
6272
6337
  })];
6273
6338
  }
6274
6339
  }
@@ -6318,28 +6383,34 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6318
6383
  */
6319
6384
  static formatSignaturesToUseroperationsSignatures(userOperationsToSign, signerSignaturePairs) {
6320
6385
  if (userOperationsToSign.length < 1) throw new RangeError("There should be at least one userOperationsToSign");
6321
- const defaultOverrides = {
6386
+ const defaultWebAuthnOverrides = {
6322
6387
  eip7212WebAuthnPrecompileVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6323
- eip7212WebAuthnContractVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6388
+ eip7212WebAuthnContractVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6324
6389
  webAuthnSignerFactory: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6325
6390
  webAuthnSignerSingleton: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6326
6391
  webAuthnSignerProxyCreationCode: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
6327
- safe4337ModuleAddress: SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS,
6328
6392
  webAuthnSharedSigner: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER
6329
6393
  };
6394
+ const defaultOptions = { safe4337ModuleAddress: SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS };
6330
6395
  if (userOperationsToSign.length === 1) return [SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
6331
- ...defaultOverrides,
6332
- ...userOperationsToSign[0].overrides,
6396
+ ...defaultOptions,
6397
+ ...defaultWebAuthnOverrides,
6398
+ ...userOperationsToSign[0].options,
6399
+ ...userOperationsToSign[0].webAuthnSignatureOverrides,
6333
6400
  validAfter: userOperationsToSign[0].validAfter,
6334
6401
  validUntil: userOperationsToSign[0].validUntil,
6335
6402
  isMultiChainSignature: true
6336
6403
  })];
6337
6404
  const userOperationsHashes = [];
6338
- userOperationsToSign.forEach((userOperationToSign, _index) => {
6405
+ const resolvedValidity = userOperationsToSign.map((userOperationToSign) => ({
6406
+ validAfter: userOperationToSign.options?.validAfter ?? userOperationToSign.validAfter,
6407
+ validUntil: userOperationToSign.options?.validUntil ?? userOperationToSign.validUntil
6408
+ }));
6409
+ userOperationsToSign.forEach((userOperationToSign, index) => {
6339
6410
  const userOperationHash = SafeAccount.getUserOperationEip712Hash_V9(userOperationToSign.userOperation, userOperationToSign.chainId, {
6340
- validAfter: userOperationToSign.validAfter,
6341
- validUntil: userOperationToSign.validUntil,
6342
- safe4337ModuleAddress: userOperationToSign.overrides?.safe4337ModuleAddress ?? defaultOverrides.safe4337ModuleAddress
6411
+ validAfter: resolvedValidity[index].validAfter,
6412
+ validUntil: resolvedValidity[index].validUntil,
6413
+ safe4337ModuleAddress: userOperationToSign.options?.safe4337ModuleAddress ?? defaultOptions.safe4337ModuleAddress
6343
6414
  });
6344
6415
  userOperationsHashes.push(userOperationHash);
6345
6416
  });
@@ -6347,8 +6418,12 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6347
6418
  const userOpSignatures = [];
6348
6419
  userOperationsToSign.forEach((userOperationToSign, index) => {
6349
6420
  userOpSignatures.push(SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
6350
- ...defaultOverrides,
6351
- ...userOperationToSign.overrides,
6421
+ ...defaultOptions,
6422
+ ...defaultWebAuthnOverrides,
6423
+ ...userOperationToSign.options,
6424
+ ...userOperationToSign.webAuthnSignatureOverrides,
6425
+ validAfter: resolvedValidity[index].validAfter,
6426
+ validUntil: resolvedValidity[index].validUntil,
6352
6427
  isMultiChainSignature: true,
6353
6428
  multiChainMerkleProof: proofs[index]
6354
6429
  }));
@@ -6359,7 +6434,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6359
6434
  return SafeAccount.createWebAuthnSignerVerifierAddress(x, y, {
6360
6435
  ...overrides,
6361
6436
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6362
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6437
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6363
6438
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6364
6439
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6365
6440
  webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE
@@ -6369,7 +6444,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6369
6444
  return SafeAccount.createDeployWebAuthnVerifierMetaTransaction(x, y, {
6370
6445
  ...overrides,
6371
6446
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6372
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6447
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6373
6448
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY
6374
6449
  });
6375
6450
  }
@@ -6377,7 +6452,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6377
6452
  return SafeAccount.createDummySignerSignaturePairForExpectedSigners(expectedSigners, {
6378
6453
  ...webAuthnSignatureOverrides,
6379
6454
  eip7212WebAuthnPrecompileVerifier: webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6380
- eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6455
+ eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6381
6456
  webAuthnSignerFactory: webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6382
6457
  webAuthnSignerSingleton: webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6383
6458
  webAuthnSignerProxyCreationCode: webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
@@ -6388,7 +6463,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6388
6463
  return SafeAccount.verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, {
6389
6464
  ...overrides,
6390
6465
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6391
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6466
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6392
6467
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON
6393
6468
  });
6394
6469
  }
@@ -6726,27 +6801,139 @@ var BaseSimple7702Account = class BaseSimple7702Account extends SmartAccount {
6726
6801
  return new Wallet(privateKey).signingKey.sign(userOperationHash).serialized;
6727
6802
  }
6728
6803
  /**
6729
- * Schemes Simple7702 accepts from a Signer. Only raw-hash ECDSA, since
6730
- * the delegatee verifies a plain signature over the userOp hash.
6804
+ * Schemes Simple7702 accepts from a Signer. EntryPoint v0.8/v0.9 introduced
6805
+ * an EIP-712 domain at the EntryPoint contract, and the userOpHash IS the
6806
+ * EIP-712 digest of the PackedUserOperation under that domain — so signing
6807
+ * the typed data and signing the raw hash produce signatures that verify
6808
+ * against the same `userOpHash` (and recover to the same signer address).
6809
+ * Deterministic-ECDSA signers (ethers, viem, MetaMask) yield byte-identical
6810
+ * bytes; signers that differ in `s` / `v` normalization still validate the
6811
+ * same on-chain.
6812
+ *
6813
+ * `typedData` is listed first so JSON-RPC wallets that can only sign typed
6814
+ * data work without a separate code path; `hash` remains a valid fallback
6815
+ * for local-key signers.
6731
6816
  */
6732
- static ACCEPTED_SIGNING_SCHEMES = ["hash"];
6817
+ static ACCEPTED_SIGNING_SCHEMES = ["typedData", "hash"];
6733
6818
  /**
6734
- * Sign a UserOperation with an {@link AkSigner}. Signer must implement
6735
- * `signHash`, since Simple7702 only verifies raw ECDSA over the userOp
6736
- * hash. JSON-RPC wallets and anything that only provides `signTypedData`
6737
- * fail offline with a specific error.
6819
+ * Build the EIP-712 typed data payload for a UserOperation under the
6820
+ * EntryPoint v0.8 / v0.9 domain. Lower-level escape hatch for integrators
6821
+ * driving `signTypedData` themselves with their own signing primitive
6822
+ * (HSM, MPC, custom wallet abstraction). Most callers should pass an
6823
+ * {@link AkSigner} to {@link signUserOperationWithSigner} instead, which
6824
+ * builds this internally.
6825
+ *
6826
+ * The digest of the returned payload equals the UserOperation hash from
6827
+ * {@link createUserOperationHash}, so a wallet calling
6828
+ * `signTypedData(domain, types, message)` produces a signature that
6829
+ * verifies against the same `userOpHash` as raw ECDSA over that hash.
6830
+ * Deterministic-ECDSA signers yield byte-identical signatures; signers
6831
+ * that differ in `s` / `v` normalization still validate the same on-chain.
6832
+ *
6833
+ * Common use cases beyond direct signing:
6834
+ * - Inspect / log the typed data the wallet will display.
6835
+ * - Render a custom confirmation UI before delegating to a wallet's
6836
+ * `signTypedData`.
6837
+ * - Drive non-`ExternalSigner`-shaped signers (HSM, MPC service,
6838
+ * backend signing pipelines).
6839
+ *
6840
+ * @param userOperation - Unsigned UserOperation to wrap
6841
+ * @param chainId - Target chain ID (must match the chain that will validate
6842
+ * the signature)
6843
+ * @returns EIP-712 {@link TypedData} payload ready for `signTypedData`
6844
+ * @throws {AbstractionKitError} if this account targets an EntryPoint
6845
+ * version other than v0.8 / v0.9. Earlier EntryPoints define the
6846
+ * userOpHash differently and require raw-hash signing.
6847
+ */
6848
+ getUserOperationEip712TypedData(userOperation, chainId) {
6849
+ const ep = this.entrypointAddress.toLowerCase();
6850
+ const isV9 = ep === ENTRYPOINT_V9.toLowerCase();
6851
+ 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.`);
6852
+ const abiCoder = AbiCoder.defaultAbiCoder();
6853
+ const initCode = buildPackedInitCodeV8V9(userOperation);
6854
+ const accountGasLimits = "0x" + abiCoder.encode(["uint128"], [userOperation.verificationGasLimit]).slice(34) + abiCoder.encode(["uint128"], [userOperation.callGasLimit]).slice(34);
6855
+ const gasFees = "0x" + abiCoder.encode(["uint128"], [userOperation.maxPriorityFeePerGas]).slice(34) + abiCoder.encode(["uint128"], [userOperation.maxFeePerGas]).slice(34);
6856
+ const paymasterAndData = buildPaymasterAndData(userOperation, isV9);
6857
+ return {
6858
+ domain: {
6859
+ name: "ERC4337",
6860
+ version: "1",
6861
+ chainId,
6862
+ verifyingContract: this.entrypointAddress
6863
+ },
6864
+ types: { PackedUserOperation: [
6865
+ {
6866
+ name: "sender",
6867
+ type: "address"
6868
+ },
6869
+ {
6870
+ name: "nonce",
6871
+ type: "uint256"
6872
+ },
6873
+ {
6874
+ name: "initCode",
6875
+ type: "bytes"
6876
+ },
6877
+ {
6878
+ name: "callData",
6879
+ type: "bytes"
6880
+ },
6881
+ {
6882
+ name: "accountGasLimits",
6883
+ type: "bytes32"
6884
+ },
6885
+ {
6886
+ name: "preVerificationGas",
6887
+ type: "uint256"
6888
+ },
6889
+ {
6890
+ name: "gasFees",
6891
+ type: "bytes32"
6892
+ },
6893
+ {
6894
+ name: "paymasterAndData",
6895
+ type: "bytes"
6896
+ }
6897
+ ] },
6898
+ primaryType: "PackedUserOperation",
6899
+ message: {
6900
+ sender: userOperation.sender,
6901
+ nonce: userOperation.nonce,
6902
+ initCode,
6903
+ callData: userOperation.callData,
6904
+ accountGasLimits,
6905
+ preVerificationGas: userOperation.preVerificationGas,
6906
+ gasFees,
6907
+ paymasterAndData
6908
+ }
6909
+ };
6910
+ }
6911
+ /**
6912
+ * Sign a UserOperation with an {@link AkSigner}. The signer can implement
6913
+ * either `signTypedData` (preferred — JSON-RPC wallets, viem `WalletClient`)
6914
+ * or `signHash` (local keys, hardware wallets). Both schemes produce
6915
+ * signatures that validate against the same `userOpHash` because the
6916
+ * v0.8 / v0.9 userOpHash IS the EIP-712 digest of the PackedUserOperation
6917
+ * (deterministic-ECDSA signers yield byte-identical bytes).
6918
+ *
6919
+ * Signers that implement neither method fail offline with an actionable
6920
+ * error.
6738
6921
  */
6739
6922
  async baseSignUserOperationWithSigner(useroperation, signer, chainId) {
6740
- return invokeSigner(signer, pickScheme(signer, BaseSimple7702Account.ACCEPTED_SIGNING_SCHEMES, {
6741
- accountName: "Simple7702 (raw ECDSA over userOpHash)",
6923
+ const scheme = pickScheme(signer, BaseSimple7702Account.ACCEPTED_SIGNING_SCHEMES, {
6924
+ accountName: "Simple7702 (EIP-712 typed data or raw ECDSA over userOpHash)",
6742
6925
  signerIndex: 0
6743
- }), {
6744
- hash: createUserOperationHash(useroperation, this.entrypointAddress, chainId),
6745
- context: {
6746
- userOperation: useroperation,
6747
- chainId,
6748
- entryPoint: this.entrypointAddress
6749
- }
6926
+ });
6927
+ const hash = createUserOperationHash(useroperation, this.entrypointAddress, chainId);
6928
+ const context = {
6929
+ userOperation: useroperation,
6930
+ chainId,
6931
+ entryPoint: this.entrypointAddress
6932
+ };
6933
+ return invokeSigner(signer, scheme, {
6934
+ hash,
6935
+ typedData: scheme === "typedData" ? this.getUserOperationEip712TypedData(useroperation, chainId) : void 0,
6936
+ context
6750
6937
  });
6751
6938
  }
6752
6939
  /**
@@ -6860,13 +7047,34 @@ var Simple7702Account = class Simple7702Account extends BaseSimple7702Account {
6860
7047
  return this.baseSignUserOperation(useroperation, privateKey, chainId);
6861
7048
  }
6862
7049
  /**
6863
- * Sign a {@link UserOperationV8} using an {@link ExternalSigner}.
6864
- * Simple7702 only accepts raw-hash ECDSA; signers without `signHash`
6865
- * fail offline with an actionable error.
7050
+ * Sign a {@link UserOperationV8} using an {@link ExternalSigner}. This is
7051
+ * the recommended entry point for any non-private-key signer.
7052
+ *
7053
+ * Accepts signers that implement `signTypedData` (JSON-RPC wallets, viem
7054
+ * `WalletClient`, browser wallets), `signHash` (local keys, hardware
7055
+ * wallets), or both. The v0.8 userOpHash IS the EIP-712 digest of the
7056
+ * PackedUserOperation under the EntryPoint domain, so both schemes
7057
+ * produce signatures that validate against the same `userOpHash`.
7058
+ *
7059
+ * Wrapping a custom signing primitive is just an object literal; no
7060
+ * adapter function required:
7061
+ *
7062
+ * ```ts
7063
+ * const signer: ExternalSigner = {
7064
+ * address: ownerAddress,
7065
+ * signTypedData: async (td) => myWallet.signTypedData(td),
7066
+ * }
7067
+ * userOp.signature = await account.signUserOperationWithSigner(userOp, signer, chainId)
7068
+ * ```
6866
7069
  *
6867
7070
  * For signing with a raw private-key string, use the sync
6868
7071
  * {@link signUserOperation} method, or wrap explicitly with
6869
7072
  * `fromPrivateKey(pk)`.
7073
+ *
7074
+ * @see {@link BaseSimple7702Account.getUserOperationEip712TypedData} for
7075
+ * the lower-level escape hatch when you need the typed data outside the
7076
+ * dispatcher (e.g., to render a custom confirmation UI or feed an HSM
7077
+ * that doesn't fit the {@link ExternalSigner} shape).
6870
7078
  */
6871
7079
  async signUserOperationWithSigner(useroperation, signer, chainId) {
6872
7080
  return this.baseSignUserOperationWithSigner(useroperation, signer, chainId);
@@ -6937,10 +7145,33 @@ var Simple7702AccountV09 = class Simple7702AccountV09 extends BaseSimple7702Acco
6937
7145
  return this.baseSignUserOperation(useroperation, privateKey, chainId);
6938
7146
  }
6939
7147
  /**
6940
- * Sign a {@link UserOperationV9} using an {@link ExternalSigner}.
6941
- * Simple7702 only accepts raw-hash ECDSA; signers without `signHash`
6942
- * fail offline with an actionable error. For a raw pk string, use the
6943
- * sync {@link signUserOperation} method or wrap with `fromPrivateKey`.
7148
+ * Sign a {@link UserOperationV9} using an {@link ExternalSigner}. This is
7149
+ * the recommended entry point for any non-private-key signer.
7150
+ *
7151
+ * Accepts signers that implement `signTypedData` (JSON-RPC wallets, viem
7152
+ * `WalletClient`, browser wallets), `signHash` (local keys, hardware
7153
+ * wallets), or both. The v0.9 userOpHash IS the EIP-712 digest of the
7154
+ * PackedUserOperation under the EntryPoint domain, so both schemes
7155
+ * produce signatures that validate against the same `userOpHash`.
7156
+ *
7157
+ * Wrapping a custom signing primitive is just an object literal; no
7158
+ * adapter function required:
7159
+ *
7160
+ * ```ts
7161
+ * const signer: ExternalSigner = {
7162
+ * address: ownerAddress,
7163
+ * signTypedData: async (td) => myWallet.signTypedData(td),
7164
+ * }
7165
+ * userOp.signature = await account.signUserOperationWithSigner(userOp, signer, chainId)
7166
+ * ```
7167
+ *
7168
+ * For signing with a raw private-key string, use the sync
7169
+ * {@link signUserOperation} method, or wrap explicitly with
7170
+ * `fromPrivateKey(pk)`.
7171
+ *
7172
+ * @see {@link BaseSimple7702Account.getUserOperationEip712TypedData} for
7173
+ * the lower-level escape hatch when you need the typed data outside the
7174
+ * dispatcher.
6944
7175
  */
6945
7176
  async signUserOperationWithSigner(useroperation, signer, chainId) {
6946
7177
  return this.baseSignUserOperationWithSigner(useroperation, signer, chainId);
@@ -7951,6 +8182,280 @@ function createWorldIdSignal(accountAddress, accountNonce, chainId) {
7951
8182
  ]));
7952
8183
  }
7953
8184
  //#endregion
8185
+ //#region src/account/Safe/adapters.ts
8186
+ /**
8187
+ * Adapt a WebAuthn credential to a Signer for `signUserOperationWithSigners`
8188
+ * on Safe accounts. Safe-specific (uses Safe's WebAuthn shared signer /
8189
+ * verifier proxy / signature encoding) — for non-Safe accounts, use the
8190
+ * account's own WebAuthn adapter.
8191
+ *
8192
+ * Hides the address routing (shared signer for the init UserOp, per-owner
8193
+ * verifier proxy after that), the `type: "contract"` tag, and the
8194
+ * Safe-specific signature encoding. The caller supplies a
8195
+ * {@link FromSafeWebauthnParams.getAssertion} callback that runs the
8196
+ * actual WebAuthn ceremony — this is where you call
8197
+ * `navigator.credentials.get(...)` (browser) or an equivalent native
8198
+ * bridge, since the SDK doesn't import `navigator` itself.
8199
+ *
8200
+ * Only `signHash` is exposed: WebAuthn signs a flat challenge, so a typed-data
8201
+ * preview would never reach the authenticator anyway.
8202
+ *
8203
+ * **Override consistency.** Pass the same `accountClass` you passed to
8204
+ * `initializeNewAccount` so the adapter sources the right Safe Passkey
8205
+ * module defaults — v0.2.0 / FCL P256 for `SafeAccount` / `SafeAccountV0_2_0`
8206
+ * / `SafeAccountV0_3_0`, v0.2.1 / Daimo P256 + RIP-7951 for
8207
+ * `SafeMultiChainSigAccountV1`. Every individual WebAuthn override
8208
+ * (`webAuthnSharedSigner`, `webAuthnSignerFactory`, `webAuthnSignerSingleton`,
8209
+ * `webAuthnSignerProxyCreationCode`, `eip7212WebAuthnPrecompileVerifier`,
8210
+ * `eip7212WebAuthnContractVerifier`) must likewise match what was passed to
8211
+ * `InitCodeOverrides` at init time — only set them when you've also
8212
+ * overridden them at init. The on-chain owner set is locked to whatever was
8213
+ * used at init: `webAuthnSharedSigner` for `isInit=true`, the deterministic
8214
+ * verifier proxy derived from the other five for `isInit=false`. A mismatch
8215
+ * produces a signature pointing at an address that isn't an owner; on-chain
8216
+ * `checkSignatures` reverts with `GS026` and the bundler surfaces it as a
8217
+ * generic "Invalid UserOp signature" with no offline diagnostic.
8218
+ *
8219
+ * @example
8220
+ * import { fromSafeWebauthn, SafeAccountV0_3_0 } from "abstractionkit";
8221
+ *
8222
+ * // Pass `expectedSigners: [{ x, y }]` so createUserOperation picks the
8223
+ * // WebAuthn dummy signature for gas estimation. Without it, the
8224
+ * // bundler sizes verification gas against the EOA dummy and the
8225
+ * // real signed UserOp gets rejected (or under-budgeted on-chain) at submit.
8226
+ * let userOperation = await safe.createUserOperation(
8227
+ * transactions, nodeUrl, bundlerUrl,
8228
+ * { expectedSigners: [{ x, y }] },
8229
+ * );
8230
+ *
8231
+ * const signer = fromSafeWebauthn({
8232
+ * publicKey: { x, y },
8233
+ * isInit: userOperation.nonce === 0n,
8234
+ * accountClass: SafeAccountV0_3_0, // SafeMultiChainSigAccountV1 for multi-chain
8235
+ * getAssertion: async (challenge) => {
8236
+ * const assertion = await navigator.credentials.get({
8237
+ * publicKey: { challenge, rpId, allowCredentials, userVerification },
8238
+ * });
8239
+ * return {
8240
+ * authenticatorData: assertion.response.authenticatorData,
8241
+ * clientDataFields: extractClientDataFields(assertion.response),
8242
+ * rs: extractSignature(assertion.response),
8243
+ * };
8244
+ * },
8245
+ * });
8246
+ * userOperation.signature = await safe.signUserOperationWithSigners(
8247
+ * userOperation, [signer], chainId,
8248
+ * );
8249
+ */
8250
+ function fromSafeWebauthn(params) {
8251
+ const { publicKey, isInit, getAssertion, accountClass, webAuthnSharedSigner, webAuthnSignerFactory, webAuthnSignerSingleton, webAuthnSignerProxyCreationCode, eip7212WebAuthnPrecompileVerifier, eip7212WebAuthnContractVerifier } = params;
8252
+ 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).");
8253
+ return {
8254
+ address: isInit ? webAuthnSharedSigner ?? accountClass.DEFAULT_WEB_AUTHN_SHARED_SIGNER : SafeAccount.createWebAuthnSignerVerifierAddress(publicKey.x, publicKey.y, {
8255
+ webAuthnSignerFactory: webAuthnSignerFactory ?? accountClass.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
8256
+ webAuthnSignerSingleton: webAuthnSignerSingleton ?? accountClass.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
8257
+ webAuthnSignerProxyCreationCode: webAuthnSignerProxyCreationCode ?? accountClass.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
8258
+ eip7212WebAuthnPrecompileVerifier: eip7212WebAuthnPrecompileVerifier ?? accountClass.DEFAULT_WEB_AUTHN_PRECOMPILE,
8259
+ eip7212WebAuthnContractVerifier: eip7212WebAuthnContractVerifier ?? accountClass.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
8260
+ }),
8261
+ type: "contract",
8262
+ signHash: async (hash) => {
8263
+ const assertion = await getAssertion(getBytes(hash));
8264
+ return SafeAccount.createWebAuthnSignature(assertion);
8265
+ }
8266
+ };
8267
+ }
8268
+ /**
8269
+ * Coerce a `{ x, y }` pair where each coord may be `bigint`, hex string
8270
+ * (`"0x..."`), decimal string, or a safe-integer number into a canonical
8271
+ * {@link WebauthnPublicKey} with bigint coords. Used internally by
8272
+ * {@link pubkeyCoordinatesFromJson} — for non-JSON inputs (URL params,
8273
+ * RPC responses), pass the pre-parsed object straight to that helper.
8274
+ *
8275
+ * @throws if either coordinate is missing, the wrong type, or an
8276
+ * unparseable string.
8277
+ */
8278
+ function toBigintPubkey(pubkey) {
8279
+ if (!pubkey || pubkey.x == null || pubkey.y == null) throw new Error("toBigintPubkey: pubkey must be `{ x, y }` with both coords set");
8280
+ return {
8281
+ x: coerceBigint(pubkey.x, "x"),
8282
+ y: coerceBigint(pubkey.y, "y")
8283
+ };
8284
+ }
8285
+ function coerceBigint(v, field) {
8286
+ let coerced;
8287
+ if (typeof v === "bigint") coerced = v;
8288
+ else if (typeof v === "string") try {
8289
+ coerced = BigInt(v);
8290
+ } catch {
8291
+ throw new Error(`toBigintPubkey: pubkey.${field} ("${v}") is not a valid bigint string. Accepted: non-negative bigint, decimal string, or 0x-prefixed hex string.`);
8292
+ }
8293
+ else if (typeof v === "number") {
8294
+ 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.`);
8295
+ coerced = BigInt(v);
8296
+ } else throw new Error(`toBigintPubkey: pubkey.${field} must be bigint, string, or number (got ${typeof v})`);
8297
+ 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.`);
8298
+ return coerced;
8299
+ }
8300
+ /**
8301
+ * Serialize a WebAuthn pubkey to a JSON string with hex-encoded
8302
+ * coordinates. Inverse of {@link pubkeyCoordinatesFromJson}.
8303
+ *
8304
+ * Any JSON-string persistence — localStorage, backend indexes, query
8305
+ * strings, IPC payloads — eventually needs a custom replacer for
8306
+ * `bigint` (which `JSON.stringify` can't serialize on its own). This
8307
+ * helper ships the canonical version so the round-trip is consistent
8308
+ * across call sites.
8309
+ *
8310
+ * @example
8311
+ * ```ts
8312
+ * localStorage.setItem("passkey", pubkeyCoordinatesToJson({ x: 0x7a..., y: 0x2e... }));
8313
+ * // Stored as: {"x":"0x7a...","y":"0x2e..."}
8314
+ * ```
8315
+ */
8316
+ function pubkeyCoordinatesToJson(pubkey) {
8317
+ return JSON.stringify({
8318
+ x: "0x" + pubkey.x.toString(16),
8319
+ y: "0x" + pubkey.y.toString(16)
8320
+ });
8321
+ }
8322
+ /**
8323
+ * Parse a JSON string produced by {@link pubkeyCoordinatesToJson} (or
8324
+ * any JSON object with `x` / `y` fields as bigint-compatible values)
8325
+ * back into a {@link WebauthnPublicKey} with bigint coords.
8326
+ *
8327
+ * Lenient about input shape: accepts a JSON string, a pre-parsed object
8328
+ * (skip `JSON.parse` if you already ran it), and either hex (`"0x..."`)
8329
+ * or decimal-string coords. Same one-line cost regardless of where the
8330
+ * string came from — localStorage, backend response, query parameter.
8331
+ *
8332
+ * @example
8333
+ * ```ts
8334
+ * const raw = localStorage.getItem("passkey");
8335
+ * if (raw) {
8336
+ * const pubkey = pubkeyCoordinatesFromJson(raw);
8337
+ * // pubkey: { x: bigint, y: bigint }
8338
+ * }
8339
+ * ```
8340
+ */
8341
+ function pubkeyCoordinatesFromJson(input) {
8342
+ return toBigintPubkey(typeof input === "string" ? JSON.parse(input) : input);
8343
+ }
8344
+ /**
8345
+ * Turn a structural {@link AuthenticatorAssertionLike} into
8346
+ * {@link WebauthnSignatureData}, ready to feed straight into
8347
+ * `SafeAccount.createWebAuthnSignature` or the `getAssertion` callback
8348
+ * of `fromSafeWebauthn`.
8349
+ *
8350
+ * Replaces the ~13-line manual pipeline every Safe-passkeys consumer
8351
+ * has been writing — `JSON.parse` of `clientDataJSON`, destructure +
8352
+ * re-serialize the non-`type` / non-`challenge` fields, hex-encode,
8353
+ * normalize `authenticatorData`, parse DER signature → `(r, s)` —
8354
+ * with a single call.
8355
+ *
8356
+ * @example Browser:
8357
+ * ```ts
8358
+ * const assertion = await navigator.credentials.get({...});
8359
+ * return webauthnSignatureFromAssertion(assertion.response);
8360
+ * ```
8361
+ *
8362
+ * @example `ox/WebAuthnP256`:
8363
+ * ```ts
8364
+ * const { metadata, signature } = await sign({ challenge, credentialId });
8365
+ * return webauthnSignatureFromAssertion({
8366
+ * authenticatorData: metadata.authenticatorData, // hex string from ox
8367
+ * clientDataJSON: metadata.clientDataJSON, // string from ox
8368
+ * signature, // { r, s } from ox
8369
+ * });
8370
+ * ```
8371
+ */
8372
+ function webauthnSignatureFromAssertion(response) {
8373
+ const authenticatorData = toArrayBuffer(response.authenticatorData);
8374
+ const clientDataJSON = toUtf8String(response.clientDataJSON);
8375
+ const rs = toRSPair(response.signature);
8376
+ return {
8377
+ authenticatorData,
8378
+ clientDataFields: extractClientDataFieldsHex(clientDataJSON),
8379
+ rs: [rs.r, rs.s]
8380
+ };
8381
+ }
8382
+ function toArrayBuffer(input) {
8383
+ if (input instanceof ArrayBuffer) return input;
8384
+ const bytes = getBytes(input);
8385
+ return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
8386
+ }
8387
+ function toUtf8String(input) {
8388
+ if (typeof input === "string") return input;
8389
+ const bytes = input instanceof Uint8Array ? input : new Uint8Array(input);
8390
+ return new TextDecoder("utf-8").decode(bytes);
8391
+ }
8392
+ function toRSPair(input) {
8393
+ if (input !== null && typeof input === "object" && "r" in input && "s" in input && typeof input.r === "bigint" && typeof input.s === "bigint") return {
8394
+ r: input.r,
8395
+ s: input.s
8396
+ };
8397
+ return parseDerP256Signature(input instanceof Uint8Array ? input : new Uint8Array(input));
8398
+ }
8399
+ /**
8400
+ * Re-serialize every clientDataJSON field except `type` and `challenge`.
8401
+ * Robust to authenticators adding or reordering keys (e.g. Safari's
8402
+ * `crossOrigin`, future WebAuthn L3 fields) — parses JSON instead of
8403
+ * using a regex, validates the shape is a plain object, and emits hex
8404
+ * via `TextEncoder` (browser-safe; `Buffer` isn't defined in Vite /
8405
+ * Rollup / esbuild bundles without a polyfill).
8406
+ */
8407
+ function extractClientDataFieldsHex(clientDataJSON) {
8408
+ let parsed;
8409
+ try {
8410
+ parsed = JSON.parse(clientDataJSON);
8411
+ } catch (err) {
8412
+ throw new Error(`webauthnSignatureFromAssertion: clientDataJSON is not valid JSON (${err.message})`);
8413
+ }
8414
+ 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})`);
8415
+ const { type: _type, challenge: _challenge, ...rest } = parsed;
8416
+ const fields = Object.entries(rest).map(([key, value]) => `"${key}":${JSON.stringify(value)}`).join(",");
8417
+ return hexlify(new TextEncoder().encode(fields));
8418
+ }
8419
+ /**
8420
+ * Parse a DER-encoded ECDSA P-256 signature into `(r, s)` bigints with
8421
+ * low-S normalization. Defends against truncated / malformed DER: every
8422
+ * length and tag is bounds-checked against the buffer before slicing,
8423
+ * because `Uint8Array.subarray` silently clamps OOB indices and would
8424
+ * otherwise produce attacker-controlled-length r/s.
8425
+ *
8426
+ * DER layout:
8427
+ * 0x30 | total-len | 0x02 | r-len | r-bytes | 0x02 | s-len | s-bytes
8428
+ */
8429
+ function parseDerP256Signature(der) {
8430
+ const malformed = () => /* @__PURE__ */ new Error("webauthnSignatureFromAssertion: malformed DER signature");
8431
+ if (der.length < 8 || der[0] !== 48) throw malformed();
8432
+ const headerLen = der[1] === 129 ? 3 : 2;
8433
+ const outerLen = der[1] === 129 ? der[2] : der[1];
8434
+ if (der.length !== headerLen + outerLen) throw malformed();
8435
+ let offset = headerLen;
8436
+ if (offset + 2 > der.length) throw malformed();
8437
+ if (der[offset] !== 2) throw malformed();
8438
+ const rLen = der[offset + 1];
8439
+ if (rLen <= 0 || offset + 2 + rLen > der.length) throw malformed();
8440
+ const rBytes = der.subarray(offset + 2, offset + 2 + rLen);
8441
+ offset += 2 + rLen;
8442
+ if (offset + 2 > der.length) throw malformed();
8443
+ if (der[offset] !== 2) throw malformed();
8444
+ const sLen = der[offset + 1];
8445
+ if (sLen <= 0 || offset + 2 + sLen > der.length) throw malformed();
8446
+ const sBytes = der.subarray(offset + 2, offset + 2 + sLen);
8447
+ if (offset + 2 + sLen !== der.length) throw malformed();
8448
+ const r = rBytes.length === 0 ? 0n : BigInt(hexlify(rBytes));
8449
+ let s = sBytes.length === 0 ? 0n : BigInt(hexlify(sBytes));
8450
+ const P256_N = 115792089210356248762697446949407573529996955224135760342422259061068512044369n;
8451
+ const P256_N_HALF = P256_N >> 1n;
8452
+ if (s > P256_N_HALF) s = P256_N - s;
8453
+ return {
8454
+ r,
8455
+ s
8456
+ };
8457
+ }
8458
+ //#endregion
7954
8459
  //#region src/signer/adapters.ts
7955
8460
  /**
7956
8461
  * Build a Signer from a raw private-key hex string. Supports both raw-hash
@@ -8089,6 +8594,7 @@ var abstractionkit_exports = /* @__PURE__ */ __exportAll({
8089
8594
  fetchGasPrice: () => fetchGasPrice,
8090
8595
  fromEthersWallet: () => fromEthersWallet,
8091
8596
  fromPrivateKey: () => fromPrivateKey,
8597
+ fromSafeWebauthn: () => fromSafeWebauthn,
8092
8598
  fromViem: () => fromViem,
8093
8599
  fromViemWalletClient: () => fromViemWalletClient,
8094
8600
  getBalanceOf: () => getBalanceOf,
@@ -8096,6 +8602,8 @@ var abstractionkit_exports = /* @__PURE__ */ __exportAll({
8096
8602
  getDepositInfo: () => getDepositInfo,
8097
8603
  getFunctionSelector: () => getFunctionSelector,
8098
8604
  getSafeMessageEip712Data: () => getSafeMessageEip712Data,
8605
+ pubkeyCoordinatesFromJson: () => pubkeyCoordinatesFromJson,
8606
+ pubkeyCoordinatesToJson: () => pubkeyCoordinatesToJson,
8099
8607
  sendJsonRpcRequest: () => sendJsonRpcRequest,
8100
8608
  shareTenderlySimulationAndCreateLink: () => shareTenderlySimulationAndCreateLink,
8101
8609
  signHash: () => signHash,
@@ -8104,9 +8612,10 @@ var abstractionkit_exports = /* @__PURE__ */ __exportAll({
8104
8612
  simulateUserOperationCallDataWithTenderly: () => simulateUserOperationCallDataWithTenderly,
8105
8613
  simulateUserOperationCallDataWithTenderlyAndCreateShareLink: () => simulateUserOperationCallDataWithTenderlyAndCreateShareLink,
8106
8614
  simulateUserOperationWithTenderly: () => simulateUserOperationWithTenderly,
8107
- simulateUserOperationWithTenderlyAndCreateShareLink: () => simulateUserOperationWithTenderlyAndCreateShareLink
8615
+ simulateUserOperationWithTenderlyAndCreateShareLink: () => simulateUserOperationWithTenderlyAndCreateShareLink,
8616
+ webauthnSignatureFromAssertion: () => webauthnSignatureFromAssertion
8108
8617
  });
8109
8618
  //#endregion
8110
- export { ALLOWANCE_MODULE_V0_1_0_ADDRESS, AbstractionKitError, AllowanceModule, BaseUserOperationDummyValues, Bundler, CALIBUR_CANDIDE_V0_1_0_SINGLETON_ADDRESS, CALIBUR_UNISWAP_V1_0_0_SINGLETON_ADDRESS, Calibur7702Account, CaliburKeyType, CandidePaymaster, DEFAULT_SECP256R1_PRECOMPILE_ADDRESS, EIP712_MULTI_CHAIN_OPERATIONS_PRIMARY_TYPE, EIP712_MULTI_CHAIN_OPERATIONS_TYPE, EIP712_RECOVERY_MODULE_TYPE, EIP712_SAFE_OPERATION_PRIMARY_TYPE, EIP712_SAFE_OPERATION_V6_TYPE, EIP712_SAFE_OPERATION_V7_TYPE, ENTRYPOINT_V6, ENTRYPOINT_V7, ENTRYPOINT_V8, ENTRYPOINT_V9, EOADummySignerSignaturePair, EXECUTE_RECOVERY_PRIMARY_TYPE, Erc7677Paymaster, ExperimentalAllowAllParallelPaymaster, GasOption, Operation, PolygonChain, SAFE_MESSAGE_MODULE_TYPE, SAFE_MESSAGE_PRIMARY_TYPE, SafeAccountFactory, SafeAccountV0_2_0, SafeAccountV0_3_0, SafeAccountV1_5_0_M_0_3_0, SafeModuleExecutorFunctionSelector, SafeMultiChainSigAccountV1, SendUseroperationResponse, Simple7702Account, Simple7702AccountV09, SmartAccount, SmartAccountFactory, SocialRecoveryModule, SocialRecoveryModuleGracePeriodSelector, WebauthnDummySignerSignaturePair, WorldIdPermissionlessPaymaster, ZeroAddress, abstractionkit_exports as abstractionkit, calculateUserOperationMaxGasCost, callTenderlySimulateBundle, createAndSignEip7702DelegationAuthorization, createAndSignEip7702RawTransaction, createAndSignLegacyRawTransaction, createCallData, createEip7702DelegationAuthorizationHash, createEip7702TransactionHash, createUserOperationHash, createWorldIdSignal, fetchAccountNonce, fetchGasPrice, fromEthersWallet, fromPrivateKey, fromViem, fromViemWalletClient, getBalanceOf, getDelegatedAddress, getDepositInfo, getFunctionSelector, getSafeMessageEip712Data, sendJsonRpcRequest, shareTenderlySimulationAndCreateLink, signHash, simulateSenderCallDataWithTenderly, simulateSenderCallDataWithTenderlyAndCreateShareLink, simulateUserOperationCallDataWithTenderly, simulateUserOperationCallDataWithTenderlyAndCreateShareLink, simulateUserOperationWithTenderly, simulateUserOperationWithTenderlyAndCreateShareLink };
8619
+ export { ALLOWANCE_MODULE_V0_1_0_ADDRESS, AbstractionKitError, AllowanceModule, BaseUserOperationDummyValues, Bundler, CALIBUR_CANDIDE_V0_1_0_SINGLETON_ADDRESS, CALIBUR_UNISWAP_V1_0_0_SINGLETON_ADDRESS, Calibur7702Account, CaliburKeyType, CandidePaymaster, DEFAULT_SECP256R1_PRECOMPILE_ADDRESS, EIP712_MULTI_CHAIN_OPERATIONS_PRIMARY_TYPE, EIP712_MULTI_CHAIN_OPERATIONS_TYPE, EIP712_RECOVERY_MODULE_TYPE, EIP712_SAFE_OPERATION_PRIMARY_TYPE, EIP712_SAFE_OPERATION_V6_TYPE, EIP712_SAFE_OPERATION_V7_TYPE, ENTRYPOINT_V6, ENTRYPOINT_V7, ENTRYPOINT_V8, ENTRYPOINT_V9, EOADummySignerSignaturePair, EXECUTE_RECOVERY_PRIMARY_TYPE, Erc7677Paymaster, ExperimentalAllowAllParallelPaymaster, GasOption, Operation, PolygonChain, SAFE_MESSAGE_MODULE_TYPE, SAFE_MESSAGE_PRIMARY_TYPE, SafeAccountFactory, SafeAccountV0_2_0, SafeAccountV0_3_0, SafeAccountV1_5_0_M_0_3_0, SafeModuleExecutorFunctionSelector, SafeMultiChainSigAccountV1, SendUseroperationResponse, Simple7702Account, Simple7702AccountV09, SmartAccount, SmartAccountFactory, SocialRecoveryModule, SocialRecoveryModuleGracePeriodSelector, WebauthnDummySignerSignaturePair, WorldIdPermissionlessPaymaster, ZeroAddress, abstractionkit_exports as abstractionkit, calculateUserOperationMaxGasCost, callTenderlySimulateBundle, createAndSignEip7702DelegationAuthorization, createAndSignEip7702RawTransaction, createAndSignLegacyRawTransaction, createCallData, createEip7702DelegationAuthorizationHash, createEip7702TransactionHash, createUserOperationHash, createWorldIdSignal, fetchAccountNonce, fetchGasPrice, fromEthersWallet, fromPrivateKey, fromSafeWebauthn, fromViem, fromViemWalletClient, getBalanceOf, getDelegatedAddress, getDepositInfo, getFunctionSelector, getSafeMessageEip712Data, pubkeyCoordinatesFromJson, pubkeyCoordinatesToJson, sendJsonRpcRequest, shareTenderlySimulationAndCreateLink, signHash, simulateSenderCallDataWithTenderly, simulateSenderCallDataWithTenderlyAndCreateShareLink, simulateUserOperationCallDataWithTenderly, simulateUserOperationCallDataWithTenderlyAndCreateShareLink, simulateUserOperationWithTenderly, simulateUserOperationWithTenderlyAndCreateShareLink, webauthnSignatureFromAssertion };
8111
8620
 
8112
8621
  //# sourceMappingURL=index.mjs.map