@account-kit/signer 4.0.0-beta.1 → 4.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/base.d.ts +42 -5
- package/dist/esm/base.js +186 -29
- package/dist/esm/base.js.map +1 -1
- package/dist/esm/client/base.d.ts +22 -4
- package/dist/esm/client/base.js +36 -2
- package/dist/esm/client/base.js.map +1 -1
- package/dist/esm/client/index.d.ts +108 -7
- package/dist/esm/client/index.js +282 -14
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/client/types.d.ts +31 -1
- package/dist/esm/client/types.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/metrics.d.ts +17 -0
- package/dist/esm/metrics.js +7 -0
- package/dist/esm/metrics.js.map +1 -0
- package/dist/esm/oauth.d.ts +19 -0
- package/dist/esm/oauth.js +26 -0
- package/dist/esm/oauth.js.map +1 -0
- package/dist/esm/session/manager.d.ts +3 -2
- package/dist/esm/session/manager.js +29 -15
- package/dist/esm/session/manager.js.map +1 -1
- package/dist/esm/session/types.d.ts +1 -1
- package/dist/esm/session/types.js.map +1 -1
- package/dist/esm/signer.d.ts +52 -7
- package/dist/esm/signer.js +46 -3
- package/dist/esm/signer.js.map +1 -1
- package/dist/esm/types.d.ts +8 -1
- package/dist/esm/types.js +3 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/typeAssertions.d.ts +1 -0
- package/dist/esm/utils/typeAssertions.js +4 -0
- package/dist/esm/utils/typeAssertions.js.map +1 -0
- 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 +42 -5
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/client/base.d.ts +22 -4
- package/dist/types/client/base.d.ts.map +1 -1
- package/dist/types/client/index.d.ts +108 -7
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/client/types.d.ts +31 -1
- package/dist/types/client/types.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/metrics.d.ts +18 -0
- package/dist/types/metrics.d.ts.map +1 -0
- package/dist/types/oauth.d.ts +20 -0
- package/dist/types/oauth.d.ts.map +1 -0
- package/dist/types/session/manager.d.ts +3 -2
- package/dist/types/session/manager.d.ts.map +1 -1
- package/dist/types/session/types.d.ts +1 -1
- package/dist/types/session/types.d.ts.map +1 -1
- package/dist/types/signer.d.ts +52 -7
- package/dist/types/signer.d.ts.map +1 -1
- package/dist/types/types.d.ts +8 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/typeAssertions.d.ts +2 -0
- package/dist/types/utils/typeAssertions.d.ts.map +1 -0
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +6 -5
- package/src/base.ts +260 -65
- package/src/client/base.ts +49 -4
- package/src/client/index.ts +317 -20
- package/src/client/types.ts +33 -1
- package/src/index.ts +5 -1
- package/src/metrics.ts +23 -0
- package/src/oauth.ts +36 -0
- package/src/session/manager.ts +46 -19
- package/src/session/types.ts +1 -1
- package/src/signer.ts +91 -4
- package/src/types.ts +9 -1
- package/src/utils/typeAssertions.ts +3 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type SignerEventsSchema = [
|
|
2
|
+
{
|
|
3
|
+
EventName: "signer_authnticate";
|
|
4
|
+
EventData: {
|
|
5
|
+
authType: "email" | "passkey_anon" | "passkey_email" | "oauthReturn";
|
|
6
|
+
provider?: never;
|
|
7
|
+
} | {
|
|
8
|
+
authType: "oauth";
|
|
9
|
+
provider: string;
|
|
10
|
+
};
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
EventName: "signer_sign_message";
|
|
14
|
+
EventData: undefined;
|
|
15
|
+
}
|
|
16
|
+
];
|
|
17
|
+
export declare const SignerLogger: import("@account-kit/logging").EventLogger<SignerEventsSchema>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAkBvC,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAqB;IAC3D,OAAO,EAAE,qBAAqB;IAC9B,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC","sourcesContent":["import { createLogger } from \"@account-kit/logging\";\nimport { VERSION } from \"./version.js\";\n\nexport type SignerEventsSchema = [\n {\n EventName: \"signer_authnticate\";\n EventData:\n | {\n authType: \"email\" | \"passkey_anon\" | \"passkey_email\" | \"oauthReturn\";\n provider?: never;\n }\n | { authType: \"oauth\"; provider: string };\n },\n {\n EventName: \"signer_sign_message\";\n EventData: undefined;\n }\n];\n\nexport const SignerLogger = createLogger<SignerEventsSchema>({\n package: \"@account-kit/signer\",\n version: VERSION,\n});\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { KnownAuthProvider } from "./signer";
|
|
2
|
+
/**
|
|
3
|
+
* Turnkey requires the nonce in the id token to be in this format.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} turnkeyPublicKey key from a Turnkey iframe
|
|
6
|
+
* @returns {string} nonce to be used in OIDC
|
|
7
|
+
*/
|
|
8
|
+
export declare function getOauthNonce(turnkeyPublicKey: string): string;
|
|
9
|
+
export type ScopeAndClaims = {
|
|
10
|
+
scope: string;
|
|
11
|
+
claims?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Returns the default scope and claims when using a known auth provider
|
|
15
|
+
*
|
|
16
|
+
* @param {string} knownAuthProviderId id of a known auth provider, e.g. "google"
|
|
17
|
+
* @returns {ScopeAndClaims | undefined} default scope and claims
|
|
18
|
+
*/
|
|
19
|
+
export declare function getDefaultScopeAndClaims(knownAuthProviderId: KnownAuthProvider): ScopeAndClaims | undefined;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { sha256 } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* Turnkey requires the nonce in the id token to be in this format.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} turnkeyPublicKey key from a Turnkey iframe
|
|
6
|
+
* @returns {string} nonce to be used in OIDC
|
|
7
|
+
*/
|
|
8
|
+
export function getOauthNonce(turnkeyPublicKey) {
|
|
9
|
+
return sha256(new TextEncoder().encode(turnkeyPublicKey)).slice(2);
|
|
10
|
+
}
|
|
11
|
+
const DEFAULT_SCOPE_AND_CLAIMS = {
|
|
12
|
+
google: { scope: "openid email" },
|
|
13
|
+
apple: { scope: "openid email" },
|
|
14
|
+
facebook: { scope: "openid email" },
|
|
15
|
+
auth0: { scope: "openid email" },
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Returns the default scope and claims when using a known auth provider
|
|
19
|
+
*
|
|
20
|
+
* @param {string} knownAuthProviderId id of a known auth provider, e.g. "google"
|
|
21
|
+
* @returns {ScopeAndClaims | undefined} default scope and claims
|
|
22
|
+
*/
|
|
23
|
+
export function getDefaultScopeAndClaims(knownAuthProviderId) {
|
|
24
|
+
return DEFAULT_SCOPE_AND_CLAIMS[knownAuthProviderId];
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=oauth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAG9B;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,gBAAwB;IACpD,OAAO,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACrE,CAAC;AAOD,MAAM,wBAAwB,GAA8C;IAC1E,MAAM,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE;IACjC,KAAK,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE;IAChC,QAAQ,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE;IACnC,KAAK,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE;CACjC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CACtC,mBAAsC;IAEtC,OAAO,wBAAwB,CAAC,mBAAmB,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import { sha256 } from \"viem\";\nimport type { KnownAuthProvider } from \"./signer\";\n\n/**\n * Turnkey requires the nonce in the id token to be in this format.\n *\n * @param {string} turnkeyPublicKey key from a Turnkey iframe\n * @returns {string} nonce to be used in OIDC\n */\nexport function getOauthNonce(turnkeyPublicKey: string): string {\n return sha256(new TextEncoder().encode(turnkeyPublicKey)).slice(2);\n}\n\nexport type ScopeAndClaims = {\n scope: string;\n claims?: string;\n};\n\nconst DEFAULT_SCOPE_AND_CLAIMS: Record<KnownAuthProvider, ScopeAndClaims> = {\n google: { scope: \"openid email\" },\n apple: { scope: \"openid email\" },\n facebook: { scope: \"openid email\" },\n auth0: { scope: \"openid email\" },\n};\n\n/**\n * Returns the default scope and claims when using a known auth provider\n *\n * @param {string} knownAuthProviderId id of a known auth provider, e.g. \"google\"\n * @returns {ScopeAndClaims | undefined} default scope and claims\n */\nexport function getDefaultScopeAndClaims(\n knownAuthProviderId: KnownAuthProvider\n): ScopeAndClaims | undefined {\n return DEFAULT_SCOPE_AND_CLAIMS[knownAuthProviderId];\n}\n"]}
|
|
@@ -10,14 +10,14 @@ export declare const SessionManagerParamsSchema: z.ZodObject<{
|
|
|
10
10
|
expirationTimeMs: z.ZodDefault<z.ZodNumber>;
|
|
11
11
|
client: z.ZodType<BaseSignerClient<unknown>, z.ZodTypeDef, BaseSignerClient<unknown>>;
|
|
12
12
|
}, "strip", z.ZodTypeAny, {
|
|
13
|
+
storage: (Storage | "localStorage" | "sessionStorage") & (Storage | "localStorage" | "sessionStorage" | undefined);
|
|
13
14
|
sessionKey: string;
|
|
14
|
-
storage: ("localStorage" | "sessionStorage" | Storage) & ("localStorage" | "sessionStorage" | Storage | undefined);
|
|
15
15
|
expirationTimeMs: number;
|
|
16
16
|
client: BaseSignerClient<unknown>;
|
|
17
17
|
}, {
|
|
18
18
|
client: BaseSignerClient<unknown>;
|
|
19
19
|
sessionKey?: string | undefined;
|
|
20
|
-
storage?: "localStorage" | "sessionStorage" |
|
|
20
|
+
storage?: Storage | "localStorage" | "sessionStorage" | undefined;
|
|
21
21
|
expirationTimeMs?: number | undefined;
|
|
22
22
|
}>;
|
|
23
23
|
export type SessionManagerParams = z.input<typeof SessionManagerParamsSchema>;
|
|
@@ -42,4 +42,5 @@ export declare class SessionManager {
|
|
|
42
42
|
initialize(): void;
|
|
43
43
|
private getInitialState;
|
|
44
44
|
private registerEventListeners;
|
|
45
|
+
private setSessionWithUserAndBundle;
|
|
45
46
|
}
|
|
@@ -2,6 +2,7 @@ import EventEmitter from "eventemitter3";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { createJSONStorage, persist, subscribeWithSelector, } from "zustand/middleware";
|
|
4
4
|
import { createStore } from "zustand/vanilla";
|
|
5
|
+
import { assertNever } from "../utils/typeAssertions.js";
|
|
5
6
|
export const DEFAULT_SESSION_MS = 15 * 60 * 1000; // 15 minutes
|
|
6
7
|
export const SessionManagerParamsSchema = z.object({
|
|
7
8
|
sessionKey: z.string().default("alchemy-signer-session"),
|
|
@@ -57,11 +58,17 @@ export class SessionManager {
|
|
|
57
58
|
return null;
|
|
58
59
|
}
|
|
59
60
|
switch (existingSession.type) {
|
|
60
|
-
case "email":
|
|
61
|
+
case "email":
|
|
62
|
+
case "oauth": {
|
|
63
|
+
const connectedEventName = existingSession.type === "email"
|
|
64
|
+
? "connectedEmail"
|
|
65
|
+
: "connectedOauth";
|
|
61
66
|
const result = await this.client
|
|
62
|
-
.
|
|
67
|
+
.completeAuthWithBundle({
|
|
63
68
|
bundle: existingSession.bundle,
|
|
64
69
|
orgId: existingSession.user.orgId,
|
|
70
|
+
authenticatingType: existingSession.type,
|
|
71
|
+
connectedEventName,
|
|
65
72
|
})
|
|
66
73
|
.catch((e) => {
|
|
67
74
|
console.warn("Failed to load user from session", e);
|
|
@@ -81,7 +88,7 @@ export class SessionManager {
|
|
|
81
88
|
return this.client.lookupUserWithPasskey(existingSession.user);
|
|
82
89
|
}
|
|
83
90
|
default:
|
|
84
|
-
|
|
91
|
+
assertNever(existingSession, `Unknown session type: ${existingSession.type}`);
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
94
|
});
|
|
@@ -174,18 +181,7 @@ export class SessionManager {
|
|
|
174
181
|
}
|
|
175
182
|
});
|
|
176
183
|
this.client.on("disconnected", () => this.clearSession());
|
|
177
|
-
this.client.on("connectedEmail", (user, bundle) => {
|
|
178
|
-
const existingSession = this.getSession();
|
|
179
|
-
if (existingSession != null &&
|
|
180
|
-
existingSession.type === "email" &&
|
|
181
|
-
existingSession.user.userId === user.userId &&
|
|
182
|
-
// if the bundle is different, then we've refreshed the session
|
|
183
|
-
// so we need to reset the session
|
|
184
|
-
existingSession.bundle === bundle) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
this.setSession({ type: "email", user, bundle });
|
|
188
|
-
});
|
|
184
|
+
this.client.on("connectedEmail", (user, bundle) => this.setSessionWithUserAndBundle({ type: "email", user, bundle }));
|
|
189
185
|
this.client.on("connectedPasskey", (user) => {
|
|
190
186
|
const existingSession = this.getSession();
|
|
191
187
|
if (existingSession != null &&
|
|
@@ -195,6 +191,7 @@ export class SessionManager {
|
|
|
195
191
|
}
|
|
196
192
|
this.setSession({ type: "passkey", user });
|
|
197
193
|
});
|
|
194
|
+
this.client.on("connectedOauth", (user, bundle) => this.setSessionWithUserAndBundle({ type: "oauth", user, bundle }));
|
|
198
195
|
// sync local state if persisted state has changed from another tab
|
|
199
196
|
window.addEventListener("focus", () => {
|
|
200
197
|
this.store.persist.rehydrate();
|
|
@@ -202,6 +199,23 @@ export class SessionManager {
|
|
|
202
199
|
});
|
|
203
200
|
}
|
|
204
201
|
});
|
|
202
|
+
Object.defineProperty(this, "setSessionWithUserAndBundle", {
|
|
203
|
+
enumerable: true,
|
|
204
|
+
configurable: true,
|
|
205
|
+
writable: true,
|
|
206
|
+
value: ({ type, user, bundle, }) => {
|
|
207
|
+
const existingSession = this.getSession();
|
|
208
|
+
if (existingSession != null &&
|
|
209
|
+
existingSession.type === type &&
|
|
210
|
+
existingSession.user.userId === user.userId &&
|
|
211
|
+
// if the bundle is different, then we've refreshed the session
|
|
212
|
+
// so we need to reset the session
|
|
213
|
+
existingSession.bundle === bundle) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
this.setSession({ type, user, bundle });
|
|
217
|
+
}
|
|
218
|
+
});
|
|
205
219
|
const { sessionKey, storage: storageType, expirationTimeMs, client, } = SessionManagerParamsSchema.parse(params);
|
|
206
220
|
this.sessionKey = sessionKey;
|
|
207
221
|
const storage = typeof storageType === "string"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/session/manager.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from \"eventemitter3\";\nimport { z } from \"zod\";\nimport {\n createJSONStorage,\n persist,\n subscribeWithSelector,\n} from \"zustand/middleware\";\nimport { createStore, type Mutate, type StoreApi } from \"zustand/vanilla\";\nimport type { BaseSignerClient } from \"../client/base\";\nimport type { User } from \"../client/types\";\nimport type { Session, SessionManagerEvents } from \"./types\";\n\nexport const DEFAULT_SESSION_MS = 15 * 60 * 1000; // 15 minutes\n\nexport const SessionManagerParamsSchema = z.object({\n sessionKey: z.string().default(\"alchemy-signer-session\"),\n storage: z\n .enum([\"localStorage\", \"sessionStorage\"])\n .default(\"localStorage\")\n .or(z.custom<Storage>()),\n expirationTimeMs: z\n .number()\n .default(DEFAULT_SESSION_MS)\n .describe(\n \"The time in milliseconds that a session should last before expiring [default: 15 minutes]\"\n ),\n client: z.custom<BaseSignerClient>(),\n});\n\nexport type SessionManagerParams = z.input<typeof SessionManagerParamsSchema>;\n\ntype SessionState = {\n session: Session | null;\n};\n\ntype Store = Mutate<\n StoreApi<SessionState>,\n [[\"zustand/subscribeWithSelector\", never], [\"zustand/persist\", SessionState]]\n>;\n\nexport class SessionManager {\n private sessionKey: string;\n private client: BaseSignerClient;\n private eventEmitter: EventEmitter<SessionManagerEvents>;\n readonly expirationTimeMs: number;\n private store: Store;\n\n constructor(params: SessionManagerParams) {\n const {\n sessionKey,\n storage: storageType,\n expirationTimeMs,\n client,\n } = SessionManagerParamsSchema.parse(params);\n this.sessionKey = sessionKey;\n const storage =\n typeof storageType === \"string\"\n ? storageType === \"localStorage\"\n ? localStorage\n : sessionStorage\n : storageType;\n this.expirationTimeMs = expirationTimeMs;\n this.client = client;\n this.eventEmitter = new EventEmitter<SessionManagerEvents>();\n\n this.store = createStore(\n subscribeWithSelector(\n persist(this.getInitialState, {\n name: this.sessionKey,\n storage: createJSONStorage<SessionState>(() => storage),\n })\n )\n );\n\n this.registerEventListeners();\n }\n\n public getSessionUser = async (): Promise<User | null> => {\n const existingSession = this.getSession();\n if (existingSession == null) {\n return null;\n }\n\n switch (existingSession.type) {\n case \"email\": {\n const result = await this.client\n .completeEmailAuth({\n bundle: existingSession.bundle,\n orgId: existingSession.user.orgId,\n })\n .catch((e) => {\n console.warn(\"Failed to load user from session\", e);\n return null;\n });\n\n if (!result) {\n this.clearSession();\n return null;\n }\n\n return result;\n }\n case \"passkey\": {\n // we don't need to do much here if we already have a user\n // this will setup the client with the user context, but\n // requests still have to be signed by the user on first request\n // so this is fine\n return this.client.lookupUserWithPasskey(existingSession.user);\n }\n default:\n throw new Error(\"Unknown session type\");\n }\n };\n\n public clearSession = () => {\n this.store.setState({ session: null });\n };\n\n public setTemporarySession = (session: { orgId: string }) => {\n // temporary session must be placed in localStorage so that it can be accessed across tabs\n localStorage.setItem(\n `${this.sessionKey}:temporary`,\n JSON.stringify(session)\n );\n };\n\n public getTemporarySession = (): { orgId: string } | null => {\n // temporary session must be placed in localStorage so that it can be accessed across tabs\n const sessionStr = localStorage.getItem(`${this.sessionKey}:temporary`);\n\n if (!sessionStr) {\n return null;\n }\n\n return JSON.parse(sessionStr);\n };\n\n on = <E extends keyof SessionManagerEvents>(\n event: E,\n listener: SessionManagerEvents[E]\n ) => {\n this.eventEmitter.on(event, listener as any);\n\n return () => this.eventEmitter.removeListener(event, listener as any);\n };\n\n private getSession = (): Session | null => {\n const session = this.store.getState().session;\n\n if (!session) {\n return null;\n }\n\n /**\n * TODO: this isn't really good enough\n * A user's session could be about to expire and we would still return it\n *\n * Instead we should check if a session is about to expire and refresh it\n * We should revisit this later\n */\n if (session.expirationDateMs < Date.now()) {\n this.store.setState({ session: null });\n return null;\n }\n\n return session;\n };\n\n private setSession = (\n session:\n | Omit<Extract<Session, { type: \"email\" }>, \"expirationDateMs\">\n | Omit<Extract<Session, { type: \"passkey\" }>, \"expirationDateMs\">\n ) => {\n this.store.setState({\n session: {\n ...session,\n expirationDateMs: Date.now() + this.expirationTimeMs,\n },\n });\n };\n\n public initialize() {\n this.getSessionUser()\n .then((user) => {\n // once we complete auth we can update the state of the session to connected or disconnected\n if (user) this.eventEmitter.emit(\"connected\", this.getSession()!);\n else this.eventEmitter.emit(\"disconnected\");\n })\n .finally(() => {\n this.eventEmitter.emit(\"initialized\");\n });\n }\n\n private getInitialState(): SessionState {\n return {\n session: null,\n };\n }\n\n private registerEventListeners = () => {\n this.store.subscribe(\n ({ session }) => session,\n (session, prevSession) => {\n if (session != null && prevSession == null) {\n this.eventEmitter.emit(\"connected\", session);\n } else if (session == null && prevSession != null) {\n this.eventEmitter.emit(\"disconnected\");\n }\n }\n );\n\n this.client.on(\"disconnected\", () => this.clearSession());\n\n this.client.on(\"connectedEmail\", (user, bundle) => {\n const existingSession = this.getSession();\n if (\n existingSession != null &&\n existingSession.type === \"email\" &&\n existingSession.user.userId === user.userId &&\n // if the bundle is different, then we've refreshed the session\n // so we need to reset the session\n existingSession.bundle === bundle\n ) {\n return;\n }\n\n this.setSession({ type: \"email\", user, bundle });\n });\n\n this.client.on(\"connectedPasskey\", (user) => {\n const existingSession = this.getSession();\n if (\n existingSession != null &&\n existingSession.type === \"passkey\" &&\n existingSession.user.userId === user.userId\n ) {\n return;\n }\n\n this.setSession({ type: \"passkey\", user });\n });\n\n // sync local state if persisted state has changed from another tab\n window.addEventListener(\"focus\", () => {\n this.store.persist.rehydrate();\n this.initialize();\n });\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/session/manager.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from \"eventemitter3\";\nimport { z } from \"zod\";\nimport {\n createJSONStorage,\n persist,\n subscribeWithSelector,\n} from \"zustand/middleware\";\nimport { createStore, type Mutate, type StoreApi } from \"zustand/vanilla\";\nimport type { BaseSignerClient } from \"../client/base\";\nimport type { User } from \"../client/types\";\nimport { assertNever } from \"../utils/typeAssertions.js\";\nimport type { Session, SessionManagerEvents } from \"./types\";\n\nexport const DEFAULT_SESSION_MS = 15 * 60 * 1000; // 15 minutes\n\nexport const SessionManagerParamsSchema = z.object({\n sessionKey: z.string().default(\"alchemy-signer-session\"),\n storage: z\n .enum([\"localStorage\", \"sessionStorage\"])\n .default(\"localStorage\")\n .or(z.custom<Storage>()),\n expirationTimeMs: z\n .number()\n .default(DEFAULT_SESSION_MS)\n .describe(\n \"The time in milliseconds that a session should last before expiring [default: 15 minutes]\"\n ),\n client: z.custom<BaseSignerClient>(),\n});\n\nexport type SessionManagerParams = z.input<typeof SessionManagerParamsSchema>;\n\ntype SessionState = {\n session: Session | null;\n};\n\ntype Store = Mutate<\n StoreApi<SessionState>,\n [[\"zustand/subscribeWithSelector\", never], [\"zustand/persist\", SessionState]]\n>;\n\nexport class SessionManager {\n private sessionKey: string;\n private client: BaseSignerClient;\n private eventEmitter: EventEmitter<SessionManagerEvents>;\n readonly expirationTimeMs: number;\n private store: Store;\n\n constructor(params: SessionManagerParams) {\n const {\n sessionKey,\n storage: storageType,\n expirationTimeMs,\n client,\n } = SessionManagerParamsSchema.parse(params);\n this.sessionKey = sessionKey;\n const storage =\n typeof storageType === \"string\"\n ? storageType === \"localStorage\"\n ? localStorage\n : sessionStorage\n : storageType;\n this.expirationTimeMs = expirationTimeMs;\n this.client = client;\n this.eventEmitter = new EventEmitter<SessionManagerEvents>();\n\n this.store = createStore(\n subscribeWithSelector(\n persist(this.getInitialState, {\n name: this.sessionKey,\n storage: createJSONStorage<SessionState>(() => storage),\n })\n )\n );\n\n this.registerEventListeners();\n }\n\n public getSessionUser = async (): Promise<User | null> => {\n const existingSession = this.getSession();\n if (existingSession == null) {\n return null;\n }\n\n switch (existingSession.type) {\n case \"email\":\n case \"oauth\": {\n const connectedEventName =\n existingSession.type === \"email\"\n ? \"connectedEmail\"\n : \"connectedOauth\";\n const result = await this.client\n .completeAuthWithBundle({\n bundle: existingSession.bundle,\n orgId: existingSession.user.orgId,\n authenticatingType: existingSession.type,\n connectedEventName,\n })\n .catch((e) => {\n console.warn(\"Failed to load user from session\", e);\n return null;\n });\n\n if (!result) {\n this.clearSession();\n return null;\n }\n\n return result;\n }\n case \"passkey\": {\n // we don't need to do much here if we already have a user\n // this will setup the client with the user context, but\n // requests still have to be signed by the user on first request\n // so this is fine\n return this.client.lookupUserWithPasskey(existingSession.user);\n }\n default:\n assertNever(\n existingSession,\n `Unknown session type: ${(existingSession as any).type}`\n );\n }\n };\n\n public clearSession = () => {\n this.store.setState({ session: null });\n };\n\n public setTemporarySession = (session: { orgId: string }) => {\n // temporary session must be placed in localStorage so that it can be accessed across tabs\n localStorage.setItem(\n `${this.sessionKey}:temporary`,\n JSON.stringify(session)\n );\n };\n\n public getTemporarySession = (): { orgId: string } | null => {\n // temporary session must be placed in localStorage so that it can be accessed across tabs\n const sessionStr = localStorage.getItem(`${this.sessionKey}:temporary`);\n\n if (!sessionStr) {\n return null;\n }\n\n return JSON.parse(sessionStr);\n };\n\n on = <E extends keyof SessionManagerEvents>(\n event: E,\n listener: SessionManagerEvents[E]\n ) => {\n this.eventEmitter.on(event, listener as any);\n\n return () => this.eventEmitter.removeListener(event, listener as any);\n };\n\n private getSession = (): Session | null => {\n const session = this.store.getState().session;\n\n if (!session) {\n return null;\n }\n\n /**\n * TODO: this isn't really good enough\n * A user's session could be about to expire and we would still return it\n *\n * Instead we should check if a session is about to expire and refresh it\n * We should revisit this later\n */\n if (session.expirationDateMs < Date.now()) {\n this.store.setState({ session: null });\n return null;\n }\n\n return session;\n };\n\n private setSession = (\n session:\n | Omit<Extract<Session, { type: \"email\" | \"oauth\" }>, \"expirationDateMs\">\n | Omit<Extract<Session, { type: \"passkey\" }>, \"expirationDateMs\">\n ) => {\n this.store.setState({\n session: {\n ...session,\n expirationDateMs: Date.now() + this.expirationTimeMs,\n },\n });\n };\n\n public initialize() {\n this.getSessionUser()\n .then((user) => {\n // once we complete auth we can update the state of the session to connected or disconnected\n if (user) this.eventEmitter.emit(\"connected\", this.getSession()!);\n else this.eventEmitter.emit(\"disconnected\");\n })\n .finally(() => {\n this.eventEmitter.emit(\"initialized\");\n });\n }\n\n private getInitialState(): SessionState {\n return {\n session: null,\n };\n }\n\n private registerEventListeners = () => {\n this.store.subscribe(\n ({ session }) => session,\n (session, prevSession) => {\n if (session != null && prevSession == null) {\n this.eventEmitter.emit(\"connected\", session);\n } else if (session == null && prevSession != null) {\n this.eventEmitter.emit(\"disconnected\");\n }\n }\n );\n\n this.client.on(\"disconnected\", () => this.clearSession());\n\n this.client.on(\"connectedEmail\", (user, bundle) =>\n this.setSessionWithUserAndBundle({ type: \"email\", user, bundle })\n );\n\n this.client.on(\"connectedPasskey\", (user) => {\n const existingSession = this.getSession();\n if (\n existingSession != null &&\n existingSession.type === \"passkey\" &&\n existingSession.user.userId === user.userId\n ) {\n return;\n }\n\n this.setSession({ type: \"passkey\", user });\n });\n\n this.client.on(\"connectedOauth\", (user, bundle) =>\n this.setSessionWithUserAndBundle({ type: \"oauth\", user, bundle })\n );\n\n // sync local state if persisted state has changed from another tab\n window.addEventListener(\"focus\", () => {\n this.store.persist.rehydrate();\n this.initialize();\n });\n };\n\n private setSessionWithUserAndBundle = ({\n type,\n user,\n bundle,\n }: {\n type: \"email\" | \"oauth\";\n user: User;\n bundle: string;\n }) => {\n const existingSession = this.getSession();\n if (\n existingSession != null &&\n existingSession.type === type &&\n existingSession.user.userId === user.userId &&\n // if the bundle is different, then we've refreshed the session\n // so we need to reset the session\n existingSession.bundle === bundle\n ) {\n return;\n }\n\n this.setSession({ type, user, bundle });\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/session/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { User } from \"../client/types\";\n\nexport type Session =\n | {\n type: \"email\";\n bundle: string;\n expirationDateMs: number;\n user: User;\n }\n | { type: \"passkey\"; user: User; expirationDateMs: number };\n\nexport type SessionManagerEvents = {\n connected(session: Session): void;\n disconnected(): void;\n initialized(): void;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/session/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { User } from \"../client/types\";\n\nexport type Session =\n | {\n type: \"email\" | \"oauth\";\n bundle: string;\n expirationDateMs: number;\n user: User;\n }\n | { type: \"passkey\"; user: User; expirationDateMs: number };\n\nexport type SessionManagerEvents = {\n connected(session: Session): void;\n disconnected(): void;\n initialized(): void;\n};\n"]}
|
package/dist/esm/signer.d.ts
CHANGED
|
@@ -22,7 +22,38 @@ export type AuthParams = {
|
|
|
22
22
|
createNew: true;
|
|
23
23
|
username: string;
|
|
24
24
|
creationOpts?: CredentialCreationOptionOverrides;
|
|
25
|
+
} | ({
|
|
26
|
+
type: "oauth";
|
|
27
|
+
scope?: string;
|
|
28
|
+
claims?: string;
|
|
29
|
+
} & OauthProviderConfig & OauthRedirectConfig) | {
|
|
30
|
+
type: "oauthReturn";
|
|
31
|
+
bundle: string;
|
|
32
|
+
orgId: string;
|
|
33
|
+
idToken: string;
|
|
34
|
+
};
|
|
35
|
+
export type OauthProviderConfig = {
|
|
36
|
+
authProviderId: "auth0";
|
|
37
|
+
isCustomProvider?: false;
|
|
38
|
+
auth0Connection?: string;
|
|
39
|
+
} | {
|
|
40
|
+
authProviderId: KnownAuthProvider;
|
|
41
|
+
isCustomProvider?: false;
|
|
42
|
+
auth0Connection?: never;
|
|
43
|
+
} | {
|
|
44
|
+
authProviderId: string;
|
|
45
|
+
isCustomProvider: true;
|
|
46
|
+
auth0Connection?: never;
|
|
47
|
+
};
|
|
48
|
+
export type OauthRedirectConfig = {
|
|
49
|
+
mode: "redirect";
|
|
50
|
+
redirectUrl: string;
|
|
51
|
+
} | {
|
|
52
|
+
mode: "popup";
|
|
53
|
+
redirectUrl?: never;
|
|
25
54
|
};
|
|
55
|
+
export type KnownAuthProvider = "google" | "apple" | "facebook" | "auth0";
|
|
56
|
+
export type OauthMode = "redirect" | "popup";
|
|
26
57
|
export declare const AlchemySignerParamsSchema: z.ZodObject<{
|
|
27
58
|
client: z.ZodUnion<[z.ZodType<AlchemySignerWebClient, z.ZodTypeDef, AlchemySignerWebClient>, z.ZodObject<{
|
|
28
59
|
connection: z.ZodUnion<[z.ZodObject<{
|
|
@@ -86,6 +117,8 @@ export declare const AlchemySignerParamsSchema: z.ZodObject<{
|
|
|
86
117
|
}>;
|
|
87
118
|
rpId: z.ZodOptional<z.ZodString>;
|
|
88
119
|
rootOrgId: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
120
|
+
oauthCallbackUrl: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
121
|
+
enablePopupOauth: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
89
122
|
}, "strip", z.ZodTypeAny, {
|
|
90
123
|
connection: {
|
|
91
124
|
apiKey: string;
|
|
@@ -104,11 +137,13 @@ export declare const AlchemySignerParamsSchema: z.ZodObject<{
|
|
|
104
137
|
jwt: string;
|
|
105
138
|
apiKey?: undefined;
|
|
106
139
|
};
|
|
107
|
-
rootOrgId: string;
|
|
108
140
|
iframeConfig: {
|
|
109
141
|
iframeElementId: string;
|
|
110
142
|
iframeContainerId: string;
|
|
111
143
|
};
|
|
144
|
+
rootOrgId: string;
|
|
145
|
+
oauthCallbackUrl: string;
|
|
146
|
+
enablePopupOauth: boolean;
|
|
112
147
|
rpId?: string | undefined;
|
|
113
148
|
}, {
|
|
114
149
|
connection: {
|
|
@@ -134,6 +169,8 @@ export declare const AlchemySignerParamsSchema: z.ZodObject<{
|
|
|
134
169
|
};
|
|
135
170
|
rpId?: string | undefined;
|
|
136
171
|
rootOrgId?: string | undefined;
|
|
172
|
+
oauthCallbackUrl?: string | undefined;
|
|
173
|
+
enablePopupOauth?: boolean | undefined;
|
|
137
174
|
}>]>;
|
|
138
175
|
sessionConfig: z.ZodOptional<z.ZodObject<Omit<{
|
|
139
176
|
sessionKey: z.ZodDefault<z.ZodString>;
|
|
@@ -141,12 +178,12 @@ export declare const AlchemySignerParamsSchema: z.ZodObject<{
|
|
|
141
178
|
expirationTimeMs: z.ZodDefault<z.ZodNumber>;
|
|
142
179
|
client: z.ZodType<import("./index.js").BaseSignerClient<unknown>, z.ZodTypeDef, import("./index.js").BaseSignerClient<unknown>>;
|
|
143
180
|
}, "client">, "strip", z.ZodTypeAny, {
|
|
181
|
+
storage: (Storage | "localStorage" | "sessionStorage") & (Storage | "localStorage" | "sessionStorage" | undefined);
|
|
144
182
|
sessionKey: string;
|
|
145
|
-
storage: ("localStorage" | "sessionStorage" | Storage) & ("localStorage" | "sessionStorage" | Storage | undefined);
|
|
146
183
|
expirationTimeMs: number;
|
|
147
184
|
}, {
|
|
185
|
+
storage?: Storage | "localStorage" | "sessionStorage" | undefined;
|
|
148
186
|
sessionKey?: string | undefined;
|
|
149
|
-
storage?: "localStorage" | "sessionStorage" | Storage | undefined;
|
|
150
187
|
expirationTimeMs?: number | undefined;
|
|
151
188
|
}>>;
|
|
152
189
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -168,11 +205,13 @@ export declare const AlchemySignerParamsSchema: z.ZodObject<{
|
|
|
168
205
|
jwt: string;
|
|
169
206
|
apiKey?: undefined;
|
|
170
207
|
};
|
|
171
|
-
rootOrgId: string;
|
|
172
208
|
iframeConfig: {
|
|
173
209
|
iframeElementId: string;
|
|
174
210
|
iframeContainerId: string;
|
|
175
211
|
};
|
|
212
|
+
rootOrgId: string;
|
|
213
|
+
oauthCallbackUrl: string;
|
|
214
|
+
enablePopupOauth: boolean;
|
|
176
215
|
rpId?: string | undefined;
|
|
177
216
|
} | AlchemySignerWebClient) & ({
|
|
178
217
|
connection: {
|
|
@@ -192,16 +231,18 @@ export declare const AlchemySignerParamsSchema: z.ZodObject<{
|
|
|
192
231
|
jwt: string;
|
|
193
232
|
apiKey?: undefined;
|
|
194
233
|
};
|
|
195
|
-
rootOrgId: string;
|
|
196
234
|
iframeConfig: {
|
|
197
235
|
iframeElementId: string;
|
|
198
236
|
iframeContainerId: string;
|
|
199
237
|
};
|
|
238
|
+
rootOrgId: string;
|
|
239
|
+
oauthCallbackUrl: string;
|
|
240
|
+
enablePopupOauth: boolean;
|
|
200
241
|
rpId?: string | undefined;
|
|
201
242
|
} | AlchemySignerWebClient | undefined);
|
|
202
243
|
sessionConfig?: {
|
|
244
|
+
storage: (Storage | "localStorage" | "sessionStorage") & (Storage | "localStorage" | "sessionStorage" | undefined);
|
|
203
245
|
sessionKey: string;
|
|
204
|
-
storage: ("localStorage" | "sessionStorage" | Storage) & ("localStorage" | "sessionStorage" | Storage | undefined);
|
|
205
246
|
expirationTimeMs: number;
|
|
206
247
|
} | undefined;
|
|
207
248
|
}, {
|
|
@@ -229,6 +270,8 @@ export declare const AlchemySignerParamsSchema: z.ZodObject<{
|
|
|
229
270
|
};
|
|
230
271
|
rpId?: string | undefined;
|
|
231
272
|
rootOrgId?: string | undefined;
|
|
273
|
+
oauthCallbackUrl?: string | undefined;
|
|
274
|
+
enablePopupOauth?: boolean | undefined;
|
|
232
275
|
} | AlchemySignerWebClient) & ({
|
|
233
276
|
connection: {
|
|
234
277
|
apiKey: string;
|
|
@@ -253,10 +296,12 @@ export declare const AlchemySignerParamsSchema: z.ZodObject<{
|
|
|
253
296
|
};
|
|
254
297
|
rpId?: string | undefined;
|
|
255
298
|
rootOrgId?: string | undefined;
|
|
299
|
+
oauthCallbackUrl?: string | undefined;
|
|
300
|
+
enablePopupOauth?: boolean | undefined;
|
|
256
301
|
} | AlchemySignerWebClient | undefined);
|
|
257
302
|
sessionConfig?: {
|
|
303
|
+
storage?: Storage | "localStorage" | "sessionStorage" | undefined;
|
|
258
304
|
sessionKey?: string | undefined;
|
|
259
|
-
storage?: "localStorage" | "sessionStorage" | Storage | undefined;
|
|
260
305
|
expirationTimeMs?: number | undefined;
|
|
261
306
|
} | undefined;
|
|
262
307
|
}>;
|
package/dist/esm/signer.js
CHANGED
|
@@ -45,10 +45,53 @@ export class AlchemyWebSigner extends BaseAlchemySigner {
|
|
|
45
45
|
else {
|
|
46
46
|
client = params_.client;
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
const { emailBundle, oauthBundle, oauthOrgId, oauthError, idToken } = getAndRemoveQueryParams({
|
|
49
|
+
emailBundle: "bundle",
|
|
50
|
+
// We don't need this, but we still want to remove it from the URL.
|
|
51
|
+
emailOrgId: "orgId",
|
|
52
|
+
oauthBundle: "alchemy-bundle",
|
|
53
|
+
oauthOrgId: "alchemy-org-id",
|
|
54
|
+
oauthError: "alchemy-error",
|
|
55
|
+
idToken: "alchemy-id-token",
|
|
51
56
|
});
|
|
57
|
+
const initialError = oauthError != null
|
|
58
|
+
? { name: "OauthError", message: oauthError }
|
|
59
|
+
: undefined;
|
|
60
|
+
super({ client, sessionConfig, initialError });
|
|
61
|
+
if (emailBundle) {
|
|
62
|
+
this.authenticate({ type: "email", bundle: emailBundle });
|
|
63
|
+
}
|
|
64
|
+
else if (oauthBundle && oauthOrgId && idToken) {
|
|
65
|
+
this.authenticate({
|
|
66
|
+
type: "oauthReturn",
|
|
67
|
+
bundle: oauthBundle,
|
|
68
|
+
orgId: oauthOrgId,
|
|
69
|
+
idToken,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Reads and removes the specified query params from the URL.
|
|
76
|
+
*
|
|
77
|
+
* @param {T} keys object whose values are the query parameter keys to read and
|
|
78
|
+
* remove
|
|
79
|
+
* @returns {{ [K in keyof T]: string | undefined }} object with the same keys
|
|
80
|
+
* as the input whose values are the values of the query params.
|
|
81
|
+
*/
|
|
82
|
+
function getAndRemoveQueryParams(keys) {
|
|
83
|
+
const url = new URL(window.location.href);
|
|
84
|
+
const result = {};
|
|
85
|
+
let foundQueryParam = false;
|
|
86
|
+
for (const [key, param] of Object.entries(keys)) {
|
|
87
|
+
const value = url.searchParams.get(param) ?? undefined;
|
|
88
|
+
foundQueryParam || (foundQueryParam = value != null);
|
|
89
|
+
result[key] = value;
|
|
90
|
+
url.searchParams.delete(param);
|
|
91
|
+
}
|
|
92
|
+
if (foundQueryParam) {
|
|
93
|
+
window.history.replaceState(window.history.state, "", url.toString());
|
|
52
94
|
}
|
|
95
|
+
return result;
|
|
53
96
|
}
|
|
54
97
|
//# sourceMappingURL=signer.js.map
|
package/dist/esm/signer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EACL,+BAA+B,EAC/B,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/signer.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\nimport { BaseAlchemySigner } from \"./base.js\";\nimport {\n AlchemySignerClientParamsSchema,\n AlchemySignerWebClient,\n} from \"./client/index.js\";\nimport type { CredentialCreationOptionOverrides } from \"./client/types.js\";\nimport { SessionManagerParamsSchema } from \"./session/manager.js\";\n\nexport type AuthParams =\n | { type: \"email\"; email: string; redirectParams?: URLSearchParams }\n | { type: \"email\"; bundle: string; orgId?: string }\n | {\n type: \"passkey\";\n email: string;\n creationOpts?: CredentialCreationOptionOverrides;\n }\n | {\n type: \"passkey\";\n createNew: false;\n }\n | {\n type: \"passkey\";\n createNew: true;\n username: string;\n creationOpts?: CredentialCreationOptionOverrides;\n }\n | ({\n type: \"oauth\";\n scope?: string;\n claims?: string;\n } & OauthProviderConfig &\n OauthRedirectConfig)\n | {\n type: \"oauthReturn\";\n bundle: string;\n orgId: string;\n idToken: string;\n };\n\nexport type OauthProviderConfig =\n | {\n authProviderId: \"auth0\";\n isCustomProvider?: false;\n auth0Connection?: string;\n }\n | {\n authProviderId: KnownAuthProvider;\n isCustomProvider?: false;\n auth0Connection?: never;\n }\n | {\n authProviderId: string;\n isCustomProvider: true;\n auth0Connection?: never;\n };\n\nexport type OauthRedirectConfig =\n | { mode: \"redirect\"; redirectUrl: string }\n | { mode: \"popup\"; redirectUrl?: never };\n\nexport type KnownAuthProvider = \"google\" | \"apple\" | \"facebook\" | \"auth0\";\n\nexport type OauthMode = \"redirect\" | \"popup\";\n\nexport const AlchemySignerParamsSchema = z\n .object({\n client: z\n .custom<AlchemySignerWebClient>()\n .or(AlchemySignerClientParamsSchema),\n })\n .extend({\n sessionConfig: SessionManagerParamsSchema.omit({ client: true }).optional(),\n });\n\nexport type AlchemySignerParams = z.input<typeof AlchemySignerParamsSchema>;\n\n/**\n * A SmartAccountSigner that can be used with any SmartContractAccount\n */\nexport class AlchemyWebSigner extends BaseAlchemySigner<AlchemySignerWebClient> {\n /**\n * Initializes an instance with the provided Alchemy signer parameters after parsing them with a schema.\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 *\n * @param {AlchemySignerParams} params The parameters for the Alchemy signer, including the client and session configuration\n */\n constructor(params: AlchemySignerParams) {\n const { sessionConfig, ...params_ } =\n AlchemySignerParamsSchema.parse(params);\n\n let client: AlchemySignerWebClient;\n if (\"connection\" in params_.client) {\n client = new AlchemySignerWebClient(params_.client);\n } else {\n client = params_.client;\n }\n const { emailBundle, oauthBundle, oauthOrgId, oauthError, idToken } =\n getAndRemoveQueryParams({\n emailBundle: \"bundle\",\n // We don't need this, but we still want to remove it from the URL.\n emailOrgId: \"orgId\",\n oauthBundle: \"alchemy-bundle\",\n oauthOrgId: \"alchemy-org-id\",\n oauthError: \"alchemy-error\",\n idToken: \"alchemy-id-token\",\n });\n\n const initialError =\n oauthError != null\n ? { name: \"OauthError\", message: oauthError }\n : undefined;\n\n super({ client, sessionConfig, initialError });\n\n if (emailBundle) {\n this.authenticate({ type: \"email\", bundle: emailBundle });\n } else if (oauthBundle && oauthOrgId && idToken) {\n this.authenticate({\n type: \"oauthReturn\",\n bundle: oauthBundle,\n orgId: oauthOrgId,\n idToken,\n });\n }\n }\n}\n\n/**\n * Reads and removes the specified query params from the URL.\n *\n * @param {T} keys object whose values are the query parameter keys to read and\n * remove\n * @returns {{ [K in keyof T]: string | undefined }} object with the same keys\n * as the input whose values are the values of the query params.\n */\nfunction getAndRemoveQueryParams<T extends Record<string, string>>(\n keys: T\n): { [K in keyof T]: string | undefined } {\n const url = new URL(window.location.href);\n const result: Record<string, string | undefined> = {};\n let foundQueryParam = false;\n for (const [key, param] of Object.entries(keys)) {\n const value = url.searchParams.get(param) ?? undefined;\n foundQueryParam ||= value != null;\n result[key] = value;\n url.searchParams.delete(param);\n }\n if (foundQueryParam) {\n window.history.replaceState(window.history.state, \"\", url.toString());\n }\n return result as { [K in keyof T]: string | undefined };\n}\n"]}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -3,12 +3,19 @@ export type AlchemySignerEvents = {
|
|
|
3
3
|
connected(user: User): void;
|
|
4
4
|
disconnected(): void;
|
|
5
5
|
statusChanged(status: AlchemySignerStatus): void;
|
|
6
|
+
errorChanged(error: ErrorInfo | undefined): void;
|
|
6
7
|
};
|
|
7
8
|
export type AlchemySignerEvent = keyof AlchemySignerEvents;
|
|
8
9
|
export declare enum AlchemySignerStatus {
|
|
9
10
|
INITIALIZING = "INITIALIZING",
|
|
10
11
|
CONNECTED = "CONNECTED",
|
|
11
12
|
DISCONNECTED = "DISCONNECTED",
|
|
12
|
-
|
|
13
|
+
AUTHENTICATING_PASSKEY = "AUTHENTICATING_PASSKEY",
|
|
14
|
+
AUTHENTICATING_EMAIL = "AUTHENTICATING_EMAIL",
|
|
15
|
+
AUTHENTICATING_OAUTH = "AUTHENTICATING_OAUTH",
|
|
13
16
|
AWAITING_EMAIL_AUTH = "AWAITING_EMAIL_AUTH"
|
|
14
17
|
}
|
|
18
|
+
export interface ErrorInfo {
|
|
19
|
+
name: string;
|
|
20
|
+
message: string;
|
|
21
|
+
}
|
package/dist/esm/types.js
CHANGED
|
@@ -3,7 +3,9 @@ export var AlchemySignerStatus;
|
|
|
3
3
|
AlchemySignerStatus["INITIALIZING"] = "INITIALIZING";
|
|
4
4
|
AlchemySignerStatus["CONNECTED"] = "CONNECTED";
|
|
5
5
|
AlchemySignerStatus["DISCONNECTED"] = "DISCONNECTED";
|
|
6
|
-
AlchemySignerStatus["
|
|
6
|
+
AlchemySignerStatus["AUTHENTICATING_PASSKEY"] = "AUTHENTICATING_PASSKEY";
|
|
7
|
+
AlchemySignerStatus["AUTHENTICATING_EMAIL"] = "AUTHENTICATING_EMAIL";
|
|
8
|
+
AlchemySignerStatus["AUTHENTICATING_OAUTH"] = "AUTHENTICATING_OAUTH";
|
|
7
9
|
AlchemySignerStatus["AWAITING_EMAIL_AUTH"] = "AWAITING_EMAIL_AUTH";
|
|
8
10
|
})(AlchemySignerStatus || (AlchemySignerStatus = {}));
|
|
9
11
|
//# sourceMappingURL=types.js.map
|
package/dist/esm/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAWA,MAAM,CAAN,IAAY,mBAQX;AARD,WAAY,mBAAmB;IAC7B,oDAA6B,CAAA;IAC7B,8CAAuB,CAAA;IACvB,oDAA6B,CAAA;IAC7B,wEAAiD,CAAA;IACjD,oEAA6C,CAAA;IAC7C,oEAA6C,CAAA;IAC7C,kEAA2C,CAAA;AAC7C,CAAC,EARW,mBAAmB,KAAnB,mBAAmB,QAQ9B","sourcesContent":["import type { User } from \"./client/types\";\n\nexport type AlchemySignerEvents = {\n connected(user: User): void;\n disconnected(): void;\n statusChanged(status: AlchemySignerStatus): void;\n errorChanged(error: ErrorInfo | undefined): void;\n};\n\nexport type AlchemySignerEvent = keyof AlchemySignerEvents;\n\nexport enum AlchemySignerStatus {\n INITIALIZING = \"INITIALIZING\",\n CONNECTED = \"CONNECTED\",\n DISCONNECTED = \"DISCONNECTED\",\n AUTHENTICATING_PASSKEY = \"AUTHENTICATING_PASSKEY\",\n AUTHENTICATING_EMAIL = \"AUTHENTICATING_EMAIL\",\n AUTHENTICATING_OAUTH = \"AUTHENTICATING_OAUTH\",\n AWAITING_EMAIL_AUTH = \"AWAITING_EMAIL_AUTH\",\n}\n\nexport interface ErrorInfo {\n name: string;\n message: string;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function assertNever(_: never, message: string): never;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeAssertions.js","sourceRoot":"","sources":["../../../src/utils/typeAssertions.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,CAAQ,EAAE,OAAe;IACnD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC","sourcesContent":["export function assertNever(_: never, message: string): never {\n throw new Error(message);\n}\n"]}
|
package/dist/esm/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "4.0.0-beta.
|
|
1
|
+
export declare const VERSION = "4.0.0-beta.10";
|
package/dist/esm/version.js
CHANGED
package/dist/esm/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,yBAAyB;AACzB,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC","sourcesContent":["// This file is autogenerated by inject-version.ts. Any changes will be\n// overwritten on commit!\nexport const VERSION = \"4.0.0-beta.10\";\n"]}
|