@account-kit/signer 4.16.1-alpha.3 → 4.18.0-alpha.3

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 (80) hide show
  1. package/dist/esm/base.d.ts +16 -32
  2. package/dist/esm/base.js +127 -122
  3. package/dist/esm/base.js.map +1 -1
  4. package/dist/esm/client/base.d.ts +3 -36
  5. package/dist/esm/client/base.js +15 -20
  6. package/dist/esm/client/base.js.map +1 -1
  7. package/dist/esm/client/index.d.ts +27 -40
  8. package/dist/esm/client/index.js +41 -164
  9. package/dist/esm/client/index.js.map +1 -1
  10. package/dist/esm/client/types.d.ts +27 -65
  11. package/dist/esm/client/types.js.map +1 -1
  12. package/dist/esm/errors.d.ts +0 -6
  13. package/dist/esm/errors.js +0 -18
  14. package/dist/esm/errors.js.map +1 -1
  15. package/dist/esm/index.d.ts +1 -1
  16. package/dist/esm/index.js +1 -1
  17. package/dist/esm/index.js.map +1 -1
  18. package/dist/esm/metrics.d.ts +3 -0
  19. package/dist/esm/metrics.js.map +1 -1
  20. package/dist/esm/oauth.d.ts +5 -4
  21. package/dist/esm/oauth.js +16 -6
  22. package/dist/esm/oauth.js.map +1 -1
  23. package/dist/esm/session/manager.d.ts +0 -1
  24. package/dist/esm/session/manager.js +4 -0
  25. package/dist/esm/session/manager.js.map +1 -1
  26. package/dist/esm/session/types.d.ts +1 -1
  27. package/dist/esm/session/types.js.map +1 -1
  28. package/dist/esm/signer.d.ts +8 -5
  29. package/dist/esm/signer.js.map +1 -1
  30. package/dist/esm/types.d.ts +2 -9
  31. package/dist/esm/types.js +1 -5
  32. package/dist/esm/types.js.map +1 -1
  33. package/dist/esm/version.d.ts +1 -1
  34. package/dist/esm/version.js +1 -1
  35. package/dist/esm/version.js.map +1 -1
  36. package/dist/types/base.d.ts +16 -32
  37. package/dist/types/base.d.ts.map +1 -1
  38. package/dist/types/client/base.d.ts +3 -36
  39. package/dist/types/client/base.d.ts.map +1 -1
  40. package/dist/types/client/index.d.ts +27 -40
  41. package/dist/types/client/index.d.ts.map +1 -1
  42. package/dist/types/client/types.d.ts +27 -65
  43. package/dist/types/client/types.d.ts.map +1 -1
  44. package/dist/types/errors.d.ts +0 -6
  45. package/dist/types/errors.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 +3 -0
  49. package/dist/types/metrics.d.ts.map +1 -1
  50. package/dist/types/oauth.d.ts +5 -4
  51. package/dist/types/oauth.d.ts.map +1 -1
  52. package/dist/types/session/manager.d.ts +0 -1
  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 +8 -5
  57. package/dist/types/signer.d.ts.map +1 -1
  58. package/dist/types/types.d.ts +2 -9
  59. package/dist/types/types.d.ts.map +1 -1
  60. package/dist/types/version.d.ts +1 -1
  61. package/package.json +4 -4
  62. package/src/base.ts +120 -166
  63. package/src/client/base.ts +26 -65
  64. package/src/client/index.ts +46 -174
  65. package/src/client/types.ts +31 -75
  66. package/src/errors.ts +1 -11
  67. package/src/index.ts +1 -5
  68. package/src/metrics.ts +2 -1
  69. package/src/oauth.ts +22 -8
  70. package/src/session/manager.ts +8 -7
  71. package/src/session/types.ts +1 -1
  72. package/src/signer.ts +13 -7
  73. package/src/types.ts +1 -9
  74. package/src/version.ts +1 -1
  75. package/dist/esm/utils/parseMfaError.d.ts +0 -2
  76. package/dist/esm/utils/parseMfaError.js +0 -15
  77. package/dist/esm/utils/parseMfaError.js.map +0 -1
  78. package/dist/types/utils/parseMfaError.d.ts +0 -3
  79. package/dist/types/utils/parseMfaError.d.ts.map +0 -1
  80. package/src/utils/parseMfaError.ts +0 -15
@@ -4,7 +4,7 @@ import EventEmitter from "eventemitter3";
4
4
  import { jwtDecode } from "jwt-decode";
5
5
  import { sha256, type Hex } from "viem";
6
6
  import { NotAuthenticatedError, OAuthProvidersError } from "../errors.js";
7
- import { addOpenIdIfAbsent, getDefaultScopeAndClaims } from "../oauth.js";
7
+ import { getDefaultProviderCustomization } from "../oauth.js";
8
8
  import type { OauthMode } from "../signer.js";
9
9
  import { base64UrlEncode } from "../utils/base64UrlEncode.js";
10
10
  import { resolveRelativeUrl } from "../utils/resolveRelativeUrl.js";
@@ -14,13 +14,11 @@ import type {
14
14
  AlchemySignerClientEvents,
15
15
  AuthenticatingEventMetadata,
16
16
  CreateAccountParams,
17
- RemoveMfaParams,
18
17
  EmailAuthParams,
19
- EnableMfaParams,
20
- EnableMfaResult,
21
18
  GetOauthProviderUrlArgs,
22
19
  GetWebAuthnAttestationResult,
23
- MfaFactor,
20
+ JwtParams,
21
+ JwtResponse,
24
22
  OauthConfig,
25
23
  OauthParams,
26
24
  OauthState,
@@ -30,8 +28,8 @@ import type {
30
28
  SignerRoutes,
31
29
  SignupResponse,
32
30
  User,
33
- VerifyMfaParams,
34
31
  } from "./types.js";
32
+ import { VERSION } from "../version.js";
35
33
 
36
34
  export interface BaseSignerClientParams {
37
35
  stamper: TurnkeyClient["stamper"];
@@ -136,44 +134,7 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
136
134
 
137
135
  public abstract initEmailAuth(
138
136
  params: Omit<EmailAuthParams, "targetPublicKey">
139
- ): Promise<{ orgId: string; otpId?: string; multiFactors?: MfaFactor[] }>;
140
-
141
- /**
142
- * Retrieves the list of MFA factors configured for the current user.
143
- *
144
- * @returns {Promise<{ multiFactors: Array<MfaFactor> }>} A promise that resolves to an array of configured MFA factors
145
- */
146
- public abstract getMfaFactors(): Promise<{
147
- multiFactors: MfaFactor[];
148
- }>;
149
-
150
- /**
151
- * Initiates the setup of a new MFA factor for the current user. Mfa will need to be verified before it is active.
152
- *
153
- * @param {EnableMfaParams} params The parameters required to enable a new MFA factor
154
- * @returns {Promise<EnableMfaResult>} A promise that resolves to the factor setup information
155
- */
156
- public abstract addMfa(params: EnableMfaParams): Promise<EnableMfaResult>;
157
-
158
- /**
159
- * Verifies a newly created MFA factor to complete the setup process.
160
- *
161
- * @param {VerifyMfaParams} params The parameters required to verify the MFA factor
162
- * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors
163
- */
164
- public abstract verifyMfa(params: VerifyMfaParams): Promise<{
165
- multiFactors: MfaFactor[];
166
- }>;
167
-
168
- /**
169
- * Removes existing MFA factors by ID or factor type.
170
- *
171
- * @param {RemoveMfaParams} params The parameters specifying which factors to disable
172
- * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors
173
- */
174
- public abstract removeMfa(params: RemoveMfaParams): Promise<{
175
- multiFactors: MfaFactor[];
176
- }>;
137
+ ): Promise<{ orgId: string; otpId?: string }>;
177
138
 
178
139
  public abstract completeAuthWithBundle(params: {
179
140
  bundle: string;
@@ -195,6 +156,10 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
195
156
  args: Omit<OtpParams, "targetPublicKey">
196
157
  ): Promise<{ bundle: string }>;
197
158
 
159
+ public abstract submitJwt(
160
+ args: Omit<JwtParams, "targetPublicKey">
161
+ ): Promise<JwtResponse>;
162
+
198
163
  public abstract disconnect(): Promise<void>;
199
164
 
200
165
  public abstract exportWallet(params: TExportWalletParams): Promise<boolean>;
@@ -424,6 +389,7 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
424
389
  const basePath = "/signer";
425
390
 
426
391
  const headers = new Headers();
392
+ headers.append("Alchemy-AA-Sdk-Version", VERSION);
427
393
  headers.append("Content-Type", "application/json");
428
394
  if (this.connectionConfig.apiKey) {
429
395
  headers.append("Authorization", `Bearer ${this.connectionConfig.apiKey}`);
@@ -582,6 +548,7 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
582
548
  auth0Connection,
583
549
  scope: providedScope,
584
550
  claims: providedClaims,
551
+ otherParameters: providedOtherParameters,
585
552
  mode,
586
553
  redirectUrl,
587
554
  expirationSeconds,
@@ -604,23 +571,20 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
604
571
  throw new Error(`No auth provider found with id ${authProviderId}`);
605
572
  }
606
573
 
607
- let scope: string;
608
- let claims: string | undefined;
609
-
610
- if (providedScope) {
611
- scope = addOpenIdIfAbsent(providedScope);
612
- claims = providedClaims;
613
- } else {
614
- if (isCustomProvider) {
615
- throw new Error("scope must be provided for a custom provider");
616
- }
617
- const scopeAndClaims = getDefaultScopeAndClaims(authProviderId);
618
- if (!scopeAndClaims) {
619
- throw new Error(
620
- `Default scope not known for provider ${authProviderId}`
621
- );
622
- }
623
- ({ scope, claims } = scopeAndClaims);
574
+ let scope: string | undefined = providedScope;
575
+ let claims: string | undefined = providedClaims;
576
+ let otherParameters: Record<string, string> | undefined =
577
+ providedOtherParameters;
578
+
579
+ if (!isCustomProvider) {
580
+ const defaultCustomization =
581
+ getDefaultProviderCustomization(authProviderId);
582
+ scope ??= defaultCustomization?.scope;
583
+ claims ??= defaultCustomization?.claims;
584
+ otherParameters ??= defaultCustomization?.otherParameters;
585
+ }
586
+ if (!scope) {
587
+ throw new Error(`Default scope not known for provider ${authProviderId}`);
624
588
  }
625
589
  const { authEndpoint, clientId } = authProvider;
626
590
 
@@ -653,10 +617,7 @@ export abstract class BaseSignerClient<TExportWalletParams = unknown> {
653
617
  prompt: "select_account",
654
618
  client_id: clientId,
655
619
  nonce,
656
- // Fixes Facebook mobile login so that `window.opener` doesn't get nullified.
657
- ...(mode === "popup" && authProvider.id === "facebook"
658
- ? { sdk: "joey" }
659
- : {}),
620
+ ...otherParameters,
660
621
  };
661
622
  if (claims) {
662
623
  params.claims = claims;
@@ -14,26 +14,14 @@ import type {
14
14
  CredentialCreationOptionOverrides,
15
15
  EmailAuthParams,
16
16
  ExportWalletParams,
17
+ JwtParams,
17
18
  OauthConfig,
18
19
  OtpParams,
20
+ JwtResponse,
19
21
  User,
20
- MfaFactor,
21
- EnableMfaParams,
22
- EnableMfaResult,
23
- VerifyMfaParams,
24
- RemoveMfaParams,
25
22
  } from "./types.js";
26
- import { MfaRequiredError, NotAuthenticatedError } from "../errors.js";
27
- import { parseMfaError } from "../utils/parseMfaError.js";
28
23
 
29
24
  const CHECK_CLOSE_INTERVAL = 500;
30
- const MFA_PAYLOAD = {
31
- GET: "get_mfa",
32
- ADD: "add_mfa",
33
- DELETE: "delete_mfas",
34
- VERIFY: "verify_mfa",
35
- LIST: "list_mfas",
36
- };
37
25
 
38
26
  export const AlchemySignerClientParamsSchema = z.object({
39
27
  connection: ConnectionConfigSchema,
@@ -212,25 +200,13 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
212
200
  const { email, emailMode, expirationSeconds } = params;
213
201
  const publicKey = await this.initIframeStamper();
214
202
 
215
- try {
216
- return await this.request("/v1/auth", {
217
- email,
218
- emailMode,
219
- targetPublicKey: publicKey,
220
- expirationSeconds,
221
- redirectParams: params.redirectParams?.toString(),
222
- multiFactors: params.multiFactors,
223
- });
224
- } catch (error) {
225
- const multiFactors = parseMfaError(error);
226
-
227
- // If MFA is required, and emailMode is Magic Link, the user must submit mfa with the request or
228
- // the the server will return an error with the required mfa factors.
229
- if (multiFactors) {
230
- throw new MfaRequiredError(multiFactors);
231
- }
232
- throw error;
233
- }
203
+ return this.request("/v1/auth", {
204
+ email,
205
+ emailMode,
206
+ targetPublicKey: publicKey,
207
+ expirationSeconds,
208
+ redirectParams: params.redirectParams?.toString(),
209
+ });
234
210
  };
235
211
 
236
212
  /**
@@ -268,15 +244,46 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
268
244
  ...args,
269
245
  targetPublicKey,
270
246
  });
271
-
272
- if (!credentialBundle) {
273
- throw new Error(
274
- "Failed to submit OTP code. Check if multiFactor is required."
275
- );
276
- }
277
247
  return { bundle: credentialBundle };
278
248
  }
279
249
 
250
+ /**
251
+ * Authenticates using a custom issued JWT
252
+ *
253
+ * @example
254
+ * ```ts
255
+ * import { AlchemySignerWebClient } from "@account-kit/signer";
256
+ *
257
+ * const client = new AlchemySignerWebClient({
258
+ * connection: {
259
+ * apiKey: "your-api-key",
260
+ * },
261
+ * iframeConfig: {
262
+ * iframeContainerId: "signer-iframe-container",
263
+ * },
264
+ * });
265
+ *
266
+ * const account = await client.submitJwt({
267
+ * jwt: "custom-issued-jwt",
268
+ * authProvider: "auth-provider-name",
269
+ * });
270
+ * ```
271
+ *
272
+ * @param {Omit<JwtParams, "targetPublicKey">} args The parameters for the JWT request, excluding the target public key.
273
+ * @returns {Promise<{ bundle: string }>} A promise that resolves to an object containing the credential bundle.
274
+ */
275
+ public override async submitJwt(
276
+ args: Omit<JwtParams, "targetPublicKey">
277
+ ): Promise<JwtResponse> {
278
+ this.eventEmitter.emit("authenticating", { type: "custom-jwt" });
279
+ const targetPublicKey = await this.initIframeStamper();
280
+ return this.request("/v1/auth-jwt", {
281
+ jwt: args.jwt,
282
+ targetPublicKey,
283
+ authProvider: args.authProvider,
284
+ });
285
+ }
286
+
280
287
  /**
281
288
  * Completes auth for the user by injecting a credential bundle and retrieving
282
289
  * the user information based on the provided organization ID. Emits events
@@ -702,141 +709,6 @@ export class AlchemySignerWebClient extends BaseSignerClient<ExportWalletParams>
702
709
  const nonce = this.getOauthNonce(publicKey);
703
710
  return this.request("/v1/prepare-oauth", { nonce });
704
711
  };
705
-
706
- /**
707
- * Retrieves the list of MFA factors configured for the current user.
708
- *
709
- * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to an array of configured MFA factors
710
- * @throws {NotAuthenticatedError} If no user is authenticated
711
- */
712
- public override getMfaFactors = async (): Promise<{
713
- multiFactors: MfaFactor[];
714
- }> => {
715
- if (!this.user) {
716
- throw new NotAuthenticatedError();
717
- }
718
-
719
- const stampedRequest = await this.turnkeyClient.stampSignRawPayload({
720
- organizationId: this.user.orgId,
721
- type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2",
722
- timestampMs: Date.now().toString(),
723
- parameters: {
724
- encoding: "PAYLOAD_ENCODING_HEXADECIMAL",
725
- hashFunction: "HASH_FUNCTION_NO_OP",
726
- payload: MFA_PAYLOAD.LIST,
727
- signWith: this.user.address,
728
- },
729
- });
730
-
731
- return this.request("/v1/auth-list-multi-factors", {
732
- stampedRequest,
733
- });
734
- };
735
-
736
- /**
737
- * Initiates the setup of a new MFA factor for the current user. Mfa will need to be verified before it is active.
738
- *
739
- * @param {EnableMfaParams} params The parameters required to enable a new MFA factor
740
- * @returns {Promise<EnableMfaResult>} A promise that resolves to the factor setup information
741
- * @throws {NotAuthenticatedError} If no user is authenticated
742
- * @throws {Error} If an unsupported factor type is provided
743
- */
744
- public override addMfa = async (
745
- params: EnableMfaParams
746
- ): Promise<EnableMfaResult> => {
747
- if (!this.user) {
748
- throw new NotAuthenticatedError();
749
- }
750
-
751
- const stampedRequest = await this.turnkeyClient.stampSignRawPayload({
752
- organizationId: this.user.orgId,
753
- type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2",
754
- timestampMs: Date.now().toString(),
755
- parameters: {
756
- encoding: "PAYLOAD_ENCODING_HEXADECIMAL",
757
- hashFunction: "HASH_FUNCTION_NO_OP",
758
- payload: MFA_PAYLOAD.ADD,
759
- signWith: this.user.address,
760
- },
761
- });
762
-
763
- switch (params.multiFactorType) {
764
- case "totp":
765
- return this.request("/v1/auth-request-multi-factor", {
766
- stampedRequest,
767
- multiFactorType: params.multiFactorType,
768
- });
769
- default:
770
- throw new Error(
771
- `Unsupported MFA factor type: ${params.multiFactorType}`
772
- );
773
- }
774
- };
775
-
776
- /**
777
- * Verifies a newly created MFA factor to complete the setup process.
778
- *
779
- * @param {VerifyMfaParams} params The parameters required to verify the MFA factor
780
- * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors
781
- * @throws {NotAuthenticatedError} If no user is authenticated
782
- */
783
- public override verifyMfa = async (
784
- params: VerifyMfaParams
785
- ): Promise<{ multiFactors: MfaFactor[] }> => {
786
- if (!this.user) {
787
- throw new NotAuthenticatedError();
788
- }
789
-
790
- const stampedRequest = await this.turnkeyClient.stampSignRawPayload({
791
- organizationId: this.user.orgId,
792
- type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2",
793
- timestampMs: Date.now().toString(),
794
- parameters: {
795
- encoding: "PAYLOAD_ENCODING_HEXADECIMAL",
796
- hashFunction: "HASH_FUNCTION_NO_OP",
797
- payload: MFA_PAYLOAD.VERIFY,
798
- signWith: this.user.address,
799
- },
800
- });
801
-
802
- return this.request("/v1/auth-verify-multi-factor", {
803
- stampedRequest,
804
- multiFactorId: params.multiFactorId,
805
- multiFactorCode: params.multiFactorCode,
806
- });
807
- };
808
-
809
- /**
810
- * Removes existing MFA factors by ID.
811
- *
812
- * @param {RemoveMfaParams} params The parameters specifying which factors to disable
813
- * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors
814
- * @throws {NotAuthenticatedError} If no user is authenticated
815
- */
816
- public override removeMfa = async (
817
- params: RemoveMfaParams
818
- ): Promise<{ multiFactors: MfaFactor[] }> => {
819
- if (!this.user) {
820
- throw new NotAuthenticatedError();
821
- }
822
-
823
- const stampedRequest = await this.turnkeyClient.stampSignRawPayload({
824
- organizationId: this.user.orgId,
825
- type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2",
826
- timestampMs: Date.now().toString(),
827
- parameters: {
828
- encoding: "PAYLOAD_ENCODING_HEXADECIMAL",
829
- hashFunction: "HASH_FUNCTION_NO_OP",
830
- payload: MFA_PAYLOAD.DELETE,
831
- signWith: this.user.address,
832
- },
833
- });
834
-
835
- return this.request("/v1/auth-delete-multi-factors", {
836
- stampedRequest,
837
- multiFactorIds: params.multiFactorIds,
838
- });
839
- };
840
712
  }
841
713
 
842
714
  /**
@@ -29,6 +29,7 @@ export type CreateAccountParams =
29
29
  | {
30
30
  type: "email";
31
31
  email: string;
32
+ /** @deprecated This option will be overriden by dashboard settings. Please use the dashboard settings instead. This option will be removed in a future release. */
32
33
  emailMode?: EmailType;
33
34
  expirationSeconds?: number;
34
35
  redirectParams?: URLSearchParams;
@@ -48,11 +49,11 @@ export type EmailType = "magicLink" | "otp";
48
49
 
49
50
  export type EmailAuthParams = {
50
51
  email: string;
52
+ /** @deprecated This option will be overriden by dashboard settings. Please use the dashboard settings instead. This option will be removed in a future release. */
51
53
  emailMode?: EmailType;
52
54
  expirationSeconds?: number;
53
55
  targetPublicKey: string;
54
56
  redirectParams?: URLSearchParams;
55
- multiFactors?: VerifyMfaParams[];
56
57
  };
57
58
 
58
59
  export type OauthParams = Extract<AuthParams, { type: "oauth" }> & {
@@ -65,7 +66,18 @@ export type OtpParams = {
65
66
  otpCode: string;
66
67
  targetPublicKey: string;
67
68
  expirationSeconds?: number;
68
- multiFactors?: VerifyMfaParams[];
69
+ };
70
+
71
+ export type JwtParams = {
72
+ jwt: string;
73
+ targetPublicKey: string;
74
+ authProvider: string;
75
+ };
76
+
77
+ export type JwtResponse = {
78
+ isSignUp: boolean;
79
+ orgId: string;
80
+ credentialBundle: string;
69
81
  };
70
82
 
71
83
  export type SignupResponse = {
@@ -81,6 +93,14 @@ export type OauthConfig = {
81
93
  authProviders: AuthProviderConfig[];
82
94
  };
83
95
 
96
+ export type EmailConfig = {
97
+ mode?: "MAGIC_LINK" | "OTP";
98
+ };
99
+
100
+ export type SignerConfig = {
101
+ email: EmailConfig;
102
+ };
103
+
84
104
  export type AuthProviderConfig = {
85
105
  id: string;
86
106
  isCustomProvider?: boolean;
@@ -124,12 +144,10 @@ export type SignerEndpoints = [
124
144
  Route: "/v1/auth";
125
145
  Body: Omit<EmailAuthParams, "redirectParams"> & {
126
146
  redirectParams?: string;
127
- multiFactors?: VerifyMfaParams[];
128
147
  };
129
148
  Response: {
130
149
  orgId: string;
131
150
  otpId?: string;
132
- multiFactors?: MfaFactor[];
133
151
  };
134
152
  },
135
153
  {
@@ -160,50 +178,22 @@ export type SignerEndpoints = [
160
178
  {
161
179
  Route: "/v1/otp";
162
180
  Body: OtpParams;
163
- Response: {
164
- credentialBundle: string | null;
165
- };
166
- },
167
- {
168
- Route: "/v1/auth-list-multi-factors";
169
- Body: {
170
- stampedRequest: TSignedRequest;
171
- };
172
- Response: {
173
- multiFactors: MfaFactor[];
174
- };
175
- },
176
- {
177
- Route: "/v1/auth-delete-multi-factors";
178
- Body: {
179
- stampedRequest: TSignedRequest;
180
- multiFactorIds: string[];
181
- };
182
- Response: {
183
- multiFactors: MfaFactor[];
184
- };
181
+ Response: { credentialBundle: string };
185
182
  },
186
183
  {
187
- Route: "/v1/auth-request-multi-factor";
188
- Body: {
189
- stampedRequest: TSignedRequest;
190
- multiFactorType: MultiFactorType;
191
- };
192
- Response: EnableMfaResult;
184
+ Route: "/v1/auth-jwt";
185
+ Body: JwtParams;
186
+ Response: JwtResponse;
193
187
  },
194
188
  {
195
- Route: "/v1/auth-verify-multi-factor";
196
- Body: VerifyMfaParams & {
197
- stampedRequest: TSignedRequest;
198
- };
199
- Response: {
200
- multiFactors: MfaFactor[];
201
- };
189
+ Route: "/v1/signer-config";
190
+ Body: {};
191
+ Response: SignerConfig;
202
192
  }
203
193
  ];
204
194
 
205
195
  export type AuthenticatingEventMetadata = {
206
- type: "email" | "passkey" | "oauth" | "otp" | "otpVerify";
196
+ type: "email" | "passkey" | "oauth" | "otp" | "otpVerify" | "custom-jwt";
207
197
  };
208
198
 
209
199
  export type AlchemySignerClientEvents = {
@@ -214,6 +204,7 @@ export type AlchemySignerClientEvents = {
214
204
  connectedPasskey(user: User): void;
215
205
  connectedOauth(user: User, bundle: string): void;
216
206
  connectedOtp(user: User, bundle: string): void;
207
+ connectedJwt(user: User, bundle: string): void;
217
208
  disconnected(): void;
218
209
  };
219
210
 
@@ -242,38 +233,3 @@ export type GetOauthProviderUrlArgs = {
242
233
  oauthConfig?: OauthConfig;
243
234
  usesRelativeUrl?: boolean;
244
235
  };
245
-
246
- export type MfaFactor = {
247
- multiFactorId: string;
248
- multiFactorType: string;
249
- };
250
-
251
- type MultiFactorType = "totp";
252
-
253
- export type EnableMfaParams = {
254
- multiFactorType: MultiFactorType;
255
- };
256
-
257
- export type EnableMfaResult = {
258
- multiFactorType: MultiFactorType;
259
- multiFactorId: string;
260
- multiFactorTotpUrl: string;
261
- };
262
-
263
- export type VerifyMfaParams = {
264
- multiFactorId: string;
265
- multiFactorCode: string;
266
- };
267
-
268
- export type RemoveMfaParams = {
269
- multiFactorIds: string[];
270
- };
271
-
272
- export type MfaChallenge = {
273
- multiFactorId: string;
274
- multiFactorChallenge:
275
- | {
276
- code: string;
277
- }
278
- | Record<string, any>;
279
- };
package/src/errors.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BaseError } from "@aa-sdk/core";
2
- import type { MfaFactor } from "./client/types";
2
+
3
3
  export class NotAuthenticatedError extends BaseError {
4
4
  override name = "NotAuthenticatedError";
5
5
  constructor() {
@@ -23,13 +23,3 @@ export class OAuthProvidersError extends BaseError {
23
23
  });
24
24
  }
25
25
  }
26
-
27
- export class MfaRequiredError extends BaseError {
28
- override name = "MfaRequiredError";
29
- public multiFactors: MfaFactor[];
30
-
31
- constructor(multiFactors: MfaFactor[]) {
32
- super("MFA is required for this user");
33
- this.multiFactors = multiFactors;
34
- }
35
- }
package/src/index.ts CHANGED
@@ -6,11 +6,7 @@ export {
6
6
  OauthFailedError,
7
7
  } from "./client/index.js";
8
8
  export type * from "./client/types.js";
9
- export {
10
- NotAuthenticatedError,
11
- OAuthProvidersError,
12
- MfaRequiredError,
13
- } from "./errors.js";
9
+ export { NotAuthenticatedError, OAuthProvidersError } from "./errors.js";
14
10
  export {
15
11
  DEFAULT_SESSION_MS,
16
12
  SessionManagerParamsSchema,
package/src/metrics.ts CHANGED
@@ -14,7 +14,8 @@ export type SignerEventsSchema = [
14
14
  | "oauthReturn";
15
15
  provider?: never;
16
16
  }
17
- | { authType: "oauth"; provider: string };
17
+ | { authType: "oauth"; provider: string }
18
+ | { authType: "custom-jwt"; provider: string };
18
19
  },
19
20
  {
20
21
  EventName: "signer_sign_message";
package/src/oauth.ts CHANGED
@@ -1,27 +1,41 @@
1
1
  import type { KnownAuthProvider } from "./signer";
2
2
 
3
- export type ScopeAndClaims = {
3
+ export type AuthProviderCustomization = {
4
4
  scope: string;
5
5
  claims?: string;
6
+ otherParameters?: Record<string, string>;
6
7
  };
7
8
 
8
- const DEFAULT_SCOPE_AND_CLAIMS: Record<KnownAuthProvider, ScopeAndClaims> = {
9
+ const DEFAULT_PROVIDER_CUSTOMIZATION: Record<
10
+ KnownAuthProvider,
11
+ AuthProviderCustomization
12
+ > = {
9
13
  google: { scope: "openid email" },
10
14
  apple: { scope: "openid email" },
11
- facebook: { scope: "openid email" },
15
+ facebook: {
16
+ scope: "openid email",
17
+ // Fixes Facebook mobile login so that `window.opener` doesn't get nullified.
18
+ otherParameters: { sdk: "joey" },
19
+ },
20
+ twitch: {
21
+ scope: "openid user:read:email",
22
+ claims: JSON.stringify({ id_token: { email: null } }),
23
+ // Forces Twitch to show the login page even if the user is already logged in.
24
+ otherParameters: { force_verify: "true" },
25
+ },
12
26
  auth0: { scope: "openid email" },
13
27
  };
14
28
 
15
29
  /**
16
- * Returns the default scope and claims when using a known auth provider
30
+ * Returns the default customization parameters when using a known auth provider
17
31
  *
18
32
  * @param {string} knownAuthProviderId id of a known auth provider, e.g. "google"
19
- * @returns {ScopeAndClaims | undefined} default scope and claims
33
+ * @returns {AuthProviderCustomization | undefined} default customization parameters
20
34
  */
21
- export function getDefaultScopeAndClaims(
35
+ export function getDefaultProviderCustomization(
22
36
  knownAuthProviderId: KnownAuthProvider
23
- ): ScopeAndClaims | undefined {
24
- return DEFAULT_SCOPE_AND_CLAIMS[knownAuthProviderId];
37
+ ): AuthProviderCustomization | undefined {
38
+ return DEFAULT_PROVIDER_CUSTOMIZATION[knownAuthProviderId];
25
39
  }
26
40
 
27
41
  /**