@crossmint/client-sdk-react-ui 1.5.0 → 1.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crossmint/client-sdk-react-ui",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "repository": "https://github.com/Crossmint/crossmint-sdk",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Paella Labs Inc",
@@ -31,11 +31,11 @@
31
31
  "tailwind-merge": "2.4.0",
32
32
  "tailwindcss": "3.4.10",
33
33
  "zod": "3.22.4",
34
- "@crossmint/client-sdk-auth-core": "1.3.0",
34
+ "@crossmint/client-sdk-auth-core": "1.4.0",
35
+ "@crossmint/client-sdk-base": "1.2.8",
35
36
  "@crossmint/client-sdk-smart-wallet": "0.1.19",
36
37
  "@crossmint/client-sdk-window": "0.0.10",
37
- "@crossmint/common-sdk-base": "0.2.0",
38
- "@crossmint/client-sdk-base": "1.2.8"
38
+ "@crossmint/common-sdk-base": "0.2.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/lodash.isequal": "4.5.6",
@@ -1,5 +1,5 @@
1
1
  import { Dialog, Transition } from "@headlessui/react";
2
- import { type CSSProperties, Fragment, useEffect, useRef, useState } from "react";
2
+ import { type CSSProperties, Fragment, useRef } from "react";
3
3
  import { z } from "zod";
4
4
 
5
5
  import { IFrameWindow } from "@crossmint/client-sdk-window";
@@ -37,27 +37,19 @@ export default function AuthModal({ setModalOpen, apiKey, fetchAuthMaterial, bas
37
37
  }
38
38
 
39
39
  const iframeRef = useRef<HTMLIFrameElement | null>(null);
40
- const [iframe, setIframe] = useState<IFrameWindow<IncomingModalIframeEventsType, Record<string, never>> | null>(
41
- null
42
- );
40
+ const iframeWindowRef = useRef<IFrameWindow<IncomingModalIframeEventsType, Record<string, never>> | null>(null);
43
41
 
44
- useEffect(() => {
45
- if (iframe == null) {
42
+ const setupIframeWindowListener = () => {
43
+ if (iframeWindowRef.current == null) {
46
44
  return;
47
45
  }
48
46
 
49
- iframe.on("authMaterialFromAuthFrame", (data) => {
47
+ iframeWindowRef.current.on("authMaterialFromAuthFrame", (data) => {
50
48
  fetchAuthMaterial(data.oneTimeSecret);
51
- iframe.off("authMaterialFromAuthFrame");
49
+ iframeWindowRef.current?.off("authMaterialFromAuthFrame");
52
50
  setModalOpen(false);
53
51
  });
54
-
55
- return () => {
56
- if (iframe) {
57
- iframe.off("authMaterialFromAuthFrame");
58
- }
59
- };
60
- }, [iframe, fetchAuthMaterial, setModalOpen]);
52
+ };
61
53
 
62
54
  const handleIframeLoaded = async () => {
63
55
  if (iframeRef.current == null) {
@@ -66,11 +58,15 @@ export default function AuthModal({ setModalOpen, apiKey, fetchAuthMaterial, bas
66
58
  return;
67
59
  }
68
60
 
69
- const initIframe = await IFrameWindow.init(iframeRef.current, {
70
- incomingEvents: incomingModalIframeEvents,
71
- outgoingEvents: {},
72
- });
73
- setIframe(initIframe);
61
+ if (iframeWindowRef.current == null) {
62
+ const initIframe = await IFrameWindow.init(iframeRef.current, {
63
+ incomingEvents: incomingModalIframeEvents,
64
+ outgoingEvents: {},
65
+ });
66
+
67
+ iframeWindowRef.current = initIframe;
68
+ setupIframeWindowListener();
69
+ }
74
70
  };
75
71
 
76
72
  return (
@@ -1,6 +1,6 @@
1
1
  import { useCallback, useEffect, useRef } from "react";
2
2
 
3
- import type { CrossmintAuthService } from "@crossmint/client-sdk-auth-core/client";
3
+ import type { CrossmintAuthService, SDKExternalUser } from "@crossmint/client-sdk-auth-core/client";
4
4
  import { getJWTExpiration } from "@crossmint/client-sdk-auth-core/client";
5
5
  import { queueTask, type CancellableTask } from "@crossmint/client-sdk-base";
6
6
 
@@ -15,6 +15,7 @@ export type AuthMaterial = {
15
15
  secret: string;
16
16
  expiresAt: string;
17
17
  };
18
+ user: SDKExternalUser;
18
19
  };
19
20
 
20
21
  type UseAuthTokenRefreshProps = {
@@ -44,6 +44,10 @@ vi.mock("@crossmint/client-sdk-auth-core/client", async () => {
44
44
  secret: "new-mock-refresh-token",
45
45
  expiresAt: new Date(Date.now() + 1000 * 60 * 60).toISOString(),
46
46
  },
47
+ user: {
48
+ id: "123",
49
+ email: "test@test.com",
50
+ },
47
51
  }),
48
52
  })),
49
53
  };
@@ -2,7 +2,7 @@ import { REFRESH_TOKEN_PREFIX, SESSION_PREFIX, deleteCookie, getCookie, setCooki
2
2
  import { type ReactNode, createContext, useEffect, useState } from "react";
3
3
  import { createPortal } from "react-dom";
4
4
 
5
- import { CrossmintAuthService } from "@crossmint/client-sdk-auth-core/client";
5
+ import { CrossmintAuthService, type SDKExternalUser } from "@crossmint/client-sdk-auth-core/client";
6
6
  import type { EVMSmartWalletChain } from "@crossmint/client-sdk-smart-wallet";
7
7
  import { type UIConfig, validateApiKeyAndGetCrossmintBaseUrl } from "@crossmint/common-sdk-base";
8
8
 
@@ -30,16 +30,20 @@ type AuthContextType = {
30
30
  logout: () => void;
31
31
  jwt?: string;
32
32
  refreshToken?: string;
33
+ user?: SDKExternalUser;
33
34
  status: AuthStatus;
35
+ getUser: () => void;
34
36
  };
35
37
 
36
38
  export const AuthContext = createContext<AuthContextType>({
37
39
  login: () => {},
38
40
  logout: () => {},
39
41
  status: "logged-out",
42
+ getUser: () => {},
40
43
  });
41
44
 
42
45
  export function CrossmintAuthProvider({ embeddedWallets, children, appearance }: CrossmintAuthProviderProps) {
46
+ const [user, setUser] = useState<SDKExternalUser | undefined>(undefined);
43
47
  const { crossmint, setJwt, setRefreshToken } = useCrossmint(
44
48
  "CrossmintAuthProvider must be used within CrossmintProvider"
45
49
  );
@@ -52,6 +56,7 @@ export function CrossmintAuthProvider({ embeddedWallets, children, appearance }:
52
56
  setCookie(REFRESH_TOKEN_PREFIX, authMaterial.refreshToken.secret, authMaterial.refreshToken.expiresAt);
53
57
  setJwt(authMaterial.jwtToken);
54
58
  setRefreshToken(authMaterial.refreshToken.secret);
59
+ setUser(authMaterial.user);
55
60
  };
56
61
 
57
62
  const logout = () => {
@@ -59,19 +64,11 @@ export function CrossmintAuthProvider({ embeddedWallets, children, appearance }:
59
64
  deleteCookie(REFRESH_TOKEN_PREFIX);
60
65
  setJwt(undefined);
61
66
  setRefreshToken(undefined);
67
+ setUser(undefined);
62
68
  };
63
69
 
64
70
  useRefreshToken({ crossmintAuthService, setAuthMaterial, logout });
65
71
 
66
- const login = () => {
67
- if (crossmint.jwt != null) {
68
- console.log("User already logged in");
69
- return;
70
- }
71
-
72
- setModalOpen(true);
73
- };
74
-
75
72
  useEffect(() => {
76
73
  if (crossmint.jwt == null) {
77
74
  const jwt = getCookie(SESSION_PREFIX);
@@ -87,6 +84,15 @@ export function CrossmintAuthProvider({ embeddedWallets, children, appearance }:
87
84
  setModalOpen(false);
88
85
  }, [crossmint.jwt]);
89
86
 
87
+ const login = () => {
88
+ if (crossmint.jwt != null) {
89
+ console.log("User already logged in");
90
+ return;
91
+ }
92
+
93
+ setModalOpen(true);
94
+ };
95
+
90
96
  const getAuthStatus = (): AuthStatus => {
91
97
  if (crossmint.jwt != null) {
92
98
  return "logged-in";
@@ -103,6 +109,16 @@ export function CrossmintAuthProvider({ embeddedWallets, children, appearance }:
103
109
  return authMaterial;
104
110
  };
105
111
 
112
+ const getUser = async () => {
113
+ if (crossmint.jwt == null) {
114
+ console.log("User not logged in");
115
+ return;
116
+ }
117
+
118
+ const user = await crossmintAuthService.getUserFromClient(crossmint.jwt);
119
+ setUser(user);
120
+ };
121
+
106
122
  return (
107
123
  <AuthContext.Provider
108
124
  value={{
@@ -110,7 +126,9 @@ export function CrossmintAuthProvider({ embeddedWallets, children, appearance }:
110
126
  logout,
111
127
  jwt: crossmint.jwt,
112
128
  refreshToken: crossmint.refreshToken,
129
+ user,
113
130
  status: getAuthStatus(),
131
+ getUser,
114
132
  }}
115
133
  >
116
134
  <CrossmintWalletProvider