@account-kit/signer 4.0.0-beta.8 → 4.0.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 +9 -4
- package/dist/esm/base.js +124 -30
- package/dist/esm/base.js.map +1 -1
- package/dist/esm/client/base.d.ts +7 -12
- package/dist/esm/client/base.js +11 -1
- package/dist/esm/client/base.js.map +1 -1
- package/dist/esm/client/index.d.ts +15 -6
- package/dist/esm/client/index.js +23 -12
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/client/types.d.ts +6 -1
- package/dist/esm/client/types.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/session/manager.js +1 -0
- package/dist/esm/session/manager.js.map +1 -1
- package/dist/esm/signer.d.ts +1 -0
- 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/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 +9 -4
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/client/base.d.ts +7 -12
- package/dist/types/client/base.d.ts.map +1 -1
- package/dist/types/client/index.d.ts +15 -6
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/client/types.d.ts +6 -1
- package/dist/types/client/types.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/session/manager.d.ts.map +1 -1
- package/dist/types/signer.d.ts +1 -0
- 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/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +6 -5
- package/src/base.ts +198 -62
- package/src/client/base.ts +19 -2
- package/src/client/index.ts +29 -11
- package/src/client/types.ts +7 -1
- package/src/metrics.ts +23 -0
- package/src/session/manager.ts +2 -1
- package/src/signer.ts +60 -5
- package/src/types.ts +9 -1
- package/src/version.ts +1 -1
package/dist/esm/base.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { type SmartAccountAuthenticator } from "@aa-sdk/core";
|
|
2
|
-
import { type
|
|
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 { BaseSignerClient } from "./client/base";
|
|
4
4
|
import type { OauthConfig, User } from "./client/types";
|
|
5
5
|
import { type SessionManagerParams } from "./session/manager.js";
|
|
6
6
|
import type { AuthParams } from "./signer";
|
|
7
|
-
import { type AlchemySignerEvents } from "./types.js";
|
|
7
|
+
import { type AlchemySignerEvents, type ErrorInfo } from "./types.js";
|
|
8
8
|
export interface BaseAlchemySignerParams<TClient extends BaseSignerClient> {
|
|
9
9
|
client: TClient;
|
|
10
10
|
sessionConfig?: Omit<SessionManagerParams, "client">;
|
|
11
|
+
initialError?: ErrorInfo;
|
|
11
12
|
}
|
|
12
13
|
/**
|
|
13
14
|
* Base abstract class for Alchemy Signer, providing authentication and session management for smart accounts.
|
|
@@ -26,8 +27,9 @@ export declare abstract class BaseAlchemySigner<TClient extends BaseSignerClient
|
|
|
26
27
|
* @param {BaseAlchemySignerParams<TClient>} param0 Object containing the client and session configuration
|
|
27
28
|
* @param {TClient} param0.client The client instance to be used internally
|
|
28
29
|
* @param {SessionConfig} param0.sessionConfig Configuration for managing sessions
|
|
30
|
+
* @param {ErrorInfo | undefined} param0.initialError Error already present on the signer when initialized, if any
|
|
29
31
|
*/
|
|
30
|
-
constructor({ client, sessionConfig }: BaseAlchemySignerParams<TClient>);
|
|
32
|
+
constructor({ client, sessionConfig, initialError, }: BaseAlchemySignerParams<TClient>);
|
|
31
33
|
/**
|
|
32
34
|
* Allows you to subscribe to events emitted by the signer
|
|
33
35
|
*
|
|
@@ -94,6 +96,7 @@ export declare abstract class BaseAlchemySigner<TClient extends BaseSignerClient
|
|
|
94
96
|
* @returns {Promise<User>} the user that was authenticated
|
|
95
97
|
*/
|
|
96
98
|
authenticate: (params: AuthParams) => Promise<User>;
|
|
99
|
+
private trackAuthenticateType;
|
|
97
100
|
/**
|
|
98
101
|
* Clear a user session and log them out
|
|
99
102
|
*
|
|
@@ -237,7 +240,9 @@ export declare abstract class BaseAlchemySigner<TClient extends BaseSignerClient
|
|
|
237
240
|
* @param {() => Hex} [args.serializer] an optional serializer function. If not provided, the default `serializeTransaction` function will be used
|
|
238
241
|
* @returns {Promise<string>} a promise that resolves to the serialized transaction with the signature
|
|
239
242
|
*/
|
|
240
|
-
signTransaction:
|
|
243
|
+
signTransaction: <serializer extends SerializeTransactionFn<TransactionSerializable> = SerializeTransactionFn<TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
|
|
244
|
+
serializer?: serializer | undefined;
|
|
245
|
+
} | undefined) => Promise<IsNarrowable<TransactionSerialized<GetTransactionType<transaction>>, Hex> extends true ? TransactionSerialized<GetTransactionType<transaction>> : Hex>;
|
|
241
246
|
/**
|
|
242
247
|
* Unauthenticated call to look up a user's organizationId by email
|
|
243
248
|
*
|
package/dist/esm/base.js
CHANGED
|
@@ -4,6 +4,7 @@ import { toAccount } from "viem/accounts";
|
|
|
4
4
|
import { subscribeWithSelector } from "zustand/middleware";
|
|
5
5
|
import { createStore } from "zustand/vanilla";
|
|
6
6
|
import { NotAuthenticatedError } from "./errors.js";
|
|
7
|
+
import { SignerLogger } from "./metrics.js";
|
|
7
8
|
import { SessionManager, } from "./session/manager.js";
|
|
8
9
|
import { AlchemySignerStatus, } from "./types.js";
|
|
9
10
|
import { assertNever } from "./utils/typeAssertions.js";
|
|
@@ -20,8 +21,9 @@ export class BaseAlchemySigner {
|
|
|
20
21
|
* @param {BaseAlchemySignerParams<TClient>} param0 Object containing the client and session configuration
|
|
21
22
|
* @param {TClient} param0.client The client instance to be used internally
|
|
22
23
|
* @param {SessionConfig} param0.sessionConfig Configuration for managing sessions
|
|
24
|
+
* @param {ErrorInfo | undefined} param0.initialError Error already present on the signer when initialized, if any
|
|
23
25
|
*/
|
|
24
|
-
constructor({ client, sessionConfig }) {
|
|
26
|
+
constructor({ client, sessionConfig, initialError, }) {
|
|
25
27
|
Object.defineProperty(this, "signerType", {
|
|
26
28
|
enumerable: true,
|
|
27
29
|
configurable: true,
|
|
@@ -70,8 +72,10 @@ export class BaseAlchemySigner {
|
|
|
70
72
|
listener(), { fireImmediately: true });
|
|
71
73
|
case "statusChanged":
|
|
72
74
|
return this.store.subscribe(({ status }) => status, listener, { fireImmediately: true });
|
|
75
|
+
case "errorChanged":
|
|
76
|
+
return this.store.subscribe(({ error }) => error, (error) => listener(error ?? undefined), { fireImmediately: true });
|
|
73
77
|
default:
|
|
74
|
-
|
|
78
|
+
assertNever(event, `Unknown event type ${event}`);
|
|
75
79
|
}
|
|
76
80
|
}
|
|
77
81
|
});
|
|
@@ -141,17 +145,78 @@ export class BaseAlchemySigner {
|
|
|
141
145
|
enumerable: true,
|
|
142
146
|
configurable: true,
|
|
143
147
|
writable: true,
|
|
144
|
-
value: async (params) => {
|
|
148
|
+
value: SignerLogger.profiled("BaseAlchemySigner.authenticate", async (params) => {
|
|
149
|
+
const { type } = params;
|
|
150
|
+
const result = (() => {
|
|
151
|
+
switch (type) {
|
|
152
|
+
case "email":
|
|
153
|
+
return this.authenticateWithEmail(params);
|
|
154
|
+
case "passkey":
|
|
155
|
+
return this.authenticateWithPasskey(params);
|
|
156
|
+
case "oauth":
|
|
157
|
+
return this.authenticateWithOauth(params);
|
|
158
|
+
case "oauthReturn":
|
|
159
|
+
return this.handleOauthReturn(params);
|
|
160
|
+
default:
|
|
161
|
+
assertNever(type, `Unknown auth type: ${type}`);
|
|
162
|
+
}
|
|
163
|
+
})();
|
|
164
|
+
this.trackAuthenticateType(params);
|
|
165
|
+
return result.catch((error) => {
|
|
166
|
+
/**
|
|
167
|
+
* 2 things going on here:
|
|
168
|
+
* 1. for oauth flows we expect the status to remain in authenticating
|
|
169
|
+
* 2. we do the ternary, because if we explicitly pass in `undefined` for the status, zustand will set the value of status to `undefined`.
|
|
170
|
+
* However, if we omit it, then it will not override the current value of status.
|
|
171
|
+
*/
|
|
172
|
+
this.store.setState({
|
|
173
|
+
error: toErrorInfo(error),
|
|
174
|
+
...(type === "oauthReturn" || type === "oauth"
|
|
175
|
+
? {}
|
|
176
|
+
: { status: AlchemySignerStatus.DISCONNECTED }),
|
|
177
|
+
});
|
|
178
|
+
throw error;
|
|
179
|
+
});
|
|
180
|
+
})
|
|
181
|
+
});
|
|
182
|
+
Object.defineProperty(this, "trackAuthenticateType", {
|
|
183
|
+
enumerable: true,
|
|
184
|
+
configurable: true,
|
|
185
|
+
writable: true,
|
|
186
|
+
value: (params) => {
|
|
145
187
|
const { type } = params;
|
|
146
188
|
switch (type) {
|
|
147
|
-
case "email":
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
189
|
+
case "email": {
|
|
190
|
+
// we just want to track the start of email auth
|
|
191
|
+
if ("bundle" in params)
|
|
192
|
+
return;
|
|
193
|
+
SignerLogger.trackEvent({
|
|
194
|
+
name: "signer_authnticate",
|
|
195
|
+
data: { authType: "email" },
|
|
196
|
+
});
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
case "passkey": {
|
|
200
|
+
const isAnon = !("email" in params) && params.createNew == null;
|
|
201
|
+
SignerLogger.trackEvent({
|
|
202
|
+
name: "signer_authnticate",
|
|
203
|
+
data: {
|
|
204
|
+
authType: isAnon ? "passkey_anon" : "passkey_email",
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
151
209
|
case "oauth":
|
|
152
|
-
|
|
210
|
+
SignerLogger.trackEvent({
|
|
211
|
+
name: "signer_authnticate",
|
|
212
|
+
data: {
|
|
213
|
+
authType: "oauth",
|
|
214
|
+
provider: params.authProviderId,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
break;
|
|
153
218
|
case "oauthReturn":
|
|
154
|
-
|
|
219
|
+
break;
|
|
155
220
|
default:
|
|
156
221
|
assertNever(type, `Unknown auth type: ${type}`);
|
|
157
222
|
}
|
|
@@ -236,10 +301,10 @@ export class BaseAlchemySigner {
|
|
|
236
301
|
enumerable: true,
|
|
237
302
|
configurable: true,
|
|
238
303
|
writable: true,
|
|
239
|
-
value: async () => {
|
|
304
|
+
value: SignerLogger.profiled("BaseAlchemySigner.getAddress", async () => {
|
|
240
305
|
const { address } = await this.inner.whoami();
|
|
241
306
|
return address;
|
|
242
|
-
}
|
|
307
|
+
})
|
|
243
308
|
});
|
|
244
309
|
/**
|
|
245
310
|
* Signs a raw message after hashing it.
|
|
@@ -269,10 +334,14 @@ export class BaseAlchemySigner {
|
|
|
269
334
|
enumerable: true,
|
|
270
335
|
configurable: true,
|
|
271
336
|
writable: true,
|
|
272
|
-
value: async (msg) => {
|
|
337
|
+
value: SignerLogger.profiled("BaseAlchemySigner.signMessage", async (msg) => {
|
|
273
338
|
const messageHash = hashMessage(msg);
|
|
274
|
-
|
|
275
|
-
|
|
339
|
+
const result = await this.inner.signRawMessage(messageHash);
|
|
340
|
+
SignerLogger.trackEvent({
|
|
341
|
+
name: "signer_sign_message",
|
|
342
|
+
});
|
|
343
|
+
return result;
|
|
344
|
+
})
|
|
276
345
|
});
|
|
277
346
|
/**
|
|
278
347
|
* Signs a typed message by first hashing it and then signing the hashed message using the `signRawMessage` method.
|
|
@@ -307,10 +376,10 @@ export class BaseAlchemySigner {
|
|
|
307
376
|
enumerable: true,
|
|
308
377
|
configurable: true,
|
|
309
378
|
writable: true,
|
|
310
|
-
value: async (params) => {
|
|
379
|
+
value: SignerLogger.profiled("BaseAlchemySigner.signTypedData", async (params) => {
|
|
311
380
|
const messageHash = hashTypedData(params);
|
|
312
381
|
return this.inner.signRawMessage(messageHash);
|
|
313
|
-
}
|
|
382
|
+
})
|
|
314
383
|
});
|
|
315
384
|
/**
|
|
316
385
|
* Serializes a transaction, signs it with a raw message, and then returns the serialized transaction with the signature.
|
|
@@ -346,7 +415,7 @@ export class BaseAlchemySigner {
|
|
|
346
415
|
enumerable: true,
|
|
347
416
|
configurable: true,
|
|
348
417
|
writable: true,
|
|
349
|
-
value: async (tx, args) => {
|
|
418
|
+
value: SignerLogger.profiled("BaseAlchemySigner.signTransaction", async (tx, args) => {
|
|
350
419
|
const serializeFn = args?.serializer ?? serializeTransaction;
|
|
351
420
|
const serializedTx = serializeFn(tx);
|
|
352
421
|
const signatureHex = await this.inner.signRawMessage(keccak256(serializedTx));
|
|
@@ -356,7 +425,7 @@ export class BaseAlchemySigner {
|
|
|
356
425
|
v: BigInt(takeBytes(signatureHex, { count: 1, offset: 64 })),
|
|
357
426
|
};
|
|
358
427
|
return serializeFn(tx, signature);
|
|
359
|
-
}
|
|
428
|
+
})
|
|
360
429
|
});
|
|
361
430
|
/**
|
|
362
431
|
* Unauthenticated call to look up a user's organizationId by email
|
|
@@ -386,7 +455,7 @@ export class BaseAlchemySigner {
|
|
|
386
455
|
enumerable: true,
|
|
387
456
|
configurable: true,
|
|
388
457
|
writable: true,
|
|
389
|
-
value: async (email) => {
|
|
458
|
+
value: SignerLogger.profiled("BaseAlchemySigner.getUser", async (email) => {
|
|
390
459
|
const result = await this.inner.lookupUserByEmail(email);
|
|
391
460
|
if (result.orgId == null) {
|
|
392
461
|
return null;
|
|
@@ -394,7 +463,7 @@ export class BaseAlchemySigner {
|
|
|
394
463
|
return {
|
|
395
464
|
orgId: result.orgId,
|
|
396
465
|
};
|
|
397
|
-
}
|
|
466
|
+
})
|
|
398
467
|
});
|
|
399
468
|
/**
|
|
400
469
|
* Adds a passkey to the user's account
|
|
@@ -424,9 +493,9 @@ export class BaseAlchemySigner {
|
|
|
424
493
|
enumerable: true,
|
|
425
494
|
configurable: true,
|
|
426
495
|
writable: true,
|
|
427
|
-
value: async (params) => {
|
|
496
|
+
value: SignerLogger.profiled("BaseAlchemySigner.addPasskey", async (params) => {
|
|
428
497
|
return this.inner.addPasskey(params ?? {});
|
|
429
|
-
}
|
|
498
|
+
})
|
|
430
499
|
});
|
|
431
500
|
/**
|
|
432
501
|
* Used to export the wallet for a given user
|
|
@@ -527,7 +596,10 @@ export class BaseAlchemySigner {
|
|
|
527
596
|
redirectParams: params.redirectParams,
|
|
528
597
|
});
|
|
529
598
|
this.sessionManager.setTemporarySession({ orgId });
|
|
530
|
-
this.store.setState({
|
|
599
|
+
this.store.setState({
|
|
600
|
+
status: AlchemySignerStatus.AWAITING_EMAIL_AUTH,
|
|
601
|
+
error: null,
|
|
602
|
+
});
|
|
531
603
|
// We wait for the session manager to emit a connected event if
|
|
532
604
|
// cross tab sessions are permitted
|
|
533
605
|
return new Promise((resolve) => {
|
|
@@ -549,6 +621,7 @@ export class BaseAlchemySigner {
|
|
|
549
621
|
bundle: params.bundle,
|
|
550
622
|
orgId: temporarySession.orgId,
|
|
551
623
|
connectedEventName: "connectedEmail",
|
|
624
|
+
authenticatingType: "email",
|
|
552
625
|
});
|
|
553
626
|
return user;
|
|
554
627
|
}
|
|
@@ -608,10 +681,12 @@ export class BaseAlchemySigner {
|
|
|
608
681
|
enumerable: true,
|
|
609
682
|
configurable: true,
|
|
610
683
|
writable: true,
|
|
611
|
-
value: ({ bundle, orgId, }) => this.inner.completeAuthWithBundle({
|
|
684
|
+
value: ({ bundle, orgId, idToken, }) => this.inner.completeAuthWithBundle({
|
|
612
685
|
bundle,
|
|
613
686
|
orgId,
|
|
614
687
|
connectedEventName: "connectedOauth",
|
|
688
|
+
authenticatingType: "oauth",
|
|
689
|
+
idToken,
|
|
615
690
|
})
|
|
616
691
|
});
|
|
617
692
|
Object.defineProperty(this, "registerListeners", {
|
|
@@ -623,6 +698,7 @@ export class BaseAlchemySigner {
|
|
|
623
698
|
this.store.setState({
|
|
624
699
|
user: session.user,
|
|
625
700
|
status: AlchemySignerStatus.CONNECTED,
|
|
701
|
+
error: null,
|
|
626
702
|
});
|
|
627
703
|
});
|
|
628
704
|
this.sessionManager.on("disconnected", () => {
|
|
@@ -636,10 +712,26 @@ export class BaseAlchemySigner {
|
|
|
636
712
|
status: state.user
|
|
637
713
|
? AlchemySignerStatus.CONNECTED
|
|
638
714
|
: AlchemySignerStatus.DISCONNECTED,
|
|
715
|
+
...(state.user ? { error: null } : undefined),
|
|
639
716
|
}));
|
|
640
717
|
});
|
|
641
|
-
this.inner.on("authenticating", () => {
|
|
642
|
-
|
|
718
|
+
this.inner.on("authenticating", ({ type }) => {
|
|
719
|
+
const status = (() => {
|
|
720
|
+
switch (type) {
|
|
721
|
+
case "email":
|
|
722
|
+
return AlchemySignerStatus.AUTHENTICATING_EMAIL;
|
|
723
|
+
case "passkey":
|
|
724
|
+
return AlchemySignerStatus.AUTHENTICATING_PASSKEY;
|
|
725
|
+
case "oauth":
|
|
726
|
+
return AlchemySignerStatus.AUTHENTICATING_OAUTH;
|
|
727
|
+
default:
|
|
728
|
+
assertNever(type, "unhandled authenticating type");
|
|
729
|
+
}
|
|
730
|
+
})();
|
|
731
|
+
this.store.setState({
|
|
732
|
+
status,
|
|
733
|
+
error: null,
|
|
734
|
+
});
|
|
643
735
|
});
|
|
644
736
|
}
|
|
645
737
|
});
|
|
@@ -647,6 +739,7 @@ export class BaseAlchemySigner {
|
|
|
647
739
|
this.store = createStore(subscribeWithSelector(() => ({
|
|
648
740
|
user: null,
|
|
649
741
|
status: AlchemySignerStatus.INITIALIZING,
|
|
742
|
+
error: initialError ?? null,
|
|
650
743
|
})));
|
|
651
744
|
// NOTE: it's important that the session manager share a client
|
|
652
745
|
// with the signer. The SessionManager leverages the Signer's client
|
|
@@ -655,14 +748,15 @@ export class BaseAlchemySigner {
|
|
|
655
748
|
...sessionConfig,
|
|
656
749
|
client: this.inner,
|
|
657
750
|
});
|
|
658
|
-
this.store = createStore(subscribeWithSelector(() => ({
|
|
659
|
-
user: null,
|
|
660
|
-
status: AlchemySignerStatus.INITIALIZING,
|
|
661
|
-
})));
|
|
662
751
|
// register listeners first
|
|
663
752
|
this.registerListeners();
|
|
664
753
|
// then initialize so that we can catch those events
|
|
665
754
|
this.sessionManager.initialize();
|
|
666
755
|
}
|
|
667
756
|
}
|
|
757
|
+
function toErrorInfo(error) {
|
|
758
|
+
return error instanceof Error
|
|
759
|
+
? { name: error.name, message: error.message }
|
|
760
|
+
: { name: "Error", message: "Unknown error" };
|
|
761
|
+
}
|
|
668
762
|
//# 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 CustomSource,\n type Hex,\n type LocalAccount,\n type SignableMessage,\n type TypedData,\n type TypedDataDefinition,\n} from \"viem\";\nimport { toAccount } from \"viem/accounts\";\nimport type { Mutate, StoreApi } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport { createStore } from \"zustand/vanilla\";\nimport type { BaseSignerClient } from \"./client/base\";\nimport type { OauthConfig, OauthParams, User } from \"./client/types\";\nimport { NotAuthenticatedError } from \"./errors.js\";\nimport {\n SessionManager,\n type SessionManagerParams,\n} from \"./session/manager.js\";\nimport type { AuthParams } from \"./signer\";\nimport {\n AlchemySignerStatus,\n type AlchemySignerEvent,\n type AlchemySignerEvents,\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}\n\ntype AlchemySignerStore = {\n user: User | null;\n status: AlchemySignerStatus;\n};\n\ntype InternalStore = Mutate<\n StoreApi<AlchemySignerStore>,\n [[\"zustand/subscribeWithSelector\", never]]\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: string = \"alchemy-signer\";\n inner: TClient;\n private sessionManager: SessionManager;\n private store: InternalStore;\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 */\n constructor({ client, sessionConfig }: BaseAlchemySignerParams<TClient>) {\n this.inner = client;\n this.store = createStore(\n subscribeWithSelector(\n () =>\n ({\n user: null,\n status: AlchemySignerStatus.INITIALIZING,\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 this.store = createStore(\n subscribeWithSelector(\n () =>\n ({\n user: null,\n status: AlchemySignerStatus.INITIALIZING,\n } satisfies AlchemySignerStore)\n )\n );\n // register listeners first\n this.registerListeners();\n // then initialize so that we can catch those events\n this.sessionManager.initialize();\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 default:\n throw new Error(`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> = async (params) => {\n const { type } = params;\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 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}`> = async () => {\n const { address } = await this.inner.whoami();\n\n return address;\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}`> = async (\n msg\n ) => {\n const messageHash = hashMessage(msg);\n\n return this.inner.signRawMessage(messageHash);\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> = async (params) => {\n const messageHash = hashTypedData(params);\n\n return this.inner.signRawMessage(messageHash);\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: CustomSource[\"signTransaction\"] = 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 = {\n r: takeBytes(signatureHex, { count: 32 }),\n s: takeBytes(signatureHex, { count: 32, offset: 32 }),\n v: BigInt(takeBytes(signatureHex, { count: 1, offset: 64 })),\n };\n\n return serializeFn(tx, signature);\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> = async (\n email\n ) => {\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 async (params) => {\n return this.inner.addPasskey(params ?? {});\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 private authenticateWithEmail = async (\n params: Extract<AuthParams, { type: \"email\" }>\n ): Promise<User> => {\n if (\"email\" in params) {\n const existingUser = await this.getUser(params.email);\n const expirationSeconds = Math.floor(\n this.sessionManager.expirationTimeMs / 1000\n );\n\n const { orgId } = existingUser\n ? await this.inner.initEmailAuth({\n email: params.email,\n expirationSeconds,\n redirectParams: params.redirectParams,\n })\n : await this.inner.createAccount({\n type: \"email\",\n email: params.email,\n expirationSeconds,\n redirectParams: params.redirectParams,\n });\n\n this.sessionManager.setTemporarySession({ orgId });\n this.store.setState({ status: AlchemySignerStatus.AWAITING_EMAIL_AUTH });\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(\n \"connected\",\n (session) => {\n resolve(session.user);\n removeListener();\n }\n );\n });\n } else {\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 });\n\n return user;\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({ status: AlchemySignerStatus.DISCONNECTED });\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: Math.floor(\n this.sessionManager.expirationTimeMs / 1000\n ),\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 handleOauthReturn = ({\n bundle,\n orgId,\n }: Extract<AuthParams, { type: \"oauthReturn\" }>): Promise<User> =>\n this.inner.completeAuthWithBundle({\n bundle,\n orgId,\n connectedEventName: \"connectedOauth\",\n });\n\n private registerListeners = () => {\n this.sessionManager.on(\"connected\", (session) => {\n this.store.setState({\n user: session.user,\n status: AlchemySignerStatus.CONNECTED,\n });\n });\n\n this.sessionManager.on(\"disconnected\", () => {\n this.store.setState({\n user: null,\n status: AlchemySignerStatus.DISCONNECTED,\n });\n });\n\n this.sessionManager.on(\"initialized\", () => {\n this.store.setState((state) => ({\n status: state.user\n ? AlchemySignerStatus.CONNECTED\n : AlchemySignerStatus.DISCONNECTED,\n }));\n });\n\n this.inner.on(\"authenticating\", () => {\n this.store.setState({ status: AlchemySignerStatus.AUTHENTICATING });\n });\n };\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 type { Mutate, StoreApi } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport { createStore } from \"zustand/vanilla\";\nimport type { BaseSignerClient } from \"./client/base\";\nimport type { OauthConfig, OauthParams, User } 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 { AuthParams } from \"./signer\";\nimport {\n AlchemySignerStatus,\n type AlchemySignerEvent,\n type AlchemySignerEvents,\n type ErrorInfo,\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};\n\ntype InternalStore = Mutate<\n StoreApi<AlchemySignerStore>,\n [[\"zustand/subscribeWithSelector\", never]]\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: string = \"alchemy-signer\";\n inner: TClient;\n private sessionManager: SessionManager;\n private store: InternalStore;\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 } 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 }\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 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 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 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 = {\n r: takeBytes(signatureHex, { count: 32 }),\n s: takeBytes(signatureHex, { count: 32, offset: 32 }),\n v: BigInt(takeBytes(signatureHex, { count: 1, offset: 64 })),\n };\n\n return serializeFn(tx, signature);\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 /**\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 private authenticateWithEmail = async (\n params: Extract<AuthParams, { type: \"email\" }>\n ): Promise<User> => {\n if (\"email\" in params) {\n const existingUser = await this.getUser(params.email);\n const expirationSeconds = Math.floor(\n this.sessionManager.expirationTimeMs / 1000\n );\n\n const { orgId } = existingUser\n ? await this.inner.initEmailAuth({\n email: params.email,\n expirationSeconds,\n redirectParams: params.redirectParams,\n })\n : await this.inner.createAccount({\n type: \"email\",\n email: params.email,\n expirationSeconds,\n redirectParams: params.redirectParams,\n });\n\n this.sessionManager.setTemporarySession({ orgId });\n this.store.setState({\n status: AlchemySignerStatus.AWAITING_EMAIL_AUTH,\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(\n \"connected\",\n (session) => {\n resolve(session.user);\n removeListener();\n }\n );\n });\n } else {\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 return user;\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({ status: AlchemySignerStatus.DISCONNECTED });\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: Math.floor(\n this.sessionManager.expirationTimeMs / 1000\n ),\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 handleOauthReturn = ({\n bundle,\n orgId,\n idToken,\n }: Extract<AuthParams, { type: \"oauthReturn\" }>): Promise<User> =>\n this.inner.completeAuthWithBundle({\n bundle,\n orgId,\n connectedEventName: \"connectedOauth\",\n authenticatingType: \"oauth\",\n idToken,\n });\n\n private registerListeners = () => {\n this.sessionManager.on(\"connected\", (session) => {\n this.store.setState({\n user: session.user,\n status: AlchemySignerStatus.CONNECTED,\n error: null,\n });\n });\n\n this.sessionManager.on(\"disconnected\", () => {\n this.store.setState({\n user: null,\n status: AlchemySignerStatus.DISCONNECTED,\n });\n });\n\n this.sessionManager.on(\"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 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 default:\n assertNever(type, \"unhandled authenticating type\");\n }\n })();\n\n this.store.setState({\n status,\n error: null,\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"]}
|
|
@@ -2,7 +2,7 @@ import { type ConnectionConfig } from "@aa-sdk/core";
|
|
|
2
2
|
import { TurnkeyClient, type TSignedRequest } from "@turnkey/http";
|
|
3
3
|
import EventEmitter from "eventemitter3";
|
|
4
4
|
import type { Hex } from "viem";
|
|
5
|
-
import type { AlchemySignerClientEvents, CreateAccountParams, EmailAuthParams, GetWebAuthnAttestationResult, OauthConfig, OauthParams, SignerBody, SignerResponse, SignupResponse, User } from "./types.js";
|
|
5
|
+
import type { AlchemySignerClientEvents, AuthenticatingEventMetadata, CreateAccountParams, EmailAuthParams, GetWebAuthnAttestationResult, OauthConfig, OauthParams, SignerBody, SignerResponse, SignupResponse, User } from "./types.js";
|
|
6
6
|
export interface BaseSignerClientParams {
|
|
7
7
|
stamper: TurnkeyClient["stamper"];
|
|
8
8
|
connection: ConnectionConfig;
|
|
@@ -64,6 +64,8 @@ export declare abstract class BaseSignerClient<TExportWalletParams = unknown> {
|
|
|
64
64
|
bundle: string;
|
|
65
65
|
orgId: string;
|
|
66
66
|
connectedEventName: keyof AlchemySignerClientEvents;
|
|
67
|
+
authenticatingType: AuthenticatingEventMetadata["type"];
|
|
68
|
+
idToken?: string;
|
|
67
69
|
}): Promise<User>;
|
|
68
70
|
abstract oauthWithRedirect(args: Extract<OauthParams, {
|
|
69
71
|
mode: "redirect";
|
|
@@ -98,10 +100,11 @@ export declare abstract class BaseSignerClient<TExportWalletParams = unknown> {
|
|
|
98
100
|
* Retrieves the current user or fetches the user information if not already available.
|
|
99
101
|
*
|
|
100
102
|
* @param {string} [orgId] optional organization ID, defaults to the user's organization ID
|
|
103
|
+
* @param {string} idToken an OIDC ID token containing additional user information
|
|
101
104
|
* @returns {Promise<User>} A promise that resolves to the user object
|
|
102
105
|
* @throws {Error} if no organization ID is provided when there is no current user
|
|
103
106
|
*/
|
|
104
|
-
whoami: (orgId?: string | undefined) => Promise<User>;
|
|
107
|
+
whoami: (orgId?: string | undefined, idToken?: string) => Promise<User>;
|
|
105
108
|
/**
|
|
106
109
|
* Generates a stamped whoami request for the current user. This request can then be used to call /signer/v1/whoami to get the user information.
|
|
107
110
|
* This is useful if you want to get the user information in a different context like a server. You can pass the stamped request to the server
|
|
@@ -251,11 +254,7 @@ export declare abstract class BaseSignerClient<TExportWalletParams = unknown> {
|
|
|
251
254
|
privateKeys: {
|
|
252
255
|
privateKeyId?: string | undefined;
|
|
253
256
|
addresses?: {
|
|
254
|
-
format?: "ADDRESS_FORMAT_UNCOMPRESSED" | "ADDRESS_FORMAT_COMPRESSED" | "ADDRESS_FORMAT_ETHEREUM" | "ADDRESS_FORMAT_SOLANA" | "ADDRESS_FORMAT_COSMOS" | undefined;
|
|
255
|
-
* Returns the current user or null if no user is set.
|
|
256
|
-
*
|
|
257
|
-
* @returns {User | null} the current user object or null if no user is available
|
|
258
|
-
*/
|
|
257
|
+
format?: "ADDRESS_FORMAT_UNCOMPRESSED" | "ADDRESS_FORMAT_COMPRESSED" | "ADDRESS_FORMAT_ETHEREUM" | "ADDRESS_FORMAT_SOLANA" | "ADDRESS_FORMAT_COSMOS" | undefined;
|
|
259
258
|
address?: string | undefined;
|
|
260
259
|
}[] | undefined;
|
|
261
260
|
}[];
|
|
@@ -271,11 +270,7 @@ export declare abstract class BaseSignerClient<TExportWalletParams = unknown> {
|
|
|
271
270
|
privateKeys: {
|
|
272
271
|
privateKeyId?: string | undefined;
|
|
273
272
|
addresses?: {
|
|
274
|
-
format?: "ADDRESS_FORMAT_UNCOMPRESSED" | "ADDRESS_FORMAT_COMPRESSED" | "ADDRESS_FORMAT_ETHEREUM" | "ADDRESS_FORMAT_SOLANA" | "ADDRESS_FORMAT_COSMOS" | undefined;
|
|
275
|
-
* Returns the current user or null if no user is set.
|
|
276
|
-
*
|
|
277
|
-
* @returns {User | null} the current user object or null if no user is available
|
|
278
|
-
*/
|
|
273
|
+
format?: "ADDRESS_FORMAT_UNCOMPRESSED" | "ADDRESS_FORMAT_COMPRESSED" | "ADDRESS_FORMAT_ETHEREUM" | "ADDRESS_FORMAT_SOLANA" | "ADDRESS_FORMAT_COSMOS" | undefined;
|
|
279
274
|
address?: string | undefined;
|
|
280
275
|
}[] | undefined;
|
|
281
276
|
}[];
|
package/dist/esm/client/base.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ConnectionConfigSchema } from "@aa-sdk/core";
|
|
2
2
|
import { TurnkeyClient } from "@turnkey/http";
|
|
3
3
|
import EventEmitter from "eventemitter3";
|
|
4
|
+
import { jwtDecode } from "jwt-decode";
|
|
4
5
|
import { NotAuthenticatedError } from "../errors.js";
|
|
5
6
|
import { base64UrlEncode } from "../utils/base64UrlEncode.js";
|
|
6
7
|
import { assertNever } from "../utils/typeAssertions.js";
|
|
@@ -121,6 +122,7 @@ export class BaseSignerClient {
|
|
|
121
122
|
* Retrieves the current user or fetches the user information if not already available.
|
|
122
123
|
*
|
|
123
124
|
* @param {string} [orgId] optional organization ID, defaults to the user's organization ID
|
|
125
|
+
* @param {string} idToken an OIDC ID token containing additional user information
|
|
124
126
|
* @returns {Promise<User>} A promise that resolves to the user object
|
|
125
127
|
* @throws {Error} if no organization ID is provided when there is no current user
|
|
126
128
|
*/
|
|
@@ -128,7 +130,7 @@ export class BaseSignerClient {
|
|
|
128
130
|
enumerable: true,
|
|
129
131
|
configurable: true,
|
|
130
132
|
writable: true,
|
|
131
|
-
value: async (orgId = this.user?.orgId) => {
|
|
133
|
+
value: async (orgId = this.user?.orgId, idToken) => {
|
|
132
134
|
if (this.user) {
|
|
133
135
|
return this.user;
|
|
134
136
|
}
|
|
@@ -141,6 +143,14 @@ export class BaseSignerClient {
|
|
|
141
143
|
const user = await this.request("/v1/whoami", {
|
|
142
144
|
stampedRequest,
|
|
143
145
|
});
|
|
146
|
+
if (idToken) {
|
|
147
|
+
const claims = jwtDecode(idToken);
|
|
148
|
+
user.idToken = idToken;
|
|
149
|
+
user.claims = claims;
|
|
150
|
+
if (typeof claims.email === "string") {
|
|
151
|
+
user.email = claims.email;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
144
154
|
const credentialId = (() => {
|
|
145
155
|
try {
|
|
146
156
|
return JSON.parse(stampedRequest?.stamp.stampHeaderValue)
|