@account-kit/smart-contracts 4.41.0 → 4.42.0

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.
Files changed (37) hide show
  1. package/dist/esm/src/ma-v2/account/common/modularAccountV2Base.d.ts +17 -3
  2. package/dist/esm/src/ma-v2/account/common/modularAccountV2Base.js +23 -5
  3. package/dist/esm/src/ma-v2/account/common/modularAccountV2Base.js.map +1 -1
  4. package/dist/esm/src/ma-v2/account/modularAccountV2.d.ts +15 -1
  5. package/dist/esm/src/ma-v2/account/modularAccountV2.js +67 -7
  6. package/dist/esm/src/ma-v2/account/modularAccountV2.js.map +1 -1
  7. package/dist/esm/src/ma-v2/client/client.d.ts +15 -7
  8. package/dist/esm/src/ma-v2/client/client.js +23 -7
  9. package/dist/esm/src/ma-v2/client/client.js.map +1 -1
  10. package/dist/esm/src/ma-v2/errors.d.ts +22 -0
  11. package/dist/esm/src/ma-v2/errors.js +44 -0
  12. package/dist/esm/src/ma-v2/errors.js.map +1 -0
  13. package/dist/esm/src/ma-v2/index.d.ts +1 -0
  14. package/dist/esm/src/ma-v2/index.js +1 -0
  15. package/dist/esm/src/ma-v2/index.js.map +1 -1
  16. package/dist/esm/src/ma-v2/modules/webauthn-validation/signingMethods.d.ts +36 -0
  17. package/dist/esm/src/ma-v2/modules/webauthn-validation/signingMethods.js +119 -0
  18. package/dist/esm/src/ma-v2/modules/webauthn-validation/signingMethods.js.map +1 -0
  19. package/dist/types/src/ma-v2/account/common/modularAccountV2Base.d.ts +17 -3
  20. package/dist/types/src/ma-v2/account/common/modularAccountV2Base.d.ts.map +1 -1
  21. package/dist/types/src/ma-v2/account/modularAccountV2.d.ts +15 -1
  22. package/dist/types/src/ma-v2/account/modularAccountV2.d.ts.map +1 -1
  23. package/dist/types/src/ma-v2/client/client.d.ts +15 -7
  24. package/dist/types/src/ma-v2/client/client.d.ts.map +1 -1
  25. package/dist/types/src/ma-v2/errors.d.ts +23 -0
  26. package/dist/types/src/ma-v2/errors.d.ts.map +1 -0
  27. package/dist/types/src/ma-v2/index.d.ts +1 -0
  28. package/dist/types/src/ma-v2/index.d.ts.map +1 -1
  29. package/dist/types/src/ma-v2/modules/webauthn-validation/signingMethods.d.ts +37 -0
  30. package/dist/types/src/ma-v2/modules/webauthn-validation/signingMethods.d.ts.map +1 -0
  31. package/package.json +5 -5
  32. package/src/ma-v2/account/common/modularAccountV2Base.ts +71 -8
  33. package/src/ma-v2/account/modularAccountV2.ts +115 -9
  34. package/src/ma-v2/client/client.ts +73 -17
  35. package/src/ma-v2/errors.ts +33 -0
  36. package/src/ma-v2/index.ts +1 -0
  37. package/src/ma-v2/modules/webauthn-validation/signingMethods.ts +158 -0
@@ -7,6 +7,8 @@ import {
7
7
  getEntryPoint,
8
8
  EntityIdOverrideError,
9
9
  InvalidModularAccountV2Mode,
10
+ createBundlerClient,
11
+ getAccountAddress,
10
12
  } from "@aa-sdk/core";
11
13
  import {
12
14
  concatHex,
@@ -25,9 +27,17 @@ import {
25
27
  type SignerEntity,
26
28
  type ModularAccountV2,
27
29
  createMAv2Base,
30
+ type WebauthnModularAccountV2,
28
31
  } from "./common/modularAccountV2Base.js";
29
32
  import { DEFAULT_OWNER_ENTITY_ID } from "../utils.js";
30
33
  import { predictModularAccountV2Address } from "./predictAddress.js";
34
+ import type { ToWebAuthnAccountParameters } from "viem/account-abstraction";
35
+ import { parsePublicKey } from "webauthn-p256";
36
+ import {
37
+ SignerRequiredFor7702Error,
38
+ SignerRequiredForDefaultError,
39
+ WebauthnCredentialsRequiredError,
40
+ } from "../errors.js";
31
41
 
32
42
  export type CreateModularAccountV2Params<
33
43
  TTransport extends Transport = Transport,
@@ -54,6 +64,24 @@ export type CreateModularAccountV2Params<
54
64
  }
55
65
  );
56
66
 
67
+ export type CreateWebauthnModularAccountV2Params<
68
+ TTransport extends Transport = Transport,
69
+ > = Pick<
70
+ ToSmartContractAccountParams<"ModularAccountV2", TTransport, Chain, "0.7.0">,
71
+ "transport" | "chain" | "accountAddress"
72
+ > & {
73
+ mode: "webauthn";
74
+ credential: ToWebAuthnAccountParameters["credential"];
75
+ getFn?: ToWebAuthnAccountParameters["getFn"] | undefined;
76
+ rpId?: ToWebAuthnAccountParameters["rpId"] | undefined;
77
+ entryPoint?: EntryPointDef<"0.7.0", Chain>;
78
+ deferredAction?: Hex;
79
+ signerEntity?: SignerEntity;
80
+ salt?: bigint;
81
+ factoryAddress?: Address;
82
+ initCode?: Hex;
83
+ };
84
+
57
85
  export async function createModularAccountV2<
58
86
  TTransport extends Transport = Transport,
59
87
  TSigner extends SmartAccountSigner = SmartAccountSigner,
@@ -61,6 +89,12 @@ export async function createModularAccountV2<
61
89
  config: CreateModularAccountV2Params<TTransport, TSigner>,
62
90
  ): Promise<ModularAccountV2<TSigner>>;
63
91
 
92
+ export async function createModularAccountV2<
93
+ TTransport extends Transport = Transport,
94
+ >(
95
+ config: CreateWebauthnModularAccountV2Params<TTransport>,
96
+ ): Promise<WebauthnModularAccountV2>;
97
+
64
98
  /**
65
99
  * Creates a ModularAccount V2 account, with the mode depending on the provided "mode" field.
66
100
  * Possible modes include: "default", which is SMA Bytecode, and "7702", which is SMA 7702.
@@ -90,16 +124,20 @@ export async function createModularAccountV2<
90
124
  * });
91
125
  * ```
92
126
  *
93
- * @param {CreateModularAccountV2Params} config Configuration parameters for creating a Modular Account V2.
94
- * @returns {Promise<ModularAccountV2>} A promise that resolves to an `ModularAccountV2` providing methods for nonce retrieval, transaction execution, and more.
127
+ * @param {CreateModularAccountV2Params | CreateWebauthnModularAccountV2Params} config Configuration parameters for creating a Modular Account V2.
128
+ * @returns {Promise<ModularAccountV2 | WebauthnModularAccountV2>} A promise that resolves to an `ModularAccountV2` providing methods for nonce retrieval, transaction execution, and more.
95
129
  */
96
- export async function createModularAccountV2(
97
- config: CreateModularAccountV2Params,
98
- ): Promise<ModularAccountV2> {
130
+ export async function createModularAccountV2<
131
+ TTransport extends Transport = Transport,
132
+ TSigner extends SmartAccountSigner = SmartAccountSigner,
133
+ >(
134
+ config:
135
+ | CreateModularAccountV2Params<TTransport, TSigner>
136
+ | CreateWebauthnModularAccountV2Params<TTransport>,
137
+ ): Promise<ModularAccountV2<TSigner> | WebauthnModularAccountV2> {
99
138
  const {
100
139
  transport,
101
140
  chain,
102
- signer,
103
141
  accountAddress: _accountAddress,
104
142
  entryPoint = getEntryPoint(chain, { version: "0.7.0" }),
105
143
  signerEntity = {
@@ -110,12 +148,63 @@ export async function createModularAccountV2(
110
148
  deferredAction,
111
149
  } = config;
112
150
 
151
+ const signer = "signer" in config ? config.signer : undefined;
152
+
153
+ const credential = "credential" in config ? config.credential : undefined;
154
+
155
+ const getFn = "getFn" in config ? config.getFn : undefined;
156
+
157
+ const rpId = "rpId" in config ? config.rpId : undefined;
158
+
159
+ const client = createBundlerClient({
160
+ transport,
161
+ chain,
162
+ });
163
+
113
164
  const accountFunctions = await (async () => {
114
165
  switch (config.mode) {
166
+ case "webauthn": {
167
+ if (!credential) throw new WebauthnCredentialsRequiredError();
168
+ const publicKey = credential.publicKey;
169
+ const { x, y } = parsePublicKey(publicKey);
170
+ const {
171
+ salt = 0n,
172
+ factoryAddress = getDefaultMAV2FactoryAddress(chain),
173
+ initCode,
174
+ } = config;
175
+
176
+ const getAccountInitCode = async () => {
177
+ if (initCode) {
178
+ return initCode;
179
+ }
180
+
181
+ return concatHex([
182
+ factoryAddress,
183
+ encodeFunctionData({
184
+ abi: accountFactoryAbi,
185
+ functionName: "createWebAuthnAccount",
186
+ args: [x, y, salt, entityId],
187
+ }),
188
+ ]);
189
+ };
190
+
191
+ const accountAddress = await getAccountAddress({
192
+ client,
193
+ entryPoint,
194
+ accountAddress: _accountAddress,
195
+ getAccountInitCode,
196
+ });
197
+
198
+ return {
199
+ getAccountInitCode,
200
+ accountAddress,
201
+ };
202
+ }
115
203
  case "7702": {
116
204
  const getAccountInitCode = async (): Promise<Hex> => {
117
205
  return "0x";
118
206
  };
207
+ if (!signer) throw new SignerRequiredFor7702Error();
119
208
  const signerAddress = await signer.getAddress();
120
209
  const accountAddress = _accountAddress ?? signerAddress;
121
210
  if (
@@ -138,6 +227,7 @@ export async function createModularAccountV2(
138
227
  }
139
228
  case "default":
140
229
  case undefined: {
230
+ if (!signer) throw new SignerRequiredForDefaultError();
141
231
  const {
142
232
  salt = 0n,
143
233
  factoryAddress = getDefaultMAV2FactoryAddress(chain),
@@ -157,7 +247,7 @@ export async function createModularAccountV2(
157
247
  encodeFunctionData({
158
248
  abi: accountFactoryAbi,
159
249
  functionName: "createSemiModularAccount",
160
- args: [signerAddress, salt],
250
+ args: [await signer.getAddress(), salt],
161
251
  }),
162
252
  ]);
163
253
  };
@@ -182,8 +272,24 @@ export async function createModularAccountV2(
182
272
  }
183
273
  })();
184
274
 
185
- return createMAv2Base({
186
- source: "ModularAccountV2",
275
+ if (!signer) {
276
+ if (!credential) throw new WebauthnCredentialsRequiredError();
277
+ return await createMAv2Base({
278
+ source: "ModularAccountV2", // TO DO: remove need to pass in source?
279
+ transport,
280
+ chain,
281
+ entryPoint,
282
+ signerEntity,
283
+ deferredAction,
284
+ credential,
285
+ getFn,
286
+ rpId,
287
+ ...accountFunctions,
288
+ });
289
+ }
290
+
291
+ return await createMAv2Base({
292
+ source: "ModularAccountV2", // TO DO: remove need to pass in source?
187
293
  transport,
188
294
  chain,
189
295
  signer,
@@ -1,17 +1,18 @@
1
1
  import {
2
- type SmartAccountClient,
3
- type SmartAccountSigner,
4
- type SmartAccountClientConfig,
5
- type NotType,
6
2
  createSmartAccountClient,
7
3
  default7702GasEstimator,
8
4
  default7702UserOpSigner,
5
+ webauthnGasEstimator,
6
+ type SmartAccountClient,
7
+ type SmartAccountClientConfig,
8
+ type SmartAccountSigner,
9
9
  } from "@aa-sdk/core";
10
10
  import { type Chain, type Transport } from "viem";
11
11
 
12
12
  import {
13
13
  createModularAccountV2,
14
14
  type CreateModularAccountV2Params,
15
+ type CreateWebauthnModularAccountV2Params,
15
16
  } from "../account/modularAccountV2.js";
16
17
 
17
18
  import {
@@ -23,24 +24,54 @@ import {
23
24
  } from "@account-kit/infra";
24
25
  import type { LightAccount } from "../../light-account/accounts/account.js";
25
26
 
26
- import type { ModularAccountV2 } from "../account/common/modularAccountV2Base.js";
27
+ import type { ToWebAuthnAccountParameters } from "viem/account-abstraction";
28
+ import type {
29
+ ModularAccountV2,
30
+ WebauthnModularAccountV2,
31
+ } from "../account/common/modularAccountV2Base.js";
27
32
 
28
33
  export type ModularAccountV2Client<
29
34
  TSigner extends SmartAccountSigner = SmartAccountSigner,
30
35
  TChain extends Chain = Chain,
31
36
  TTransport extends Transport | AlchemyTransport = Transport,
32
- > = SmartAccountClient<TTransport, TChain, ModularAccountV2<TSigner>>;
37
+ > = TTransport extends AlchemyTransport
38
+ ? AlchemySmartAccountClient<TChain, ModularAccountV2<TSigner>>
39
+ : SmartAccountClient<TTransport, TChain, ModularAccountV2<TSigner>>;
40
+
41
+ export type WebauthnModularAccountV2Client<
42
+ TChain extends Chain = Chain,
43
+ TTransport extends Transport | AlchemyTransport = Transport,
44
+ > = TTransport extends AlchemyTransport
45
+ ? AlchemySmartAccountClient<TChain, WebauthnModularAccountV2>
46
+ : SmartAccountClient<TTransport, TChain, WebauthnModularAccountV2>;
33
47
 
34
48
  export type CreateModularAccountV2ClientParams<
35
- TTransport extends Transport = Transport,
49
+ TTransport extends Transport | AlchemyTransport = Transport,
36
50
  TChain extends Chain = Chain,
37
51
  TSigner extends SmartAccountSigner = SmartAccountSigner,
38
52
  > = CreateModularAccountV2Params<TTransport, TSigner> &
39
53
  Omit<
40
- SmartAccountClientConfig<TTransport, TChain>,
54
+ TTransport extends AlchemyTransport
55
+ ? AlchemySmartAccountClientConfig<TChain>
56
+ : SmartAccountClientConfig<TTransport, TChain>,
41
57
  "transport" | "account" | "chain"
42
58
  >;
43
59
 
60
+ export type CreateWebauthnModularAccountV2ClientParams<
61
+ TTransport extends Transport | AlchemyTransport = Transport,
62
+ TChain extends Chain = Chain,
63
+ > = CreateWebauthnModularAccountV2Params<TTransport> &
64
+ Omit<
65
+ TTransport extends AlchemyTransport
66
+ ? AlchemySmartAccountClientConfig<TChain>
67
+ : SmartAccountClientConfig<TTransport, TChain>,
68
+ "transport" | "account" | "chain"
69
+ > & {
70
+ credential: ToWebAuthnAccountParameters["credential"];
71
+ getFn?: ToWebAuthnAccountParameters["getFn"];
72
+ rpId?: ToWebAuthnAccountParameters["rpId"];
73
+ };
74
+
44
75
  export type CreateModularAccountV2AlchemyClientParams<
45
76
  TTransport extends Transport = Transport,
46
77
  TChain extends Chain = Chain,
@@ -70,10 +101,15 @@ export function createModularAccountV2Client<
70
101
  TChain extends Chain = Chain,
71
102
  TSigner extends SmartAccountSigner = SmartAccountSigner,
72
103
  >(
73
- args: CreateModularAccountV2ClientParams<TTransport, TChain, TSigner> &
74
- NotType<TTransport, AlchemyTransport>,
75
- ): Promise<ModularAccountV2Client<TSigner, TChain>>;
104
+ args: CreateModularAccountV2ClientParams<TTransport, TChain, TSigner>,
105
+ ): Promise<ModularAccountV2Client<TSigner, TChain, TTransport>>;
76
106
 
107
+ export function createModularAccountV2Client<
108
+ TTransport extends Transport = Transport,
109
+ TChain extends Chain = Chain,
110
+ >(
111
+ args: CreateWebauthnModularAccountV2ClientParams<TTransport, TChain>,
112
+ ): Promise<WebauthnModularAccountV2Client<TChain, TTransport>>;
77
113
  /**
78
114
  * Creates a Modular Account V2 client using the provided configuration parameters.
79
115
  *
@@ -108,19 +144,39 @@ export function createModularAccountV2Client<
108
144
  export async function createModularAccountV2Client(
109
145
  config:
110
146
  | CreateModularAccountV2ClientParams
147
+ | CreateWebauthnModularAccountV2ClientParams
111
148
  | CreateModularAccountV2AlchemyClientParams,
112
149
  ): Promise<SmartAccountClient | AlchemySmartAccountClient> {
113
150
  const { transport, chain } = config;
114
151
 
115
- const account = await createModularAccountV2(config);
152
+ let account;
153
+
154
+ if (config.mode === "webauthn") {
155
+ account = await createModularAccountV2(
156
+ config as CreateWebauthnModularAccountV2Params<Transport>,
157
+ );
158
+ } else {
159
+ account = await createModularAccountV2(
160
+ config as CreateModularAccountV2Params,
161
+ );
162
+ }
116
163
 
117
- const middlewareToAppend =
118
- config.mode === "7702"
119
- ? {
164
+ const middlewareToAppend = await (async () => {
165
+ switch (config.mode) {
166
+ case "7702":
167
+ return {
120
168
  gasEstimator: default7702GasEstimator(config.gasEstimator),
121
169
  signUserOperation: default7702UserOpSigner(config.signUserOperation),
122
- }
123
- : {};
170
+ };
171
+ case "webauthn":
172
+ return {
173
+ gasEstimator: webauthnGasEstimator(config.gasEstimator),
174
+ };
175
+ case "default":
176
+ default:
177
+ return {};
178
+ }
179
+ })();
124
180
 
125
181
  if (isAlchemyTransport(transport, chain)) {
126
182
  return createAlchemySmartAccountClient({
@@ -0,0 +1,33 @@
1
+ import { BaseError } from "@aa-sdk/core";
2
+
3
+ /**
4
+ * Error when Webauthn credentials are not passed to Webauthn Modular Account V2
5
+ */
6
+ export class WebauthnCredentialsRequiredError extends BaseError {
7
+ override name = "WebauthnCredentialsRequiredError";
8
+ constructor() {
9
+ super(
10
+ "Webauthn credentials are required to create a Webauthn Modular Account V2",
11
+ );
12
+ }
13
+ }
14
+
15
+ /**
16
+ * Error when a signer is not passed to 7702 version of Modular Account V2
17
+ */
18
+ export class SignerRequiredFor7702Error extends BaseError {
19
+ override name = "SignerRequiredFor7702Error";
20
+ constructor() {
21
+ super("A signer is required to create a 7702 Modular Account V2");
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Error when a signer is not passed to default Modular Account V2
27
+ */
28
+ export class SignerRequiredForDefaultError extends BaseError {
29
+ override name = "SignerRequiredForDefaultError";
30
+ constructor() {
31
+ super("A signer is required to create a default Modular Account V2");
32
+ }
33
+ }
@@ -46,3 +46,4 @@ export { SingleSignerValidationModule } from "./modules/single-signer-validation
46
46
  export { timeRangeModuleAbi } from "./modules/time-range-module/abis/timeRangeModuleAbi.js";
47
47
  export { TimeRangeModule } from "./modules/time-range-module/module.js";
48
48
  export { webauthnValidationModuleAbi } from "./modules/webauthn-validation/abis/webauthnValidationAbi.js";
49
+ export { WebAuthnValidationModule } from "./modules/webauthn-validation/module.js";
@@ -0,0 +1,158 @@
1
+ import * as WebAuthnP256 from "ox/WebAuthnP256";
2
+ import {
3
+ type Address,
4
+ type Chain,
5
+ concatHex,
6
+ encodeAbiParameters,
7
+ hashMessage,
8
+ hashTypedData,
9
+ type Hex,
10
+ type SignableMessage,
11
+ type TypedData,
12
+ type TypedDataDefinition,
13
+ } from "viem";
14
+ import { type ToWebAuthnAccountParameters } from "viem/account-abstraction";
15
+ import { pack1271Signature } from "../../utils.js";
16
+ import { getDefaultWebauthnValidationModuleAddress } from "../utils.js";
17
+
18
+ /**
19
+ * Creates an object with methods for generating a dummy signature, signing user operation hashes, signing messages, and signing typed data.
20
+ *
21
+ * @example
22
+
23
+ * ```ts
24
+ * import { webauthnSigningFunctions } from "@account-kit/smart-contracts";
25
+ * import { LocalAccountSigner } from "@aa-sdk/core";
26
+ *
27
+ * const messageSigner = webauthnSigningFunctions(credential, getFn, rpId, chain, account.address, account.signerEntity.entityId);
28
+ * ```
29
+ *
30
+ * @param {ToWebAuthnAccountParameters} credential the Webauthn public key credential object
31
+ * @param {ToWebAuthnAccountParameters["getFn"]} getFn function to retrieve the WebAuthn credential
32
+ * @param {ToWebAuthnAccountParameters["rpId"]} rpId the relying party ID for the WebAuthn credential
33
+ * @param {Chain} chain Chain object for the signer
34
+ * @param {Address} accountAddress address of the smart account using this signer
35
+ * @param {number} entityId the entity id of the signing validation
36
+ * @param {Hex} deferredActionData optional deferred action data to prepend to the uo signatures
37
+ * @returns {object} an object with methods for signing operations and managing signatures
38
+ */
39
+ export const webauthnSigningFunctions = (
40
+ credential: ToWebAuthnAccountParameters["credential"],
41
+ getFn: ToWebAuthnAccountParameters["getFn"],
42
+ rpId: ToWebAuthnAccountParameters["rpId"],
43
+ chain: Chain,
44
+ accountAddress: Address,
45
+ entityId: number,
46
+ deferredActionData?: Hex,
47
+ ) => {
48
+ const { id, publicKey } = credential;
49
+
50
+ const sign = async ({ hash }: { hash: Hex }) => {
51
+ const { metadata, signature } = await WebAuthnP256.sign({
52
+ credentialId: id,
53
+ getFn,
54
+ challenge: hash,
55
+ rpId,
56
+ });
57
+
58
+ return encodeAbiParameters(
59
+ [
60
+ {
61
+ name: "params",
62
+ type: "tuple",
63
+ components: [
64
+ { name: "authenticatorData", type: "bytes" },
65
+ { name: "clientDataJSON", type: "string" },
66
+ { name: "challengeIndex", type: "uint256" },
67
+ { name: "typeIndex", type: "uint256" },
68
+ { name: "r", type: "uint256" },
69
+ { name: "s", type: "uint256" },
70
+ ],
71
+ },
72
+ ],
73
+ [
74
+ {
75
+ authenticatorData: metadata.authenticatorData,
76
+ clientDataJSON: metadata.clientDataJSON,
77
+ challengeIndex: BigInt(metadata.challengeIndex),
78
+ typeIndex: BigInt(metadata.typeIndex),
79
+ r: signature.r,
80
+ s: signature.s,
81
+ },
82
+ ],
83
+ );
84
+ };
85
+
86
+ return {
87
+ id,
88
+ publicKey,
89
+ getDummySignature: (): Hex =>
90
+ "0xff000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000170000000000000000000000000000000000000000000000000000000000000001949fc7c88032b9fcb5f6efc7a7b8c63668eae9871b765e23123bb473ff57aa831a7c0d9276168ebcc29f2875a0239cffdf2a9cd1c2007c5c77c071db9264df1d000000000000000000000000000000000000000000000000000000000000002549960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008a7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2273496a396e6164474850596759334b7156384f7a4a666c726275504b474f716d59576f4d57516869467773222c226f726967696e223a2268747470733a2f2f7369676e2e636f696e626173652e636f6d222c2263726f73734f726967696e223a66616c73657d00000000000000000000000000000000000000000000",
91
+ sign,
92
+ signUserOperationHash: async (uoHash: Hex): Promise<Hex> => {
93
+ let sig = await sign({ hash: hashMessage({ raw: uoHash }) });
94
+ if (deferredActionData) {
95
+ sig = concatHex([deferredActionData, sig]);
96
+ deferredActionData = undefined;
97
+ }
98
+
99
+ return concatHex(["0xff", sig]);
100
+ },
101
+
102
+ async signMessage({ message }: { message: SignableMessage }): Promise<Hex> {
103
+ const hash = hashTypedData({
104
+ domain: {
105
+ chainId: Number(chain.id),
106
+ verifyingContract: getDefaultWebauthnValidationModuleAddress(chain),
107
+ salt: concatHex([`0x${"00".repeat(12)}`, accountAddress]),
108
+ },
109
+ types: {
110
+ ReplaySafeHash: [{ name: "hash", type: "bytes32" }],
111
+ },
112
+ message: {
113
+ hash: hashMessage(message),
114
+ },
115
+ primaryType: "ReplaySafeHash",
116
+ });
117
+
118
+ return pack1271Signature({
119
+ validationSignature: await sign({ hash }),
120
+ entityId,
121
+ });
122
+ },
123
+
124
+ signTypedData: async <
125
+ const typedData extends TypedData | Record<string, unknown>,
126
+ primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
127
+ >(
128
+ typedDataDefinition: TypedDataDefinition<typedData, primaryType>,
129
+ ): Promise<Hex> => {
130
+ const isDeferredAction =
131
+ typedDataDefinition?.primaryType === "DeferredAction" &&
132
+ // @ts-expect-error the domain type I think changed in viem, so this is not working correctly (TODO: fix this)
133
+ "verifyingContract" in typedDataDefinition.domain &&
134
+ typedDataDefinition.domain.verifyingContract === accountAddress;
135
+
136
+ const hash = await hashTypedData({
137
+ domain: {
138
+ chainId: Number(chain.id),
139
+ verifyingContract: getDefaultWebauthnValidationModuleAddress(chain),
140
+ salt: concatHex([`0x${"00".repeat(12)}`, accountAddress]),
141
+ },
142
+ types: {
143
+ ReplaySafeHash: [{ name: "hash", type: "bytes32" }],
144
+ },
145
+ message: {
146
+ hash: hashTypedData(typedDataDefinition),
147
+ },
148
+ primaryType: "ReplaySafeHash",
149
+ });
150
+
151
+ const validationSignature = await sign({ hash });
152
+
153
+ return isDeferredAction
154
+ ? pack1271Signature({ validationSignature, entityId })
155
+ : validationSignature;
156
+ },
157
+ };
158
+ };