@account-kit/signer 4.0.0-beta.0 → 4.0.0-beta.10

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 (77) hide show
  1. package/dist/esm/base.d.ts +43 -8
  2. package/dist/esm/base.js +186 -29
  3. package/dist/esm/base.js.map +1 -1
  4. package/dist/esm/client/base.d.ts +22 -4
  5. package/dist/esm/client/base.js +36 -2
  6. package/dist/esm/client/base.js.map +1 -1
  7. package/dist/esm/client/index.d.ts +108 -7
  8. package/dist/esm/client/index.js +282 -14
  9. package/dist/esm/client/index.js.map +1 -1
  10. package/dist/esm/client/types.d.ts +31 -1
  11. package/dist/esm/client/types.js.map +1 -1
  12. package/dist/esm/index.d.ts +1 -1
  13. package/dist/esm/index.js +1 -1
  14. package/dist/esm/index.js.map +1 -1
  15. package/dist/esm/metrics.d.ts +17 -0
  16. package/dist/esm/metrics.js +7 -0
  17. package/dist/esm/metrics.js.map +1 -0
  18. package/dist/esm/oauth.d.ts +19 -0
  19. package/dist/esm/oauth.js +26 -0
  20. package/dist/esm/oauth.js.map +1 -0
  21. package/dist/esm/session/manager.d.ts +3 -2
  22. package/dist/esm/session/manager.js +29 -15
  23. package/dist/esm/session/manager.js.map +1 -1
  24. package/dist/esm/session/types.d.ts +1 -1
  25. package/dist/esm/session/types.js.map +1 -1
  26. package/dist/esm/signer.d.ts +52 -7
  27. package/dist/esm/signer.js +46 -3
  28. package/dist/esm/signer.js.map +1 -1
  29. package/dist/esm/types.d.ts +8 -1
  30. package/dist/esm/types.js +3 -1
  31. package/dist/esm/types.js.map +1 -1
  32. package/dist/esm/utils/typeAssertions.d.ts +1 -0
  33. package/dist/esm/utils/typeAssertions.js +4 -0
  34. package/dist/esm/utils/typeAssertions.js.map +1 -0
  35. package/dist/esm/version.d.ts +1 -1
  36. package/dist/esm/version.js +1 -1
  37. package/dist/esm/version.js.map +1 -1
  38. package/dist/types/base.d.ts +43 -8
  39. package/dist/types/base.d.ts.map +1 -1
  40. package/dist/types/client/base.d.ts +22 -4
  41. package/dist/types/client/base.d.ts.map +1 -1
  42. package/dist/types/client/index.d.ts +108 -7
  43. package/dist/types/client/index.d.ts.map +1 -1
  44. package/dist/types/client/types.d.ts +31 -1
  45. package/dist/types/client/types.d.ts.map +1 -1
  46. package/dist/types/index.d.ts +1 -1
  47. package/dist/types/index.d.ts.map +1 -1
  48. package/dist/types/metrics.d.ts +18 -0
  49. package/dist/types/metrics.d.ts.map +1 -0
  50. package/dist/types/oauth.d.ts +20 -0
  51. package/dist/types/oauth.d.ts.map +1 -0
  52. package/dist/types/session/manager.d.ts +3 -2
  53. package/dist/types/session/manager.d.ts.map +1 -1
  54. package/dist/types/session/types.d.ts +1 -1
  55. package/dist/types/session/types.d.ts.map +1 -1
  56. package/dist/types/signer.d.ts +52 -7
  57. package/dist/types/signer.d.ts.map +1 -1
  58. package/dist/types/types.d.ts +8 -1
  59. package/dist/types/types.d.ts.map +1 -1
  60. package/dist/types/utils/typeAssertions.d.ts +2 -0
  61. package/dist/types/utils/typeAssertions.d.ts.map +1 -0
  62. package/dist/types/version.d.ts +1 -1
  63. package/dist/types/version.d.ts.map +1 -1
  64. package/package.json +7 -10
  65. package/src/base.ts +261 -66
  66. package/src/client/base.ts +49 -4
  67. package/src/client/index.ts +317 -20
  68. package/src/client/types.ts +33 -1
  69. package/src/index.ts +5 -1
  70. package/src/metrics.ts +23 -0
  71. package/src/oauth.ts +36 -0
  72. package/src/session/manager.ts +46 -19
  73. package/src/session/types.ts +1 -1
  74. package/src/signer.ts +91 -4
  75. package/src/types.ts +9 -1
  76. package/src/utils/typeAssertions.ts +3 -0
  77. package/src/version.ts +1 -1
@@ -2,7 +2,7 @@ import { type ConnectionConfig } from "@aa-sdk/core";
2
2
  import { TurnkeyClient, type TSignedRequest } from "@turnkey/http";
3
3
  import EventEmitter from "eventemitter3";
4
4
  import type { Hex } from "viem";
5
- import type { AlchemySignerClientEvents, CreateAccountParams, EmailAuthParams, GetWebAuthnAttestationResult, SignerBody, SignerResponse, SignupResponse, User } from "./types.js";
5
+ import type { AlchemySignerClientEvents, AuthenticatingEventMetadata, CreateAccountParams, EmailAuthParams, GetWebAuthnAttestationResult, OauthConfig, OauthParams, SignerBody, SignerResponse, SignupResponse, User } from "./types.js";
6
6
  export interface BaseSignerClientParams {
7
7
  stamper: TurnkeyClient["stamper"];
8
8
  connection: ConnectionConfig;
@@ -23,12 +23,19 @@ export declare abstract class BaseSignerClient<TExportWalletParams = unknown> {
23
23
  protected turnkeyClient: TurnkeyClient;
24
24
  protected rootOrg: string;
25
25
  protected eventEmitter: EventEmitter<AlchemySignerClientEvents>;
26
+ protected oauthConfig: OauthConfig | undefined;
26
27
  /**
27
28
  * Create a new instance of the Alchemy Signer client
28
29
  *
29
30
  * @param {BaseSignerClientParams} params the parameters required to create the client
30
31
  */
31
32
  constructor(params: BaseSignerClientParams);
33
+ /**
34
+ * Asynchronously fetches and sets the OAuth configuration.
35
+ *
36
+ * @returns {Promise<OauthConfig>} A promise that resolves to the OAuth configuration
37
+ */
38
+ initOauth: () => Promise<OauthConfig>;
32
39
  protected get user(): User | undefined;
33
40
  protected set user(user: User | undefined);
34
41
  /**
@@ -53,13 +60,23 @@ export declare abstract class BaseSignerClient<TExportWalletParams = unknown> {
53
60
  abstract initEmailAuth(params: Omit<EmailAuthParams, "targetPublicKey">): Promise<{
54
61
  orgId: string;
55
62
  }>;
56
- abstract completeEmailAuth(params: {
63
+ abstract completeAuthWithBundle(params: {
57
64
  bundle: string;
58
65
  orgId: string;
66
+ connectedEventName: keyof AlchemySignerClientEvents;
67
+ authenticatingType: AuthenticatingEventMetadata["type"];
68
+ idToken?: string;
59
69
  }): Promise<User>;
70
+ abstract oauthWithRedirect(args: Extract<OauthParams, {
71
+ mode: "redirect";
72
+ }>): Promise<never>;
73
+ abstract oauthWithPopup(args: Extract<OauthParams, {
74
+ mode: "popup";
75
+ }>): Promise<User>;
60
76
  abstract disconnect(): Promise<void>;
61
77
  abstract exportWallet(params: TExportWalletParams): Promise<boolean>;
62
78
  abstract lookupUserWithPasskey(user?: User): Promise<User>;
79
+ protected abstract getOauthConfig(): Promise<OauthConfig>;
63
80
  protected abstract getWebAuthnAttestation(options: CredentialCreationOptions, userDetails?: {
64
81
  username: string;
65
82
  }): Promise<GetWebAuthnAttestationResult>;
@@ -83,10 +100,11 @@ export declare abstract class BaseSignerClient<TExportWalletParams = unknown> {
83
100
  * Retrieves the current user or fetches the user information if not already available.
84
101
  *
85
102
  * @param {string} [orgId] optional organization ID, defaults to the user's organization ID
103
+ * @param {string} idToken an OIDC ID token containing additional user information
86
104
  * @returns {Promise<User>} A promise that resolves to the user object
87
105
  * @throws {Error} if no organization ID is provided when there is no current user
88
106
  */
89
- whoami: (orgId?: string | undefined) => Promise<User>;
107
+ whoami: (orgId?: string | undefined, idToken?: string) => Promise<User>;
90
108
  /**
91
109
  * Generates a stamped whoami request for the current user. This request can then be used to call /signer/v1/whoami to get the user information.
92
110
  * This is useful if you want to get the user information in a different context like a server. You can pass the stamped request to the server
@@ -129,7 +147,7 @@ export declare abstract class BaseSignerClient<TExportWalletParams = unknown> {
129
147
  * @param {SignerBody<R>} body The request body containing the data to be sent
130
148
  * @returns {Promise<SignerResponse<R>>} A promise that resolves to the response from the signer
131
149
  */
132
- request: <R extends "/v1/signup" | "/v1/whoami" | "/v1/auth" | "/v1/lookup" | "/v1/sign-payload">(route: R, body: SignerBody<R>) => Promise<SignerResponse<R>>;
150
+ request: <R extends "/v1/signup" | "/v1/whoami" | "/v1/auth" | "/v1/lookup" | "/v1/sign-payload" | "/v1/prepare-oauth">(route: R, body: SignerBody<R>) => Promise<SignerResponse<R>>;
133
151
  private exportAsSeedPhrase;
134
152
  private exportAsPrivateKey;
135
153
  protected pollActivityCompletion: <T extends "createOrganizationResult" | "createAuthenticatorsResult" | "createUsersResult" | "createPrivateKeysResult" | "createInvitationsResult" | "acceptInvitationResult" | "signRawPayloadResult" | "createPolicyResult" | "disablePrivateKeyResult" | "deleteUsersResult" | "deleteAuthenticatorsResult" | "deleteInvitationResult" | "deleteOrganizationResult" | "deletePolicyResult" | "createUserTagResult" | "deleteUserTagsResult" | "signTransactionResult" | "deleteApiKeysResult" | "createApiKeysResult" | "createPrivateKeyTagResult" | "deletePrivateKeyTagsResult" | "setPaymentMethodResult" | "activateBillingTierResult" | "deletePaymentMethodResult" | "createApiOnlyUsersResult" | "updateRootQuorumResult" | "updateUserTagResult" | "updatePrivateKeyTagResult" | "createSubOrganizationResult" | "updateAllowedOriginsResult" | "createPrivateKeysResultV2" | "updateUserResult" | "updatePolicyResult" | "createSubOrganizationResultV3" | "createWalletResult" | "createWalletAccountsResult" | "initUserEmailRecoveryResult" | "recoverUserResult" | "setOrganizationFeatureResult" | "removeOrganizationFeatureResult" | "exportPrivateKeyResult" | "exportWalletResult" | "createSubOrganizationResultV4" | "emailAuthResult" | "exportWalletAccountResult">(activity: Awaited<ReturnType<(typeof this.turnkeyClient)["getActivity"]>>["activity"], organizationId: string, resultKey: T) => Promise<NonNullable<{
@@ -1,8 +1,10 @@
1
1
  import { ConnectionConfigSchema } from "@aa-sdk/core";
2
2
  import { TurnkeyClient } from "@turnkey/http";
3
3
  import EventEmitter from "eventemitter3";
4
+ import { jwtDecode } from "jwt-decode";
4
5
  import { NotAuthenticatedError } from "../errors.js";
5
6
  import { base64UrlEncode } from "../utils/base64UrlEncode.js";
7
+ import { assertNever } from "../utils/typeAssertions.js";
6
8
  /**
7
9
  * Base class for all Alchemy Signer clients
8
10
  */
@@ -43,6 +45,26 @@ export class BaseSignerClient {
43
45
  writable: true,
44
46
  value: void 0
45
47
  });
48
+ Object.defineProperty(this, "oauthConfig", {
49
+ enumerable: true,
50
+ configurable: true,
51
+ writable: true,
52
+ value: void 0
53
+ });
54
+ /**
55
+ * Asynchronously fetches and sets the OAuth configuration.
56
+ *
57
+ * @returns {Promise<OauthConfig>} A promise that resolves to the OAuth configuration
58
+ */
59
+ Object.defineProperty(this, "initOauth", {
60
+ enumerable: true,
61
+ configurable: true,
62
+ writable: true,
63
+ value: async () => {
64
+ this.oauthConfig = await this.getOauthConfig();
65
+ return this.oauthConfig;
66
+ }
67
+ });
46
68
  // #endregion
47
69
  // #region PUBLIC METHODS
48
70
  /**
@@ -100,6 +122,7 @@ export class BaseSignerClient {
100
122
  * Retrieves the current user or fetches the user information if not already available.
101
123
  *
102
124
  * @param {string} [orgId] optional organization ID, defaults to the user's organization ID
125
+ * @param {string} idToken an OIDC ID token containing additional user information
103
126
  * @returns {Promise<User>} A promise that resolves to the user object
104
127
  * @throws {Error} if no organization ID is provided when there is no current user
105
128
  */
@@ -107,7 +130,7 @@ export class BaseSignerClient {
107
130
  enumerable: true,
108
131
  configurable: true,
109
132
  writable: true,
110
- value: async (orgId = this.user?.orgId) => {
133
+ value: async (orgId = this.user?.orgId, idToken) => {
111
134
  if (this.user) {
112
135
  return this.user;
113
136
  }
@@ -120,6 +143,14 @@ export class BaseSignerClient {
120
143
  const user = await this.request("/v1/whoami", {
121
144
  stampedRequest,
122
145
  });
146
+ if (idToken) {
147
+ const claims = jwtDecode(idToken);
148
+ user.idToken = idToken;
149
+ user.claims = claims;
150
+ if (typeof claims.email === "string") {
151
+ user.email = claims.email;
152
+ }
153
+ }
123
154
  const credentialId = (() => {
124
155
  try {
125
156
  return JSON.parse(stampedRequest?.stamp.stampHeaderValue)
@@ -377,11 +408,14 @@ export class BaseSignerClient {
377
408
  * @returns {Promise<boolean>} A promise that resolves to true if the export is successful
378
409
  */
379
410
  exportWalletInner(params) {
380
- switch (params.exportAs) {
411
+ const { exportAs } = params;
412
+ switch (exportAs) {
381
413
  case "PRIVATE_KEY":
382
414
  return this.exportAsPrivateKey(params.exportStamper);
383
415
  case "SEED_PHRASE":
384
416
  return this.exportAsSeedPhrase(params.exportStamper);
417
+ default:
418
+ assertNever(exportAs, `Unknown export mode: ${exportAs}`);
385
419
  }
386
420
  }
387
421
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/client/base.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConnectionConfigSchema, type ConnectionConfig } from \"@aa-sdk/core\";\nimport { TurnkeyClient, type TSignedRequest } from \"@turnkey/http\";\nimport EventEmitter from \"eventemitter3\";\nimport type { Hex } from \"viem\";\nimport { NotAuthenticatedError } from \"../errors.js\";\nimport { base64UrlEncode } from \"../utils/base64UrlEncode.js\";\nimport type {\n AlchemySignerClientEvent,\n AlchemySignerClientEvents,\n CreateAccountParams,\n EmailAuthParams,\n GetWebAuthnAttestationResult,\n SignerBody,\n SignerResponse,\n SignerRoutes,\n SignupResponse,\n User,\n} from \"./types.js\";\n\nexport interface BaseSignerClientParams {\n stamper: TurnkeyClient[\"stamper\"];\n connection: ConnectionConfig;\n rootOrgId?: string;\n rpId?: string;\n}\n\nexport type ExportWalletStamper = TurnkeyClient[\"stamper\"] & {\n injectWalletExportBundle(bundle: string): Promise<boolean>;\n injectKeyExportBundle(bundle: string): Promise<boolean>;\n publicKey(): string | null;\n};\n\n/**\n * Base class for all Alchemy Signer clients\n */\nexport abstract class BaseSignerClient<TExportWalletParams = unknown> {\n private _user: User | undefined;\n private connectionConfig: ConnectionConfig;\n protected turnkeyClient: TurnkeyClient;\n protected rootOrg: string;\n protected eventEmitter: EventEmitter<AlchemySignerClientEvents>;\n\n /**\n * Create a new instance of the Alchemy Signer client\n *\n * @param {BaseSignerClientParams} params the parameters required to create the client\n */\n constructor(params: BaseSignerClientParams) {\n const { stamper, connection, rootOrgId } = params;\n\n this.rootOrg = rootOrgId ?? \"24c1acf5-810f-41e0-a503-d5d13fa8e830\";\n this.eventEmitter = new EventEmitter<AlchemySignerClientEvents>();\n this.connectionConfig = ConnectionConfigSchema.parse(connection);\n this.turnkeyClient = new TurnkeyClient(\n { baseUrl: \"https://api.turnkey.com\" },\n stamper\n );\n }\n\n protected get user() {\n return this._user;\n }\n\n protected set user(user: User | undefined) {\n if (user && !this._user) {\n this.eventEmitter.emit(\"connected\", user);\n } else if (!user && this._user) {\n this.eventEmitter.emit(\"disconnected\");\n }\n\n this._user = user;\n }\n\n /**\n * Sets the stamper of the TurnkeyClient.\n *\n * @param {TurnkeyClient[\"stamper\"]} stamper the stamper function to set for the TurnkeyClient\n */\n protected setStamper(stamper: TurnkeyClient[\"stamper\"]) {\n this.turnkeyClient.stamper = stamper;\n }\n\n /**\n * Exports wallet credentials based on the specified type, either as a SEED_PHRASE or PRIVATE_KEY.\n *\n * @param {object} params The parameters for exporting the wallet\n * @param {ExportWalletStamper} params.exportStamper The stamper used for exporting the wallet\n * @param {\"SEED_PHRASE\" | \"PRIVATE_KEY\"} params.exportAs Specifies the format for exporting the wallet, either as a SEED_PHRASE or PRIVATE_KEY\n * @returns {Promise<boolean>} A promise that resolves to true if the export is successful\n */\n protected exportWalletInner(params: {\n exportStamper: ExportWalletStamper;\n exportAs: \"SEED_PHRASE\" | \"PRIVATE_KEY\";\n }): Promise<boolean> {\n switch (params.exportAs) {\n case \"PRIVATE_KEY\":\n return this.exportAsPrivateKey(params.exportStamper);\n case \"SEED_PHRASE\":\n return this.exportAsSeedPhrase(params.exportStamper);\n }\n }\n\n // #region ABSTRACT METHODS\n\n public abstract createAccount(\n params: CreateAccountParams\n ): Promise<SignupResponse>;\n\n public abstract initEmailAuth(\n params: Omit<EmailAuthParams, \"targetPublicKey\">\n ): Promise<{ orgId: string }>;\n\n public abstract completeEmailAuth(params: {\n bundle: string;\n orgId: string;\n }): Promise<User>;\n\n public abstract disconnect(): Promise<void>;\n\n public abstract exportWallet(params: TExportWalletParams): Promise<boolean>;\n\n public abstract lookupUserWithPasskey(user?: User): Promise<User>;\n\n protected abstract getWebAuthnAttestation(\n options: CredentialCreationOptions,\n userDetails?: { username: string }\n ): Promise<GetWebAuthnAttestationResult>;\n\n // #endregion\n\n // #region PUBLIC METHODS\n\n /**\n * Listen to events emitted by the client\n *\n * @param {AlchemySignerClientEvent} event the event you want to listen to\n * @param {AlchemySignerClientEvents[AlchemySignerClientEvent]} listener the callback function to execute when an event is fired\n * @returns {() => void} a function that will remove the listener when called\n */\n public on = <E extends AlchemySignerClientEvent>(\n event: E,\n listener: AlchemySignerClientEvents[E]\n ) => {\n this.eventEmitter.on(event, listener as any);\n\n return () => this.eventEmitter.removeListener(event, listener as any);\n };\n\n /**\n * Handles the creation of authenticators using WebAuthn attestation and the provided options. Requires the user to be authenticated.\n *\n * @param {CredentialCreationOptions} options The options used to create the WebAuthn attestation\n * @returns {Promise<string[]>} A promise that resolves to an array of authenticator IDs\n * @throws {NotAuthenticatedError} If the user is not authenticated\n */\n public addPasskey = async (options: CredentialCreationOptions) => {\n if (!this.user) {\n throw new NotAuthenticatedError();\n }\n const { attestation, challenge } = await this.getWebAuthnAttestation(\n options\n );\n\n const { activity } = await this.turnkeyClient.createAuthenticators({\n type: \"ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2\",\n timestampMs: Date.now().toString(),\n organizationId: this.user.orgId,\n parameters: {\n userId: this.user.userId,\n authenticators: [\n {\n attestation,\n authenticatorName: `passkey-${Date.now().toString()}`,\n challenge: base64UrlEncode(challenge),\n },\n ],\n },\n });\n\n const { authenticatorIds } = await this.pollActivityCompletion(\n activity,\n this.user.orgId,\n \"createAuthenticatorsResult\"\n );\n\n return authenticatorIds;\n };\n\n /**\n * Retrieves the current user or fetches the user information if not already available.\n *\n * @param {string} [orgId] optional organization ID, defaults to the user's organization ID\n * @returns {Promise<User>} A promise that resolves to the user object\n * @throws {Error} if no organization ID is provided when there is no current user\n */\n public whoami = async (orgId = this.user?.orgId): Promise<User> => {\n if (this.user) {\n return this.user;\n }\n\n if (!orgId) {\n throw new Error(\"No orgId provided\");\n }\n\n const stampedRequest = await this.turnkeyClient.stampGetWhoami({\n organizationId: orgId,\n });\n\n const user = await this.request(\"/v1/whoami\", {\n stampedRequest,\n });\n\n const credentialId = (() => {\n try {\n return JSON.parse(stampedRequest?.stamp.stampHeaderValue)\n .credentialId as string;\n } catch (e) {\n return undefined;\n }\n })();\n\n this.user = {\n ...user,\n credentialId,\n };\n\n return this.user;\n };\n\n /**\n * Generates a stamped whoami request for the current user. This request can then be used to call /signer/v1/whoami to get the user information.\n * This is useful if you want to get the user information in a different context like a server. You can pass the stamped request to the server\n * and then call our API to get the user information. Using this stamp is the most trusted way to get the user information since a stamp can only\n * belong to the user who created it.\n *\n * @returns {Promise<TSignedRequest>} a promise that resolves to the \"whoami\" information for the logged in user\n * @throws {Error} if no organization ID is provided\n */\n public stampWhoami = async (): Promise<TSignedRequest> => {\n if (!this.user) {\n throw new Error(\"User must be authenticated to stamp a whoami request\");\n }\n\n return await this.turnkeyClient.stampGetWhoami({\n organizationId: this.user.orgId,\n });\n };\n\n /**\n * Looks up information based on an email address.\n *\n * @param {string} email the email address to look up\n * @returns {Promise<any>} the result of the lookup request\n */\n public lookupUserByEmail = async (email: string) => {\n return this.request(\"/v1/lookup\", { email });\n };\n\n /**\n * This will sign a message with the user's private key, without doing any transformations on the message.\n * For SignMessage or SignTypedData, the caller should hash the message before calling this method and pass\n * that result here.\n *\n * @param {Hex} msg the hex representation of the bytes to sign\n * @returns {Promise<Hex>} the signature over the raw hex\n */\n public signRawMessage = async (msg: Hex): Promise<Hex> => {\n if (!this.user) {\n throw new NotAuthenticatedError();\n }\n\n const stampedRequest = await this.turnkeyClient.stampSignRawPayload({\n organizationId: this.user.orgId,\n type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2\",\n timestampMs: Date.now().toString(),\n parameters: {\n encoding: \"PAYLOAD_ENCODING_HEXADECIMAL\",\n hashFunction: \"HASH_FUNCTION_NO_OP\",\n payload: msg,\n signWith: this.user.address,\n },\n });\n\n const { signature } = await this.request(\"/v1/sign-payload\", {\n stampedRequest,\n });\n\n return signature;\n };\n\n /**\n * Returns the current user or null if no user is set.\n *\n * @returns {User | null} the current user object or null if no user is available\n */\n public getUser = (): User | null => {\n return this.user ?? null;\n };\n\n /**\n * Sends a POST request to the given signer route with the specified body and returns the response.\n * Not intended to be used directly, use the specific methods instead on the client instead.\n *\n * @param {SignerRoutes} route The route to which the request should be sent\n * @param {SignerBody<R>} body The request body containing the data to be sent\n * @returns {Promise<SignerResponse<R>>} A promise that resolves to the response from the signer\n */\n public request = async <R extends SignerRoutes>(\n route: R,\n body: SignerBody<R>\n ): Promise<SignerResponse<R>> => {\n const url = this.connectionConfig.rpcUrl ?? \"https://api.g.alchemy.com\";\n const basePath = \"/signer\";\n\n const headers = new Headers();\n headers.append(\"Content-Type\", \"application/json\");\n if (this.connectionConfig.apiKey) {\n headers.append(\"Authorization\", `Bearer ${this.connectionConfig.apiKey}`);\n } else if (this.connectionConfig.jwt) {\n headers.append(\"Authorization\", `Bearer ${this.connectionConfig.jwt}`);\n }\n\n const response = await fetch(`${url}${basePath}${route}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n headers,\n });\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n\n const json = await response.json();\n\n return json as SignerResponse<R>;\n };\n\n // #endregion\n\n // #region PRIVATE METHODS\n private exportAsSeedPhrase = async (stamper: ExportWalletStamper) => {\n if (!this.user) {\n throw new NotAuthenticatedError();\n }\n\n const { wallets } = await this.turnkeyClient.getWallets({\n organizationId: this.user.orgId,\n });\n\n const walletAccounts = await Promise.all(\n wallets.map(({ walletId }) =>\n this.turnkeyClient.getWalletAccounts({\n organizationId: this.user!.orgId,\n walletId,\n })\n )\n ).then((x) => x.flatMap((x) => x.accounts));\n\n const walletAccount = walletAccounts.find(\n (x) => x.address === this.user!.address\n );\n\n if (!walletAccount) {\n throw new Error(\n `Could not find wallet associated with ${this.user.address}`\n );\n }\n\n const { activity } = await this.turnkeyClient.exportWallet({\n organizationId: this.user.orgId,\n type: \"ACTIVITY_TYPE_EXPORT_WALLET\",\n timestampMs: Date.now().toString(),\n parameters: {\n walletId: walletAccount!.walletId,\n targetPublicKey: stamper.publicKey()!,\n },\n });\n\n const { exportBundle } = await this.pollActivityCompletion(\n activity,\n this.user.orgId,\n \"exportWalletResult\"\n );\n\n const result = await stamper.injectWalletExportBundle(exportBundle);\n\n if (!result) {\n throw new Error(\"Failed to inject wallet export bundle\");\n }\n\n return result;\n };\n\n private exportAsPrivateKey = async (stamper: ExportWalletStamper) => {\n if (!this.user) {\n throw new NotAuthenticatedError();\n }\n\n const { activity } = await this.turnkeyClient.exportWalletAccount({\n organizationId: this.user.orgId,\n type: \"ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT\",\n timestampMs: Date.now().toString(),\n parameters: {\n address: this.user.address,\n targetPublicKey: stamper.publicKey()!,\n },\n });\n\n const { exportBundle } = await this.pollActivityCompletion(\n activity,\n this.user.orgId,\n \"exportWalletAccountResult\"\n );\n\n const result = await stamper.injectKeyExportBundle(exportBundle);\n\n if (!result) {\n throw new Error(\"Failed to inject wallet export bundle\");\n }\n\n return result;\n };\n\n // eslint-disable-next-line eslint-rules/require-jsdoc-on-reexported-functions\n protected pollActivityCompletion = async <\n T extends keyof Awaited<\n ReturnType<(typeof this.turnkeyClient)[\"getActivity\"]>\n >[\"activity\"][\"result\"]\n >(\n activity: Awaited<\n ReturnType<(typeof this.turnkeyClient)[\"getActivity\"]>\n >[\"activity\"],\n organizationId: string,\n resultKey: T\n ): Promise<\n NonNullable<\n Awaited<\n ReturnType<(typeof this.turnkeyClient)[\"getActivity\"]>\n >[\"activity\"][\"result\"][T]\n >\n > => {\n if (activity.status === \"ACTIVITY_STATUS_COMPLETED\") {\n return activity.result[resultKey]!;\n }\n\n const {\n activity: { status, id, result },\n } = await this.turnkeyClient.getActivity({\n activityId: activity.id,\n organizationId,\n });\n\n if (status === \"ACTIVITY_STATUS_COMPLETED\") {\n return result[resultKey]!;\n }\n\n if (\n status === \"ACTIVITY_STATUS_FAILED\" ||\n status === \"ACTIVITY_STATUS_REJECTED\" ||\n status === \"ACTIVITY_STATUS_CONSENSUS_NEEDED\"\n ) {\n throw new Error(\n `Failed to get activity with with id ${id} (status: ${status})`\n );\n }\n\n // TODO: add ability to configure this + add exponential backoff\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n return this.pollActivityCompletion(activity, organizationId, resultKey);\n };\n // #endregion\n}\n"]}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/client/base.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConnectionConfigSchema, type ConnectionConfig } from \"@aa-sdk/core\";\nimport { TurnkeyClient, type TSignedRequest } from \"@turnkey/http\";\nimport EventEmitter from \"eventemitter3\";\nimport { jwtDecode } from \"jwt-decode\";\nimport type { Hex } from \"viem\";\nimport { NotAuthenticatedError } from \"../errors.js\";\nimport { base64UrlEncode } from \"../utils/base64UrlEncode.js\";\nimport { assertNever } from \"../utils/typeAssertions.js\";\nimport type {\n AlchemySignerClientEvent,\n AlchemySignerClientEvents,\n AuthenticatingEventMetadata,\n CreateAccountParams,\n EmailAuthParams,\n GetWebAuthnAttestationResult,\n OauthConfig,\n OauthParams,\n SignerBody,\n SignerResponse,\n SignerRoutes,\n SignupResponse,\n User,\n} from \"./types.js\";\n\nexport interface BaseSignerClientParams {\n stamper: TurnkeyClient[\"stamper\"];\n connection: ConnectionConfig;\n rootOrgId?: string;\n rpId?: string;\n}\n\nexport type ExportWalletStamper = TurnkeyClient[\"stamper\"] & {\n injectWalletExportBundle(bundle: string): Promise<boolean>;\n injectKeyExportBundle(bundle: string): Promise<boolean>;\n publicKey(): string | null;\n};\n\n/**\n * Base class for all Alchemy Signer clients\n */\nexport abstract class BaseSignerClient<TExportWalletParams = unknown> {\n private _user: User | undefined;\n private connectionConfig: ConnectionConfig;\n protected turnkeyClient: TurnkeyClient;\n protected rootOrg: string;\n protected eventEmitter: EventEmitter<AlchemySignerClientEvents>;\n protected oauthConfig: OauthConfig | undefined;\n\n /**\n * Create a new instance of the Alchemy Signer client\n *\n * @param {BaseSignerClientParams} params the parameters required to create the client\n */\n constructor(params: BaseSignerClientParams) {\n const { stamper, connection, rootOrgId } = params;\n this.rootOrg = rootOrgId ?? \"24c1acf5-810f-41e0-a503-d5d13fa8e830\";\n this.eventEmitter = new EventEmitter<AlchemySignerClientEvents>();\n this.connectionConfig = ConnectionConfigSchema.parse(connection);\n this.turnkeyClient = new TurnkeyClient(\n { baseUrl: \"https://api.turnkey.com\" },\n stamper\n );\n }\n\n /**\n * Asynchronously fetches and sets the OAuth configuration.\n *\n * @returns {Promise<OauthConfig>} A promise that resolves to the OAuth configuration\n */\n public initOauth = async (): Promise<OauthConfig> => {\n this.oauthConfig = await this.getOauthConfig();\n return this.oauthConfig;\n };\n\n protected get user() {\n return this._user;\n }\n\n protected set user(user: User | undefined) {\n if (user && !this._user) {\n this.eventEmitter.emit(\"connected\", user);\n } else if (!user && this._user) {\n this.eventEmitter.emit(\"disconnected\");\n }\n\n this._user = user;\n }\n\n /**\n * Sets the stamper of the TurnkeyClient.\n *\n * @param {TurnkeyClient[\"stamper\"]} stamper the stamper function to set for the TurnkeyClient\n */\n protected setStamper(stamper: TurnkeyClient[\"stamper\"]) {\n this.turnkeyClient.stamper = stamper;\n }\n\n /**\n * Exports wallet credentials based on the specified type, either as a SEED_PHRASE or PRIVATE_KEY.\n *\n * @param {object} params The parameters for exporting the wallet\n * @param {ExportWalletStamper} params.exportStamper The stamper used for exporting the wallet\n * @param {\"SEED_PHRASE\" | \"PRIVATE_KEY\"} params.exportAs Specifies the format for exporting the wallet, either as a SEED_PHRASE or PRIVATE_KEY\n * @returns {Promise<boolean>} A promise that resolves to true if the export is successful\n */\n protected exportWalletInner(params: {\n exportStamper: ExportWalletStamper;\n exportAs: \"SEED_PHRASE\" | \"PRIVATE_KEY\";\n }): Promise<boolean> {\n const { exportAs } = params;\n switch (exportAs) {\n case \"PRIVATE_KEY\":\n return this.exportAsPrivateKey(params.exportStamper);\n case \"SEED_PHRASE\":\n return this.exportAsSeedPhrase(params.exportStamper);\n default:\n assertNever(exportAs, `Unknown export mode: ${exportAs}`);\n }\n }\n\n // #region ABSTRACT METHODS\n\n public abstract createAccount(\n params: CreateAccountParams\n ): Promise<SignupResponse>;\n\n public abstract initEmailAuth(\n params: Omit<EmailAuthParams, \"targetPublicKey\">\n ): Promise<{ orgId: string }>;\n\n public abstract completeAuthWithBundle(params: {\n bundle: string;\n orgId: string;\n connectedEventName: keyof AlchemySignerClientEvents;\n authenticatingType: AuthenticatingEventMetadata[\"type\"];\n idToken?: string;\n }): Promise<User>;\n\n public abstract oauthWithRedirect(\n args: Extract<OauthParams, { mode: \"redirect\" }>\n ): Promise<never>;\n\n public abstract oauthWithPopup(\n args: Extract<OauthParams, { mode: \"popup\" }>\n ): Promise<User>;\n\n public abstract disconnect(): Promise<void>;\n\n public abstract exportWallet(params: TExportWalletParams): Promise<boolean>;\n\n public abstract lookupUserWithPasskey(user?: User): Promise<User>;\n\n protected abstract getOauthConfig(): Promise<OauthConfig>;\n\n protected abstract getWebAuthnAttestation(\n options: CredentialCreationOptions,\n userDetails?: { username: string }\n ): Promise<GetWebAuthnAttestationResult>;\n\n // #endregion\n\n // #region PUBLIC METHODS\n\n /**\n * Listen to events emitted by the client\n *\n * @param {AlchemySignerClientEvent} event the event you want to listen to\n * @param {AlchemySignerClientEvents[AlchemySignerClientEvent]} listener the callback function to execute when an event is fired\n * @returns {() => void} a function that will remove the listener when called\n */\n public on = <E extends AlchemySignerClientEvent>(\n event: E,\n listener: AlchemySignerClientEvents[E]\n ) => {\n this.eventEmitter.on(event, listener as any);\n\n return () => this.eventEmitter.removeListener(event, listener as any);\n };\n\n /**\n * Handles the creation of authenticators using WebAuthn attestation and the provided options. Requires the user to be authenticated.\n *\n * @param {CredentialCreationOptions} options The options used to create the WebAuthn attestation\n * @returns {Promise<string[]>} A promise that resolves to an array of authenticator IDs\n * @throws {NotAuthenticatedError} If the user is not authenticated\n */\n public addPasskey = async (options: CredentialCreationOptions) => {\n if (!this.user) {\n throw new NotAuthenticatedError();\n }\n const { attestation, challenge } = await this.getWebAuthnAttestation(\n options\n );\n\n const { activity } = await this.turnkeyClient.createAuthenticators({\n type: \"ACTIVITY_TYPE_CREATE_AUTHENTICATORS_V2\",\n timestampMs: Date.now().toString(),\n organizationId: this.user.orgId,\n parameters: {\n userId: this.user.userId,\n authenticators: [\n {\n attestation,\n authenticatorName: `passkey-${Date.now().toString()}`,\n challenge: base64UrlEncode(challenge),\n },\n ],\n },\n });\n\n const { authenticatorIds } = await this.pollActivityCompletion(\n activity,\n this.user.orgId,\n \"createAuthenticatorsResult\"\n );\n\n return authenticatorIds;\n };\n\n /**\n * Retrieves the current user or fetches the user information if not already available.\n *\n * @param {string} [orgId] optional organization ID, defaults to the user's organization ID\n * @param {string} idToken an OIDC ID token containing additional user information\n * @returns {Promise<User>} A promise that resolves to the user object\n * @throws {Error} if no organization ID is provided when there is no current user\n */\n public whoami = async (\n orgId = this.user?.orgId,\n idToken?: string\n ): Promise<User> => {\n if (this.user) {\n return this.user;\n }\n\n if (!orgId) {\n throw new Error(\"No orgId provided\");\n }\n\n const stampedRequest = await this.turnkeyClient.stampGetWhoami({\n organizationId: orgId,\n });\n\n const user = await this.request(\"/v1/whoami\", {\n stampedRequest,\n });\n\n if (idToken) {\n const claims: Record<string, unknown> = jwtDecode(idToken);\n user.idToken = idToken;\n user.claims = claims;\n if (typeof claims.email === \"string\") {\n user.email = claims.email;\n }\n }\n\n const credentialId = (() => {\n try {\n return JSON.parse(stampedRequest?.stamp.stampHeaderValue)\n .credentialId as string;\n } catch (e) {\n return undefined;\n }\n })();\n\n this.user = {\n ...user,\n credentialId,\n };\n\n return this.user;\n };\n\n /**\n * Generates a stamped whoami request for the current user. This request can then be used to call /signer/v1/whoami to get the user information.\n * This is useful if you want to get the user information in a different context like a server. You can pass the stamped request to the server\n * and then call our API to get the user information. Using this stamp is the most trusted way to get the user information since a stamp can only\n * belong to the user who created it.\n *\n * @returns {Promise<TSignedRequest>} a promise that resolves to the \"whoami\" information for the logged in user\n * @throws {Error} if no organization ID is provided\n */\n public stampWhoami = async (): Promise<TSignedRequest> => {\n if (!this.user) {\n throw new Error(\"User must be authenticated to stamp a whoami request\");\n }\n\n return await this.turnkeyClient.stampGetWhoami({\n organizationId: this.user.orgId,\n });\n };\n\n /**\n * Looks up information based on an email address.\n *\n * @param {string} email the email address to look up\n * @returns {Promise<any>} the result of the lookup request\n */\n public lookupUserByEmail = async (email: string) => {\n return this.request(\"/v1/lookup\", { email });\n };\n\n /**\n * This will sign a message with the user's private key, without doing any transformations on the message.\n * For SignMessage or SignTypedData, the caller should hash the message before calling this method and pass\n * that result here.\n *\n * @param {Hex} msg the hex representation of the bytes to sign\n * @returns {Promise<Hex>} the signature over the raw hex\n */\n public signRawMessage = async (msg: Hex): Promise<Hex> => {\n if (!this.user) {\n throw new NotAuthenticatedError();\n }\n\n const stampedRequest = await this.turnkeyClient.stampSignRawPayload({\n organizationId: this.user.orgId,\n type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2\",\n timestampMs: Date.now().toString(),\n parameters: {\n encoding: \"PAYLOAD_ENCODING_HEXADECIMAL\",\n hashFunction: \"HASH_FUNCTION_NO_OP\",\n payload: msg,\n signWith: this.user.address,\n },\n });\n\n const { signature } = await this.request(\"/v1/sign-payload\", {\n stampedRequest,\n });\n\n return signature;\n };\n\n /**\n * Returns the current user or null if no user is set.\n *\n * @returns {User | null} the current user object or null if no user is available\n */\n public getUser = (): User | null => {\n return this.user ?? null;\n };\n\n /**\n * Sends a POST request to the given signer route with the specified body and returns the response.\n * Not intended to be used directly, use the specific methods instead on the client instead.\n *\n * @param {SignerRoutes} route The route to which the request should be sent\n * @param {SignerBody<R>} body The request body containing the data to be sent\n * @returns {Promise<SignerResponse<R>>} A promise that resolves to the response from the signer\n */\n public request = async <R extends SignerRoutes>(\n route: R,\n body: SignerBody<R>\n ): Promise<SignerResponse<R>> => {\n const url = this.connectionConfig.rpcUrl ?? \"https://api.g.alchemy.com\";\n\n const basePath = \"/signer\";\n\n const headers = new Headers();\n headers.append(\"Content-Type\", \"application/json\");\n if (this.connectionConfig.apiKey) {\n headers.append(\"Authorization\", `Bearer ${this.connectionConfig.apiKey}`);\n } else if (this.connectionConfig.jwt) {\n headers.append(\"Authorization\", `Bearer ${this.connectionConfig.jwt}`);\n }\n\n const response = await fetch(`${url}${basePath}${route}`, {\n method: \"POST\",\n body: JSON.stringify(body),\n headers,\n });\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n\n const json = await response.json();\n\n return json as SignerResponse<R>;\n };\n\n // #endregion\n\n // #region PRIVATE METHODS\n private exportAsSeedPhrase = async (stamper: ExportWalletStamper) => {\n if (!this.user) {\n throw new NotAuthenticatedError();\n }\n\n const { wallets } = await this.turnkeyClient.getWallets({\n organizationId: this.user.orgId,\n });\n\n const walletAccounts = await Promise.all(\n wallets.map(({ walletId }) =>\n this.turnkeyClient.getWalletAccounts({\n organizationId: this.user!.orgId,\n walletId,\n })\n )\n ).then((x) => x.flatMap((x) => x.accounts));\n\n const walletAccount = walletAccounts.find(\n (x) => x.address === this.user!.address\n );\n\n if (!walletAccount) {\n throw new Error(\n `Could not find wallet associated with ${this.user.address}`\n );\n }\n\n const { activity } = await this.turnkeyClient.exportWallet({\n organizationId: this.user.orgId,\n type: \"ACTIVITY_TYPE_EXPORT_WALLET\",\n timestampMs: Date.now().toString(),\n parameters: {\n walletId: walletAccount!.walletId,\n targetPublicKey: stamper.publicKey()!,\n },\n });\n\n const { exportBundle } = await this.pollActivityCompletion(\n activity,\n this.user.orgId,\n \"exportWalletResult\"\n );\n\n const result = await stamper.injectWalletExportBundle(exportBundle);\n\n if (!result) {\n throw new Error(\"Failed to inject wallet export bundle\");\n }\n\n return result;\n };\n\n private exportAsPrivateKey = async (stamper: ExportWalletStamper) => {\n if (!this.user) {\n throw new NotAuthenticatedError();\n }\n\n const { activity } = await this.turnkeyClient.exportWalletAccount({\n organizationId: this.user.orgId,\n type: \"ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT\",\n timestampMs: Date.now().toString(),\n parameters: {\n address: this.user.address,\n targetPublicKey: stamper.publicKey()!,\n },\n });\n\n const { exportBundle } = await this.pollActivityCompletion(\n activity,\n this.user.orgId,\n \"exportWalletAccountResult\"\n );\n\n const result = await stamper.injectKeyExportBundle(exportBundle);\n\n if (!result) {\n throw new Error(\"Failed to inject wallet export bundle\");\n }\n\n return result;\n };\n\n // eslint-disable-next-line eslint-rules/require-jsdoc-on-reexported-functions\n protected pollActivityCompletion = async <\n T extends keyof Awaited<\n ReturnType<(typeof this.turnkeyClient)[\"getActivity\"]>\n >[\"activity\"][\"result\"]\n >(\n activity: Awaited<\n ReturnType<(typeof this.turnkeyClient)[\"getActivity\"]>\n >[\"activity\"],\n organizationId: string,\n resultKey: T\n ): Promise<\n NonNullable<\n Awaited<\n ReturnType<(typeof this.turnkeyClient)[\"getActivity\"]>\n >[\"activity\"][\"result\"][T]\n >\n > => {\n if (activity.status === \"ACTIVITY_STATUS_COMPLETED\") {\n return activity.result[resultKey]!;\n }\n\n const {\n activity: { status, id, result },\n } = await this.turnkeyClient.getActivity({\n activityId: activity.id,\n organizationId,\n });\n\n if (status === \"ACTIVITY_STATUS_COMPLETED\") {\n return result[resultKey]!;\n }\n\n if (\n status === \"ACTIVITY_STATUS_FAILED\" ||\n status === \"ACTIVITY_STATUS_REJECTED\" ||\n status === \"ACTIVITY_STATUS_CONSENSUS_NEEDED\"\n ) {\n throw new Error(\n `Failed to get activity with with id ${id} (status: ${status})`\n );\n }\n\n // TODO: add ability to configure this + add exponential backoff\n await new Promise((resolve) => setTimeout(resolve, 500));\n\n return this.pollActivityCompletion(activity, organizationId, resultKey);\n };\n // #endregion\n}\n"]}
@@ -1,6 +1,8 @@
1
+ import { BaseError } from "@aa-sdk/core";
1
2
  import { z } from "zod";
3
+ import type { AuthParams } from "../signer.js";
2
4
  import { BaseSignerClient } from "./base.js";
3
- import type { CreateAccountParams, CredentialCreationOptionOverrides, EmailAuthParams, ExportWalletParams, User } from "./types.js";
5
+ import type { AlchemySignerClientEvents, AuthenticatingEventMetadata, CreateAccountParams, CredentialCreationOptionOverrides, EmailAuthParams, ExportWalletParams, OauthConfig, User } from "./types.js";
4
6
  export declare const AlchemySignerClientParamsSchema: z.ZodObject<{
5
7
  connection: z.ZodUnion<[z.ZodObject<{
6
8
  rpcUrl: z.ZodOptional<z.ZodNever>;
@@ -63,6 +65,8 @@ export declare const AlchemySignerClientParamsSchema: z.ZodObject<{
63
65
  }>;
64
66
  rpId: z.ZodOptional<z.ZodString>;
65
67
  rootOrgId: z.ZodDefault<z.ZodOptional<z.ZodString>>;
68
+ oauthCallbackUrl: z.ZodDefault<z.ZodOptional<z.ZodString>>;
69
+ enablePopupOauth: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
66
70
  }, "strip", z.ZodTypeAny, {
67
71
  connection: {
68
72
  apiKey: string;
@@ -81,11 +85,13 @@ export declare const AlchemySignerClientParamsSchema: z.ZodObject<{
81
85
  jwt: string;
82
86
  apiKey?: undefined;
83
87
  };
84
- rootOrgId: string;
85
88
  iframeConfig: {
86
89
  iframeElementId: string;
87
90
  iframeContainerId: string;
88
91
  };
92
+ rootOrgId: string;
93
+ oauthCallbackUrl: string;
94
+ enablePopupOauth: boolean;
89
95
  rpId?: string | undefined;
90
96
  }, {
91
97
  connection: {
@@ -111,6 +117,8 @@ export declare const AlchemySignerClientParamsSchema: z.ZodObject<{
111
117
  };
112
118
  rpId?: string | undefined;
113
119
  rootOrgId?: string | undefined;
120
+ oauthCallbackUrl?: string | undefined;
121
+ enablePopupOauth?: boolean | undefined;
114
122
  }>;
115
123
  export type AlchemySignerClientParams = z.input<typeof AlchemySignerClientParamsSchema>;
116
124
  /**
@@ -120,6 +128,7 @@ export type AlchemySignerClientParams = z.input<typeof AlchemySignerClientParams
120
128
  export declare class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams> {
121
129
  private iframeStamper;
122
130
  private webauthnStamper;
131
+ oauthCallbackUrl: string;
123
132
  iframeContainerId: string;
124
133
  /**
125
134
  * Initializes a new instance with the given parameters, setting up the connection, iframe configuration, and WebAuthn stamper.
@@ -195,7 +204,9 @@ export declare class AlchemySignerWebClient extends BaseSignerClient<ExportWalle
195
204
  orgId: string;
196
205
  }>;
197
206
  /**
198
- * 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.
207
+ * Completes auth for the user by injecting a credential bundle and retrieving
208
+ * the user information based on the provided organization ID. Emits events
209
+ * during the process.
199
210
  *
200
211
  * @example
201
212
  * ```ts
@@ -210,15 +221,23 @@ export declare class AlchemySignerWebClient extends BaseSignerClient<ExportWalle
210
221
  * },
211
222
  * });
212
223
  *
213
- * const account = await client.completeEmailAuth({ orgId: "user-org-id", bundle: "bundle-from-email" });
224
+ * const account = await client.completeAuthWithBundle({ orgId: "user-org-id", bundle: "bundle-from-email", connectedEventName: "connectedEmail" });
214
225
  * ```
215
226
  *
216
- * @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
217
- * @returns {Promise<User>} A promise that resolves to the authenticated user information
227
+ * @param {{ bundle: string; orgId: string, connectedEventName: keyof AlchemySignerClientEvents, idToken?: string }} config
228
+ * The configuration object for the authentication function containing the
229
+ * credential bundle to inject and the organization id associated with the
230
+ * user, as well as the event to be emitted on success and optionally an OIDC
231
+ * ID token with extra user information
232
+ * @returns {Promise<User>} A promise that resolves to the authenticated user
233
+ * information
218
234
  */
219
- completeEmailAuth: ({ bundle, orgId, }: {
235
+ completeAuthWithBundle: ({ bundle, orgId, connectedEventName, idToken, authenticatingType, }: {
220
236
  bundle: string;
221
237
  orgId: string;
238
+ connectedEventName: keyof AlchemySignerClientEvents;
239
+ authenticatingType: AuthenticatingEventMetadata["type"];
240
+ idToken?: string | undefined;
222
241
  }) => Promise<User>;
223
242
  /**
224
243
  * 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.
@@ -291,6 +310,68 @@ export declare class AlchemySignerWebClient extends BaseSignerClient<ExportWalle
291
310
  * ```
292
311
  */
293
312
  disconnect: () => Promise<void>;
313
+ /**
314
+ * Redirects the user to the OAuth provider URL based on the provided arguments. This function will always reject after 1 second if the redirection does not occur.
315
+ *
316
+ * @example
317
+ * ```ts
318
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
319
+ *
320
+ * const client = new AlchemySignerWebClient({
321
+ * connection: {
322
+ * apiKey: "your-api-key",
323
+ * },
324
+ * iframeConfig: {
325
+ * iframeContainerId: "signer-iframe-container",
326
+ * },
327
+ * });
328
+ *
329
+ * await client.oauthWithRedirect({
330
+ * type: "oauth",
331
+ * authProviderId: "google",
332
+ * mode: "redirect",
333
+ * redirectUrl: "/",
334
+ * });
335
+ * ```
336
+ *
337
+ * @param {Extract<AuthParams, { type: "oauth"; mode: "redirect" }>} args The arguments required to obtain the OAuth provider URL
338
+ * @returns {Promise<never>} A promise that will never resolve, only reject if the redirection fails
339
+ */
340
+ oauthWithRedirect: (args: Extract<AuthParams, {
341
+ type: "oauth";
342
+ mode: "redirect";
343
+ }>) => Promise<never>;
344
+ /**
345
+ * Initiates an OAuth authentication flow in a popup window and returns the authenticated user.
346
+ *
347
+ * @example
348
+ * ```ts
349
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
350
+ *
351
+ * const client = new AlchemySignerWebClient({
352
+ * connection: {
353
+ * apiKey: "your-api-key",
354
+ * },
355
+ * iframeConfig: {
356
+ * iframeContainerId: "signer-iframe-container",
357
+ * },
358
+ * });
359
+ *
360
+ * const user = await client.oauthWithPopup({
361
+ * type: "oauth",
362
+ * authProviderId: "google",
363
+ * mode: "popup"
364
+ * });
365
+ * ```
366
+ *
367
+ * @param {Extract<AuthParams, { type: "oauth"; mode: "popup" }>} args The authentication parameters specifying OAuth type and popup mode
368
+ * @returns {Promise<User>} A promise that resolves to a `User` object containing the authenticated user information
369
+ */
370
+ oauthWithPopup: (args: Extract<AuthParams, {
371
+ type: "oauth";
372
+ mode: "popup";
373
+ }>) => Promise<User>;
374
+ private getOauthProviderUrl;
294
375
  private initIframeStamper;
295
376
  private initWebauthnStamper;
296
377
  protected getWebAuthnAttestation: (options?: CredentialCreationOptionOverrides, userDetails?: {
@@ -305,4 +386,24 @@ export declare class AlchemySignerWebClient extends BaseSignerClient<ExportWalle
305
386
  transports: ("AUTHENTICATOR_TRANSPORT_BLE" | "AUTHENTICATOR_TRANSPORT_INTERNAL" | "AUTHENTICATOR_TRANSPORT_NFC" | "AUTHENTICATOR_TRANSPORT_USB" | "AUTHENTICATOR_TRANSPORT_HYBRID")[];
306
387
  };
307
388
  }>;
389
+ protected getOauthConfig: () => Promise<OauthConfig>;
390
+ private getOauthConfigForMode;
391
+ }
392
+ /**
393
+ * This error is thrown when the OAuth flow is cancelled because the auth popup
394
+ * window was closed.
395
+ */
396
+ export declare class OauthCancelledError extends BaseError {
397
+ name: string;
398
+ /**
399
+ * Constructor for initializing an error indicating that the OAuth flow was
400
+ * cancelled.
401
+ */
402
+ constructor();
403
+ }
404
+ /**
405
+ * This error is thrown when an error occurs during the OAuth login flow.
406
+ */
407
+ export declare class OauthFailedError extends BaseError {
408
+ name: string;
308
409
  }