abstractionkit 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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";
@@ -2754,6 +2783,33 @@ var SafeAccount = class SafeAccount extends SmartAccount {
2754
2783
  ]).slice(-40)}`);
2755
2784
  }
2756
2785
  /**
2786
+ * Check whether a Safe account is already deployed at the given address.
2787
+ *
2788
+ * Use this to decide between connecting to an existing account
2789
+ * (`new SafeAccountV0_3_0(address)`) and initializing a new one
2790
+ * (`SafeAccountV0_3_0.initializeNewAccount(owners)`). Once an account is
2791
+ * deployed, the factory data carried by `initializeNewAccount` is no
2792
+ * longer needed and including it would waste gas.
2793
+ *
2794
+ * Note: this only checks whether bytecode exists at `accountAddress`, not
2795
+ * whether the deployed code is actually a Safe or whether its on-chain
2796
+ * configuration matches a given set of owners.
2797
+ *
2798
+ * @param accountAddress - the Safe account address to check
2799
+ * @param nodeRpcUrl - Ethereum JSON-RPC node URL
2800
+ * @returns `true` if bytecode is deployed at `accountAddress`, `false` otherwise
2801
+ *
2802
+ * @example
2803
+ * ```ts
2804
+ * const account = (await SafeAccountV0_3_0.isDeployed(addr, rpc))
2805
+ * ? new SafeAccountV0_3_0(addr)
2806
+ * : SafeAccountV0_3_0.initializeNewAccount(owners);
2807
+ * ```
2808
+ */
2809
+ static async isDeployed(accountAddress, nodeRpcUrl) {
2810
+ return (await sendEthGetCodeRequest(nodeRpcUrl, accountAddress, "latest")).length > 2;
2811
+ }
2812
+ /**
2757
2813
  * encode calldata for a single MetaTransaction to be executed by Safe account
2758
2814
  * @param metaTransaction - metaTransaction to create calldata for
2759
2815
  * @param overrides - overrides for the default values
@@ -3150,7 +3206,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3150
3206
  */
3151
3207
  static createAccountAddressAndFactoryAddressAndData(owners, overrides, safe4337ModuleAddress, safeModuleSetupAddress) {
3152
3208
  if (owners.length < 1) throw new RangeError("There should be at least one owner");
3153
- 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);
3154
3210
  let safeAccountFactory;
3155
3211
  if (overrides.safeAccountFactoryAddress != null) safeAccountFactory = new SafeAccountFactory(overrides.safeAccountFactoryAddress);
3156
3212
  else safeAccountFactory = new SafeAccountFactory();
@@ -3172,7 +3228,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3172
3228
  factoryGeneratorFunctionCallData
3173
3229
  ];
3174
3230
  }
3175
- 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) {
3176
3232
  if (owners.length < 1) throw new RangeError("There should be at least one owner");
3177
3233
  if (threshold < 1) throw new RangeError("threshold should be at least one");
3178
3234
  if (threshold > owners.length) throw new RangeError("threshold can't be larger than number of owners");
@@ -3248,7 +3304,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3248
3304
  if (threshold < 1) throw new RangeError("threshold should be at least one");
3249
3305
  if (threshold > owners.length) throw new RangeError("threshold can't be larger than number of owners");
3250
3306
  if (c2Nonce < 0n) throw new RangeError("c2Nonce can't be negative");
3251
- 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);
3252
3308
  let safeAccountFactory;
3253
3309
  if (overrides.safeAccountFactoryAddress != null) safeAccountFactory = new SafeAccountFactory(overrides.safeAccountFactoryAddress);
3254
3310
  else safeAccountFactory = new SafeAccountFactory();
@@ -3310,9 +3366,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3310
3366
  eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier,
3311
3367
  webAuthnSignerFactory: overrides.webAuthnSignerFactory,
3312
3368
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton,
3313
- webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode,
3314
- validAfter,
3315
- validUntil
3369
+ webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode
3316
3370
  });
3317
3371
  userOperation.signature = SafeAccount.formatSignaturesToUseroperationSignature(dummySignerSignaturePairs, {
3318
3372
  validAfter,
@@ -3379,7 +3433,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3379
3433
  maxFeePerGas = overrides.maxFeePerGas ?? maxFeePerGas * BigInt((overrides.maxFeePerGasPercentageMultiplier ?? 0) + 100) / 100n;
3380
3434
  maxPriorityFeePerGas = overrides.maxPriorityFeePerGas ?? maxPriorityFeePerGas * BigInt((overrides.maxPriorityFeePerGasPercentageMultiplier ?? 0) + 100) / 100n;
3381
3435
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3382
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3436
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3383
3437
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3384
3438
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3385
3439
  const webAuthnSignerProxyCreationCode = overrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -3454,16 +3508,14 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3454
3508
  eip7212WebAuthnContractVerifier,
3455
3509
  webAuthnSignerFactory,
3456
3510
  webAuthnSignerSingleton,
3457
- webAuthnSignerProxyCreationCode,
3458
- validAfter,
3459
- validUntil
3511
+ webAuthnSignerProxyCreationCode
3460
3512
  });
3461
3513
  }
3462
3514
  userOperation.signature = SafeAccount.formatSignaturesToUseroperationSignature(dummySignerSignaturePairs, {
3463
3515
  validAfter,
3464
3516
  validUntil,
3465
- webAuthnSharedSigner,
3466
- isMultiChainSignature: overrides.isMultiChainSignature
3517
+ isMultiChainSignature: overrides.isMultiChainSignature,
3518
+ webAuthnSharedSigner
3467
3519
  });
3468
3520
  if (!(overrides.skipGasEstimation ?? false) && (overrides.preVerificationGas == null || overrides.verificationGasLimit == null || overrides.callGasLimit == null)) if (bundlerRpc != null) {
3469
3521
  userOperation.callGasLimit = 0n;
@@ -3530,14 +3582,15 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3530
3582
  * @param useroperation - useroperation to sign
3531
3583
  * @param privateKeys - for the signers
3532
3584
  * @param chainId - target chain id
3533
- * @param overrides - overrides for the default values
3534
- * @param overrides.validAfter - timestamp the signature will be valid after
3535
- * @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}
3536
3588
  * @returns signature
3537
3589
  */
3538
- static baseSignSingleUserOperation(useroperation, privateKeys, chainId, entrypointAddress, safe4337ModuleAddress, overrides = {}) {
3539
- const validAfter = overrides.validAfter ?? 0n;
3540
- 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;
3541
3594
  if (privateKeys.length < 1) throw new RangeError("There should be at least one privateKey");
3542
3595
  if (chainId < 0n) throw new RangeError("chainId can't be negative");
3543
3596
  if (validAfter < 0n) throw new RangeError("validAfter can't be negative");
@@ -3546,7 +3599,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3546
3599
  validAfter,
3547
3600
  validUntil,
3548
3601
  entrypointAddress,
3549
- safe4337ModuleAddress
3602
+ safe4337ModuleAddress: moduleAddress
3550
3603
  });
3551
3604
  const signerSignaturePairs = [];
3552
3605
  for (const privateKey of privateKeys) {
@@ -3558,9 +3611,9 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3558
3611
  });
3559
3612
  }
3560
3613
  return SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
3614
+ ...options,
3561
3615
  validAfter,
3562
- validUntil,
3563
- isMultiChainSignature: overrides.isMultiChainSignature
3616
+ validUntil
3564
3617
  });
3565
3618
  }
3566
3619
  /**
@@ -3583,20 +3636,24 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3583
3636
  * @param useroperation - UserOperation to sign
3584
3637
  * @param signers - Signer instances (`fromViem(account)`, `fromEthersWallet(wallet)`, etc.)
3585
3638
  * @param chainId - target chain id
3586
- * @param entrypointAddress - target EntryPoint
3587
- * @param safe4337ModuleAddress - Safe 4337 module
3588
- * @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}.
3589
3644
  * @returns formatted signature
3590
3645
  */
3591
- static async baseSignUserOperationWithSigners(useroperation, signers, chainId, entrypointAddress, safe4337ModuleAddress, context, overrides = {}) {
3592
- const validAfter = overrides.validAfter ?? 0n;
3593
- 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;
3594
3651
  if (signers.length < 1) throw new RangeError("There should be at least one signer");
3595
3652
  const typedDataRaw = SafeAccount.getUserOperationEip712Data(useroperation, chainId, {
3596
3653
  validAfter,
3597
3654
  validUntil,
3598
3655
  entrypointAddress,
3599
- safe4337ModuleAddress
3656
+ safe4337ModuleAddress: moduleAddress
3600
3657
  });
3601
3658
  const userOpHash = TypedDataEncoder.hash(typedDataRaw.domain, typedDataRaw.types, typedDataRaw.messageValue);
3602
3659
  const { EIP712Domain: _drop, ...primaryTypes } = typedDataRaw.types;
@@ -3617,12 +3674,13 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3617
3674
  context
3618
3675
  })))).map((signature, i) => ({
3619
3676
  signer: normalizedAddresses[i],
3620
- signature
3677
+ signature,
3678
+ isContractSignature: signers[i].type === "contract"
3621
3679
  }));
3622
3680
  return SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
3681
+ ...options,
3623
3682
  validAfter,
3624
- validUntil,
3625
- isMultiChainSignature: overrides.isMultiChainSignature
3683
+ validUntil
3626
3684
  });
3627
3685
  }
3628
3686
  /**
@@ -3635,7 +3693,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3635
3693
  */
3636
3694
  static createWebAuthnSignerVerifierAddress(x, y, overrides = {}) {
3637
3695
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3638
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3696
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3639
3697
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3640
3698
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3641
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____");
@@ -3666,15 +3724,15 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3666
3724
  /**
3667
3725
  * format a list of eip712 signatures to a useroperation signature
3668
3726
  * @param signerSignaturePairs - a list of a pair of a signer and it's signature
3669
- * @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.
3670
3728
  * @returns signature
3671
3729
  */
3672
- static formatSignaturesToUseroperationSignature(signerSignaturePairs, overrides = {}) {
3673
- const validAfter = overrides.validAfter ?? 0n;
3674
- const validUntil = overrides.validUntil ?? 0n;
3675
- const signature = SafeAccount.buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, overrides);
3676
- if (overrides.isMultiChainSignature) if (overrides.multiChainMerkleProof != null) {
3677
- 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;
3678
3736
  if (merkleProofLength < 128 || merkleProofLength % 64 !== 0) throw new RangeError("invalid multiChainMerkleProof length.");
3679
3737
  let merkleTreeDepthHex = (merkleProofLength / 64 - 1).toString(16);
3680
3738
  if (merkleTreeDepthHex.length % 2 === 0) merkleTreeDepthHex = `0x${merkleTreeDepthHex}`;
@@ -3688,7 +3746,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3688
3746
  merkleTreeDepthHex,
3689
3747
  validAfter,
3690
3748
  validUntil,
3691
- overrides.multiChainMerkleProof + signature.slice(2)
3749
+ options.multiChainMerkleProof + signature.slice(2)
3692
3750
  ]);
3693
3751
  } else return solidityPacked([
3694
3752
  "bytes1",
@@ -3721,7 +3779,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3721
3779
  if (typeof signer === "string") return signer.toLowerCase();
3722
3780
  else {
3723
3781
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3724
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3782
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3725
3783
  const webAuthnSignerFactory = overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3726
3784
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3727
3785
  const webAuthnSignerProxyCreationCode = overrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -3747,7 +3805,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3747
3805
  /**
3748
3806
  * format a list of eip712 signatures to a safe signature (without the time range)
3749
3807
  * @param signerSignaturePairs - a list of a pair of a signer and it's signature
3750
- * @param overrides - overrides for the default values
3808
+ * @param webAuthnSignatureOverrides - WebAuthn-only configuration (verifier addresses, init flag)
3751
3809
  * @returns signature
3752
3810
  */
3753
3811
  static buildSignaturesFromSingerSignaturePairs(signerSignaturePairs, webAuthnSignatureOverrides = {}) {
@@ -3761,7 +3819,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
3761
3819
  if (webAuthnSignatureOverrides.isInit) signer = webAuthnSignatureOverrides.webAuthnSharedSigner ?? SafeAccount.DEFAULT_WEB_AUTHN_SHARED_SIGNER;
3762
3820
  else {
3763
3821
  const eip7212WebAuthnPrecompileVerifier = webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
3764
- const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
3822
+ const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
3765
3823
  const webAuthnSignerFactory = webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
3766
3824
  const webAuthnSignerSingleton = webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
3767
3825
  const webAuthnSignerProxyCreationCode = webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -4032,7 +4090,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
4032
4090
  */
4033
4091
  static createDeployWebAuthnVerifierMetaTransaction(x, y, overrides = {}) {
4034
4092
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4035
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4093
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4036
4094
  return {
4037
4095
  to: overrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
4038
4096
  value: 0n,
@@ -4134,7 +4192,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
4134
4192
  signerSignaturePair.signer = webauthnsharedsigner;
4135
4193
  } else {
4136
4194
  const eip7212WebAuthnPrecompileVerifier = webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4137
- const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4195
+ const eip7212WebAuthnContractVerifier = webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4138
4196
  const webAuthnSignerFactory = webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_FACTORY;
4139
4197
  const webAuthnSignerSingleton = webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
4140
4198
  const webAuthnSignerProxyCreationCode = webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE;
@@ -4168,7 +4226,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
4168
4226
  static async verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, overrides = {}) {
4169
4227
  if (messageHash.length !== 66 || messageHash.slice(0, 2) !== "0x") throw new RangeError("Invalid messageHash, must be a 0x-prefixed keccak256 hash.");
4170
4228
  const eip7212WebAuthnPrecompileVerifier = overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_PRECOMPILE;
4171
- const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_FCLP256_VERIFIER;
4229
+ const eip7212WebAuthnContractVerifier = overrides.eip7212WebAuthnContractVerifier ?? SafeAccount.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER;
4172
4230
  const webAuthnSignerSingleton = overrides.webAuthnSignerSingleton ?? SafeAccount.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON;
4173
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____");
4174
4232
  const callData = createCallData("0x1626ba7e", ["bytes32", "bytes"], [messageHash, signature]);
@@ -4298,7 +4356,7 @@ var SafeAccount = class SafeAccount extends SmartAccount {
4298
4356
  * @param toolVersion - tool version; defaults to the current abstractionkit version
4299
4357
  * @returns the on-chain identifier as a hex string (not 0x prefixed)
4300
4358
  */
4301
- function generateOnChainIdentifier(project, platform = "Web", tool = "abstractionkit", toolVersion = "0.3.3") {
4359
+ function generateOnChainIdentifier(project, platform = "Web", tool = "abstractionkit", toolVersion = "0.3.5") {
4302
4360
  const identifierPrefix = "5afe";
4303
4361
  const identifierVersion = "00";
4304
4362
  const projectHash = keccak256(`0x${Buffer.from(project, "utf8").toString("hex")}`).slice(-20);
@@ -5302,15 +5360,15 @@ var SafeAccountV0_3_0 = class SafeAccountV0_3_0 extends SafeAccount {
5302
5360
  * @param useroperation - The UserOperation to sign
5303
5361
  * @param privateKeys - Array of private keys for the signers
5304
5362
  * @param chainId - The target chain ID
5305
- * @param overrides - Override validAfter and validUntil timestamps
5363
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5306
5364
  * @returns The formatted signature string ready to set on the UserOperation
5307
5365
  *
5308
5366
  * @example
5309
5367
  * const signature = smartAccount.signUserOperation(userOp, [privateKey], 1n);
5310
5368
  * userOp.signature = signature;
5311
5369
  */
5312
- signUserOperation(useroperation, privateKeys, chainId, overrides = {}) {
5313
- 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);
5314
5372
  }
5315
5373
  /**
5316
5374
  * Sign a UserOperation with one or more {@link ExternalSigner} instances
@@ -5332,16 +5390,21 @@ var SafeAccountV0_3_0 = class SafeAccountV0_3_0 extends SafeAccount {
5332
5390
  * @param useroperation - UserOperation to sign
5333
5391
  * @param signers - one ExternalSigner per owner (any order)
5334
5392
  * @param chainId - target chain ID
5335
- * @param overrides - optional validAfter / validUntil / multi-chain flag
5393
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5336
5394
  * @returns Promise resolving to the formatted signature string
5337
5395
  */
5338
- signUserOperationWithSigners(useroperation, signers, chainId, overrides = {}) {
5396
+ signUserOperationWithSigners(useroperation, signers, chainId, options = {}) {
5339
5397
  const context = {
5340
5398
  userOperation: useroperation,
5341
5399
  chainId,
5342
5400
  entryPoint: this.entrypointAddress
5343
5401
  };
5344
- 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
+ });
5345
5408
  }
5346
5409
  };
5347
5410
  //#endregion
@@ -5584,28 +5647,39 @@ var SafeAccountV0_2_0 = class SafeAccountV0_2_0 extends SafeAccount {
5584
5647
  * @param useroperation - The UserOperation to sign
5585
5648
  * @param privateKeys - Array of private keys for the signers
5586
5649
  * @param chainId - The target chain ID
5587
- * @param overrides - Override validAfter and validUntil timestamps
5650
+ * @param options - {@link SafeSignatureOptions} timing, multi-chain encoding, module address
5588
5651
  * @returns The formatted signature string ready to set on the UserOperation
5589
5652
  *
5590
5653
  * @example
5591
5654
  * const signature = smartAccount.signUserOperation(userOp, [privateKey], 1n);
5592
5655
  * userOp.signature = signature;
5593
5656
  */
5594
- signUserOperation(useroperation, privateKeys, chainId, overrides = {}) {
5595
- 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);
5596
5659
  }
5597
5660
  /**
5598
5661
  * Sign a UserOperation using one or more {@link AkSigner} instances.
5599
5662
  * See {@link SafeAccountV0_3_0.signUserOperationWithSigners} for full
5600
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
5601
5670
  */
5602
- signUserOperationWithSigners(useroperation, signers, chainId, overrides = {}) {
5671
+ signUserOperationWithSigners(useroperation, signers, chainId, options = {}) {
5603
5672
  const context = {
5604
5673
  userOperation: useroperation,
5605
5674
  chainId,
5606
5675
  entryPoint: this.entrypointAddress
5607
5676
  };
5608
- 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
+ });
5609
5683
  }
5610
5684
  };
5611
5685
  //#endregion
@@ -5624,6 +5698,7 @@ var SafeAccountV0_2_0 = class SafeAccountV0_2_0 extends SafeAccount {
5624
5698
  var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAccountV0_3_0 {
5625
5699
  static DEFAULT_WEB_AUTHN_PRECOMPILE = "0x0000000000000000000000000000000000000100";
5626
5700
  static DEFAULT_WEB_AUTHN_DAIMO_VERIFIER = "0xc2b78104907F722DABAc4C69f826a522B2754De4";
5701
+ static DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER = "0xc2b78104907F722DABAc4C69f826a522B2754De4";
5627
5702
  /**
5628
5703
  * Create a SafeAccountV1_5_0_M_0_3_0 instance for an existing deployed account.
5629
5704
  * For new (undeployed) accounts, use the static `initializeNewAccount` method instead.
@@ -5672,7 +5747,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5672
5747
  ...overrides,
5673
5748
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5674
5749
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5675
- 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
5676
5751
  };
5677
5752
  return SafeAccountV0_3_0.initializeNewAccount(owners, modOverrides);
5678
5753
  }
@@ -5689,7 +5764,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5689
5764
  ...overrides,
5690
5765
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5691
5766
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5692
- 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
5693
5768
  };
5694
5769
  return SafeAccountV0_3_0.createAccountAddress(owners, modOverrides);
5695
5770
  }
@@ -5706,7 +5781,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5706
5781
  ...overrides,
5707
5782
  safeAccountSingleton: overrides.safeAccountSingleton ?? Safe_L2_V1_5_0,
5708
5783
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5709
- 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
5710
5785
  };
5711
5786
  return SafeAccountV0_3_0.createFactoryAddressAndData(owners, modOverrides);
5712
5787
  }
@@ -5724,7 +5799,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5724
5799
  return super.createUserOperation(transactions, providerRpc, bundlerRpc, {
5725
5800
  ...overrides,
5726
5801
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5727
- 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
5728
5803
  });
5729
5804
  }
5730
5805
  /**
@@ -5739,7 +5814,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5739
5814
  return super.estimateUserOperationGas(userOperation, bundlerRpc, {
5740
5815
  ...overrides,
5741
5816
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5742
- 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
5743
5818
  });
5744
5819
  }
5745
5820
  /**
@@ -5755,7 +5830,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5755
5830
  return SafeAccount.createWebAuthnSignerVerifierAddress(x, y, {
5756
5831
  ...overrides,
5757
5832
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5758
- 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
5759
5834
  });
5760
5835
  }
5761
5836
  /**
@@ -5771,7 +5846,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5771
5846
  return SafeAccount.createDeployWebAuthnVerifierMetaTransaction(x, y, {
5772
5847
  ...overrides,
5773
5848
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5774
- 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
5775
5850
  });
5776
5851
  }
5777
5852
  /**
@@ -5785,7 +5860,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5785
5860
  return SafeAccount.createDummySignerSignaturePairForExpectedSigners(expectedSigners, {
5786
5861
  ...webAuthnSignatureOverrides,
5787
5862
  eip7212WebAuthnPrecompileVerifier: webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5788
- 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
5789
5864
  });
5790
5865
  }
5791
5866
  /**
@@ -5803,7 +5878,7 @@ var SafeAccountV1_5_0_M_0_3_0 = class SafeAccountV1_5_0_M_0_3_0 extends SafeAcco
5803
5878
  return SafeAccount.verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, {
5804
5879
  ...overrides,
5805
5880
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeAccountV1_5_0_M_0_3_0.DEFAULT_WEB_AUTHN_PRECOMPILE,
5806
- 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
5807
5882
  });
5808
5883
  }
5809
5884
  };
@@ -5897,6 +5972,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
5897
5972
  static DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE = DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE_V_0_2_1;
5898
5973
  static DEFAULT_WEB_AUTHN_PRECOMPILE = DEFAULT_WEB_AUTHN_PRECOMPILE_RIP_7951;
5899
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;
5900
5976
  /**
5901
5977
  * Create a SafeMultiChainSigAccount instance for an existing or new account.
5902
5978
  * @param accountAddress - the Safe account address
@@ -5922,7 +5998,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
5922
5998
  ...overrides,
5923
5999
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
5924
6000
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
5925
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6001
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5926
6002
  };
5927
6003
  const [accountAddress, ,] = SafeAccount.createAccountAddressAndFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
5928
6004
  return accountAddress;
@@ -5952,7 +6028,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
5952
6028
  ...overrides,
5953
6029
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
5954
6030
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
5955
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6031
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
5956
6032
  };
5957
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);
5958
6034
  const safe = new SafeMultiChainSigAccountV1(accountAddress, {
@@ -6029,7 +6105,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6029
6105
  static createInitializerCallData(owners, threshold, overrides = {}) {
6030
6106
  const safe4337ModuleAddress = overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS;
6031
6107
  const safeModuleSetupAddress = overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS;
6032
- 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);
6033
6109
  }
6034
6110
  /**
6035
6111
  * create account factory address and factory data
@@ -6042,7 +6118,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6042
6118
  ...overrides,
6043
6119
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
6044
6120
  eip7212WebAuthnPrecompileVerifierForSharedSigner: overrides.eip7212WebAuthnPrecompileVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6045
- eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER
6121
+ eip7212WebAuthnContractVerifierForSharedSigner: overrides.eip7212WebAuthnContractVerifierForSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER
6046
6122
  };
6047
6123
  return SafeAccount.createFactoryAddressAndData(owners, modOverrides, overrides.safe4337ModuleAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS, overrides.safeModuleSetupAddress ?? SafeMultiChainSigAccountV1.DEFAULT_SAFE_MODULE_SETUP_ADDRESS);
6048
6124
  }
@@ -6064,7 +6140,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6064
6140
  isMultiChainSignature: true,
6065
6141
  webAuthnSharedSigner: overrides.webAuthnSharedSigner ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER,
6066
6142
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6067
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6143
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6068
6144
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6069
6145
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6070
6146
  webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE
@@ -6092,14 +6168,13 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6092
6168
  * @param useroperation - useroperation to sign
6093
6169
  * @param privateKeys - for the signers
6094
6170
  * @param chainId - target chain id
6095
- * @param overrides - overrides for the default values
6096
- * @param overrides.validAfter - timestamp the signature will be valid after
6097
- * @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.
6098
6172
  * @returns signature
6099
6173
  */
6100
- 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");
6101
6176
  return SafeAccount.baseSignSingleUserOperation(userOperation, privateKeys, chainId, this.entrypointAddress, this.safe4337ModuleAddress, {
6102
- ...overrides,
6177
+ ...options,
6103
6178
  isMultiChainSignature: true
6104
6179
  });
6105
6180
  }
@@ -6108,16 +6183,28 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6108
6183
  * {@link AkSigner} instances. See
6109
6184
  * {@link SafeAccountV0_3_0.signUserOperationWithSigners} for the full
6110
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
6111
6192
  */
6112
- 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");
6113
6195
  const context = {
6114
6196
  userOperation,
6115
6197
  chainId,
6116
6198
  entryPoint: this.entrypointAddress
6117
6199
  };
6118
- return SafeAccount.baseSignUserOperationWithSigners(userOperation, signers, chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, {
6119
- ...overrides,
6120
- 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
+ }
6121
6208
  });
6122
6209
  }
6123
6210
  /**
@@ -6238,10 +6325,15 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6238
6325
  return userOpSignatures;
6239
6326
  } else {
6240
6327
  const u = userOperationsToSign[0];
6241
- return [await SafeAccount.baseSignUserOperationWithSigners(u.userOperation, signers, u.chainId, this.entrypointAddress, this.safe4337ModuleAddress, context, {
6242
- validAfter: u.validAfter,
6243
- validUntil: u.validUntil,
6244
- 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
+ }
6245
6337
  })];
6246
6338
  }
6247
6339
  }
@@ -6291,28 +6383,34 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6291
6383
  */
6292
6384
  static formatSignaturesToUseroperationsSignatures(userOperationsToSign, signerSignaturePairs) {
6293
6385
  if (userOperationsToSign.length < 1) throw new RangeError("There should be at least one userOperationsToSign");
6294
- const defaultOverrides = {
6386
+ const defaultWebAuthnOverrides = {
6295
6387
  eip7212WebAuthnPrecompileVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6296
- eip7212WebAuthnContractVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6388
+ eip7212WebAuthnContractVerifier: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6297
6389
  webAuthnSignerFactory: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6298
6390
  webAuthnSignerSingleton: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6299
6391
  webAuthnSignerProxyCreationCode: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
6300
- safe4337ModuleAddress: SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS,
6301
6392
  webAuthnSharedSigner: SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SHARED_SIGNER
6302
6393
  };
6394
+ const defaultOptions = { safe4337ModuleAddress: SafeMultiChainSigAccountV1.DEFAULT_SAFE_4337_MODULE_ADDRESS };
6303
6395
  if (userOperationsToSign.length === 1) return [SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
6304
- ...defaultOverrides,
6305
- ...userOperationsToSign[0].overrides,
6396
+ ...defaultOptions,
6397
+ ...defaultWebAuthnOverrides,
6398
+ ...userOperationsToSign[0].options,
6399
+ ...userOperationsToSign[0].webAuthnSignatureOverrides,
6306
6400
  validAfter: userOperationsToSign[0].validAfter,
6307
6401
  validUntil: userOperationsToSign[0].validUntil,
6308
6402
  isMultiChainSignature: true
6309
6403
  })];
6310
6404
  const userOperationsHashes = [];
6311
- 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) => {
6312
6410
  const userOperationHash = SafeAccount.getUserOperationEip712Hash_V9(userOperationToSign.userOperation, userOperationToSign.chainId, {
6313
- validAfter: userOperationToSign.validAfter,
6314
- validUntil: userOperationToSign.validUntil,
6315
- safe4337ModuleAddress: userOperationToSign.overrides?.safe4337ModuleAddress ?? defaultOverrides.safe4337ModuleAddress
6411
+ validAfter: resolvedValidity[index].validAfter,
6412
+ validUntil: resolvedValidity[index].validUntil,
6413
+ safe4337ModuleAddress: userOperationToSign.options?.safe4337ModuleAddress ?? defaultOptions.safe4337ModuleAddress
6316
6414
  });
6317
6415
  userOperationsHashes.push(userOperationHash);
6318
6416
  });
@@ -6320,8 +6418,12 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6320
6418
  const userOpSignatures = [];
6321
6419
  userOperationsToSign.forEach((userOperationToSign, index) => {
6322
6420
  userOpSignatures.push(SafeAccount.formatSignaturesToUseroperationSignature(signerSignaturePairs, {
6323
- ...defaultOverrides,
6324
- ...userOperationToSign.overrides,
6421
+ ...defaultOptions,
6422
+ ...defaultWebAuthnOverrides,
6423
+ ...userOperationToSign.options,
6424
+ ...userOperationToSign.webAuthnSignatureOverrides,
6425
+ validAfter: resolvedValidity[index].validAfter,
6426
+ validUntil: resolvedValidity[index].validUntil,
6325
6427
  isMultiChainSignature: true,
6326
6428
  multiChainMerkleProof: proofs[index]
6327
6429
  }));
@@ -6332,7 +6434,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6332
6434
  return SafeAccount.createWebAuthnSignerVerifierAddress(x, y, {
6333
6435
  ...overrides,
6334
6436
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6335
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6437
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6336
6438
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6337
6439
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6338
6440
  webAuthnSignerProxyCreationCode: overrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE
@@ -6342,7 +6444,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6342
6444
  return SafeAccount.createDeployWebAuthnVerifierMetaTransaction(x, y, {
6343
6445
  ...overrides,
6344
6446
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6345
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6447
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6346
6448
  webAuthnSignerFactory: overrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY
6347
6449
  });
6348
6450
  }
@@ -6350,7 +6452,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6350
6452
  return SafeAccount.createDummySignerSignaturePairForExpectedSigners(expectedSigners, {
6351
6453
  ...webAuthnSignatureOverrides,
6352
6454
  eip7212WebAuthnPrecompileVerifier: webAuthnSignatureOverrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6353
- eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6455
+ eip7212WebAuthnContractVerifier: webAuthnSignatureOverrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6354
6456
  webAuthnSignerFactory: webAuthnSignatureOverrides.webAuthnSignerFactory ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_FACTORY,
6355
6457
  webAuthnSignerSingleton: webAuthnSignatureOverrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON,
6356
6458
  webAuthnSignerProxyCreationCode: webAuthnSignatureOverrides.webAuthnSignerProxyCreationCode ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_PROXY_CREATION_CODE,
@@ -6361,7 +6463,7 @@ var SafeMultiChainSigAccountV1 = class SafeMultiChainSigAccountV1 extends SafeAc
6361
6463
  return SafeAccount.verifyWebAuthnSignatureForMessageHash(nodeRpcUrl, signer, messageHash, signature, {
6362
6464
  ...overrides,
6363
6465
  eip7212WebAuthnPrecompileVerifier: overrides.eip7212WebAuthnPrecompileVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_PRECOMPILE,
6364
- eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_DAIMO_VERIFIER,
6466
+ eip7212WebAuthnContractVerifier: overrides.eip7212WebAuthnContractVerifier ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_CONTRACT_VERIFIER,
6365
6467
  webAuthnSignerSingleton: overrides.webAuthnSignerSingleton ?? SafeMultiChainSigAccountV1.DEFAULT_WEB_AUTHN_SIGNER_SINGLETON
6366
6468
  });
6367
6469
  }
@@ -6699,27 +6801,139 @@ var BaseSimple7702Account = class BaseSimple7702Account extends SmartAccount {
6699
6801
  return new Wallet(privateKey).signingKey.sign(userOperationHash).serialized;
6700
6802
  }
6701
6803
  /**
6702
- * Schemes Simple7702 accepts from a Signer. Only raw-hash ECDSA, since
6703
- * 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.
6704
6816
  */
6705
- static ACCEPTED_SIGNING_SCHEMES = ["hash"];
6817
+ static ACCEPTED_SIGNING_SCHEMES = ["typedData", "hash"];
6706
6818
  /**
6707
- * Sign a UserOperation with an {@link AkSigner}. Signer must implement
6708
- * `signHash`, since Simple7702 only verifies raw ECDSA over the userOp
6709
- * hash. JSON-RPC wallets and anything that only provides `signTypedData`
6710
- * 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.
6711
6921
  */
6712
6922
  async baseSignUserOperationWithSigner(useroperation, signer, chainId) {
6713
- return invokeSigner(signer, pickScheme(signer, BaseSimple7702Account.ACCEPTED_SIGNING_SCHEMES, {
6714
- 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)",
6715
6925
  signerIndex: 0
6716
- }), {
6717
- hash: createUserOperationHash(useroperation, this.entrypointAddress, chainId),
6718
- context: {
6719
- userOperation: useroperation,
6720
- chainId,
6721
- entryPoint: this.entrypointAddress
6722
- }
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
6723
6937
  });
6724
6938
  }
6725
6939
  /**
@@ -6833,13 +7047,34 @@ var Simple7702Account = class Simple7702Account extends BaseSimple7702Account {
6833
7047
  return this.baseSignUserOperation(useroperation, privateKey, chainId);
6834
7048
  }
6835
7049
  /**
6836
- * Sign a {@link UserOperationV8} using an {@link ExternalSigner}.
6837
- * Simple7702 only accepts raw-hash ECDSA; signers without `signHash`
6838
- * 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
+ * ```
6839
7069
  *
6840
7070
  * For signing with a raw private-key string, use the sync
6841
7071
  * {@link signUserOperation} method, or wrap explicitly with
6842
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).
6843
7078
  */
6844
7079
  async signUserOperationWithSigner(useroperation, signer, chainId) {
6845
7080
  return this.baseSignUserOperationWithSigner(useroperation, signer, chainId);
@@ -6910,10 +7145,33 @@ var Simple7702AccountV09 = class Simple7702AccountV09 extends BaseSimple7702Acco
6910
7145
  return this.baseSignUserOperation(useroperation, privateKey, chainId);
6911
7146
  }
6912
7147
  /**
6913
- * Sign a {@link UserOperationV9} using an {@link ExternalSigner}.
6914
- * Simple7702 only accepts raw-hash ECDSA; signers without `signHash`
6915
- * fail offline with an actionable error. For a raw pk string, use the
6916
- * 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.
6917
7175
  */
6918
7176
  async signUserOperationWithSigner(useroperation, signer, chainId) {
6919
7177
  return this.baseSignUserOperationWithSigner(useroperation, signer, chainId);
@@ -7924,6 +8182,280 @@ function createWorldIdSignal(accountAddress, accountNonce, chainId) {
7924
8182
  ]));
7925
8183
  }
7926
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
7927
8459
  //#region src/signer/adapters.ts
7928
8460
  /**
7929
8461
  * Build a Signer from a raw private-key hex string. Supports both raw-hash
@@ -8062,6 +8594,7 @@ var abstractionkit_exports = /* @__PURE__ */ __exportAll({
8062
8594
  fetchGasPrice: () => fetchGasPrice,
8063
8595
  fromEthersWallet: () => fromEthersWallet,
8064
8596
  fromPrivateKey: () => fromPrivateKey,
8597
+ fromSafeWebauthn: () => fromSafeWebauthn,
8065
8598
  fromViem: () => fromViem,
8066
8599
  fromViemWalletClient: () => fromViemWalletClient,
8067
8600
  getBalanceOf: () => getBalanceOf,
@@ -8069,6 +8602,8 @@ var abstractionkit_exports = /* @__PURE__ */ __exportAll({
8069
8602
  getDepositInfo: () => getDepositInfo,
8070
8603
  getFunctionSelector: () => getFunctionSelector,
8071
8604
  getSafeMessageEip712Data: () => getSafeMessageEip712Data,
8605
+ pubkeyCoordinatesFromJson: () => pubkeyCoordinatesFromJson,
8606
+ pubkeyCoordinatesToJson: () => pubkeyCoordinatesToJson,
8072
8607
  sendJsonRpcRequest: () => sendJsonRpcRequest,
8073
8608
  shareTenderlySimulationAndCreateLink: () => shareTenderlySimulationAndCreateLink,
8074
8609
  signHash: () => signHash,
@@ -8077,9 +8612,10 @@ var abstractionkit_exports = /* @__PURE__ */ __exportAll({
8077
8612
  simulateUserOperationCallDataWithTenderly: () => simulateUserOperationCallDataWithTenderly,
8078
8613
  simulateUserOperationCallDataWithTenderlyAndCreateShareLink: () => simulateUserOperationCallDataWithTenderlyAndCreateShareLink,
8079
8614
  simulateUserOperationWithTenderly: () => simulateUserOperationWithTenderly,
8080
- simulateUserOperationWithTenderlyAndCreateShareLink: () => simulateUserOperationWithTenderlyAndCreateShareLink
8615
+ simulateUserOperationWithTenderlyAndCreateShareLink: () => simulateUserOperationWithTenderlyAndCreateShareLink,
8616
+ webauthnSignatureFromAssertion: () => webauthnSignatureFromAssertion
8081
8617
  });
8082
8618
  //#endregion
8083
- 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 };
8084
8620
 
8085
8621
  //# sourceMappingURL=index.mjs.map