@fourt/sdk 1.1.6 → 1.2.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/index.cjs +268 -139
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -41
- package/dist/index.d.ts +66 -41
- package/dist/index.js +270 -141
- package/dist/index.js.map +1 -1
- package/package.json +14 -15
package/dist/index.cjs
CHANGED
|
@@ -39,14 +39,13 @@ var import_zustand = require("zustand");
|
|
|
39
39
|
var import_middleware = require("zustand/middleware");
|
|
40
40
|
var SessionStore = class {
|
|
41
41
|
_store;
|
|
42
|
-
/**
|
|
43
|
-
* Initializes a new instance of the `SessionStore` class by creating a new `zustand`store with the initial state.
|
|
44
|
-
*/
|
|
45
42
|
constructor() {
|
|
46
43
|
this._store = (0, import_zustand.createStore)()(
|
|
47
44
|
(0, import_middleware.persist)(this._getInitialState, {
|
|
48
|
-
name: "fourt
|
|
49
|
-
storage: (0, import_middleware.createJSONStorage)(() => localStorage)
|
|
45
|
+
name: "fourt-session",
|
|
46
|
+
storage: (0, import_middleware.createJSONStorage)(() => localStorage),
|
|
47
|
+
// keep only these keys in persisted storage
|
|
48
|
+
partialize: (state) => ({ bundle: state.bundle, type: state.type })
|
|
50
49
|
})
|
|
51
50
|
);
|
|
52
51
|
}
|
|
@@ -402,26 +401,29 @@ var UserModule = class {
|
|
|
402
401
|
this._webSignerClient = _webSignerClient;
|
|
403
402
|
}
|
|
404
403
|
/**
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
* @returns {User | undefined} user information.
|
|
404
|
+
* Retrieves information for the authenticated user.
|
|
405
|
+
* Assumes a user is already logged in, otherwise it will throw an error.
|
|
408
406
|
*/
|
|
409
|
-
|
|
410
|
-
return this._webSignerClient.
|
|
407
|
+
async getInfo() {
|
|
408
|
+
return this._webSignerClient.getUser();
|
|
411
409
|
}
|
|
412
|
-
/**
|
|
413
|
-
*
|
|
414
|
-
* @returns {string | undefined} user token.
|
|
410
|
+
/**
|
|
411
|
+
* Checks if a user is currently logged in to the fourt.io SDK.
|
|
415
412
|
*/
|
|
416
|
-
|
|
413
|
+
async isLoggedIn() {
|
|
414
|
+
return this._webSignerClient.isLoggedIn();
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Generates an access token with a lifespan of 15 minutes.
|
|
418
|
+
* Assumes a user is already logged in, otherwise it will throw an error.
|
|
419
|
+
*/
|
|
420
|
+
async getToken() {
|
|
417
421
|
return this._webSignerClient.getToken();
|
|
418
422
|
}
|
|
419
423
|
/**
|
|
420
424
|
* Logs out the user.
|
|
421
|
-
*
|
|
422
|
-
* @returns {void}
|
|
423
425
|
*/
|
|
424
|
-
logout() {
|
|
426
|
+
async logout() {
|
|
425
427
|
return this._webSignerClient.logout();
|
|
426
428
|
}
|
|
427
429
|
};
|
|
@@ -488,14 +490,17 @@ var UnauthenticatedError = class _UnauthenticatedError extends SDKError {
|
|
|
488
490
|
}
|
|
489
491
|
};
|
|
490
492
|
|
|
491
|
-
// src/types/
|
|
493
|
+
// src/types/routes.ts
|
|
492
494
|
var ROUTE_METHOD_MAP = {
|
|
493
495
|
"/v1/signup": "POST",
|
|
494
496
|
"/v1/email-auth": "POST",
|
|
495
497
|
"/v1/lookup": "POST",
|
|
496
498
|
"/v1/signin": "POST",
|
|
497
499
|
"/v1/sign": "POST",
|
|
498
|
-
"v1/oauth/init": "POST"
|
|
500
|
+
"/v1/oauth/init": "POST",
|
|
501
|
+
"/v1/refresh": "POST",
|
|
502
|
+
"/v1/logout": "POST",
|
|
503
|
+
"/v1/me": "GET"
|
|
499
504
|
};
|
|
500
505
|
|
|
501
506
|
// src/signer/index.ts
|
|
@@ -505,7 +510,8 @@ var SignerClient = class {
|
|
|
505
510
|
_turnkeyClient;
|
|
506
511
|
_configuration;
|
|
507
512
|
_sessionStore;
|
|
508
|
-
|
|
513
|
+
_refreshPromise;
|
|
514
|
+
_refreshTimer;
|
|
509
515
|
constructor({
|
|
510
516
|
stamper,
|
|
511
517
|
configuration: { apiUrl, paymasterRpcUrl, ...requiredConfiguration }
|
|
@@ -521,54 +527,97 @@ var SignerClient = class {
|
|
|
521
527
|
};
|
|
522
528
|
this._sessionStore = new SessionStore();
|
|
523
529
|
}
|
|
524
|
-
logout() {
|
|
525
|
-
this._user = void 0;
|
|
526
|
-
this.sessionStore.clearAll();
|
|
527
|
-
}
|
|
528
530
|
get configuration() {
|
|
529
531
|
return this._configuration;
|
|
530
532
|
}
|
|
531
|
-
|
|
532
|
-
if (this.
|
|
533
|
-
|
|
534
|
-
this.
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
533
|
+
async getUser() {
|
|
534
|
+
if (this._sessionStore.user) return this._sessionStore.user;
|
|
535
|
+
try {
|
|
536
|
+
const user = await this.request("/v1/me");
|
|
537
|
+
this._sessionStore.user = user;
|
|
538
|
+
return user;
|
|
539
|
+
} catch (error) {
|
|
540
|
+
if (error instanceof UnauthorizedError) {
|
|
541
|
+
try {
|
|
542
|
+
await this._refreshToken();
|
|
543
|
+
const user = await this.request("/v1/me");
|
|
544
|
+
this._sessionStore.user = user;
|
|
545
|
+
return user;
|
|
546
|
+
} catch (error2) {
|
|
547
|
+
throw error2;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
throw error;
|
|
541
551
|
}
|
|
542
|
-
if (this.sessionStore.user) this._user = this.sessionStore.user;
|
|
543
|
-
return this._user;
|
|
544
552
|
}
|
|
545
|
-
|
|
546
|
-
|
|
553
|
+
async isLoggedIn() {
|
|
554
|
+
const token = this._sessionStore.token;
|
|
555
|
+
if (token && !this._isTokenExpired(token)) return true;
|
|
556
|
+
try {
|
|
557
|
+
await this._refreshToken();
|
|
558
|
+
return !!this._sessionStore.token;
|
|
559
|
+
} catch {
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
547
562
|
}
|
|
548
|
-
|
|
549
|
-
this.
|
|
563
|
+
async getToken() {
|
|
564
|
+
if (!this._sessionStore.token) {
|
|
565
|
+
try {
|
|
566
|
+
await this._refreshToken();
|
|
567
|
+
} catch {
|
|
568
|
+
throw new UnauthorizedError({
|
|
569
|
+
message: "No token found, user might not be logged in"
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
} else if (this._isTokenExpired(this._sessionStore.token)) {
|
|
573
|
+
try {
|
|
574
|
+
await this._refreshToken();
|
|
575
|
+
} catch {
|
|
576
|
+
throw new UnauthorizedError({
|
|
577
|
+
message: "Token expired and refresh failed"
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
const token = this._sessionStore.token;
|
|
582
|
+
if (!token) {
|
|
583
|
+
throw new UnauthorizedError({
|
|
584
|
+
message: "No token found, user might not be logged in"
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
return token;
|
|
550
588
|
}
|
|
551
|
-
|
|
552
|
-
|
|
589
|
+
_isTokenExpired(token) {
|
|
590
|
+
try {
|
|
591
|
+
const decoded = (0, import_jwt_decode.jwtDecode)(token);
|
|
592
|
+
if (decoded.exp) {
|
|
593
|
+
return decoded.exp * 1e3 <= Date.now();
|
|
594
|
+
}
|
|
595
|
+
return true;
|
|
596
|
+
} catch {
|
|
597
|
+
return true;
|
|
598
|
+
}
|
|
553
599
|
}
|
|
554
|
-
|
|
555
|
-
|
|
600
|
+
async logout() {
|
|
601
|
+
if (this._refreshTimer) clearTimeout(this._refreshTimer);
|
|
602
|
+
this._refreshTimer = void 0;
|
|
603
|
+
await this.request("/v1/logout");
|
|
604
|
+
this._sessionStore.clearAll();
|
|
556
605
|
}
|
|
557
606
|
async signRawMessage(msg) {
|
|
558
|
-
if (!this.
|
|
607
|
+
if (!this._sessionStore.token || !this._sessionStore.user) {
|
|
559
608
|
throw new UnauthorizedError({
|
|
560
609
|
message: "SignerClient must be authenticated to sign a message"
|
|
561
610
|
});
|
|
562
611
|
}
|
|
563
612
|
const stampedRequest = await this._turnkeyClient.stampSignRawPayload({
|
|
564
|
-
organizationId: this.
|
|
613
|
+
organizationId: this._sessionStore.user.subOrgId,
|
|
565
614
|
type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2",
|
|
566
615
|
timestampMs: Date.now().toString(),
|
|
567
616
|
parameters: {
|
|
568
617
|
encoding: "PAYLOAD_ENCODING_HEXADECIMAL",
|
|
569
618
|
hashFunction: "HASH_FUNCTION_NO_OP",
|
|
570
619
|
payload: msg,
|
|
571
|
-
signWith: this.
|
|
620
|
+
signWith: this._sessionStore.user.walletAddress
|
|
572
621
|
}
|
|
573
622
|
});
|
|
574
623
|
const { signature } = await this.request("/v1/sign", {
|
|
@@ -576,8 +625,11 @@ var SignerClient = class {
|
|
|
576
625
|
});
|
|
577
626
|
return signature;
|
|
578
627
|
}
|
|
579
|
-
|
|
580
|
-
|
|
628
|
+
set stamper(stamper) {
|
|
629
|
+
this._turnkeyClient.stamper = stamper;
|
|
630
|
+
}
|
|
631
|
+
get stamper() {
|
|
632
|
+
return this._turnkeyClient.stamper;
|
|
581
633
|
}
|
|
582
634
|
async lookUpUser(email) {
|
|
583
635
|
try {
|
|
@@ -597,7 +649,7 @@ var SignerClient = class {
|
|
|
597
649
|
}
|
|
598
650
|
}
|
|
599
651
|
async whoAmI(subOrgId) {
|
|
600
|
-
const orgId = subOrgId || this.
|
|
652
|
+
const orgId = subOrgId || this._sessionStore.user?.subOrgId;
|
|
601
653
|
if (!orgId) throw new BadRequestError({ message: "No orgId provided" });
|
|
602
654
|
const stampedRequest = await this._turnkeyClient.stampGetWhoami({
|
|
603
655
|
organizationId: orgId
|
|
@@ -612,19 +664,20 @@ var SignerClient = class {
|
|
|
612
664
|
return void 0;
|
|
613
665
|
}
|
|
614
666
|
})();
|
|
615
|
-
this.
|
|
667
|
+
this._sessionStore.user = {
|
|
616
668
|
...user,
|
|
617
669
|
credentialId
|
|
618
670
|
};
|
|
619
|
-
this.
|
|
620
|
-
this.
|
|
671
|
+
this._sessionStore.token = token;
|
|
672
|
+
this._scheduleRefresh(token);
|
|
621
673
|
}
|
|
622
674
|
async request(route, body) {
|
|
623
675
|
const url = new URL(`${route}`, this._configuration.apiUrl);
|
|
624
|
-
const token = this.
|
|
676
|
+
const token = this._sessionStore.token;
|
|
625
677
|
const headers = {
|
|
626
678
|
"Content-Type": "application/json",
|
|
627
|
-
"X-FOURT-KEY": this._configuration.apiKey
|
|
679
|
+
"X-FOURT-KEY": this._configuration.apiKey,
|
|
680
|
+
"X-CSRF-TOKEN": this._getCookie("csrfToken") ?? ""
|
|
628
681
|
};
|
|
629
682
|
if (token) {
|
|
630
683
|
headers["Authorization"] = `Bearer ${token}`;
|
|
@@ -639,7 +692,6 @@ var SignerClient = class {
|
|
|
639
692
|
if (error) {
|
|
640
693
|
switch (error.kind) {
|
|
641
694
|
case "UnauthorizedError": {
|
|
642
|
-
this.logout();
|
|
643
695
|
throw new UnauthorizedError({ message: error.message });
|
|
644
696
|
}
|
|
645
697
|
case "NotFoundError": {
|
|
@@ -655,11 +707,88 @@ var SignerClient = class {
|
|
|
655
707
|
}
|
|
656
708
|
return { ...data };
|
|
657
709
|
}
|
|
710
|
+
_scheduleRefresh(token) {
|
|
711
|
+
try {
|
|
712
|
+
const decoded = (0, import_jwt_decode.jwtDecode)(token);
|
|
713
|
+
if (!decoded.exp) return;
|
|
714
|
+
const expiryDate = new Date(decoded.exp * 1e3);
|
|
715
|
+
const refreshDate = (0, import_date_fns.subMinutes)(expiryDate, 2);
|
|
716
|
+
const delay = (0, import_date_fns.isBefore)(refreshDate, /* @__PURE__ */ new Date()) ? 0 : (0, import_date_fns.differenceInMilliseconds)(refreshDate, /* @__PURE__ */ new Date());
|
|
717
|
+
if (this._refreshTimer) clearTimeout(this._refreshTimer);
|
|
718
|
+
this._refreshTimer = setTimeout(() => {
|
|
719
|
+
this._refreshTimer = void 0;
|
|
720
|
+
this._refreshToken();
|
|
721
|
+
}, delay);
|
|
722
|
+
} catch {
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
async _refreshToken() {
|
|
726
|
+
if (this._refreshPromise) return this._refreshPromise;
|
|
727
|
+
this._refreshPromise = (async () => {
|
|
728
|
+
const TIMEOUT_MS = 1e4;
|
|
729
|
+
const RETRY_DELAY_MS = 5e3;
|
|
730
|
+
try {
|
|
731
|
+
const refreshPromise = this.request("/v1/refresh");
|
|
732
|
+
const data = await Promise.race([
|
|
733
|
+
refreshPromise,
|
|
734
|
+
new Promise(
|
|
735
|
+
(_, reject) => setTimeout(() => reject(new Error("Refresh timeout")), TIMEOUT_MS)
|
|
736
|
+
)
|
|
737
|
+
]);
|
|
738
|
+
if (!data || !data.token) {
|
|
739
|
+
throw new UnauthorizedError({
|
|
740
|
+
message: "Refresh did not return a token"
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
this._sessionStore.token = data.token;
|
|
744
|
+
this._scheduleRefresh(data.token);
|
|
745
|
+
} catch (error) {
|
|
746
|
+
if (error instanceof UnauthorizedError) {
|
|
747
|
+
try {
|
|
748
|
+
this._sessionStore.clearAll();
|
|
749
|
+
} catch {
|
|
750
|
+
}
|
|
751
|
+
throw error;
|
|
752
|
+
}
|
|
753
|
+
if (this._refreshTimer) clearTimeout(this._refreshTimer);
|
|
754
|
+
const MAX_RETRIES = 5;
|
|
755
|
+
let retryCount = 0;
|
|
756
|
+
this._refreshTimer = setTimeout(() => {
|
|
757
|
+
this._refreshTimer = void 0;
|
|
758
|
+
void this._refreshToken().catch(() => {
|
|
759
|
+
retryCount++;
|
|
760
|
+
if (retryCount <= MAX_RETRIES) {
|
|
761
|
+
const nextDelay = Math.min(
|
|
762
|
+
RETRY_DELAY_MS * 2 ** (retryCount - 1),
|
|
763
|
+
6e4
|
|
764
|
+
);
|
|
765
|
+
this._refreshTimer = setTimeout(() => {
|
|
766
|
+
this._refreshTimer = void 0;
|
|
767
|
+
void this._refreshToken().catch(() => {
|
|
768
|
+
});
|
|
769
|
+
}, nextDelay);
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
}, RETRY_DELAY_MS);
|
|
773
|
+
throw error;
|
|
774
|
+
} finally {
|
|
775
|
+
this._refreshPromise = void 0;
|
|
776
|
+
}
|
|
777
|
+
})();
|
|
778
|
+
return this._refreshPromise;
|
|
779
|
+
}
|
|
780
|
+
_getCookie(name) {
|
|
781
|
+
if (typeof document === "undefined") return null;
|
|
782
|
+
const match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)"));
|
|
783
|
+
return match ? decodeURIComponent(match[2]) : null;
|
|
784
|
+
}
|
|
658
785
|
};
|
|
659
786
|
|
|
660
787
|
// src/signer/web.ts
|
|
661
788
|
var WebSignerClient = class extends SignerClient {
|
|
662
|
-
|
|
789
|
+
iframeStamper;
|
|
790
|
+
webauthnStamper;
|
|
791
|
+
iframeConfig;
|
|
663
792
|
oauthConfiguration;
|
|
664
793
|
/**
|
|
665
794
|
* Initializes a new instance of the `WebSignerClient` class.
|
|
@@ -672,54 +801,56 @@ var WebSignerClient = class extends SignerClient {
|
|
|
672
801
|
iframe,
|
|
673
802
|
oauth
|
|
674
803
|
}) {
|
|
675
|
-
const
|
|
804
|
+
const iframeConfig = {
|
|
805
|
+
iframeElementId: iframe?.iframeElementId ?? "turnkey-iframe",
|
|
806
|
+
iframeContainerId: iframe?.iframeContainerId ?? "signer-iframe-container"
|
|
807
|
+
};
|
|
676
808
|
const iframeContainer = document.createElement("div");
|
|
677
|
-
iframeContainer.id = iframeContainerId;
|
|
809
|
+
iframeContainer.id = iframeConfig.iframeContainerId;
|
|
678
810
|
iframeContainer.style.display = "none";
|
|
679
811
|
document.body.appendChild(iframeContainer);
|
|
680
|
-
const webauthnStamper = new import_webauthn_stamper.WebauthnStamper({ rpId: webauthn.rpId });
|
|
681
812
|
const iframeStamper = new import_iframe_stamper.IframeStamper({
|
|
682
813
|
iframeUrl: "https://auth.turnkey.com",
|
|
683
|
-
iframeElementId:
|
|
684
|
-
iframeContainer: document.getElementById(iframeContainerId)
|
|
814
|
+
iframeElementId: iframeConfig.iframeElementId,
|
|
815
|
+
iframeContainer: document.getElementById(iframeConfig.iframeContainerId)
|
|
685
816
|
});
|
|
686
817
|
super({
|
|
687
818
|
stamper: iframeStamper,
|
|
688
819
|
// Initialized to iframeStamper; can be either webauthnStamper or iframeStamper
|
|
689
820
|
configuration
|
|
690
821
|
});
|
|
691
|
-
this.
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
};
|
|
822
|
+
this.iframeStamper = iframeStamper;
|
|
823
|
+
this.iframeConfig = iframeConfig;
|
|
824
|
+
this.webauthnStamper = new import_webauthn_stamper.WebauthnStamper({ rpId: webauthn.rpId });
|
|
695
825
|
this.oauthConfiguration = oauth;
|
|
696
826
|
}
|
|
827
|
+
async logout() {
|
|
828
|
+
super.logout();
|
|
829
|
+
this.iframeStamper.clear();
|
|
830
|
+
const stamper = new import_iframe_stamper.IframeStamper({
|
|
831
|
+
iframeUrl: "https://auth.turnkey.com",
|
|
832
|
+
iframeElementId: this.iframeConfig.iframeElementId,
|
|
833
|
+
iframeContainer: document.getElementById(
|
|
834
|
+
this.iframeConfig.iframeContainerId
|
|
835
|
+
)
|
|
836
|
+
});
|
|
837
|
+
this.iframeStamper = stamper;
|
|
838
|
+
await this._initIframeStamper();
|
|
839
|
+
}
|
|
697
840
|
async signRawMessage(msg) {
|
|
698
|
-
await this.
|
|
841
|
+
await this._updateStamper();
|
|
699
842
|
return super.signRawMessage(msg);
|
|
700
843
|
}
|
|
701
|
-
async logout() {
|
|
702
|
-
this._stampers.iframe.clear();
|
|
703
|
-
await this._stampers.iframe.init();
|
|
704
|
-
return super.logout();
|
|
705
|
-
}
|
|
706
844
|
/**
|
|
707
|
-
*
|
|
845
|
+
* Get the pre-filled URL for initiating oauth with a specific provider.
|
|
708
846
|
*
|
|
847
|
+
* @param {string} provider provider for which we are getting the URL, currently google or apple
|
|
709
848
|
*/
|
|
710
|
-
async
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
} else {
|
|
716
|
-
this.stamper = this._stampers.iframe;
|
|
717
|
-
await this.completeAuthWithBundle({
|
|
718
|
-
bundle: this._sessionStore.bundle,
|
|
719
|
-
subOrgId: this.user?.subOrgId,
|
|
720
|
-
sessionType: this._sessionStore.type
|
|
721
|
-
});
|
|
722
|
-
}
|
|
849
|
+
async getOAuthInitUrl(provider) {
|
|
850
|
+
const { url } = await this.request("/v1/oauth/init", {
|
|
851
|
+
provider
|
|
852
|
+
});
|
|
853
|
+
return url;
|
|
723
854
|
}
|
|
724
855
|
/**
|
|
725
856
|
* Signs in a user with webauthn.
|
|
@@ -731,15 +862,15 @@ var WebSignerClient = class extends SignerClient {
|
|
|
731
862
|
if (!existingUserSubOrgId) {
|
|
732
863
|
await this._createAccount({ method: "webauthn", email });
|
|
733
864
|
} else {
|
|
734
|
-
this.stamper = this.
|
|
865
|
+
this.stamper = this.webauthnStamper;
|
|
735
866
|
await this.whoAmI(existingUserSubOrgId);
|
|
736
867
|
this._sessionStore.type = "passkeys" /* Passkeys */;
|
|
737
|
-
if (!this.user || !this.user.credentialId) {
|
|
868
|
+
if (!this._sessionStore.user || !this._sessionStore.user.credentialId) {
|
|
738
869
|
return;
|
|
739
870
|
}
|
|
740
|
-
this.
|
|
871
|
+
this.webauthnStamper.allowCredentials = [
|
|
741
872
|
{
|
|
742
|
-
id: LibBase64.toBuffer(this.user.credentialId),
|
|
873
|
+
id: LibBase64.toBuffer(this._sessionStore.user.credentialId),
|
|
743
874
|
type: "public-key",
|
|
744
875
|
transports: ["internal", "usb"]
|
|
745
876
|
}
|
|
@@ -762,23 +893,6 @@ var WebSignerClient = class extends SignerClient {
|
|
|
762
893
|
async getIframePublicKey() {
|
|
763
894
|
return await this._initIframeStamper();
|
|
764
895
|
}
|
|
765
|
-
/**
|
|
766
|
-
* Signs in a user with email.
|
|
767
|
-
*
|
|
768
|
-
* @param {EmailInitializeAuthParams} params params for the sign in
|
|
769
|
-
*/
|
|
770
|
-
async _signInWithEmail({
|
|
771
|
-
email,
|
|
772
|
-
expirationSeconds,
|
|
773
|
-
redirectUrl
|
|
774
|
-
}) {
|
|
775
|
-
return this.request("/v1/email-auth", {
|
|
776
|
-
email,
|
|
777
|
-
targetPublicKey: await this.getIframePublicKey(),
|
|
778
|
-
expirationSeconds,
|
|
779
|
-
redirectUrl: redirectUrl.toString()
|
|
780
|
-
});
|
|
781
|
-
}
|
|
782
896
|
/**
|
|
783
897
|
* Completes the authentication process with a credential bundle.
|
|
784
898
|
*
|
|
@@ -790,7 +904,7 @@ var WebSignerClient = class extends SignerClient {
|
|
|
790
904
|
sessionType
|
|
791
905
|
}) {
|
|
792
906
|
await this._initIframeStamper();
|
|
793
|
-
const result = await this.
|
|
907
|
+
const result = await this.iframeStamper.injectCredentialBundle(bundle);
|
|
794
908
|
if (!result) {
|
|
795
909
|
throw new Error("Failed to inject credential bundle");
|
|
796
910
|
}
|
|
@@ -798,6 +912,40 @@ var WebSignerClient = class extends SignerClient {
|
|
|
798
912
|
this._sessionStore.type = sessionType;
|
|
799
913
|
this._sessionStore.bundle = bundle;
|
|
800
914
|
}
|
|
915
|
+
/**
|
|
916
|
+
* Checks for an existing session and if exists, updates the stamper accordingly.
|
|
917
|
+
*/
|
|
918
|
+
async _updateStamper() {
|
|
919
|
+
if (this._sessionStore.type === void 0 && (this._sessionStore.bundle === void 0 || this._sessionStore.token === void 0))
|
|
920
|
+
return;
|
|
921
|
+
if (this._sessionStore.type === "passkeys" /* Passkeys */) {
|
|
922
|
+
this.stamper = this.webauthnStamper;
|
|
923
|
+
} else {
|
|
924
|
+
this.stamper = this.iframeStamper;
|
|
925
|
+
await this.completeAuthWithBundle({
|
|
926
|
+
bundle: this._sessionStore.bundle,
|
|
927
|
+
subOrgId: this._sessionStore.user?.subOrgId,
|
|
928
|
+
sessionType: this._sessionStore.type
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Signs in a user with email.
|
|
934
|
+
*
|
|
935
|
+
* @param {EmailInitializeAuthParams} params params for the sign in
|
|
936
|
+
*/
|
|
937
|
+
async _signInWithEmail({
|
|
938
|
+
email,
|
|
939
|
+
expirationSeconds,
|
|
940
|
+
redirectUrl
|
|
941
|
+
}) {
|
|
942
|
+
return this.request("/v1/email-auth", {
|
|
943
|
+
email,
|
|
944
|
+
targetPublicKey: await this.getIframePublicKey(),
|
|
945
|
+
expirationSeconds,
|
|
946
|
+
redirectUrl: redirectUrl.toString()
|
|
947
|
+
});
|
|
948
|
+
}
|
|
801
949
|
/**
|
|
802
950
|
* Creates a passkey account using the webauthn stamper.
|
|
803
951
|
*
|
|
@@ -807,28 +955,20 @@ var WebSignerClient = class extends SignerClient {
|
|
|
807
955
|
const { challenge, attestation } = await this._webauthnGenerateAttestation(
|
|
808
956
|
params.email
|
|
809
957
|
);
|
|
810
|
-
const {
|
|
811
|
-
token,
|
|
812
|
-
user: { id, email, subOrgId, walletAddress, salt, smartAccountAddress }
|
|
813
|
-
} = await this.request("/v1/signup", {
|
|
958
|
+
const { token, user } = await this.request("/v1/signup", {
|
|
814
959
|
passkey: {
|
|
815
960
|
challenge: LibBase64.fromBuffer(challenge),
|
|
816
961
|
attestation
|
|
817
962
|
},
|
|
818
963
|
email: params.email
|
|
819
964
|
});
|
|
820
|
-
this.user = {
|
|
821
|
-
|
|
822
|
-
email,
|
|
823
|
-
subOrgId,
|
|
824
|
-
walletAddress,
|
|
825
|
-
salt,
|
|
826
|
-
smartAccountAddress,
|
|
965
|
+
this._sessionStore.user = {
|
|
966
|
+
...user,
|
|
827
967
|
credentialId: attestation.credentialId
|
|
828
968
|
};
|
|
829
|
-
this._sessionStore.user = this.user;
|
|
830
969
|
this._sessionStore.type = "passkeys" /* Passkeys */;
|
|
831
970
|
this._sessionStore.token = token;
|
|
971
|
+
this._scheduleRefresh(token);
|
|
832
972
|
}
|
|
833
973
|
/**
|
|
834
974
|
* Creates an email account using the iframe stamper.
|
|
@@ -899,22 +1039,11 @@ var WebSignerClient = class extends SignerClient {
|
|
|
899
1039
|
return { challenge, attestation, authenticatorUserId };
|
|
900
1040
|
}
|
|
901
1041
|
async _initIframeStamper() {
|
|
902
|
-
if (!this.
|
|
903
|
-
await this.
|
|
1042
|
+
if (!this.iframeStamper.publicKey()) {
|
|
1043
|
+
await this.iframeStamper.init();
|
|
904
1044
|
}
|
|
905
|
-
this.stamper = this.
|
|
906
|
-
return this.
|
|
907
|
-
}
|
|
908
|
-
/**
|
|
909
|
-
* Get the pre-filled URL for initiating oauth with a specific provider.
|
|
910
|
-
*
|
|
911
|
-
* @param {string} provider provider for which we are getting the URL, currently google or apple
|
|
912
|
-
*/
|
|
913
|
-
async getOAuthInitUrl(provider) {
|
|
914
|
-
const { url } = await this.request("v1/oauth/init", {
|
|
915
|
-
provider
|
|
916
|
-
});
|
|
917
|
-
return url;
|
|
1045
|
+
this.stamper = this.iframeStamper;
|
|
1046
|
+
return this.iframeStamper.publicKey();
|
|
918
1047
|
}
|
|
919
1048
|
};
|
|
920
1049
|
|
|
@@ -928,13 +1057,13 @@ var ViemModule = class {
|
|
|
928
1057
|
this._signerClient = _signerClient;
|
|
929
1058
|
}
|
|
930
1059
|
async toLocalAccount() {
|
|
931
|
-
const user = this._signerClient.
|
|
1060
|
+
const user = await this._signerClient.getUser();
|
|
932
1061
|
if (!user) {
|
|
933
1062
|
throw new UnauthenticatedError({ message: "Signer not authenticated" });
|
|
934
1063
|
}
|
|
935
1064
|
return (0, import_accounts.toAccount)({
|
|
936
1065
|
address: user.walletAddress,
|
|
937
|
-
signMessage: (
|
|
1066
|
+
signMessage: ({ message }) => this.signMessage(message),
|
|
938
1067
|
signTypedData: (typedDataDefinition) => this.signTypedData(typedDataDefinition),
|
|
939
1068
|
signTransaction: this.signTransaction
|
|
940
1069
|
});
|
|
@@ -943,7 +1072,7 @@ var ViemModule = class {
|
|
|
943
1072
|
client,
|
|
944
1073
|
owner
|
|
945
1074
|
}) {
|
|
946
|
-
const user = this._signerClient.
|
|
1075
|
+
const user = await this._signerClient.getUser();
|
|
947
1076
|
if (!user) {
|
|
948
1077
|
throw new UnauthenticatedError({ message: "Signer not authenticated" });
|
|
949
1078
|
}
|
|
@@ -979,7 +1108,7 @@ var ViemModule = class {
|
|
|
979
1108
|
}
|
|
980
1109
|
async signTransaction(transaction, options) {
|
|
981
1110
|
const serializeFn = options?.serializer ?? import_viem.serializeTransaction;
|
|
982
|
-
const serializedTx = serializeFn(transaction);
|
|
1111
|
+
const serializedTx = await serializeFn(transaction);
|
|
983
1112
|
const signatureHex = await this._signerClient.signRawMessage(
|
|
984
1113
|
(0, import_viem.keccak256)(serializedTx)
|
|
985
1114
|
);
|