@account-kit/signer 4.0.0-alpha.5 → 4.0.0-alpha.6

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 (44) hide show
  1. package/dist/cjs/base.js.map +1 -1
  2. package/dist/cjs/client/base.d.ts +1 -1
  3. package/dist/cjs/client/base.js.map +1 -1
  4. package/dist/cjs/client/index.js.map +1 -1
  5. package/dist/cjs/index.d.ts +5 -4
  6. package/dist/cjs/index.js +9 -7
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/signer.d.ts +1 -1
  9. package/dist/cjs/signer.js +5 -5
  10. package/dist/cjs/signer.js.map +1 -1
  11. package/dist/cjs/version.d.ts +1 -1
  12. package/dist/cjs/version.js +1 -1
  13. package/dist/cjs/version.js.map +1 -1
  14. package/dist/esm/base.js.map +1 -1
  15. package/dist/esm/client/base.d.ts +1 -1
  16. package/dist/esm/client/base.js.map +1 -1
  17. package/dist/esm/client/index.js.map +1 -1
  18. package/dist/esm/index.d.ts +5 -4
  19. package/dist/esm/index.js +3 -2
  20. package/dist/esm/index.js.map +1 -1
  21. package/dist/esm/signer.d.ts +1 -1
  22. package/dist/esm/signer.js +5 -5
  23. package/dist/esm/signer.js.map +1 -1
  24. package/dist/esm/version.d.ts +1 -1
  25. package/dist/esm/version.js +1 -1
  26. package/dist/esm/version.js.map +1 -1
  27. package/dist/types/base.d.ts +248 -14
  28. package/dist/types/base.d.ts.map +1 -1
  29. package/dist/types/client/base.d.ts +52 -6
  30. package/dist/types/client/base.d.ts.map +1 -1
  31. package/dist/types/client/index.d.ts +158 -0
  32. package/dist/types/client/index.d.ts.map +1 -1
  33. package/dist/types/index.d.ts +5 -4
  34. package/dist/types/index.d.ts.map +1 -1
  35. package/dist/types/signer.d.ts +22 -1
  36. package/dist/types/signer.d.ts.map +1 -1
  37. package/dist/types/version.d.ts +1 -1
  38. package/package.json +4 -3
  39. package/src/base.ts +250 -16
  40. package/src/client/base.ts +53 -6
  41. package/src/client/index.ts +159 -1
  42. package/src/index.ts +5 -6
  43. package/src/signer.ts +27 -6
  44. package/src/version.ts +1 -1
package/src/base.ts CHANGED
@@ -44,6 +44,10 @@ type InternalStore = Mutate<
44
44
  [["zustand/subscribeWithSelector", never]]
45
45
  >;
46
46
 
47
+ /**
48
+ * Base abstract class for Alchemy Signer, providing authentication and session management for smart accounts.
49
+ * Implements the `SmartAccountAuthenticator` interface and handles various signer events.
50
+ */
47
51
  export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
48
52
  implements SmartAccountAuthenticator<AuthParams, User, TClient>
49
53
  {
@@ -52,6 +56,15 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
52
56
  private sessionManager: SessionManager;
53
57
  private store: InternalStore;
54
58
 
59
+ /**
60
+ * Initializes an instance with the provided client and session configuration.
61
+ * This function sets up the internal store, initializes the session manager,
62
+ * registers listeners and initializes the session manager to manage session state.
63
+ *
64
+ * @param {BaseAlchemySignerParams<TClient>} param0 Object containing the client and session configuration
65
+ * @param {TClient} param0.client The client instance to be used internally
66
+ * @param {SessionConfig} param0.sessionConfig Configuration for managing sessions
67
+ */
55
68
  constructor({ client, sessionConfig }: BaseAlchemySignerParams<TClient>) {
56
69
  this.inner = client;
57
70
  this.store = createStore(
@@ -88,9 +101,9 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
88
101
  /**
89
102
  * Allows you to subscribe to events emitted by the signer
90
103
  *
91
- * @param event the event to subscribe to
92
- * @param listener the function to run when the event is emitted
93
- * @returns a function to remove the listener
104
+ * @param {AlchemySignerEvent} event the event to subscribe to
105
+ * @param {AlchemySignerEvents[AlchemySignerEvent]} listener the function to run when the event is emitted
106
+ * @returns {() => void} a function to remove the listener
94
107
  */
95
108
  on = <E extends AlchemySignerEvent>(
96
109
  event: E,
@@ -132,8 +145,29 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
132
145
  /**
133
146
  * Authenticate a user with either an email or a passkey and create a session for that user
134
147
  *
135
- * @param params - undefined if passkey login, otherwise an object with email and bundle to resolve
136
- * @returns the user that was authenticated
148
+ * @example
149
+ * ```ts
150
+ * import { AlchemyWebSigner } from "@account-kit/signer";
151
+ *
152
+ * const signer = new AlchemyWebSigner({
153
+ * client: {
154
+ * connection: {
155
+ * rpcUrl: "/api/rpc",
156
+ * },
157
+ * iframeConfig: {
158
+ * iframeContainerId: "alchemy-signer-iframe-container",
159
+ * },
160
+ * },
161
+ * });
162
+ *
163
+ * const result = await signer.authenticate({
164
+ * type: "email",
165
+ * email: "foo@mail.com",
166
+ * });
167
+ * ```
168
+ *
169
+ * @param {AuthParams} params - undefined if passkey login, otherwise an object with email and bundle to resolve
170
+ * @returns {Promise<User>} the user that was authenticated
137
171
  */
138
172
  authenticate: (params: AuthParams) => Promise<User> = async (params) => {
139
173
  if (params.type === "email") {
@@ -144,7 +178,27 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
144
178
  };
145
179
 
146
180
  /**
147
- * NOTE: right now this only clears the session locally.
181
+ * Clear a user session and log them out
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * import { AlchemyWebSigner } from "@account-kit/signer";
186
+ *
187
+ * const signer = new AlchemyWebSigner({
188
+ * client: {
189
+ * connection: {
190
+ * rpcUrl: "/api/rpc",
191
+ * },
192
+ * iframeConfig: {
193
+ * iframeContainerId: "alchemy-signer-iframe-container",
194
+ * },
195
+ * },
196
+ * });
197
+ *
198
+ * await signer.disconnect();
199
+ * ```
200
+ *
201
+ * @returns {Promise<void>} a promise that resolves when the user is logged out
148
202
  */
149
203
  disconnect: () => Promise<void> = async () => {
150
204
  await this.inner.disconnect();
@@ -155,10 +209,29 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
155
209
  * If a user has an ongoing session, it will use that session and
156
210
  * try to authenticate
157
211
  *
212
+ * @example
213
+ * ```ts
214
+ * import { AlchemyWebSigner } from "@account-kit/signer";
215
+ *
216
+ * const signer = new AlchemyWebSigner({
217
+ * client: {
218
+ * connection: {
219
+ * rpcUrl: "/api/rpc",
220
+ * },
221
+ * iframeConfig: {
222
+ * iframeContainerId: "alchemy-signer-iframe-container",
223
+ * },
224
+ * },
225
+ * });
226
+ *
227
+ * // throws if not logged in
228
+ * const user = await signer.getAuthDetails();
229
+ * ```
230
+ *
158
231
  * @throws if there is no user logged in
159
- * @returns the current user
232
+ * @returns {Promise<User>} the current user
160
233
  */
161
- getAuthDetails: () => Promise<User> = async () => {
234
+ getAuthDetails = async (): Promise<User> => {
162
235
  const sessionUser = await this.sessionManager.getSessionUser();
163
236
  if (sessionUser != null) {
164
237
  return sessionUser;
@@ -167,12 +240,41 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
167
240
  return this.inner.whoami();
168
241
  };
169
242
 
243
+ /**
244
+ * Retrieves the address of the current user by calling the `whoami` method on `this.inner`.
245
+ *
246
+ * @returns {Promise<string>} A promise that resolves to the address of the current user.
247
+ */
170
248
  getAddress: () => Promise<`0x${string}`> = async () => {
171
249
  const { address } = await this.inner.whoami();
172
250
 
173
251
  return address;
174
252
  };
175
253
 
254
+ /**
255
+ * Signs a raw message after hashing it.
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * import { AlchemyWebSigner } from "@account-kit/signer";
260
+ *
261
+ * const signer = new AlchemyWebSigner({
262
+ * client: {
263
+ * connection: {
264
+ * rpcUrl: "/api/rpc",
265
+ * },
266
+ * iframeConfig: {
267
+ * iframeContainerId: "alchemy-signer-iframe-container",
268
+ * },
269
+ * },
270
+ * });
271
+ *
272
+ * const signature = await signer.signMessage("Hello, world!");
273
+ * ```
274
+ *
275
+ * @param {string} msg the message to be hashed and then signed
276
+ * @returns {Promise<string>} a promise that resolves to the signed message
277
+ */
176
278
  signMessage: (msg: SignableMessage) => Promise<`0x${string}`> = async (
177
279
  msg
178
280
  ) => {
@@ -181,6 +283,35 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
181
283
  return this.inner.signRawMessage(messageHash);
182
284
  };
183
285
 
286
+ /**
287
+ * Signs a typed message by first hashing it and then signing the hashed message using the `signRawMessage` method.
288
+ *
289
+ * @example
290
+ * ```ts
291
+ * import { AlchemyWebSigner } from "@account-kit/signer";
292
+ *
293
+ * const signer = new AlchemyWebSigner({
294
+ * client: {
295
+ * connection: {
296
+ * rpcUrl: "/api/rpc",
297
+ * },
298
+ * iframeConfig: {
299
+ * iframeContainerId: "alchemy-signer-iframe-container",
300
+ * },
301
+ * },
302
+ * });
303
+ *
304
+ * const signature = await signer.signTypedData({
305
+ * domain: {},
306
+ * types: {},
307
+ * primaryType: "",
308
+ * message: {},
309
+ * });
310
+ * ```
311
+ *
312
+ * @param {TypedDataDefinition<TTypedData, TPrimaryType>} params The parameters for the typed message to be hashed and signed
313
+ * @returns {Promise<any>} A promise that resolves to the signed message
314
+ */
184
315
  signTypedData: <
185
316
  const TTypedData extends TypedData | { [key: string]: unknown },
186
317
  TPrimaryType extends keyof TTypedData | "EIP712Domain" = keyof TTypedData
@@ -192,6 +323,36 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
192
323
  return this.inner.signRawMessage(messageHash);
193
324
  };
194
325
 
326
+ /**
327
+ * Serializes a transaction, signs it with a raw message, and then returns the serialized transaction with the signature.
328
+ *
329
+ * @example
330
+ * ```ts
331
+ * import { AlchemyWebSigner } from "@account-kit/signer";
332
+ *
333
+ * const signer = new AlchemyWebSigner({
334
+ * client: {
335
+ * connection: {
336
+ * rpcUrl: "/api/rpc",
337
+ * },
338
+ * iframeConfig: {
339
+ * iframeContainerId: "alchemy-signer-iframe-container",
340
+ * },
341
+ * },
342
+ * });
343
+ *
344
+ * const tx = await signer.signTransaction({
345
+ * to: "0x1234",
346
+ * value: "0x1234",
347
+ * data: "0x1234",
348
+ * });
349
+ * ```
350
+ *
351
+ * @param {Transaction} tx the transaction to be serialized and signed
352
+ * @param {{serializer?: SerializeTransactionFn}} args options for serialization
353
+ * @param {() => Hex} [args.serializer] an optional serializer function. If not provided, the default `serializeTransaction` function will be used
354
+ * @returns {Promise<string>} a promise that resolves to the serialized transaction with the signature
355
+ */
195
356
  signTransaction: CustomSource["signTransaction"] = async (tx, args) => {
196
357
  const serializeFn = args?.serializer ?? serializeTransaction;
197
358
  const serializedTx = serializeFn(tx);
@@ -211,8 +372,26 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
211
372
  /**
212
373
  * Unauthenticated call to look up a user's organizationId by email
213
374
  *
214
- * @param email the email to lookup
215
- * @returns the organization id for the user if they exist
375
+ * @example
376
+ * ```ts
377
+ * import { AlchemyWebSigner } from "@account-kit/signer";
378
+ *
379
+ * const signer = new AlchemyWebSigner({
380
+ * client: {
381
+ * connection: {
382
+ * rpcUrl: "/api/rpc",
383
+ * },
384
+ * iframeConfig: {
385
+ * iframeContainerId: "alchemy-signer-iframe-container",
386
+ * },
387
+ * },
388
+ * });
389
+ *
390
+ * const result = await signer.getUser("foo@mail.com");
391
+ * ```
392
+ *
393
+ * @param {string} email the email to lookup
394
+ * @returns {Promise<{orgId: string}>} the organization id for the user if they exist
216
395
  */
217
396
  getUser: (email: string) => Promise<{ orgId: string } | null> = async (
218
397
  email
@@ -231,8 +410,26 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
231
410
  /**
232
411
  * Adds a passkey to the user's account
233
412
  *
234
- * @param params optional parameters for the passkey creation
235
- * @returns an array of the authenticator ids added to the user
413
+ * @example
414
+ * ```ts
415
+ * import { AlchemyWebSigner } from "@account-kit/signer";
416
+ *
417
+ * const signer = new AlchemyWebSigner({
418
+ * client: {
419
+ * connection: {
420
+ * rpcUrl: "/api/rpc",
421
+ * },
422
+ * iframeConfig: {
423
+ * iframeContainerId: "alchemy-signer-iframe-container",
424
+ * },
425
+ * },
426
+ * });
427
+ *
428
+ * const result = await signer.addPasskey()
429
+ * ```
430
+ *
431
+ * @param {CredentialCreationOptions | undefined} params optional parameters for the passkey creation
432
+ * @returns {Promise<string[]>} an array of the authenticator ids added to the user
236
433
  */
237
434
  addPasskey: (params?: CredentialCreationOptions) => Promise<string[]> =
238
435
  async (params) => {
@@ -244,8 +441,27 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
244
441
  * If the user is authenticated with an Email, this will return a seed phrase
245
442
  * If the user is authenticated with a Passkey, this will return a private key
246
443
  *
247
- * @param params export wallet parameters
248
- * @returns true if the wallet was exported successfully
444
+ * @example
445
+ * ```ts
446
+ * import { AlchemyWebSigner } from "@account-kit/signer";
447
+ *
448
+ * const signer = new AlchemyWebSigner({
449
+ * client: {
450
+ * connection: {
451
+ * rpcUrl: "/api/rpc",
452
+ * },
453
+ * iframeConfig: {
454
+ * iframeContainerId: "alchemy-signer-iframe-container",
455
+ * },
456
+ * },
457
+ * });
458
+ *
459
+ * // the params passed to this are different based on the specific signer
460
+ * const result = signer.exportWallet()
461
+ * ```
462
+ *
463
+ * @param {unknown} params export wallet parameters
464
+ * @returns {boolean} true if the wallet was exported successfully
249
465
  */
250
466
  exportWallet: (
251
467
  params: Parameters<(typeof this.inner)["exportWallet"]>[0]
@@ -257,10 +473,28 @@ export abstract class BaseAlchemySigner<TClient extends BaseSignerClient>
257
473
  * This method lets you adapt your AlchemySigner to a viem LocalAccount, which
258
474
  * will let you use the signer as an EOA directly.
259
475
  *
476
+ * @example
477
+ * ```ts
478
+ * import { AlchemyWebSigner } from "@account-kit/signer";
479
+ *
480
+ * const signer = new AlchemyWebSigner({
481
+ * client: {
482
+ * connection: {
483
+ * rpcUrl: "/api/rpc",
484
+ * },
485
+ * iframeConfig: {
486
+ * iframeContainerId: "alchemy-signer-iframe-container",
487
+ * },
488
+ * },
489
+ * });
490
+ *
491
+ * const account = signer.toViemAccount();
492
+ * ```
493
+ *
260
494
  * @throws if your signer is not authenticated
261
- * @returns a LocalAccount object that can be used with viem's wallet client
495
+ * @returns {LocalAccount} a LocalAccount object that can be used with viem's wallet client
262
496
  */
263
- toViemAccount: () => LocalAccount = () => {
497
+ toViemAccount = (): LocalAccount => {
264
498
  // if we want this method to be synchronous, then we need to do this check here
265
499
  // otherwise we can use the sessionManager to get the user
266
500
  if (!this.inner.getUser()) {
@@ -71,10 +71,23 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
71
71
  this._user = user;
72
72
  }
73
73
 
74
+ /**
75
+ * Sets the stamper of the TurnkeyClient.
76
+ *
77
+ * @param {TurnkeyClient["stamper"]} stamper the stamper function to set for the TurnkeyClient
78
+ */
74
79
  protected setStamper(stamper: TurnkeyClient["stamper"]) {
75
80
  this.turnkeyClient.stamper = stamper;
76
81
  }
77
82
 
83
+ /**
84
+ * Exports wallet credentials based on the specified type, either as a SEED_PHRASE or PRIVATE_KEY.
85
+ *
86
+ * @param {object} params The parameters for exporting the wallet
87
+ * @param {ExportWalletStamper} params.exportStamper The stamper used for exporting the wallet
88
+ * @param {"SEED_PHRASE" | "PRIVATE_KEY"} params.exportAs Specifies the format for exporting the wallet, either as a SEED_PHRASE or PRIVATE_KEY
89
+ * @returns {Promise<boolean>} A promise that resolves to true if the export is successful
90
+ */
78
91
  protected exportWalletInner(params: {
79
92
  exportStamper: ExportWalletStamper;
80
93
  exportAs: "SEED_PHRASE" | "PRIVATE_KEY";
@@ -120,9 +133,9 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
120
133
  /**
121
134
  * Listen to events emitted by the client
122
135
  *
123
- * @param event the event you want to listen to
124
- * @param listener the callback function to execute when an event is fired
125
- * @returns a function that will remove the listener when called
136
+ * @param {AlchemySignerClientEvent} event the event you want to listen to
137
+ * @param {AlchemySignerClientEvents[AlchemySignerClientEvent]} listener the callback function to execute when an event is fired
138
+ * @returns {() => void} a function that will remove the listener when called
126
139
  */
127
140
  public on = <E extends AlchemySignerClientEvent>(
128
141
  event: E,
@@ -133,6 +146,13 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
133
146
  return () => this.eventEmitter.removeListener(event, listener as any);
134
147
  };
135
148
 
149
+ /**
150
+ * Handles the creation of authenticators using WebAuthn attestation and the provided options. Requires the user to be authenticated.
151
+ *
152
+ * @param {CredentialCreationOptions} options The options used to create the WebAuthn attestation
153
+ * @returns {Promise<string[]>} A promise that resolves to an array of authenticator IDs
154
+ * @throws {NotAuthenticatedError} If the user is not authenticated
155
+ */
136
156
  public addPasskey = async (options: CredentialCreationOptions) => {
137
157
  if (!this.user) {
138
158
  throw new NotAuthenticatedError();
@@ -166,6 +186,13 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
166
186
  return authenticatorIds;
167
187
  };
168
188
 
189
+ /**
190
+ * Retrieves the current user or fetches the user information if not already available.
191
+ *
192
+ * @param {string} [orgId] optional organization ID, defaults to the user's organization ID
193
+ * @returns {Promise<User>} A promise that resolves to the user object
194
+ * @throws {Error} if no organization ID is provided when there is no current user
195
+ */
169
196
  public whoami = async (orgId = this.user?.orgId): Promise<User> => {
170
197
  if (this.user) {
171
198
  return this.user;
@@ -200,6 +227,12 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
200
227
  return this.user;
201
228
  };
202
229
 
230
+ /**
231
+ * Looks up information based on an email address.
232
+ *
233
+ * @param {string} email the email address to look up
234
+ * @returns {Promise<any>} the result of the lookup request
235
+ */
203
236
  public lookupUserByEmail = async (email: string) => {
204
237
  return this.request("/v1/lookup", { email });
205
238
  };
@@ -209,10 +242,10 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
209
242
  * For SignMessage or SignTypedData, the caller should hash the message before calling this method and pass
210
243
  * that result here.
211
244
  *
212
- * @param msg the hex representation of the bytes to sign
213
- * @returns the signature over the raw hex
245
+ * @param {Hex} msg the hex representation of the bytes to sign
246
+ * @returns {Promise<Hex>} the signature over the raw hex
214
247
  */
215
- public signRawMessage = async (msg: Hex) => {
248
+ public signRawMessage = async (msg: Hex): Promise<Hex> => {
216
249
  if (!this.user) {
217
250
  throw new NotAuthenticatedError();
218
251
  }
@@ -236,10 +269,23 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
236
269
  return signature;
237
270
  };
238
271
 
272
+ /**
273
+ * Returns the current user or null if no user is set.
274
+ *
275
+ * @returns {User | null} the current user object or null if no user is available
276
+ */
239
277
  public getUser = (): User | null => {
240
278
  return this.user ?? null;
241
279
  };
242
280
 
281
+ /**
282
+ * Sends a POST request to the given signer route with the specified body and returns the response.
283
+ * Not intended to be used directly, use the specific methods instead on the client instead.
284
+ *
285
+ * @param {SignerRoutes} route The route to which the request should be sent
286
+ * @param {SignerBody<R>} body The request body containing the data to be sent
287
+ * @returns {Promise<SignerResponse<R>>} A promise that resolves to the response from the signer
288
+ */
243
289
  public request = async <R extends SignerRoutes>(
244
290
  route: R,
245
291
  body: SignerBody<R>
@@ -356,6 +402,7 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
356
402
  return result;
357
403
  };
358
404
 
405
+ // eslint-disable-next-line eslint-rules/require-jsdoc-on-reexported-functions
359
406
  protected pollActivityCompletion = async <
360
407
  T extends keyof Awaited<
361
408
  ReturnType<(typeof this.turnkeyClient)["getActivity"]>
@@ -40,6 +40,29 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
40
40
  private webauthnStamper: WebauthnStamper;
41
41
  iframeContainerId: string;
42
42
 
43
+ /**
44
+ * Initializes a new instance with the given parameters, setting up the connection, iframe configuration, and WebAuthn stamper.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
49
+ *
50
+ * const client = new AlchemySignerWebClient({
51
+ * connection: {
52
+ * apiKey: "your-api-key",
53
+ * },
54
+ * iframeConfig: {
55
+ * iframeContainerId: "signer-iframe-container",
56
+ * },
57
+ * });
58
+ * ```
59
+ *
60
+ * @param {AlchemySignerClientParams} params the parameters required to initialize the client
61
+ * @param {ConnectionConfig} params.connection The connection details needed to connect to the service
62
+ * @param {{ iframeElementId?: string; iframeContainerId: string }} params.iframeConfig The configuration details for setting up the iframe stamper
63
+ * @param {string} params.rpId The relying party ID, defaulting to the current hostname if not provided
64
+ * @param {string} params.rootOrgId The root organization ID
65
+ */
43
66
  constructor(params: AlchemySignerClientParams) {
44
67
  const { connection, iframeConfig, rpId, rootOrgId } =
45
68
  AlchemySignerClientParamsSchema.parse(params);
@@ -64,7 +87,29 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
64
87
  });
65
88
  }
66
89
 
67
- public createAccount = async (params: CreateAccountParams) => {
90
+ /**
91
+ * Authenticates the user by either email or passkey account creation flow. Emits events during the process.
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
96
+ *
97
+ * const client = new AlchemySignerWebClient({
98
+ * connection: {
99
+ * apiKey: "your-api-key",
100
+ * },
101
+ * iframeConfig: {
102
+ * iframeContainerId: "signer-iframe-container",
103
+ * },
104
+ * });
105
+ *
106
+ * const account = await client.createAccount({ type: "email", email: "you@mail.com" });
107
+ * ```
108
+ *
109
+ * @param {CreateAccountParams} params The parameters for creating an account, including the type (email or passkey) and additional details.
110
+ * @returns {Promise<SignupResponse>} A promise that resolves with the response object containing the account creation result.
111
+ */
112
+ createAccount = async (params: CreateAccountParams) => {
68
113
  this.eventEmitter.emit("authenticating");
69
114
  if (params.type === "email") {
70
115
  const { email, expirationSeconds } = params;
@@ -105,6 +150,29 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
105
150
  return result;
106
151
  };
107
152
 
153
+ /**
154
+ * Begin authenticating a user with their email and an expiration time for the authentication request. Initializes the iframe stamper to get the target public key.
155
+ * This method sends an email to the user to complete their login
156
+ *
157
+ * @example
158
+ * ```ts
159
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
160
+ *
161
+ * const client = new AlchemySignerWebClient({
162
+ * connection: {
163
+ * apiKey: "your-api-key",
164
+ * },
165
+ * iframeConfig: {
166
+ * iframeContainerId: "signer-iframe-container",
167
+ * },
168
+ * });
169
+ *
170
+ * const account = await client.initEmailAuth({ email: "you@mail.com" });
171
+ * ```
172
+ *
173
+ * @param {Omit<EmailAuthParams, "targetPublicKey">} params The parameters for email authentication, excluding the target public key
174
+ * @returns {Promise<any>} The response from the authentication request
175
+ */
108
176
  public initEmailAuth = async (
109
177
  params: Omit<EmailAuthParams, "targetPublicKey">
110
178
  ) => {
@@ -120,6 +188,28 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
120
188
  });
121
189
  };
122
190
 
191
+ /**
192
+ * Completes email auth for the user by injecting a credential bundle and retrieving the user information based on the provided organization ID. Emits events during the process.
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
197
+ *
198
+ * const client = new AlchemySignerWebClient({
199
+ * connection: {
200
+ * apiKey: "your-api-key",
201
+ * },
202
+ * iframeConfig: {
203
+ * iframeContainerId: "signer-iframe-container",
204
+ * },
205
+ * });
206
+ *
207
+ * const account = await client.completeEmailAuth({ orgId: "user-org-id", bundle: "bundle-from-email" });
208
+ * ```
209
+ *
210
+ * @param {{ bundle: string; orgId: string }} config The configuration object for the authentication function containing the credential bundle to inject and the organization id associated with the user
211
+ * @returns {Promise<User>} A promise that resolves to the authenticated user information
212
+ */
123
213
  public completeEmailAuth = async ({
124
214
  bundle,
125
215
  orgId,
@@ -142,6 +232,28 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
142
232
  return user;
143
233
  };
144
234
 
235
+ /**
236
+ * Asynchronously handles the authentication process using WebAuthn Stamper. If a user is provided, sets the user and returns it. Otherwise, retrieves the current user and initializes the WebAuthn stamper.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
241
+ *
242
+ * const client = new AlchemySignerWebClient({
243
+ * connection: {
244
+ * apiKey: "your-api-key",
245
+ * },
246
+ * iframeConfig: {
247
+ * iframeContainerId: "signer-iframe-container",
248
+ * },
249
+ * });
250
+ *
251
+ * const account = await client.lookupUserWithPasskey();
252
+ * ```
253
+ *
254
+ * @param {User} [user] An optional user object to authenticate
255
+ * @returns {Promise<User>} A promise that resolves to the authenticated user object
256
+ */
145
257
  public lookupUserWithPasskey = async (user: User | undefined = undefined) => {
146
258
  this.eventEmitter.emit("authenticating");
147
259
  await this.initWebauthnStamper(user);
@@ -157,6 +269,33 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
157
269
  return result;
158
270
  };
159
271
 
272
+ /**
273
+ * Initiates the export of a wallet by creating an iframe stamper and calling the appropriate export function.
274
+ * The export can be based on a seed phrase or a private key.
275
+ *
276
+ * @example
277
+ * ```ts
278
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
279
+ *
280
+ * const client = new AlchemySignerWebClient({
281
+ * connection: {
282
+ * apiKey: "your-api-key",
283
+ * },
284
+ * iframeConfig: {
285
+ * iframeContainerId: "signer-iframe-container",
286
+ * },
287
+ * });
288
+ *
289
+ * const account = await client.exportWallet({
290
+ * iframeContainerId: "export-iframe-container",
291
+ * });
292
+ * ```
293
+ *
294
+ * @param {ExportWalletParams} config The parameters for exporting the wallet
295
+ * @param {string} config.iframeContainerId The ID of the container element that will hold the iframe stamper
296
+ * @param {string} [config.iframeElementId] Optional ID for the iframe element
297
+ * @returns {Promise<void>} A promise that resolves when the export process is complete
298
+ */
160
299
  public exportWallet = async ({
161
300
  iframeContainerId,
162
301
  iframeElementId = "turnkey-export-iframe",
@@ -181,6 +320,25 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
181
320
  });
182
321
  };
183
322
 
323
+ /**
324
+ * Asynchronous function that clears the user and resets the iframe stamper.
325
+ *
326
+ * @example
327
+ * ```ts
328
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
329
+ *
330
+ * const client = new AlchemySignerWebClient({
331
+ * connection: {
332
+ * apiKey: "your-api-key",
333
+ * },
334
+ * iframeConfig: {
335
+ * iframeContainerId: "signer-iframe-container",
336
+ * },
337
+ * });
338
+ *
339
+ * const account = await client.disconnect();
340
+ * ```
341
+ */
184
342
  public disconnect = async () => {
185
343
  this.user = undefined;
186
344
  this.iframeStamper.clear();