@account-kit/signer 4.31.1 → 4.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/base.d.ts +6 -2
- package/dist/esm/base.js +131 -33
- package/dist/esm/base.js.map +1 -1
- package/dist/esm/client/base.d.ts +132 -9
- package/dist/esm/client/base.js +34 -4
- package/dist/esm/client/base.js.map +1 -1
- package/dist/esm/client/index.d.ts +36 -14
- package/dist/esm/client/index.js +36 -18
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/client/types.d.ts +19 -0
- package/dist/esm/client/types.js.map +1 -1
- package/dist/esm/signer.d.ts +88 -33
- package/dist/esm/signer.js +28 -3
- package/dist/esm/signer.js.map +1 -1
- package/dist/esm/solanaSigner.d.ts +3 -3
- package/dist/esm/solanaSigner.js +1 -1
- package/dist/esm/solanaSigner.js.map +1 -1
- package/dist/esm/types.d.ts +1 -0
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/types/base.d.ts +6 -2
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/client/base.d.ts +132 -9
- package/dist/types/client/base.d.ts.map +1 -1
- package/dist/types/client/index.d.ts +36 -14
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/client/types.d.ts +19 -0
- package/dist/types/client/types.d.ts.map +1 -1
- package/dist/types/signer.d.ts +88 -33
- package/dist/types/signer.d.ts.map +1 -1
- package/dist/types/solanaSigner.d.ts +3 -3
- package/dist/types/solanaSigner.d.ts.map +1 -1
- package/dist/types/types.d.ts +1 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +5 -6
- package/src/base.ts +172 -56
- package/src/client/base.ts +36 -7
- package/src/client/index.ts +41 -18
- package/src/client/types.ts +21 -0
- package/src/signer.ts +36 -3
- package/src/solanaSigner.ts +4 -4
- package/src/types.ts +1 -0
- package/src/version.ts +1 -1
package/dist/esm/base.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type SmartAccountAuthenticator } from "@aa-sdk/core";
|
|
|
2
2
|
import { type GetTransactionType, type Hex, type IsNarrowable, type LocalAccount, type SerializeTransactionFn, type SignableMessage, type TransactionSerializable, type TransactionSerialized, type TypedData, type TypedDataDefinition } from "viem";
|
|
3
3
|
import { type Authorization } from "viem/experimental";
|
|
4
4
|
import type { BaseSignerClient } from "./client/base";
|
|
5
|
-
import type
|
|
5
|
+
import { type MfaFactor, type OauthConfig, type User, type VerifyMfaParams, type AddMfaParams, type AddMfaResult, type RemoveMfaParams, type AuthLinkingPrompt } from "./client/types.js";
|
|
6
6
|
import { type SessionManagerParams } from "./session/manager.js";
|
|
7
7
|
import type { AuthParams } from "./signer";
|
|
8
8
|
import { SolanaSigner } from "./solanaSigner.js";
|
|
@@ -11,6 +11,7 @@ export interface BaseAlchemySignerParams<TClient extends BaseSignerClient> {
|
|
|
11
11
|
client: TClient;
|
|
12
12
|
sessionConfig?: Omit<SessionManagerParams, "client">;
|
|
13
13
|
initialError?: ErrorInfo;
|
|
14
|
+
initialAuthLinkingPrompt?: AuthLinkingPrompt;
|
|
14
15
|
}
|
|
15
16
|
export type EmailConfig = {
|
|
16
17
|
mode?: "MAGIC_LINK" | "OTP";
|
|
@@ -38,7 +39,7 @@ export declare abstract class BaseAlchemySigner<TClient extends BaseSignerClient
|
|
|
38
39
|
* @param {SessionConfig} param0.sessionConfig Configuration for managing sessions
|
|
39
40
|
* @param {ErrorInfo | undefined} param0.initialError Error already present on the signer when initialized, if any
|
|
40
41
|
*/
|
|
41
|
-
constructor({ client, sessionConfig, initialError, }: BaseAlchemySignerParams<TClient>);
|
|
42
|
+
constructor({ client, sessionConfig, initialError, initialAuthLinkingPrompt, }: BaseAlchemySignerParams<TClient>);
|
|
42
43
|
/**
|
|
43
44
|
* Allows you to subscribe to events emitted by the signer
|
|
44
45
|
*
|
|
@@ -450,6 +451,7 @@ export declare abstract class BaseAlchemySigner<TClient extends BaseSignerClient
|
|
|
450
451
|
private authenticateWithPasskey;
|
|
451
452
|
private authenticateWithOauth;
|
|
452
453
|
private authenticateWithOtp;
|
|
454
|
+
private setAwaitingEmailAuth;
|
|
453
455
|
private handleOauthReturn;
|
|
454
456
|
private handleMfaRequired;
|
|
455
457
|
private getExpirationSeconds;
|
|
@@ -613,4 +615,6 @@ export declare abstract class BaseAlchemySigner<TClient extends BaseSignerClient
|
|
|
613
615
|
*/
|
|
614
616
|
getConfig: () => Promise<SignerConfig>;
|
|
615
617
|
protected fetchConfig: () => Promise<SignerConfig>;
|
|
618
|
+
private setAuthLinkingPrompt;
|
|
619
|
+
private waitForConnected;
|
|
616
620
|
}
|
package/dist/esm/base.js
CHANGED
|
@@ -4,6 +4,7 @@ import { toAccount } from "viem/accounts";
|
|
|
4
4
|
import { hashAuthorization } from "viem/experimental";
|
|
5
5
|
import { subscribeWithSelector } from "zustand/middleware";
|
|
6
6
|
import { createStore } from "zustand/vanilla";
|
|
7
|
+
import {} from "./client/types.js";
|
|
7
8
|
import { NotAuthenticatedError } from "./errors.js";
|
|
8
9
|
import { SignerLogger } from "./metrics.js";
|
|
9
10
|
import { SessionManager, } from "./session/manager.js";
|
|
@@ -25,7 +26,7 @@ export class BaseAlchemySigner {
|
|
|
25
26
|
* @param {SessionConfig} param0.sessionConfig Configuration for managing sessions
|
|
26
27
|
* @param {ErrorInfo | undefined} param0.initialError Error already present on the signer when initialized, if any
|
|
27
28
|
*/
|
|
28
|
-
constructor({ client, sessionConfig, initialError, }) {
|
|
29
|
+
constructor({ client, sessionConfig, initialError, initialAuthLinkingPrompt, }) {
|
|
29
30
|
Object.defineProperty(this, "signerType", {
|
|
30
31
|
enumerable: true,
|
|
31
32
|
configurable: true,
|
|
@@ -73,22 +74,28 @@ export class BaseAlchemySigner {
|
|
|
73
74
|
// is fired. In the Client and SessionManager we use EventEmitter because it's easier to handle internally
|
|
74
75
|
switch (event) {
|
|
75
76
|
case "connected":
|
|
76
|
-
return this.store
|
|
77
|
-
listener(this.store.getState().user)
|
|
77
|
+
return subscribeWithDelayedFireImmediately(this.store, ({ status }) => status, (status) => status === AlchemySignerStatus.CONNECTED &&
|
|
78
|
+
listener(this.store.getState().user));
|
|
78
79
|
case "disconnected":
|
|
79
|
-
return this.store
|
|
80
|
-
listener()
|
|
80
|
+
return subscribeWithDelayedFireImmediately(this.store, ({ status }) => status, (status) => status === AlchemySignerStatus.DISCONNECTED &&
|
|
81
|
+
listener());
|
|
81
82
|
case "statusChanged":
|
|
82
|
-
return this.store
|
|
83
|
+
return subscribeWithDelayedFireImmediately(this.store, ({ status }) => status, listener);
|
|
83
84
|
case "errorChanged":
|
|
84
|
-
return this.store
|
|
85
|
+
return subscribeWithDelayedFireImmediately(this.store, ({ error }) => error, (error) => listener(error ?? undefined));
|
|
85
86
|
case "newUserSignup":
|
|
86
|
-
return this.store
|
|
87
|
+
return subscribeWithDelayedFireImmediately(this.store, ({ isNewUser }) => isNewUser, (isNewUser) => {
|
|
87
88
|
if (isNewUser)
|
|
88
89
|
listener();
|
|
89
|
-
}
|
|
90
|
+
});
|
|
90
91
|
case "mfaStatusChanged":
|
|
91
|
-
return this.store
|
|
92
|
+
return subscribeWithDelayedFireImmediately(this.store, ({ mfaStatus }) => mfaStatus, (mfaStatus) => listener(mfaStatus));
|
|
93
|
+
case "emailAuthLinkingRequired":
|
|
94
|
+
return subscribeWithDelayedFireImmediately(this.store, ({ authLinkingStatus }) => authLinkingStatus, (authLinkingStatus) => {
|
|
95
|
+
if (authLinkingStatus) {
|
|
96
|
+
listener(authLinkingStatus.email);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
92
99
|
default:
|
|
93
100
|
assertNever(event, `Unknown event type ${event}`);
|
|
94
101
|
}
|
|
@@ -731,23 +738,17 @@ export class BaseAlchemySigner {
|
|
|
731
738
|
return this.completeEmailAuth(params);
|
|
732
739
|
}
|
|
733
740
|
const { orgId, otpId, isNewUser } = await this.initOrCreateEmailUser(params.email, params.emailMode, params.multiFactors, params.redirectParams);
|
|
734
|
-
this.
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
this.store.
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
});
|
|
741
|
+
this.setAwaitingEmailAuth({ orgId, otpId, isNewUser });
|
|
742
|
+
// Clear the auth linking status if the email has changed. This would mean
|
|
743
|
+
// that the previously initiated social login is not associated with the
|
|
744
|
+
// email which is now being used to login.
|
|
745
|
+
const { authLinkingStatus } = this.store.getState();
|
|
746
|
+
if (authLinkingStatus && authLinkingStatus.email !== params.email) {
|
|
747
|
+
this.store.setState({ authLinkingStatus: undefined });
|
|
748
|
+
}
|
|
743
749
|
// We wait for the session manager to emit a connected event if
|
|
744
750
|
// cross tab sessions are permitted
|
|
745
|
-
return
|
|
746
|
-
const removeListener = this.sessionManager.on("connected", (session) => {
|
|
747
|
-
resolve(session.user);
|
|
748
|
-
removeListener();
|
|
749
|
-
});
|
|
750
|
-
});
|
|
751
|
+
return this.waitForConnected();
|
|
751
752
|
}
|
|
752
753
|
});
|
|
753
754
|
Object.defineProperty(this, "authenticateWithPasskey", {
|
|
@@ -790,6 +791,7 @@ export class BaseAlchemySigner {
|
|
|
790
791
|
configurable: true,
|
|
791
792
|
writable: true,
|
|
792
793
|
value: async (args) => {
|
|
794
|
+
this.store.setState({ authLinkingStatus: undefined });
|
|
793
795
|
const params = {
|
|
794
796
|
...args,
|
|
795
797
|
expirationSeconds: this.getExpirationSeconds(),
|
|
@@ -797,9 +799,12 @@ export class BaseAlchemySigner {
|
|
|
797
799
|
if (params.mode === "redirect") {
|
|
798
800
|
return this.inner.oauthWithRedirect(params);
|
|
799
801
|
}
|
|
800
|
-
|
|
801
|
-
|
|
802
|
+
const result = await this.inner.oauthWithPopup(params);
|
|
803
|
+
if (!isAuthLinkingPrompt(result)) {
|
|
804
|
+
return result;
|
|
802
805
|
}
|
|
806
|
+
this.setAuthLinkingPrompt(result);
|
|
807
|
+
return this.waitForConnected();
|
|
803
808
|
}
|
|
804
809
|
});
|
|
805
810
|
Object.defineProperty(this, "authenticateWithOtp", {
|
|
@@ -825,12 +830,7 @@ export class BaseAlchemySigner {
|
|
|
825
830
|
});
|
|
826
831
|
if (response.mfaRequired) {
|
|
827
832
|
this.handleMfaRequired(response.encryptedPayload, response.multiFactors);
|
|
828
|
-
return
|
|
829
|
-
const removeListener = this.sessionManager.on("connected", (session) => {
|
|
830
|
-
resolve(session.user);
|
|
831
|
-
removeListener();
|
|
832
|
-
});
|
|
833
|
-
});
|
|
833
|
+
return this.waitForConnected();
|
|
834
834
|
}
|
|
835
835
|
const user = await this.inner.completeAuthWithBundle({
|
|
836
836
|
bundle: response.bundle,
|
|
@@ -845,9 +845,34 @@ export class BaseAlchemySigner {
|
|
|
845
845
|
isNewUser: false,
|
|
846
846
|
});
|
|
847
847
|
}
|
|
848
|
+
const { authLinkingStatus } = this.store.getState();
|
|
849
|
+
if (authLinkingStatus) {
|
|
850
|
+
(async () => {
|
|
851
|
+
this.inner.addOauthProvider({
|
|
852
|
+
providerName: authLinkingStatus.providerName,
|
|
853
|
+
oidcToken: authLinkingStatus.idToken,
|
|
854
|
+
});
|
|
855
|
+
})();
|
|
856
|
+
}
|
|
848
857
|
return user;
|
|
849
858
|
}
|
|
850
859
|
});
|
|
860
|
+
Object.defineProperty(this, "setAwaitingEmailAuth", {
|
|
861
|
+
enumerable: true,
|
|
862
|
+
configurable: true,
|
|
863
|
+
writable: true,
|
|
864
|
+
value: ({ orgId, otpId, isNewUser, }) => {
|
|
865
|
+
this.sessionManager.setTemporarySession({
|
|
866
|
+
orgId,
|
|
867
|
+
isNewUser,
|
|
868
|
+
});
|
|
869
|
+
this.store.setState({
|
|
870
|
+
status: AlchemySignerStatus.AWAITING_EMAIL_AUTH,
|
|
871
|
+
otpId,
|
|
872
|
+
error: null,
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
});
|
|
851
876
|
Object.defineProperty(this, "handleOauthReturn", {
|
|
852
877
|
enumerable: true,
|
|
853
878
|
configurable: true,
|
|
@@ -1111,6 +1136,38 @@ export class BaseAlchemySigner {
|
|
|
1111
1136
|
return this.inner.request("/v1/signer-config", {});
|
|
1112
1137
|
}
|
|
1113
1138
|
});
|
|
1139
|
+
Object.defineProperty(this, "setAuthLinkingPrompt", {
|
|
1140
|
+
enumerable: true,
|
|
1141
|
+
configurable: true,
|
|
1142
|
+
writable: true,
|
|
1143
|
+
value: (prompt) => {
|
|
1144
|
+
this.setAwaitingEmailAuth({
|
|
1145
|
+
orgId: prompt.orgId,
|
|
1146
|
+
otpId: prompt.otpId,
|
|
1147
|
+
isNewUser: false,
|
|
1148
|
+
});
|
|
1149
|
+
this.store.setState({
|
|
1150
|
+
authLinkingStatus: {
|
|
1151
|
+
email: prompt.email,
|
|
1152
|
+
providerName: prompt.providerName,
|
|
1153
|
+
idToken: prompt.idToken,
|
|
1154
|
+
},
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
});
|
|
1158
|
+
Object.defineProperty(this, "waitForConnected", {
|
|
1159
|
+
enumerable: true,
|
|
1160
|
+
configurable: true,
|
|
1161
|
+
writable: true,
|
|
1162
|
+
value: () => {
|
|
1163
|
+
return new Promise((resolve) => {
|
|
1164
|
+
const removeListener = this.sessionManager.on("connected", (session) => {
|
|
1165
|
+
resolve(session.user);
|
|
1166
|
+
removeListener();
|
|
1167
|
+
});
|
|
1168
|
+
});
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1114
1171
|
this.inner = client;
|
|
1115
1172
|
this.store = createStore(subscribeWithSelector(() => ({
|
|
1116
1173
|
user: null,
|
|
@@ -1133,6 +1190,9 @@ export class BaseAlchemySigner {
|
|
|
1133
1190
|
// then initialize so that we can catch those events
|
|
1134
1191
|
this.sessionManager.initialize();
|
|
1135
1192
|
this.config = this.fetchConfig();
|
|
1193
|
+
if (initialAuthLinkingPrompt) {
|
|
1194
|
+
this.setAuthLinkingPrompt(initialAuthLinkingPrompt);
|
|
1195
|
+
}
|
|
1136
1196
|
}
|
|
1137
1197
|
handleMfaRequired(encryptedPayload, multiFactors) {
|
|
1138
1198
|
// Store complete MFA context in the temporary session
|
|
@@ -1283,4 +1343,42 @@ function toErrorInfo(error) {
|
|
|
1283
1343
|
? { name: error.name, message: error.message }
|
|
1284
1344
|
: { name: "Error", message: "Unknown error" };
|
|
1285
1345
|
}
|
|
1346
|
+
// eslint-disable-next-line jsdoc/require-param, jsdoc/require-returns
|
|
1347
|
+
/**
|
|
1348
|
+
* Zustand's `fireImmediately` option calls the listener before
|
|
1349
|
+
* `store.subscribe` has returned, which breaks listeners which call
|
|
1350
|
+
* unsubscribe, e.g.
|
|
1351
|
+
*
|
|
1352
|
+
* ```ts
|
|
1353
|
+
* const unsubscribe = store.subscribe(
|
|
1354
|
+
* selector,
|
|
1355
|
+
* (update) => {
|
|
1356
|
+
* handleUpdate(update);
|
|
1357
|
+
* unsubscribe();
|
|
1358
|
+
* },
|
|
1359
|
+
* { fireImmediately: true },
|
|
1360
|
+
* )
|
|
1361
|
+
* ```
|
|
1362
|
+
*
|
|
1363
|
+
* since `unsubscribe` is still undefined at the time the listener is called. To
|
|
1364
|
+
* prevent this, if the listener triggers before `subscribe` has returned, delay
|
|
1365
|
+
* the callback to a later run of the event loop.
|
|
1366
|
+
*/
|
|
1367
|
+
function subscribeWithDelayedFireImmediately(store, selector, listener) {
|
|
1368
|
+
let subscribeHasReturned = false;
|
|
1369
|
+
const unsubscribe = store.subscribe(selector, (...args) => {
|
|
1370
|
+
if (subscribeHasReturned) {
|
|
1371
|
+
listener(...args);
|
|
1372
|
+
}
|
|
1373
|
+
else {
|
|
1374
|
+
setTimeout(() => listener(...args), 0);
|
|
1375
|
+
}
|
|
1376
|
+
}, { fireImmediately: true });
|
|
1377
|
+
subscribeHasReturned = true;
|
|
1378
|
+
return unsubscribe;
|
|
1379
|
+
}
|
|
1380
|
+
function isAuthLinkingPrompt(result) {
|
|
1381
|
+
return (result?.status ===
|
|
1382
|
+
"ACCOUNT_LINKING_CONFIRMATION_REQUIRED");
|
|
1383
|
+
}
|
|
1286
1384
|
//# sourceMappingURL=base.js.map
|
package/dist/esm/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/base.ts"],"names":[],"mappings":"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","sourcesContent":["import { takeBytes, type SmartAccountAuthenticator } from \"@aa-sdk/core\";\nimport {\n hashMessage,\n hashTypedData,\n keccak256,\n serializeTransaction,\n type GetTransactionType,\n type Hex,\n type IsNarrowable,\n type LocalAccount,\n type SerializeTransactionFn,\n type SignableMessage,\n type TransactionSerializable,\n type TransactionSerialized,\n type TypedData,\n type TypedDataDefinition,\n} from \"viem\";\nimport { toAccount } from \"viem/accounts\";\nimport { hashAuthorization, type Authorization } from \"viem/experimental\";\nimport type { Mutate, StoreApi } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport { createStore } from \"zustand/vanilla\";\nimport type { BaseSignerClient } from \"./client/base\";\nimport type {\n EmailType,\n MfaFactor,\n OauthConfig,\n OauthParams,\n User,\n VerifyMfaParams,\n AddMfaParams,\n AddMfaResult,\n RemoveMfaParams,\n} from \"./client/types\";\nimport { NotAuthenticatedError } from \"./errors.js\";\nimport { SignerLogger } from \"./metrics.js\";\nimport {\n SessionManager,\n type SessionManagerParams,\n} from \"./session/manager.js\";\nimport type { SessionManagerEvents } from \"./session/types\";\nimport type { AuthParams } from \"./signer\";\nimport { SolanaSigner } from \"./solanaSigner.js\";\nimport {\n AlchemySignerStatus,\n type AlchemySignerEvent,\n type AlchemySignerEvents,\n type ErrorInfo,\n type ValidateMultiFactorsArgs,\n} from \"./types.js\";\nimport { assertNever } from \"./utils/typeAssertions.js\";\n\nexport interface BaseAlchemySignerParams<TClient extends BaseSignerClient> {\n client: TClient;\n sessionConfig?: Omit<SessionManagerParams, \"client\">;\n initialError?: ErrorInfo;\n}\n\ntype AlchemySignerStore = {\n user: User | null;\n status: AlchemySignerStatus;\n error: ErrorInfo | null;\n otpId?: string;\n isNewUser?: boolean;\n mfaStatus: {\n mfaRequired: boolean;\n mfaFactorId?: string;\n encryptedPayload?: string;\n };\n};\n\ntype UnpackedSignature = {\n r: `0x${string}`;\n s: `0x${string}`;\n v: bigint;\n};\n\ntype InternalStore = Mutate<\n StoreApi<AlchemySignerStore>,\n [[\"zustand/subscribeWithSelector\", never]]\n>;\n\nexport type EmailConfig = {\n mode?: \"MAGIC_LINK\" | \"OTP\";\n};\n\nexport type SignerConfig = {\n email: EmailConfig;\n};\n\n/**\n * Base abstract class for Alchemy Signer, providing authentication and session management for smart accounts.\n * Implements the `SmartAccountAuthenticator` interface and handles various signer events.\n */\nexport abstract class BaseAlchemySigner<TClient extends BaseSignerClient>\n implements SmartAccountAuthenticator<AuthParams, User, TClient>\n{\n signerType: \"alchemy-signer\" | \"rn-alchemy-signer\" = \"alchemy-signer\";\n inner: TClient;\n private sessionManager: SessionManager;\n private store: InternalStore;\n private config: Promise<SignerConfig>;\n\n /**\n * Initializes an instance with the provided client and session configuration.\n * This function sets up the internal store, initializes the session manager,\n * registers listeners and initializes the session manager to manage session state.\n *\n * @param {BaseAlchemySignerParams<TClient>} param0 Object containing the client and session configuration\n * @param {TClient} param0.client The client instance to be used internally\n * @param {SessionConfig} param0.sessionConfig Configuration for managing sessions\n * @param {ErrorInfo | undefined} param0.initialError Error already present on the signer when initialized, if any\n */\n constructor({\n client,\n sessionConfig,\n initialError,\n }: BaseAlchemySignerParams<TClient>) {\n this.inner = client;\n this.store = createStore(\n subscribeWithSelector(\n () =>\n ({\n user: null,\n status: AlchemySignerStatus.INITIALIZING,\n error: initialError ?? null,\n mfaStatus: {\n mfaRequired: false,\n mfaFactorId: undefined,\n },\n } satisfies AlchemySignerStore)\n )\n );\n // NOTE: it's important that the session manager share a client\n // with the signer. The SessionManager leverages the Signer's client\n // to manage session state.\n this.sessionManager = new SessionManager({\n ...sessionConfig,\n client: this.inner,\n });\n // register listeners first\n this.registerListeners();\n // then initialize so that we can catch those events\n this.sessionManager.initialize();\n this.config = this.fetchConfig();\n }\n\n /**\n * Allows you to subscribe to events emitted by the signer\n *\n * @param {AlchemySignerEvent} event the event to subscribe to\n * @param {AlchemySignerEvents[AlchemySignerEvent]} listener the function to run when the event is emitted\n * @returns {() => void} a function to remove the listener\n */\n on = <E extends AlchemySignerEvent>(\n event: E,\n listener: AlchemySignerEvents[E]\n ) => {\n // NOTE: we're using zustand here to handle this because we are able to use the fireImmediately\n // option which deals with a possible race condition where the listener is added after the event\n // is fired. In the Client and SessionManager we use EventEmitter because it's easier to handle internally\n switch (event) {\n case \"connected\":\n return this.store.subscribe(\n ({ status }) => status,\n (status) =>\n status === AlchemySignerStatus.CONNECTED &&\n (listener as AlchemySignerEvents[\"connected\"])(\n this.store.getState().user!\n ),\n { fireImmediately: true }\n );\n case \"disconnected\":\n return this.store.subscribe(\n ({ status }) => status,\n (status) =>\n status === AlchemySignerStatus.DISCONNECTED &&\n (listener as AlchemySignerEvents[\"disconnected\"])(),\n { fireImmediately: true }\n );\n case \"statusChanged\":\n return this.store.subscribe(\n ({ status }) => status,\n listener as AlchemySignerEvents[\"statusChanged\"],\n { fireImmediately: true }\n );\n case \"errorChanged\":\n return this.store.subscribe(\n ({ error }) => error,\n (error) =>\n (listener as AlchemySignerEvents[\"errorChanged\"])(\n error ?? undefined\n ),\n { fireImmediately: true }\n );\n case \"newUserSignup\":\n return this.store.subscribe(\n ({ isNewUser }) => isNewUser,\n (isNewUser) => {\n if (isNewUser) (listener as AlchemySignerEvents[\"newUserSignup\"])();\n },\n { fireImmediately: true }\n );\n case \"mfaStatusChanged\":\n return this.store.subscribe(\n ({ mfaStatus }) => mfaStatus,\n (mfaStatus) =>\n (listener as AlchemySignerEvents[\"mfaStatusChanged\"])(mfaStatus),\n { fireImmediately: true }\n );\n default:\n assertNever(event, `Unknown event type ${event}`);\n }\n };\n\n /**\n * Prepares the config needed to use popup-based OAuth login. This must be\n * called before calling `.authenticate` with params `{ type: \"oauth\", mode:\n * \"popup\" }`, and is recommended to be called on page load.\n *\n * This method exists because browsers may prevent popups from opening unless\n * triggered by user interaction, and so the OAuth config must already have\n * been fetched at the time a user clicks a social login button.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * await signer.preparePopupOauth();\n * ```\n * @returns {Promise<OauthConfig>} the config which must be loaded before\n * using popup-based OAuth\n */\n preparePopupOauth = (): Promise<OauthConfig> => this.inner.initOauth();\n\n /**\n * Authenticate a user with either an email or a passkey and create a session for that user\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.authenticate({\n * type: \"email\",\n * email: \"foo@mail.com\",\n * });\n * ```\n *\n * @param {AuthParams} params - undefined if passkey login, otherwise an object with email and bundle to resolve\n * @returns {Promise<User>} the user that was authenticated\n */\n authenticate: (params: AuthParams) => Promise<User> = SignerLogger.profiled(\n \"BaseAlchemySigner.authenticate\",\n async (params) => {\n const { type } = params;\n const result = (() => {\n switch (type) {\n case \"email\":\n return this.authenticateWithEmail(params);\n case \"passkey\":\n return this.authenticateWithPasskey(params);\n case \"oauth\":\n return this.authenticateWithOauth(params);\n case \"oauthReturn\":\n return this.handleOauthReturn(params);\n case \"otp\":\n return this.authenticateWithOtp(params);\n default:\n assertNever(type, `Unknown auth type: ${type}`);\n }\n })();\n\n this.trackAuthenticateType(params);\n\n return result.catch((error) => {\n /**\n * 2 things going on here:\n * 1. for oauth flows we expect the status to remain in authenticating\n * 2. we do the ternary, because if we explicitly pass in `undefined` for the status, zustand will set the value of status to `undefined`.\n * However, if we omit it, then it will not override the current value of status.\n */\n this.store.setState({\n error: toErrorInfo(error),\n ...(type === \"oauthReturn\" || type === \"oauth\"\n ? {}\n : { status: AlchemySignerStatus.DISCONNECTED }),\n });\n throw error;\n });\n }\n );\n\n private trackAuthenticateType = (params: AuthParams) => {\n const { type } = params;\n switch (type) {\n case \"email\": {\n // we just want to track the start of email auth\n if (\"bundle\" in params) return;\n SignerLogger.trackEvent({\n name: \"signer_authnticate\",\n data: { authType: \"email\" },\n });\n return;\n }\n case \"passkey\": {\n const isAnon = !(\"email\" in params) && params.createNew == null;\n SignerLogger.trackEvent({\n name: \"signer_authnticate\",\n data: {\n authType: isAnon ? \"passkey_anon\" : \"passkey_email\",\n },\n });\n return;\n }\n case \"oauth\":\n SignerLogger.trackEvent({\n name: \"signer_authnticate\",\n data: {\n authType: \"oauth\",\n provider: params.authProviderId,\n },\n });\n break;\n case \"oauthReturn\":\n break;\n case \"otp\":\n SignerLogger.trackEvent({\n name: \"signer_authnticate\",\n data: { authType: \"otp\" },\n });\n break;\n default:\n assertNever(type, `Unknown auth type: ${type}`);\n }\n };\n\n /**\n * Clear a user session and log them out\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * await signer.disconnect();\n * ```\n *\n * @returns {Promise<void>} a promise that resolves when the user is logged out\n */\n disconnect: () => Promise<void> = async () => {\n await this.inner.disconnect();\n };\n\n /**\n * Gets the current logged in user\n * If a user has an ongoing session, it will use that session and\n * try to authenticate\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * // throws if not logged in\n * const user = await signer.getAuthDetails();\n * ```\n *\n * @throws if there is no user logged in\n * @returns {Promise<User>} the current user\n */\n getAuthDetails = async (): Promise<User> => {\n const sessionUser = await this.sessionManager.getSessionUser();\n if (sessionUser != null) {\n return sessionUser;\n }\n\n return this.inner.whoami();\n };\n\n /**\n * Retrieves the address of the current user by calling the `whoami` method on `this.inner`.\n *\n * @returns {Promise<string>} A promise that resolves to the address of the current user.\n */\n getAddress: () => Promise<`0x${string}`> = SignerLogger.profiled(\n \"BaseAlchemySigner.getAddress\",\n async () => {\n const { address } = await this.inner.whoami();\n\n return address;\n }\n );\n\n /**\n * Signs a raw message after hashing it.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const signature = await signer.signMessage(\"Hello, world!\");\n * ```\n *\n * @param {string} msg the message to be hashed and then signed\n * @returns {Promise<string>} a promise that resolves to the signed message\n */\n signMessage: (msg: SignableMessage) => Promise<`0x${string}`> =\n SignerLogger.profiled(\"BaseAlchemySigner.signMessage\", async (msg) => {\n const messageHash = hashMessage(msg);\n\n const result = await this.inner.signRawMessage(messageHash);\n\n SignerLogger.trackEvent({\n name: \"signer_sign_message\",\n });\n\n return result;\n });\n\n /**\n * Signs a typed message by first hashing it and then signing the hashed message using the `signRawMessage` method.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const signature = await signer.signTypedData({\n * domain: {},\n * types: {},\n * primaryType: \"\",\n * message: {},\n * });\n * ```\n *\n * @param {TypedDataDefinition<TTypedData, TPrimaryType>} params The parameters for the typed message to be hashed and signed\n * @returns {Promise<any>} A promise that resolves to the signed message\n */\n signTypedData: <\n const TTypedData extends TypedData | Record<string, unknown>,\n TPrimaryType extends keyof TTypedData | \"EIP712Domain\" = keyof TTypedData\n >(\n params: TypedDataDefinition<TTypedData, TPrimaryType>\n ) => Promise<Hex> = SignerLogger.profiled(\n \"BaseAlchemySigner.signTypedData\",\n async (params) => {\n const messageHash = hashTypedData(params);\n\n return this.inner.signRawMessage(messageHash);\n }\n );\n\n /**\n * Serializes a transaction, signs it with a raw message, and then returns the serialized transaction with the signature.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const tx = await signer.signTransaction({\n * to: \"0x1234\",\n * value: \"0x1234\",\n * data: \"0x1234\",\n * });\n * ```\n *\n * @param {Transaction} tx the transaction to be serialized and signed\n * @param {{serializer?: SerializeTransactionFn}} args options for serialization\n * @param {() => Hex} [args.serializer] an optional serializer function. If not provided, the default `serializeTransaction` function will be used\n * @returns {Promise<string>} a promise that resolves to the serialized transaction with the signature\n */\n signTransaction: <\n serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>,\n transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]\n >(\n transaction: transaction,\n options?:\n | {\n serializer?: serializer | undefined;\n }\n | undefined\n ) => Promise<\n IsNarrowable<\n TransactionSerialized<GetTransactionType<transaction>>,\n Hex\n > extends true\n ? TransactionSerialized<GetTransactionType<transaction>>\n : Hex\n > = SignerLogger.profiled(\n \"BaseAlchemySigner.signTransaction\",\n async (tx, args) => {\n const serializeFn = args?.serializer ?? serializeTransaction;\n const serializedTx = serializeFn(tx);\n const signatureHex = await this.inner.signRawMessage(\n keccak256(serializedTx)\n );\n\n const signature = this.unpackSignRawMessageBytes(signatureHex);\n\n return serializeFn(tx, signature);\n }\n );\n\n /**\n * Signs an EIP-7702 Authorization and then returns the authorization with the signature.\n *\n * @example\n * ```ts twoslash\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const tx = await signer.signAuthorization({\n * contractAddress: \"0x1234123412341234123412341234123412341234\",\n * chainId: 1,\n * nonce: 0,\n * });\n * ```\n *\n * @param {Authorization<number, false>} unsignedAuthorization the authorization to be signed\n * @returns {Promise<Authorization<number, true>> | undefined} a promise that resolves to the authorization with the signature\n */\n signAuthorization: (\n unsignedAuthorization: Authorization<number, false>\n ) => Promise<Authorization<number, true>> = SignerLogger.profiled(\n \"BaseAlchemySigner.signAuthorization\",\n async (unsignedAuthorization) => {\n const hashedAuthorization = hashAuthorization(unsignedAuthorization);\n const signedAuthorizationHex = await this.inner.signRawMessage(\n hashedAuthorization\n );\n const signature = this.unpackSignRawMessageBytes(signedAuthorizationHex);\n return { ...unsignedAuthorization, ...signature };\n }\n );\n\n /**\n * Gets the current MFA status\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const mfaStatus = signer.getMfaStatus();\n * if (mfaStatus === AlchemyMfaStatus.REQUIRED) {\n * // Handle MFA requirement\n * }\n * ```\n *\n * @returns {{ mfaRequired: boolean; mfaFactorId?: string }} The current MFA status\n */\n getMfaStatus = (): {\n mfaRequired: boolean;\n mfaFactorId?: string;\n } => {\n return this.store.getState().mfaStatus;\n };\n\n private unpackSignRawMessageBytes = (\n hex: `0x${string}`\n ): UnpackedSignature => {\n return {\n r: takeBytes(hex, { count: 32 }),\n s: takeBytes(hex, { count: 32, offset: 32 }),\n v: BigInt(takeBytes(hex, { count: 1, offset: 64 })),\n };\n };\n\n /**\n * Unauthenticated call to look up a user's organizationId by email\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.getUser(\"foo@mail.com\");\n * ```\n *\n * @param {string} email the email to lookup\n * @returns {Promise<{orgId: string}>} the organization id for the user if they exist\n */\n getUser: (email: string) => Promise<{ orgId: string } | null> =\n SignerLogger.profiled(\"BaseAlchemySigner.getUser\", async (email) => {\n const result = await this.inner.lookupUserByEmail(email);\n\n if (result.orgId == null) {\n return null;\n }\n\n return {\n orgId: result.orgId,\n };\n });\n\n /**\n * Adds a passkey to the user's account\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.addPasskey()\n * ```\n *\n * @param {CredentialCreationOptions | undefined} params optional parameters for the passkey creation\n * @returns {Promise<string[]>} an array of the authenticator ids added to the user\n */\n addPasskey: (params?: CredentialCreationOptions) => Promise<string[]> =\n SignerLogger.profiled(\"BaseAlchemySigner.addPasskey\", async (params) => {\n return this.inner.addPasskey(params ?? {});\n });\n\n getPasskeyStatus: () => Promise<{ isPasskeyAdded: boolean }> =\n SignerLogger.profiled(\"BaseAlchemySigner.getPasskeyStatus\", async () => {\n return this.inner.getPasskeyStatus();\n });\n\n /**\n * Used to export the wallet for a given user\n * If the user is authenticated with an Email, this will return a seed phrase\n * If the user is authenticated with a Passkey, this will return a private key\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * // the params passed to this are different based on the specific signer\n * const result = signer.exportWallet()\n * ```\n *\n * @param {unknown} params export wallet parameters\n * @returns {boolean} true if the wallet was exported successfully\n */\n exportWallet: (\n params: Parameters<(typeof this.inner)[\"exportWallet\"]>[0]\n ) => Promise<boolean> = async (params) => {\n return this.inner.exportWallet(params);\n };\n\n /**\n * This method lets you adapt your AlchemySigner to a viem LocalAccount, which\n * will let you use the signer as an EOA directly.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const account = signer.toViemAccount();\n * ```\n *\n * @throws if your signer is not authenticated\n * @returns {LocalAccount} a LocalAccount object that can be used with viem's wallet client\n */\n toViemAccount = (): LocalAccount => {\n // if we want this method to be synchronous, then we need to do this check here\n // otherwise we can use the sessionManager to get the user\n if (!this.inner.getUser()) {\n throw new NotAuthenticatedError();\n }\n\n return toAccount({\n address: this.inner.getUser()!.address,\n signMessage: (msg) => this.signMessage(msg.message),\n signTypedData: <\n const typedData extends TypedData | Record<string, unknown>,\n primaryType extends keyof typedData | \"EIP712Domain\" = keyof typedData\n >(\n typedDataDefinition: TypedDataDefinition<typedData, primaryType>\n ) => this.signTypedData<typedData, primaryType>(typedDataDefinition),\n signTransaction: this.signTransaction,\n });\n };\n\n /**\n * Creates a new instance of `SolanaSigner` using the provided inner value.\n * This requires the signer to be authenticated first\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const solanaSigner = signer.toSolanaSigner();\n * ```\n *\n * @returns {SolanaSigner} A new instance of `SolanaSigner`\n */\n toSolanaSigner = (): SolanaSigner => {\n if (!this.inner.getUser()) {\n throw new NotAuthenticatedError();\n }\n\n return new SolanaSigner(this.inner);\n };\n\n private authenticateWithEmail = async (\n params: Extract<AuthParams, { type: \"email\" }>\n ): Promise<User> => {\n if (\"bundle\" in params) {\n return this.completeEmailAuth(params);\n }\n\n const { orgId, otpId, isNewUser } = await this.initOrCreateEmailUser(\n params.email,\n params.emailMode,\n params.multiFactors,\n params.redirectParams\n );\n\n this.sessionManager.setTemporarySession({\n orgId,\n isNewUser,\n });\n\n this.store.setState({\n status: AlchemySignerStatus.AWAITING_EMAIL_AUTH,\n otpId,\n error: null,\n });\n\n // We wait for the session manager to emit a connected event if\n // cross tab sessions are permitted\n return new Promise<User>((resolve) => {\n const removeListener = this.sessionManager.on(\"connected\", (session) => {\n resolve(session.user);\n removeListener();\n });\n });\n };\n\n private authenticateWithPasskey = async (\n args: Extract<AuthParams, { type: \"passkey\" }>\n ): Promise<User> => {\n let user: User;\n const shouldCreateNew = async () => {\n if (\"email\" in args) {\n const existingUser = await this.getUser(args.email);\n return existingUser == null;\n }\n\n return args.createNew;\n };\n\n if (await shouldCreateNew()) {\n const result = await this.inner.createAccount(\n args as Extract<\n AuthParams,\n { type: \"passkey\" } & ({ email: string } | { createNew: true })\n >\n );\n // account creation for passkeys returns the whoami response so we don't have to\n // call it again after signup\n user = {\n address: result.address!,\n userId: result.userId!,\n orgId: result.orgId,\n };\n } else {\n user = await this.inner.lookupUserWithPasskey();\n if (!user) {\n this.store.setState({\n status: AlchemySignerStatus.DISCONNECTED,\n });\n throw new Error(\"No user found\");\n }\n }\n\n return user;\n };\n\n private authenticateWithOauth = async (\n args: Extract<AuthParams, { type: \"oauth\" }>\n ): Promise<User> => {\n const params: OauthParams = {\n ...args,\n expirationSeconds: this.getExpirationSeconds(),\n };\n if (params.mode === \"redirect\") {\n return this.inner.oauthWithRedirect(params);\n } else {\n return this.inner.oauthWithPopup(params);\n }\n };\n\n private authenticateWithOtp = async (\n args: Extract<AuthParams, { type: \"otp\" }>\n ): Promise<User> => {\n const tempSession = this.sessionManager.getTemporarySession();\n const { orgId, isNewUser } = tempSession ?? {};\n const { otpId } = this.store.getState();\n if (!orgId) {\n throw new Error(\"orgId not found in session\");\n }\n if (!otpId) {\n throw new Error(\"otpId not found in session\");\n }\n\n const response = await this.inner.submitOtpCode({\n orgId,\n otpId,\n otpCode: args.otpCode,\n expirationSeconds: this.getExpirationSeconds(),\n multiFactors: args.multiFactors,\n });\n\n if (response.mfaRequired) {\n this.handleMfaRequired(response.encryptedPayload, response.multiFactors);\n\n return new Promise<User>((resolve) => {\n const removeListener = this.sessionManager.on(\n \"connected\",\n (session) => {\n resolve(session.user);\n removeListener();\n }\n );\n });\n }\n\n const user = await this.inner.completeAuthWithBundle({\n bundle: response.bundle,\n orgId,\n connectedEventName: \"connectedOtp\",\n authenticatingType: \"otp\",\n });\n\n this.emitNewUserEvent(isNewUser);\n if (tempSession) {\n this.sessionManager.setTemporarySession({\n ...tempSession,\n isNewUser: false,\n });\n }\n\n return user;\n };\n\n private handleOauthReturn = ({\n bundle,\n orgId,\n idToken,\n isNewUser,\n }: Extract<AuthParams, { type: \"oauthReturn\" }>): Promise<User> => {\n const user = this.inner.completeAuthWithBundle({\n bundle,\n orgId,\n connectedEventName: \"connectedOauth\",\n authenticatingType: \"oauth\",\n idToken,\n });\n\n this.emitNewUserEvent(isNewUser);\n\n return user;\n };\n\n private handleMfaRequired(\n encryptedPayload: string,\n multiFactors: MfaFactor[]\n ) {\n // Store complete MFA context in the temporary session\n const tempSession = this.sessionManager.getTemporarySession();\n if (tempSession) {\n this.sessionManager.setTemporarySession({\n ...tempSession,\n encryptedPayload,\n mfaFactorId: multiFactors?.[0]?.multiFactorId,\n });\n }\n\n // Keep minimal state in the store for UI updates\n this.store.setState({\n status: AlchemySignerStatus.AWAITING_MFA_AUTH,\n error: null,\n mfaStatus: {\n mfaRequired: true,\n mfaFactorId: multiFactors?.[0]?.multiFactorId,\n },\n });\n }\n\n private getExpirationSeconds = () =>\n Math.floor(this.sessionManager.expirationTimeMs / 1000);\n\n private registerListeners = () => {\n // Declare listeners in an object to typecheck that every event type is\n // handled.\n const listeners: SessionManagerEvents = {\n connected: (session) => {\n this.store.setState({\n user: session.user,\n status: AlchemySignerStatus.CONNECTED,\n error: null,\n });\n },\n disconnected: () => {\n this.store.setState({\n user: null,\n status: AlchemySignerStatus.DISCONNECTED,\n });\n },\n initialized: () => {\n this.store.setState((state) => ({\n status: state.user\n ? AlchemySignerStatus.CONNECTED\n : AlchemySignerStatus.DISCONNECTED,\n ...(state.user ? { error: null } : undefined),\n }));\n },\n };\n\n for (const [event, listener] of Object.entries(listeners)) {\n this.sessionManager.on(event as keyof SessionManagerEvents, listener);\n }\n\n this.inner.on(\"authenticating\", ({ type }) => {\n const status = (() => {\n switch (type) {\n case \"email\":\n return AlchemySignerStatus.AUTHENTICATING_EMAIL;\n case \"passkey\":\n return AlchemySignerStatus.AUTHENTICATING_PASSKEY;\n case \"oauth\":\n return AlchemySignerStatus.AUTHENTICATING_OAUTH;\n case \"otp\":\n case \"otpVerify\":\n return AlchemySignerStatus.AWAITING_OTP_AUTH;\n default:\n assertNever(type, \"unhandled authenticating type\");\n }\n })();\n\n // trigger new user event on signer from client\n this.inner.on(\"newUserSignup\", () => {\n this.emitNewUserEvent(true);\n });\n\n this.store.setState({\n status,\n error: null,\n });\n });\n };\n\n private emitNewUserEvent = (isNewUser?: boolean) => {\n // assumes that if isNewUser is undefined it is a returning user\n if (isNewUser) this.store.setState({ isNewUser });\n };\n\n private async initOrCreateEmailUser(\n email: string,\n emailMode?: EmailType,\n multiFactors?: VerifyMfaParams[],\n redirectParams?: URLSearchParams\n ): Promise<{\n orgId: string;\n otpId?: string;\n isNewUser: boolean;\n }> {\n const existingUser = await this.getUser(email);\n const expirationSeconds = this.getExpirationSeconds();\n\n if (existingUser) {\n const { orgId, otpId } = await this.inner.initEmailAuth({\n email: email,\n emailMode: emailMode,\n expirationSeconds,\n redirectParams: redirectParams,\n multiFactors,\n });\n return {\n orgId,\n otpId,\n isNewUser: false,\n };\n }\n\n const { orgId, otpId } = await this.inner.createAccount({\n type: \"email\",\n email,\n emailMode,\n expirationSeconds,\n redirectParams,\n });\n return {\n orgId,\n otpId,\n isNewUser: true,\n };\n }\n\n private async completeEmailAuth(\n params: Extract<AuthParams, { type: \"email\"; bundle: string }>\n ): Promise<User> {\n const temporarySession = params.orgId\n ? { orgId: params.orgId }\n : this.sessionManager.getTemporarySession();\n\n if (!temporarySession) {\n this.store.setState({ status: AlchemySignerStatus.DISCONNECTED });\n throw new Error(\"Could not find email auth init session!\");\n }\n\n const user = await this.inner.completeAuthWithBundle({\n bundle: params.bundle,\n orgId: temporarySession.orgId,\n connectedEventName: \"connectedEmail\",\n authenticatingType: \"email\",\n });\n\n // fire new user event\n this.emitNewUserEvent(params.isNewUser);\n\n return user;\n }\n\n /**\n * Retrieves the list of MFA factors configured for the current user.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const { multiFactors } = await signer.getMfaFactors();\n * ```\n *\n * @throws {NotAuthenticatedError} If no user is authenticated\n * @returns {Promise<{ multiFactors: Array<MfaFactor> }>} A promise that resolves to an array of configured MFA factors\n */\n getMfaFactors: () => Promise<{ multiFactors: MfaFactor[] }> =\n SignerLogger.profiled(\"BaseAlchemySigner.getMfaFactors\", async () => {\n return this.inner.getMfaFactors();\n });\n\n /**\n * Initiates the setup of a new MFA factor for the current user.\n * The factor will need to be verified using verifyMfa before it becomes active.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.addMfa({ multiFactorType: \"totp\" });\n * // Result contains multiFactorTotpUrl to display as QR code\n * ```\n *\n * @param {AddMfaParams} params The parameters required to enable a new MFA factor\n * @throws {NotAuthenticatedError} If no user is authenticated\n * @returns {Promise<AddMfaResult>} A promise that resolves to the factor setup information\n */\n addMfa: (params: AddMfaParams) => Promise<AddMfaResult> =\n SignerLogger.profiled(\"BaseAlchemySigner.addMfa\", async (params) => {\n return this.inner.addMfa(params);\n });\n\n /**\n * Verifies a newly created MFA factor to complete the setup process.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.verifyMfa({\n * multiFactorId: \"factor-id\",\n * multiFactorCode: \"123456\" // 6-digit code from authenticator app\n * });\n * ```\n *\n * @param {VerifyMfaParams} params The parameters required to verify the MFA factor\n * @throws {NotAuthenticatedError} If no user is authenticated\n * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors\n */\n verifyMfa: (\n params: VerifyMfaParams\n ) => Promise<{ multiFactors: MfaFactor[] }> = SignerLogger.profiled(\n \"BaseAlchemySigner.verifyMfa\",\n async (params) => {\n return this.inner.verifyMfa(params);\n }\n );\n\n /**\n * Removes existing MFA factors by their IDs.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.removeMfa({\n * multiFactorIds: [\"factor-id-1\", \"factor-id-2\"]\n * });\n * ```\n *\n * @param {RemoveMfaParams} params The parameters specifying which factors to disable\n * @throws {NotAuthenticatedError} If no user is authenticated\n * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors\n */\n removeMfa: (\n params: RemoveMfaParams\n ) => Promise<{ multiFactors: MfaFactor[] }> = SignerLogger.profiled(\n \"BaseAlchemySigner.removeMfa\",\n async (params) => {\n return this.inner.removeMfa(params);\n }\n );\n\n /**\n * Validates MFA factors that were required during authentication.\n * This function should be called after MFA is required and the user has provided their MFA code.\n * It completes the authentication process by validating the MFA factors and completing the auth bundle.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * // After MFA is required and user provides code\n * const user = await signer.validateMultiFactors({\n * multiFactorCode: \"123456\", // 6-digit code from authenticator app\n * multiFactorId: \"factor-id\"\n * });\n * ```\n *\n * @param {ValidateMultiFactorsArgs} params - Parameters for validating MFA factors\n * @throws {Error} If there is no pending MFA context or if orgId is not found\n * @returns {Promise<User>} A promise that resolves to the authenticated user\n */\n public async validateMultiFactors(\n params: ValidateMultiFactorsArgs\n ): Promise<User> {\n // Get MFA context from temporary session\n const tempSession = this.sessionManager.getTemporarySession();\n if (\n !tempSession?.orgId ||\n !tempSession.encryptedPayload ||\n !tempSession.mfaFactorId\n ) {\n throw new Error(\n \"No pending MFA context found. Call submitOtpCode() first.\"\n );\n }\n\n if (\n params.multiFactorId &&\n tempSession.mfaFactorId !== params.multiFactorId\n ) {\n throw new Error(\"MFA factor ID mismatch\");\n }\n\n // Call the low-level client\n const { bundle } = await this.inner.validateMultiFactors({\n encryptedPayload: tempSession.encryptedPayload,\n multiFactors: [\n {\n multiFactorId: tempSession.mfaFactorId,\n multiFactorCode: params.multiFactorCode,\n },\n ],\n });\n\n // Complete the authentication\n const user = await this.inner.completeAuthWithBundle({\n bundle,\n orgId: tempSession.orgId,\n connectedEventName: \"connectedOtp\",\n authenticatingType: \"otp\",\n });\n\n // Remove MFA data from temporary session\n this.sessionManager.setTemporarySession({\n ...tempSession,\n encryptedPayload: undefined,\n mfaFactorId: undefined,\n });\n\n // Update UI state\n this.store.setState({\n mfaStatus: {\n mfaRequired: false,\n mfaFactorId: undefined,\n },\n });\n\n return user;\n }\n\n protected initConfig = async (): Promise<SignerConfig> => {\n this.config = this.fetchConfig();\n return this.config;\n };\n\n /**\n * Returns the signer configuration while fetching it if it's not already initialized.\n *\n * @returns {Promise<SignerConfig>} A promise that resolves to the signer configuration\n */\n public getConfig = async (): Promise<SignerConfig> => {\n if (!this.config) {\n return this.initConfig();\n }\n\n return this.config;\n };\n\n protected fetchConfig = async (): Promise<SignerConfig> => {\n return this.inner.request(\"/v1/signer-config\", {});\n };\n}\n\nfunction toErrorInfo(error: unknown): ErrorInfo {\n return error instanceof Error\n ? { name: error.name, message: error.message }\n : { name: \"Error\", message: \"Unknown error\" };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/base.ts"],"names":[],"mappings":"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","sourcesContent":["import { takeBytes, type SmartAccountAuthenticator } from \"@aa-sdk/core\";\nimport {\n hashMessage,\n hashTypedData,\n keccak256,\n serializeTransaction,\n type GetTransactionType,\n type Hex,\n type IsNarrowable,\n type LocalAccount,\n type SerializeTransactionFn,\n type SignableMessage,\n type TransactionSerializable,\n type TransactionSerialized,\n type TypedData,\n type TypedDataDefinition,\n} from \"viem\";\nimport { toAccount } from \"viem/accounts\";\nimport { hashAuthorization, type Authorization } from \"viem/experimental\";\nimport type { Mutate, StoreApi } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport { createStore } from \"zustand/vanilla\";\nimport type { BaseSignerClient } from \"./client/base\";\nimport {\n type EmailType,\n type MfaFactor,\n type OauthConfig,\n type OauthParams,\n type User,\n type VerifyMfaParams,\n type AddMfaParams,\n type AddMfaResult,\n type RemoveMfaParams,\n type AuthLinkingPrompt,\n} from \"./client/types.js\";\nimport { NotAuthenticatedError } from \"./errors.js\";\nimport { SignerLogger } from \"./metrics.js\";\nimport {\n SessionManager,\n type SessionManagerParams,\n} from \"./session/manager.js\";\nimport type { SessionManagerEvents } from \"./session/types\";\nimport type { AuthParams } from \"./signer\";\nimport { SolanaSigner } from \"./solanaSigner.js\";\nimport {\n AlchemySignerStatus,\n type AlchemySignerEvent,\n type AlchemySignerEvents,\n type ErrorInfo,\n type ValidateMultiFactorsArgs,\n} from \"./types.js\";\nimport { assertNever } from \"./utils/typeAssertions.js\";\n\nexport interface BaseAlchemySignerParams<TClient extends BaseSignerClient> {\n client: TClient;\n sessionConfig?: Omit<SessionManagerParams, \"client\">;\n initialError?: ErrorInfo;\n initialAuthLinkingPrompt?: AuthLinkingPrompt;\n}\n\ntype AlchemySignerStore = {\n user: User | null;\n status: AlchemySignerStatus;\n error: ErrorInfo | null;\n otpId?: string;\n isNewUser?: boolean;\n mfaStatus: {\n mfaRequired: boolean;\n mfaFactorId?: string;\n encryptedPayload?: string;\n };\n authLinkingStatus?: {\n email: string;\n providerName: string;\n idToken: string;\n };\n};\n\ntype UnpackedSignature = {\n r: `0x${string}`;\n s: `0x${string}`;\n v: bigint;\n};\n\ntype InternalStore = Mutate<\n StoreApi<AlchemySignerStore>,\n [[\"zustand/subscribeWithSelector\", never]]\n>;\n\nexport type EmailConfig = {\n mode?: \"MAGIC_LINK\" | \"OTP\";\n};\n\nexport type SignerConfig = {\n email: EmailConfig;\n};\n\n/**\n * Base abstract class for Alchemy Signer, providing authentication and session management for smart accounts.\n * Implements the `SmartAccountAuthenticator` interface and handles various signer events.\n */\nexport abstract class BaseAlchemySigner<TClient extends BaseSignerClient>\n implements SmartAccountAuthenticator<AuthParams, User, TClient>\n{\n signerType: \"alchemy-signer\" | \"rn-alchemy-signer\" = \"alchemy-signer\";\n inner: TClient;\n private sessionManager: SessionManager;\n private store: InternalStore;\n private config: Promise<SignerConfig>;\n\n /**\n * Initializes an instance with the provided client and session configuration.\n * This function sets up the internal store, initializes the session manager,\n * registers listeners and initializes the session manager to manage session state.\n *\n * @param {BaseAlchemySignerParams<TClient>} param0 Object containing the client and session configuration\n * @param {TClient} param0.client The client instance to be used internally\n * @param {SessionConfig} param0.sessionConfig Configuration for managing sessions\n * @param {ErrorInfo | undefined} param0.initialError Error already present on the signer when initialized, if any\n */\n constructor({\n client,\n sessionConfig,\n initialError,\n initialAuthLinkingPrompt,\n }: BaseAlchemySignerParams<TClient>) {\n this.inner = client;\n this.store = createStore(\n subscribeWithSelector(\n () =>\n ({\n user: null,\n status: AlchemySignerStatus.INITIALIZING,\n error: initialError ?? null,\n mfaStatus: {\n mfaRequired: false,\n mfaFactorId: undefined,\n },\n } satisfies AlchemySignerStore)\n )\n );\n // NOTE: it's important that the session manager share a client\n // with the signer. The SessionManager leverages the Signer's client\n // to manage session state.\n this.sessionManager = new SessionManager({\n ...sessionConfig,\n client: this.inner,\n });\n // register listeners first\n this.registerListeners();\n // then initialize so that we can catch those events\n this.sessionManager.initialize();\n this.config = this.fetchConfig();\n if (initialAuthLinkingPrompt) {\n this.setAuthLinkingPrompt(initialAuthLinkingPrompt);\n }\n }\n\n /**\n * Allows you to subscribe to events emitted by the signer\n *\n * @param {AlchemySignerEvent} event the event to subscribe to\n * @param {AlchemySignerEvents[AlchemySignerEvent]} listener the function to run when the event is emitted\n * @returns {() => void} a function to remove the listener\n */\n on = <E extends AlchemySignerEvent>(\n event: E,\n listener: AlchemySignerEvents[E]\n ) => {\n // NOTE: we're using zustand here to handle this because we are able to use the fireImmediately\n // option which deals with a possible race condition where the listener is added after the event\n // is fired. In the Client and SessionManager we use EventEmitter because it's easier to handle internally\n switch (event) {\n case \"connected\":\n return subscribeWithDelayedFireImmediately(\n this.store,\n ({ status }) => status,\n (status) =>\n status === AlchemySignerStatus.CONNECTED &&\n (listener as AlchemySignerEvents[\"connected\"])(\n this.store.getState().user!\n )\n );\n case \"disconnected\":\n return subscribeWithDelayedFireImmediately(\n this.store,\n ({ status }) => status,\n (status) =>\n status === AlchemySignerStatus.DISCONNECTED &&\n (listener as AlchemySignerEvents[\"disconnected\"])()\n );\n case \"statusChanged\":\n return subscribeWithDelayedFireImmediately(\n this.store,\n ({ status }) => status,\n listener as AlchemySignerEvents[\"statusChanged\"]\n );\n case \"errorChanged\":\n return subscribeWithDelayedFireImmediately(\n this.store,\n ({ error }) => error,\n (error) =>\n (listener as AlchemySignerEvents[\"errorChanged\"])(\n error ?? undefined\n )\n );\n case \"newUserSignup\":\n return subscribeWithDelayedFireImmediately(\n this.store,\n ({ isNewUser }) => isNewUser,\n (isNewUser) => {\n if (isNewUser) (listener as AlchemySignerEvents[\"newUserSignup\"])();\n }\n );\n case \"mfaStatusChanged\":\n return subscribeWithDelayedFireImmediately(\n this.store,\n ({ mfaStatus }) => mfaStatus,\n (mfaStatus) =>\n (listener as AlchemySignerEvents[\"mfaStatusChanged\"])(mfaStatus)\n );\n case \"emailAuthLinkingRequired\":\n return subscribeWithDelayedFireImmediately(\n this.store,\n ({ authLinkingStatus }) => authLinkingStatus,\n (authLinkingStatus) => {\n if (authLinkingStatus) {\n (listener as AlchemySignerEvents[\"emailAuthLinkingRequired\"])(\n authLinkingStatus.email\n );\n }\n }\n );\n default:\n assertNever(event, `Unknown event type ${event}`);\n }\n };\n\n /**\n * Prepares the config needed to use popup-based OAuth login. This must be\n * called before calling `.authenticate` with params `{ type: \"oauth\", mode:\n * \"popup\" }`, and is recommended to be called on page load.\n *\n * This method exists because browsers may prevent popups from opening unless\n * triggered by user interaction, and so the OAuth config must already have\n * been fetched at the time a user clicks a social login button.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * await signer.preparePopupOauth();\n * ```\n * @returns {Promise<OauthConfig>} the config which must be loaded before\n * using popup-based OAuth\n */\n preparePopupOauth = (): Promise<OauthConfig> => this.inner.initOauth();\n\n /**\n * Authenticate a user with either an email or a passkey and create a session for that user\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.authenticate({\n * type: \"email\",\n * email: \"foo@mail.com\",\n * });\n * ```\n *\n * @param {AuthParams} params - undefined if passkey login, otherwise an object with email and bundle to resolve\n * @returns {Promise<User>} the user that was authenticated\n */\n authenticate: (params: AuthParams) => Promise<User> = SignerLogger.profiled(\n \"BaseAlchemySigner.authenticate\",\n async (params) => {\n const { type } = params;\n const result = (() => {\n switch (type) {\n case \"email\":\n return this.authenticateWithEmail(params);\n case \"passkey\":\n return this.authenticateWithPasskey(params);\n case \"oauth\":\n return this.authenticateWithOauth(params);\n case \"oauthReturn\":\n return this.handleOauthReturn(params);\n case \"otp\":\n return this.authenticateWithOtp(params);\n default:\n assertNever(type, `Unknown auth type: ${type}`);\n }\n })();\n\n this.trackAuthenticateType(params);\n\n return result.catch((error) => {\n /**\n * 2 things going on here:\n * 1. for oauth flows we expect the status to remain in authenticating\n * 2. we do the ternary, because if we explicitly pass in `undefined` for the status, zustand will set the value of status to `undefined`.\n * However, if we omit it, then it will not override the current value of status.\n */\n this.store.setState({\n error: toErrorInfo(error),\n ...(type === \"oauthReturn\" || type === \"oauth\"\n ? {}\n : { status: AlchemySignerStatus.DISCONNECTED }),\n });\n throw error;\n });\n }\n );\n\n private trackAuthenticateType = (params: AuthParams) => {\n const { type } = params;\n switch (type) {\n case \"email\": {\n // we just want to track the start of email auth\n if (\"bundle\" in params) return;\n SignerLogger.trackEvent({\n name: \"signer_authnticate\",\n data: { authType: \"email\" },\n });\n return;\n }\n case \"passkey\": {\n const isAnon = !(\"email\" in params) && params.createNew == null;\n SignerLogger.trackEvent({\n name: \"signer_authnticate\",\n data: {\n authType: isAnon ? \"passkey_anon\" : \"passkey_email\",\n },\n });\n return;\n }\n case \"oauth\":\n SignerLogger.trackEvent({\n name: \"signer_authnticate\",\n data: {\n authType: \"oauth\",\n provider: params.authProviderId,\n },\n });\n break;\n case \"oauthReturn\":\n break;\n case \"otp\":\n SignerLogger.trackEvent({\n name: \"signer_authnticate\",\n data: { authType: \"otp\" },\n });\n break;\n default:\n assertNever(type, `Unknown auth type: ${type}`);\n }\n };\n\n /**\n * Clear a user session and log them out\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * await signer.disconnect();\n * ```\n *\n * @returns {Promise<void>} a promise that resolves when the user is logged out\n */\n disconnect: () => Promise<void> = async () => {\n await this.inner.disconnect();\n };\n\n /**\n * Gets the current logged in user\n * If a user has an ongoing session, it will use that session and\n * try to authenticate\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * // throws if not logged in\n * const user = await signer.getAuthDetails();\n * ```\n *\n * @throws if there is no user logged in\n * @returns {Promise<User>} the current user\n */\n getAuthDetails = async (): Promise<User> => {\n const sessionUser = await this.sessionManager.getSessionUser();\n if (sessionUser != null) {\n return sessionUser;\n }\n\n return this.inner.whoami();\n };\n\n /**\n * Retrieves the address of the current user by calling the `whoami` method on `this.inner`.\n *\n * @returns {Promise<string>} A promise that resolves to the address of the current user.\n */\n getAddress: () => Promise<`0x${string}`> = SignerLogger.profiled(\n \"BaseAlchemySigner.getAddress\",\n async () => {\n const { address } = await this.inner.whoami();\n\n return address;\n }\n );\n\n /**\n * Signs a raw message after hashing it.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const signature = await signer.signMessage(\"Hello, world!\");\n * ```\n *\n * @param {string} msg the message to be hashed and then signed\n * @returns {Promise<string>} a promise that resolves to the signed message\n */\n signMessage: (msg: SignableMessage) => Promise<`0x${string}`> =\n SignerLogger.profiled(\"BaseAlchemySigner.signMessage\", async (msg) => {\n const messageHash = hashMessage(msg);\n\n const result = await this.inner.signRawMessage(messageHash);\n\n SignerLogger.trackEvent({\n name: \"signer_sign_message\",\n });\n\n return result;\n });\n\n /**\n * Signs a typed message by first hashing it and then signing the hashed message using the `signRawMessage` method.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const signature = await signer.signTypedData({\n * domain: {},\n * types: {},\n * primaryType: \"\",\n * message: {},\n * });\n * ```\n *\n * @param {TypedDataDefinition<TTypedData, TPrimaryType>} params The parameters for the typed message to be hashed and signed\n * @returns {Promise<any>} A promise that resolves to the signed message\n */\n signTypedData: <\n const TTypedData extends TypedData | Record<string, unknown>,\n TPrimaryType extends keyof TTypedData | \"EIP712Domain\" = keyof TTypedData\n >(\n params: TypedDataDefinition<TTypedData, TPrimaryType>\n ) => Promise<Hex> = SignerLogger.profiled(\n \"BaseAlchemySigner.signTypedData\",\n async (params) => {\n const messageHash = hashTypedData(params);\n\n return this.inner.signRawMessage(messageHash);\n }\n );\n\n /**\n * Serializes a transaction, signs it with a raw message, and then returns the serialized transaction with the signature.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const tx = await signer.signTransaction({\n * to: \"0x1234\",\n * value: \"0x1234\",\n * data: \"0x1234\",\n * });\n * ```\n *\n * @param {Transaction} tx the transaction to be serialized and signed\n * @param {{serializer?: SerializeTransactionFn}} args options for serialization\n * @param {() => Hex} [args.serializer] an optional serializer function. If not provided, the default `serializeTransaction` function will be used\n * @returns {Promise<string>} a promise that resolves to the serialized transaction with the signature\n */\n signTransaction: <\n serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>,\n transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]\n >(\n transaction: transaction,\n options?:\n | {\n serializer?: serializer | undefined;\n }\n | undefined\n ) => Promise<\n IsNarrowable<\n TransactionSerialized<GetTransactionType<transaction>>,\n Hex\n > extends true\n ? TransactionSerialized<GetTransactionType<transaction>>\n : Hex\n > = SignerLogger.profiled(\n \"BaseAlchemySigner.signTransaction\",\n async (tx, args) => {\n const serializeFn = args?.serializer ?? serializeTransaction;\n const serializedTx = serializeFn(tx);\n const signatureHex = await this.inner.signRawMessage(\n keccak256(serializedTx)\n );\n\n const signature = this.unpackSignRawMessageBytes(signatureHex);\n\n return serializeFn(tx, signature);\n }\n );\n\n /**\n * Signs an EIP-7702 Authorization and then returns the authorization with the signature.\n *\n * @example\n * ```ts twoslash\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const tx = await signer.signAuthorization({\n * contractAddress: \"0x1234123412341234123412341234123412341234\",\n * chainId: 1,\n * nonce: 0,\n * });\n * ```\n *\n * @param {Authorization<number, false>} unsignedAuthorization the authorization to be signed\n * @returns {Promise<Authorization<number, true>> | undefined} a promise that resolves to the authorization with the signature\n */\n signAuthorization: (\n unsignedAuthorization: Authorization<number, false>\n ) => Promise<Authorization<number, true>> = SignerLogger.profiled(\n \"BaseAlchemySigner.signAuthorization\",\n async (unsignedAuthorization) => {\n const hashedAuthorization = hashAuthorization(unsignedAuthorization);\n const signedAuthorizationHex = await this.inner.signRawMessage(\n hashedAuthorization\n );\n const signature = this.unpackSignRawMessageBytes(signedAuthorizationHex);\n return { ...unsignedAuthorization, ...signature };\n }\n );\n\n /**\n * Gets the current MFA status\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const mfaStatus = signer.getMfaStatus();\n * if (mfaStatus === AlchemyMfaStatus.REQUIRED) {\n * // Handle MFA requirement\n * }\n * ```\n *\n * @returns {{ mfaRequired: boolean; mfaFactorId?: string }} The current MFA status\n */\n getMfaStatus = (): {\n mfaRequired: boolean;\n mfaFactorId?: string;\n } => {\n return this.store.getState().mfaStatus;\n };\n\n private unpackSignRawMessageBytes = (\n hex: `0x${string}`\n ): UnpackedSignature => {\n return {\n r: takeBytes(hex, { count: 32 }),\n s: takeBytes(hex, { count: 32, offset: 32 }),\n v: BigInt(takeBytes(hex, { count: 1, offset: 64 })),\n };\n };\n\n /**\n * Unauthenticated call to look up a user's organizationId by email\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.getUser(\"foo@mail.com\");\n * ```\n *\n * @param {string} email the email to lookup\n * @returns {Promise<{orgId: string}>} the organization id for the user if they exist\n */\n getUser: (email: string) => Promise<{ orgId: string } | null> =\n SignerLogger.profiled(\"BaseAlchemySigner.getUser\", async (email) => {\n const result = await this.inner.lookupUserByEmail(email);\n\n if (result.orgId == null) {\n return null;\n }\n\n return {\n orgId: result.orgId,\n };\n });\n\n /**\n * Adds a passkey to the user's account\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.addPasskey()\n * ```\n *\n * @param {CredentialCreationOptions | undefined} params optional parameters for the passkey creation\n * @returns {Promise<string[]>} an array of the authenticator ids added to the user\n */\n addPasskey: (params?: CredentialCreationOptions) => Promise<string[]> =\n SignerLogger.profiled(\"BaseAlchemySigner.addPasskey\", async (params) => {\n return this.inner.addPasskey(params ?? {});\n });\n\n getPasskeyStatus: () => Promise<{ isPasskeyAdded: boolean }> =\n SignerLogger.profiled(\"BaseAlchemySigner.getPasskeyStatus\", async () => {\n return this.inner.getPasskeyStatus();\n });\n\n /**\n * Used to export the wallet for a given user\n * If the user is authenticated with an Email, this will return a seed phrase\n * If the user is authenticated with a Passkey, this will return a private key\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * // the params passed to this are different based on the specific signer\n * const result = signer.exportWallet()\n * ```\n *\n * @param {unknown} params export wallet parameters\n * @returns {boolean} true if the wallet was exported successfully\n */\n exportWallet: (\n params: Parameters<(typeof this.inner)[\"exportWallet\"]>[0]\n ) => Promise<boolean> = async (params) => {\n return this.inner.exportWallet(params);\n };\n\n /**\n * This method lets you adapt your AlchemySigner to a viem LocalAccount, which\n * will let you use the signer as an EOA directly.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const account = signer.toViemAccount();\n * ```\n *\n * @throws if your signer is not authenticated\n * @returns {LocalAccount} a LocalAccount object that can be used with viem's wallet client\n */\n toViemAccount = (): LocalAccount => {\n // if we want this method to be synchronous, then we need to do this check here\n // otherwise we can use the sessionManager to get the user\n if (!this.inner.getUser()) {\n throw new NotAuthenticatedError();\n }\n\n return toAccount({\n address: this.inner.getUser()!.address,\n signMessage: (msg) => this.signMessage(msg.message),\n signTypedData: <\n const typedData extends TypedData | Record<string, unknown>,\n primaryType extends keyof typedData | \"EIP712Domain\" = keyof typedData\n >(\n typedDataDefinition: TypedDataDefinition<typedData, primaryType>\n ) => this.signTypedData<typedData, primaryType>(typedDataDefinition),\n signTransaction: this.signTransaction,\n });\n };\n\n /**\n * Creates a new instance of `SolanaSigner` using the provided inner value.\n * This requires the signer to be authenticated first\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const solanaSigner = signer.toSolanaSigner();\n * ```\n *\n * @returns {SolanaSigner} A new instance of `SolanaSigner`\n */\n toSolanaSigner = (): SolanaSigner => {\n if (!this.inner.getUser()) {\n throw new NotAuthenticatedError();\n }\n\n return new SolanaSigner(this.inner);\n };\n\n private authenticateWithEmail = async (\n params: Extract<AuthParams, { type: \"email\" }>\n ): Promise<User> => {\n if (\"bundle\" in params) {\n return this.completeEmailAuth(params);\n }\n\n const { orgId, otpId, isNewUser } = await this.initOrCreateEmailUser(\n params.email,\n params.emailMode,\n params.multiFactors,\n params.redirectParams\n );\n\n this.setAwaitingEmailAuth({ orgId, otpId, isNewUser });\n\n // Clear the auth linking status if the email has changed. This would mean\n // that the previously initiated social login is not associated with the\n // email which is now being used to login.\n const { authLinkingStatus } = this.store.getState();\n if (authLinkingStatus && authLinkingStatus.email !== params.email) {\n this.store.setState({ authLinkingStatus: undefined });\n }\n\n // We wait for the session manager to emit a connected event if\n // cross tab sessions are permitted\n return this.waitForConnected();\n };\n\n private authenticateWithPasskey = async (\n args: Extract<AuthParams, { type: \"passkey\" }>\n ): Promise<User> => {\n let user: User;\n const shouldCreateNew = async () => {\n if (\"email\" in args) {\n const existingUser = await this.getUser(args.email);\n return existingUser == null;\n }\n\n return args.createNew;\n };\n\n if (await shouldCreateNew()) {\n const result = await this.inner.createAccount(\n args as Extract<\n AuthParams,\n { type: \"passkey\" } & ({ email: string } | { createNew: true })\n >\n );\n // account creation for passkeys returns the whoami response so we don't have to\n // call it again after signup\n user = {\n address: result.address!,\n userId: result.userId!,\n orgId: result.orgId,\n };\n } else {\n user = await this.inner.lookupUserWithPasskey();\n if (!user) {\n this.store.setState({\n status: AlchemySignerStatus.DISCONNECTED,\n });\n throw new Error(\"No user found\");\n }\n }\n\n return user;\n };\n\n private authenticateWithOauth = async (\n args: Extract<AuthParams, { type: \"oauth\" }>\n ): Promise<User> => {\n this.store.setState({ authLinkingStatus: undefined });\n const params: OauthParams = {\n ...args,\n expirationSeconds: this.getExpirationSeconds(),\n };\n if (params.mode === \"redirect\") {\n return this.inner.oauthWithRedirect(params);\n }\n const result = await this.inner.oauthWithPopup(params);\n if (!isAuthLinkingPrompt(result)) {\n return result;\n }\n this.setAuthLinkingPrompt(result);\n return this.waitForConnected();\n };\n\n private authenticateWithOtp = async (\n args: Extract<AuthParams, { type: \"otp\" }>\n ): Promise<User> => {\n const tempSession = this.sessionManager.getTemporarySession();\n const { orgId, isNewUser } = tempSession ?? {};\n const { otpId } = this.store.getState();\n if (!orgId) {\n throw new Error(\"orgId not found in session\");\n }\n if (!otpId) {\n throw new Error(\"otpId not found in session\");\n }\n\n const response = await this.inner.submitOtpCode({\n orgId,\n otpId,\n otpCode: args.otpCode,\n expirationSeconds: this.getExpirationSeconds(),\n multiFactors: args.multiFactors,\n });\n\n if (response.mfaRequired) {\n this.handleMfaRequired(response.encryptedPayload, response.multiFactors);\n return this.waitForConnected();\n }\n\n const user = await this.inner.completeAuthWithBundle({\n bundle: response.bundle,\n orgId,\n connectedEventName: \"connectedOtp\",\n authenticatingType: \"otp\",\n });\n\n this.emitNewUserEvent(isNewUser);\n if (tempSession) {\n this.sessionManager.setTemporarySession({\n ...tempSession,\n isNewUser: false,\n });\n }\n\n const { authLinkingStatus } = this.store.getState();\n if (authLinkingStatus) {\n (async () => {\n this.inner.addOauthProvider({\n providerName: authLinkingStatus.providerName,\n oidcToken: authLinkingStatus.idToken,\n });\n })();\n }\n\n return user;\n };\n\n private setAwaitingEmailAuth = ({\n orgId,\n otpId,\n isNewUser,\n }: {\n orgId: string;\n otpId?: string;\n isNewUser?: boolean;\n }): void => {\n this.sessionManager.setTemporarySession({\n orgId,\n isNewUser,\n });\n this.store.setState({\n status: AlchemySignerStatus.AWAITING_EMAIL_AUTH,\n otpId,\n error: null,\n });\n };\n\n private handleOauthReturn = ({\n bundle,\n orgId,\n idToken,\n isNewUser,\n }: Extract<AuthParams, { type: \"oauthReturn\" }>): Promise<User> => {\n const user = this.inner.completeAuthWithBundle({\n bundle,\n orgId,\n connectedEventName: \"connectedOauth\",\n authenticatingType: \"oauth\",\n idToken,\n });\n\n this.emitNewUserEvent(isNewUser);\n\n return user;\n };\n\n private handleMfaRequired(\n encryptedPayload: string,\n multiFactors: MfaFactor[]\n ) {\n // Store complete MFA context in the temporary session\n const tempSession = this.sessionManager.getTemporarySession();\n if (tempSession) {\n this.sessionManager.setTemporarySession({\n ...tempSession,\n encryptedPayload,\n mfaFactorId: multiFactors?.[0]?.multiFactorId,\n });\n }\n\n // Keep minimal state in the store for UI updates\n this.store.setState({\n status: AlchemySignerStatus.AWAITING_MFA_AUTH,\n error: null,\n mfaStatus: {\n mfaRequired: true,\n mfaFactorId: multiFactors?.[0]?.multiFactorId,\n },\n });\n }\n\n private getExpirationSeconds = () =>\n Math.floor(this.sessionManager.expirationTimeMs / 1000);\n\n private registerListeners = () => {\n // Declare listeners in an object to typecheck that every event type is\n // handled.\n const listeners: SessionManagerEvents = {\n connected: (session) => {\n this.store.setState({\n user: session.user,\n status: AlchemySignerStatus.CONNECTED,\n error: null,\n });\n },\n disconnected: () => {\n this.store.setState({\n user: null,\n status: AlchemySignerStatus.DISCONNECTED,\n });\n },\n initialized: () => {\n this.store.setState((state) => ({\n status: state.user\n ? AlchemySignerStatus.CONNECTED\n : AlchemySignerStatus.DISCONNECTED,\n ...(state.user ? { error: null } : undefined),\n }));\n },\n };\n\n for (const [event, listener] of Object.entries(listeners)) {\n this.sessionManager.on(event as keyof SessionManagerEvents, listener);\n }\n\n this.inner.on(\"authenticating\", ({ type }) => {\n const status = (() => {\n switch (type) {\n case \"email\":\n return AlchemySignerStatus.AUTHENTICATING_EMAIL;\n case \"passkey\":\n return AlchemySignerStatus.AUTHENTICATING_PASSKEY;\n case \"oauth\":\n return AlchemySignerStatus.AUTHENTICATING_OAUTH;\n case \"otp\":\n case \"otpVerify\":\n return AlchemySignerStatus.AWAITING_OTP_AUTH;\n default:\n assertNever(type, \"unhandled authenticating type\");\n }\n })();\n\n // trigger new user event on signer from client\n this.inner.on(\"newUserSignup\", () => {\n this.emitNewUserEvent(true);\n });\n\n this.store.setState({\n status,\n error: null,\n });\n });\n };\n\n private emitNewUserEvent = (isNewUser?: boolean) => {\n // assumes that if isNewUser is undefined it is a returning user\n if (isNewUser) this.store.setState({ isNewUser });\n };\n\n private async initOrCreateEmailUser(\n email: string,\n emailMode?: EmailType,\n multiFactors?: VerifyMfaParams[],\n redirectParams?: URLSearchParams\n ): Promise<{\n orgId: string;\n otpId?: string;\n isNewUser: boolean;\n }> {\n const existingUser = await this.getUser(email);\n const expirationSeconds = this.getExpirationSeconds();\n\n if (existingUser) {\n const { orgId, otpId } = await this.inner.initEmailAuth({\n email: email,\n emailMode: emailMode,\n expirationSeconds,\n redirectParams: redirectParams,\n multiFactors,\n });\n return {\n orgId,\n otpId,\n isNewUser: false,\n };\n }\n\n const { orgId, otpId } = await this.inner.createAccount({\n type: \"email\",\n email,\n emailMode,\n expirationSeconds,\n redirectParams,\n });\n return {\n orgId,\n otpId,\n isNewUser: true,\n };\n }\n\n private async completeEmailAuth(\n params: Extract<AuthParams, { type: \"email\"; bundle: string }>\n ): Promise<User> {\n const temporarySession = params.orgId\n ? { orgId: params.orgId }\n : this.sessionManager.getTemporarySession();\n\n if (!temporarySession) {\n this.store.setState({ status: AlchemySignerStatus.DISCONNECTED });\n throw new Error(\"Could not find email auth init session!\");\n }\n\n const user = await this.inner.completeAuthWithBundle({\n bundle: params.bundle,\n orgId: temporarySession.orgId,\n connectedEventName: \"connectedEmail\",\n authenticatingType: \"email\",\n });\n\n // fire new user event\n this.emitNewUserEvent(params.isNewUser);\n\n return user;\n }\n\n /**\n * Retrieves the list of MFA factors configured for the current user.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const { multiFactors } = await signer.getMfaFactors();\n * ```\n *\n * @throws {NotAuthenticatedError} If no user is authenticated\n * @returns {Promise<{ multiFactors: Array<MfaFactor> }>} A promise that resolves to an array of configured MFA factors\n */\n getMfaFactors: () => Promise<{ multiFactors: MfaFactor[] }> =\n SignerLogger.profiled(\"BaseAlchemySigner.getMfaFactors\", async () => {\n return this.inner.getMfaFactors();\n });\n\n /**\n * Initiates the setup of a new MFA factor for the current user.\n * The factor will need to be verified using verifyMfa before it becomes active.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.addMfa({ multiFactorType: \"totp\" });\n * // Result contains multiFactorTotpUrl to display as QR code\n * ```\n *\n * @param {AddMfaParams} params The parameters required to enable a new MFA factor\n * @throws {NotAuthenticatedError} If no user is authenticated\n * @returns {Promise<AddMfaResult>} A promise that resolves to the factor setup information\n */\n addMfa: (params: AddMfaParams) => Promise<AddMfaResult> =\n SignerLogger.profiled(\"BaseAlchemySigner.addMfa\", async (params) => {\n return this.inner.addMfa(params);\n });\n\n /**\n * Verifies a newly created MFA factor to complete the setup process.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.verifyMfa({\n * multiFactorId: \"factor-id\",\n * multiFactorCode: \"123456\" // 6-digit code from authenticator app\n * });\n * ```\n *\n * @param {VerifyMfaParams} params The parameters required to verify the MFA factor\n * @throws {NotAuthenticatedError} If no user is authenticated\n * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors\n */\n verifyMfa: (\n params: VerifyMfaParams\n ) => Promise<{ multiFactors: MfaFactor[] }> = SignerLogger.profiled(\n \"BaseAlchemySigner.verifyMfa\",\n async (params) => {\n return this.inner.verifyMfa(params);\n }\n );\n\n /**\n * Removes existing MFA factors by their IDs.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * const result = await signer.removeMfa({\n * multiFactorIds: [\"factor-id-1\", \"factor-id-2\"]\n * });\n * ```\n *\n * @param {RemoveMfaParams} params The parameters specifying which factors to disable\n * @throws {NotAuthenticatedError} If no user is authenticated\n * @returns {Promise<{ multiFactors: MfaFactor[] }>} A promise that resolves to the updated list of MFA factors\n */\n removeMfa: (\n params: RemoveMfaParams\n ) => Promise<{ multiFactors: MfaFactor[] }> = SignerLogger.profiled(\n \"BaseAlchemySigner.removeMfa\",\n async (params) => {\n return this.inner.removeMfa(params);\n }\n );\n\n /**\n * Validates MFA factors that were required during authentication.\n * This function should be called after MFA is required and the user has provided their MFA code.\n * It completes the authentication process by validating the MFA factors and completing the auth bundle.\n *\n * @example\n * ```ts\n * import { AlchemyWebSigner } from \"@account-kit/signer\";\n *\n * const signer = new AlchemyWebSigner({\n * client: {\n * connection: {\n * rpcUrl: \"/api/rpc\",\n * },\n * iframeConfig: {\n * iframeContainerId: \"alchemy-signer-iframe-container\",\n * },\n * },\n * });\n *\n * // After MFA is required and user provides code\n * const user = await signer.validateMultiFactors({\n * multiFactorCode: \"123456\", // 6-digit code from authenticator app\n * multiFactorId: \"factor-id\"\n * });\n * ```\n *\n * @param {ValidateMultiFactorsArgs} params - Parameters for validating MFA factors\n * @throws {Error} If there is no pending MFA context or if orgId is not found\n * @returns {Promise<User>} A promise that resolves to the authenticated user\n */\n public async validateMultiFactors(\n params: ValidateMultiFactorsArgs\n ): Promise<User> {\n // Get MFA context from temporary session\n const tempSession = this.sessionManager.getTemporarySession();\n if (\n !tempSession?.orgId ||\n !tempSession.encryptedPayload ||\n !tempSession.mfaFactorId\n ) {\n throw new Error(\n \"No pending MFA context found. Call submitOtpCode() first.\"\n );\n }\n\n if (\n params.multiFactorId &&\n tempSession.mfaFactorId !== params.multiFactorId\n ) {\n throw new Error(\"MFA factor ID mismatch\");\n }\n\n // Call the low-level client\n const { bundle } = await this.inner.validateMultiFactors({\n encryptedPayload: tempSession.encryptedPayload,\n multiFactors: [\n {\n multiFactorId: tempSession.mfaFactorId,\n multiFactorCode: params.multiFactorCode,\n },\n ],\n });\n\n // Complete the authentication\n const user = await this.inner.completeAuthWithBundle({\n bundle,\n orgId: tempSession.orgId,\n connectedEventName: \"connectedOtp\",\n authenticatingType: \"otp\",\n });\n\n // Remove MFA data from temporary session\n this.sessionManager.setTemporarySession({\n ...tempSession,\n encryptedPayload: undefined,\n mfaFactorId: undefined,\n });\n\n // Update UI state\n this.store.setState({\n mfaStatus: {\n mfaRequired: false,\n mfaFactorId: undefined,\n },\n });\n\n return user;\n }\n\n protected initConfig = async (): Promise<SignerConfig> => {\n this.config = this.fetchConfig();\n return this.config;\n };\n\n /**\n * Returns the signer configuration while fetching it if it's not already initialized.\n *\n * @returns {Promise<SignerConfig>} A promise that resolves to the signer configuration\n */\n public getConfig = async (): Promise<SignerConfig> => {\n if (!this.config) {\n return this.initConfig();\n }\n\n return this.config;\n };\n\n protected fetchConfig = async (): Promise<SignerConfig> => {\n return this.inner.request(\"/v1/signer-config\", {});\n };\n\n private setAuthLinkingPrompt = (prompt: AuthLinkingPrompt) => {\n this.setAwaitingEmailAuth({\n orgId: prompt.orgId,\n otpId: prompt.otpId,\n isNewUser: false,\n });\n this.store.setState({\n authLinkingStatus: {\n email: prompt.email,\n providerName: prompt.providerName,\n idToken: prompt.idToken,\n },\n });\n };\n\n private waitForConnected = (): Promise<User> => {\n return new Promise<User>((resolve) => {\n const removeListener = this.sessionManager.on(\"connected\", (session) => {\n resolve(session.user);\n removeListener();\n });\n });\n };\n}\n\nfunction toErrorInfo(error: unknown): ErrorInfo {\n return error instanceof Error\n ? { name: error.name, message: error.message }\n : { name: \"Error\", message: \"Unknown error\" };\n}\n\n// eslint-disable-next-line jsdoc/require-param, jsdoc/require-returns\n/**\n * Zustand's `fireImmediately` option calls the listener before\n * `store.subscribe` has returned, which breaks listeners which call\n * unsubscribe, e.g.\n *\n * ```ts\n * const unsubscribe = store.subscribe(\n * selector,\n * (update) => {\n * handleUpdate(update);\n * unsubscribe();\n * },\n * { fireImmediately: true },\n * )\n * ```\n *\n * since `unsubscribe` is still undefined at the time the listener is called. To\n * prevent this, if the listener triggers before `subscribe` has returned, delay\n * the callback to a later run of the event loop.\n */\nfunction subscribeWithDelayedFireImmediately<T>(\n store: InternalStore,\n selector: (state: AlchemySignerStore) => T,\n listener: (selectedState: T, previousSelectedState: T) => void\n): () => void {\n let subscribeHasReturned = false;\n const unsubscribe = store.subscribe(\n selector,\n (...args) => {\n if (subscribeHasReturned) {\n listener(...args);\n } else {\n setTimeout(() => listener(...args), 0);\n }\n },\n { fireImmediately: true }\n );\n subscribeHasReturned = true;\n return unsubscribe;\n}\n\nfunction isAuthLinkingPrompt(result: unknown): result is AuthLinkingPrompt {\n return (\n (result as AuthLinkingPrompt)?.status ===\n \"ACCOUNT_LINKING_CONFIRMATION_REQUIRED\"\n );\n}\n"]}
|