@avalabs/avacloud-waas-react 1.3.0 → 1.4.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.
Files changed (75) hide show
  1. package/README.md +24 -1
  2. package/dist/index.d.mts +16 -3
  3. package/dist/index.d.ts +16 -3
  4. package/dist/index.js +858 -546
  5. package/dist/index.mjs +922 -611
  6. package/package.json +8 -3
  7. package/dist/_esm-QWLX263D.mjs +0 -3919
  8. package/dist/ccip-ZGPV4OUI.mjs +0 -14
  9. package/dist/chunk-CASSC3OP.mjs +0 -67
  10. package/dist/chunk-G3BBITEG.mjs +0 -367
  11. package/dist/chunk-H4SP2TEB.mjs +0 -2343
  12. package/dist/chunk-TMRHATUE.mjs +0 -5868
  13. package/dist/dejavu-mono-latin-400-normal-IE7EMRRJ.woff2 +0 -0
  14. package/dist/dejavu-mono-latin-400-normal-MXASKUMG.woff +0 -0
  15. package/dist/dejavu-mono-latin-700-normal-4E6K55SY.woff +0 -0
  16. package/dist/dejavu-mono-latin-700-normal-4R4GZIXF.woff2 +0 -0
  17. package/dist/index.css +0 -473
  18. package/dist/inter-cyrillic-400-normal-KFLOZ6L3.woff2 +0 -0
  19. package/dist/inter-cyrillic-400-normal-UGV3X2ZX.woff +0 -0
  20. package/dist/inter-cyrillic-500-normal-5QURBI26.woff +0 -0
  21. package/dist/inter-cyrillic-500-normal-MRQZIV3H.woff2 +0 -0
  22. package/dist/inter-cyrillic-600-normal-EDUIRGIU.woff +0 -0
  23. package/dist/inter-cyrillic-600-normal-VQSXM56D.woff2 +0 -0
  24. package/dist/inter-cyrillic-700-normal-6AC775OW.woff2 +0 -0
  25. package/dist/inter-cyrillic-700-normal-D4IEZ3GW.woff +0 -0
  26. package/dist/inter-cyrillic-ext-400-normal-JB453SGZ.woff2 +0 -0
  27. package/dist/inter-cyrillic-ext-400-normal-UT7C7CGZ.woff +0 -0
  28. package/dist/inter-cyrillic-ext-500-normal-JTQKN4HY.woff2 +0 -0
  29. package/dist/inter-cyrillic-ext-500-normal-WLOKRQXN.woff +0 -0
  30. package/dist/inter-cyrillic-ext-600-normal-EFECVKGZ.woff2 +0 -0
  31. package/dist/inter-cyrillic-ext-600-normal-NBG3W4IU.woff +0 -0
  32. package/dist/inter-cyrillic-ext-700-normal-4PBXEWDR.woff +0 -0
  33. package/dist/inter-cyrillic-ext-700-normal-SJP7DRTO.woff2 +0 -0
  34. package/dist/inter-greek-400-normal-7Y67TOYM.woff +0 -0
  35. package/dist/inter-greek-400-normal-BRMJUT6T.woff2 +0 -0
  36. package/dist/inter-greek-500-normal-LCPH243Y.woff +0 -0
  37. package/dist/inter-greek-500-normal-PQX5SJVP.woff2 +0 -0
  38. package/dist/inter-greek-600-normal-PKJBTQPQ.woff2 +0 -0
  39. package/dist/inter-greek-600-normal-UPKYUUFH.woff +0 -0
  40. package/dist/inter-greek-700-normal-5N2Y4K7P.woff2 +0 -0
  41. package/dist/inter-greek-700-normal-OE26ANW4.woff +0 -0
  42. package/dist/inter-greek-ext-400-normal-4HYCVGMS.woff +0 -0
  43. package/dist/inter-greek-ext-400-normal-QIS4ONLW.woff2 +0 -0
  44. package/dist/inter-greek-ext-500-normal-AOIZUIP4.woff +0 -0
  45. package/dist/inter-greek-ext-500-normal-Z2CEJP2K.woff2 +0 -0
  46. package/dist/inter-greek-ext-600-normal-FQPCNDF3.woff +0 -0
  47. package/dist/inter-greek-ext-600-normal-KM6XRHAQ.woff2 +0 -0
  48. package/dist/inter-greek-ext-700-normal-FDEUQJ34.woff +0 -0
  49. package/dist/inter-greek-ext-700-normal-LWL55ZDD.woff2 +0 -0
  50. package/dist/inter-latin-400-normal-O6KIPRV2.woff +0 -0
  51. package/dist/inter-latin-400-normal-VQ3UBCDI.woff2 +0 -0
  52. package/dist/inter-latin-500-normal-OD7WVACW.woff +0 -0
  53. package/dist/inter-latin-500-normal-PUEXTTCT.woff2 +0 -0
  54. package/dist/inter-latin-600-normal-5WVF6G4B.woff +0 -0
  55. package/dist/inter-latin-600-normal-GQRH5MIF.woff2 +0 -0
  56. package/dist/inter-latin-700-normal-5OESYTDS.woff2 +0 -0
  57. package/dist/inter-latin-700-normal-ZQVBARDV.woff +0 -0
  58. package/dist/inter-latin-ext-400-normal-BTAMM2KL.woff2 +0 -0
  59. package/dist/inter-latin-ext-400-normal-YUALTDTA.woff +0 -0
  60. package/dist/inter-latin-ext-500-normal-DV5RJSXI.woff2 +0 -0
  61. package/dist/inter-latin-ext-500-normal-KJKTVLML.woff +0 -0
  62. package/dist/inter-latin-ext-600-normal-AOYWYIP3.woff2 +0 -0
  63. package/dist/inter-latin-ext-600-normal-L5SWE5DY.woff +0 -0
  64. package/dist/inter-latin-ext-700-normal-2RDPBVFQ.woff2 +0 -0
  65. package/dist/inter-latin-ext-700-normal-XQIRBHUR.woff +0 -0
  66. package/dist/inter-vietnamese-400-normal-724F3VTF.woff +0 -0
  67. package/dist/inter-vietnamese-400-normal-KH5NGGJJ.woff2 +0 -0
  68. package/dist/inter-vietnamese-500-normal-F77QXW2X.woff2 +0 -0
  69. package/dist/inter-vietnamese-500-normal-ZTDWBSHR.woff +0 -0
  70. package/dist/inter-vietnamese-600-normal-47DK6MCQ.woff2 +0 -0
  71. package/dist/inter-vietnamese-600-normal-M4XR4C4S.woff +0 -0
  72. package/dist/inter-vietnamese-700-normal-ONTG3SOY.woff +0 -0
  73. package/dist/inter-vietnamese-700-normal-T2WXKRNY.woff2 +0 -0
  74. package/dist/mod-LKCIPMBZ.mjs +0 -2628
  75. package/dist/secp256k1-AYCAE7S6.mjs +0 -16
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/AvaCloudWalletProvider.tsx
2
- import { createContext as createContext4, useContext as useContext4, useEffect as useEffect5, useState as useState7, useCallback as useCallback5, useRef as useRef3 } from "react";
2
+ import { createContext as createContext4, useContext as useContext4, useEffect as useEffect5, useState as useState8, useCallback as useCallback6, useRef as useRef3 } from "react";
3
3
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4
4
  import { envs } from "@cubist-labs/cubesigner-sdk";
5
5
 
@@ -31,41 +31,15 @@ function getDerivationPath(vm, accountIndex) {
31
31
  return `m/44'/${coinIndex}'/0'/0/${accountIndex}`;
32
32
  }
33
33
 
34
- // src/hooks/usePostMessage.ts
35
- import { useCallback, useEffect, useRef } from "react";
36
-
37
- // src/constants/storage.ts
38
- var OIDC_TOKEN_KEY = "avacloud-auth-oidc-token";
39
- var AUTH_TOKENS_KEY = "auth_tokens";
40
- var AUTH0_STORAGE_KEYS = {
41
- IS_AUTHENTICATED: "auth0.is.authenticated",
42
- ACCESS_TOKEN: "auth0.access_token",
43
- ID_TOKEN: "auth0.id_token",
44
- EXPIRES_AT: "auth0.expires_at"
45
- };
46
- var CUBIST_USER_ID_KEY = "cubist_user_id";
47
- var ORG_CONFIG_CACHE_KEY = "avacloud-org-config-cache";
48
-
49
- // src/hooks/usePostMessage.ts
50
- var globalAuthState = {
51
- signupInProgress: false,
52
- loginInProgress: false,
53
- lastSignupTimestamp: 0,
54
- lastLoginTimestamp: 0,
55
- processingMessageIds: /* @__PURE__ */ new Set()
56
- };
57
- function cleanupProcessedMessageIds() {
58
- if (globalAuthState.processingMessageIds.size > 100) {
59
- const messageIds = Array.from(globalAuthState.processingMessageIds);
60
- globalAuthState.processingMessageIds = new Set(messageIds.slice(-50));
61
- }
62
- }
63
- function usePostMessage({
34
+ // src/hooks/usePenpalAuth.ts
35
+ import { useCallback, useEffect, useRef, useState } from "react";
36
+ import { connect, WindowMessenger } from "penpal";
37
+ import { AUTH_TOKENS_KEY, OIDC_TOKEN_KEY, AUTH0_STORAGE_KEYS, CUBIST_USER_ID_KEY, ORG_CONFIG_CACHE_KEY } from "@avacloud/waas-common";
38
+ function usePenpalAuth({
64
39
  authServiceUrl,
65
40
  orgId,
66
41
  environment,
67
42
  iframe,
68
- isIframeReady,
69
43
  onAuthSuccess,
70
44
  onAuthError,
71
45
  onOidcReceived,
@@ -73,16 +47,13 @@ function usePostMessage({
73
47
  setIsAuthenticated,
74
48
  setUser,
75
49
  setIsLoading,
76
- setIsIframeReady,
77
- cubistClient
50
+ setIsIframeReady
78
51
  }) {
79
- const lastAuthStateRef = useRef({
80
- isAuthenticated: false,
81
- userId: null,
82
- lastUpdateTime: 0
83
- });
84
- const hasRequestedOidcRef = useRef(false);
85
- const isHandlingMessageRef = useRef(false);
52
+ const connectionRef = useRef(null);
53
+ const [authService, setAuthService] = useState(null);
54
+ const [isConnected, setIsConnected] = useState(false);
55
+ const isConnectedRef = useRef(false);
56
+ const hasCheckedAuthRef = useRef(false);
86
57
  const hasLoadedCacheRef = useRef(false);
87
58
  useEffect(() => {
88
59
  if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
@@ -103,246 +74,263 @@ function usePostMessage({
103
74
  }
104
75
  }
105
76
  }, [orgId, environment, onOrgConfigUpdate]);
106
- const sendMessage = useCallback((message) => {
107
- if (iframe == null ? void 0 : iframe.contentWindow) {
108
- try {
109
- if (message.type === "SIGNUP_REQUEST") {
110
- if (globalAuthState.signupInProgress) {
111
- return;
112
- }
113
- const now = Date.now();
114
- if (now - globalAuthState.lastSignupTimestamp < 3e3) {
115
- return;
116
- }
117
- globalAuthState.signupInProgress = true;
118
- globalAuthState.lastSignupTimestamp = now;
119
- let finalMessage = message;
120
- if (!message.requestId) {
121
- finalMessage = {
122
- ...message,
123
- requestId: `signup-${now}`
124
- };
125
- }
126
- let messageToSend = finalMessage;
127
- if (finalMessage.payload && typeof finalMessage.payload.email === "string" && typeof finalMessage.payload.password === "string") {
128
- messageToSend = {
129
- type: "SIGNUP_REQUEST",
130
- email: finalMessage.payload.email,
131
- password: finalMessage.payload.password,
132
- requestId: finalMessage.requestId || `signup-${now}`
133
- };
134
- }
135
- if ("requestId" in messageToSend && messageToSend.requestId) {
136
- globalAuthState.processingMessageIds.add(messageToSend.requestId);
137
- }
138
- iframe.contentWindow.postMessage(messageToSend, authServiceUrl);
139
- return;
140
- }
141
- if (message.type === "LOGIN_REQUEST") {
142
- if (globalAuthState.loginInProgress) {
143
- return;
144
- }
145
- const now = Date.now();
146
- if (now - globalAuthState.lastLoginTimestamp < 3e3) {
147
- return;
148
- }
149
- globalAuthState.loginInProgress = true;
150
- globalAuthState.lastLoginTimestamp = now;
151
- let finalMessage = message;
152
- if (!message.requestId) {
153
- finalMessage = {
154
- ...message,
155
- requestId: `login-${now}`
77
+ const parentMethods = {
78
+ onReady: () => {
79
+ console.log("[Penpal Parent] Iframe is ready");
80
+ setIsIframeReady(true);
81
+ },
82
+ onAuthStatusChange: (status) => {
83
+ var _a;
84
+ console.log("[Penpal Parent] Auth status changed:", status);
85
+ setIsAuthenticated(status.isAuthenticated);
86
+ if (status.user) {
87
+ const userInfo = {
88
+ email: status.user.email,
89
+ sub: status.user.sub,
90
+ configured_mfa: [],
91
+ displayName: status.user.nickname || status.user.name || ((_a = status.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
92
+ rawUserData: status.user
93
+ };
94
+ setUser(userInfo);
95
+ } else {
96
+ setUser(null);
97
+ }
98
+ if (status.orgConfig) {
99
+ onOrgConfigUpdate == null ? void 0 : onOrgConfigUpdate(status.orgConfig);
100
+ if (orgId) {
101
+ try {
102
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
103
+ const configWithTimestamp = {
104
+ ...status.orgConfig,
105
+ _timestamp: Date.now()
156
106
  };
107
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
108
+ } catch (error) {
157
109
  }
158
- if (finalMessage.requestId) {
159
- globalAuthState.processingMessageIds.add(finalMessage.requestId);
160
- }
161
- iframe.contentWindow.postMessage(finalMessage, authServiceUrl);
162
- return;
163
- }
164
- iframe.contentWindow.postMessage(message, authServiceUrl);
165
- } catch (error) {
166
- if (message.type === "SIGNUP_REQUEST") {
167
- globalAuthState.signupInProgress = false;
168
- }
169
- if (message.type === "LOGIN_REQUEST") {
170
- globalAuthState.loginInProgress = false;
171
110
  }
172
111
  }
173
- }
174
- }, [iframe, authServiceUrl]);
175
- useEffect(() => {
176
- const handleMessage = async (event) => {
177
- var _a, _b, _c, _d, _e, _f, _g;
178
- if (isHandlingMessageRef.current) {
179
- return;
112
+ if (status.isAuthenticated) {
113
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
180
114
  }
181
- if (event.origin !== new URL(authServiceUrl).origin) {
115
+ setIsLoading(false);
116
+ },
117
+ onError: (error) => {
118
+ console.error("[Penpal Parent] Error from iframe:", error);
119
+ if (error.message === "User not authenticated in iframe" || error.message === "Unknown error" || error.message.includes("OIDC user not found")) {
182
120
  return;
183
121
  }
184
- if (typeof ((_a = event.data) == null ? void 0 : _a.type) !== "string") {
122
+ onAuthError == null ? void 0 : onAuthError(new Error(error.message));
123
+ setIsLoading(false);
124
+ },
125
+ onWalletUpdate: (wallet) => {
126
+ console.log("[Penpal Parent] Wallet update:", wallet);
127
+ }
128
+ };
129
+ useEffect(() => {
130
+ if (!(iframe == null ? void 0 : iframe.contentWindow)) {
131
+ return;
132
+ }
133
+ let isCancelled = false;
134
+ const setupConnection = async (attempt = 1, maxAttempts = 3) => {
135
+ if (isCancelled) return;
136
+ if (isConnectedRef.current && connectionRef.current) {
137
+ console.log("[Penpal Parent] Already connected, skipping setup");
185
138
  return;
186
139
  }
187
- if (event.data.requestId && globalAuthState.processingMessageIds.has(event.data.requestId)) {
188
- return;
140
+ console.log(`[Penpal Parent] Setting up connection to iframe (attempt ${attempt}/${maxAttempts})...`);
141
+ if (connectionRef.current) {
142
+ connectionRef.current.destroy();
143
+ connectionRef.current = null;
144
+ setAuthService(null);
145
+ setIsConnected(false);
146
+ isConnectedRef.current = false;
189
147
  }
190
148
  try {
191
- isHandlingMessageRef.current = true;
192
- if (event.data.type === "ERROR") {
193
- globalAuthState.signupInProgress = false;
194
- globalAuthState.loginInProgress = false;
195
- } else if (event.data.type === "AUTH_STATUS" && event.data.isAuthenticated) {
196
- globalAuthState.signupInProgress = false;
197
- globalAuthState.loginInProgress = false;
198
- cleanupProcessedMessageIds();
199
- } else if (event.data.type === "RECEIVE_OIDC") {
200
- globalAuthState.signupInProgress = false;
201
- globalAuthState.loginInProgress = false;
149
+ const authServiceOrigin = new URL(authServiceUrl).origin;
150
+ const messenger = new WindowMessenger({
151
+ remoteWindow: iframe.contentWindow,
152
+ allowedOrigins: [authServiceOrigin]
153
+ });
154
+ const connection = connect({
155
+ messenger,
156
+ methods: parentMethods,
157
+ timeout: 1e4
158
+ // 10 second connection timeout per attempt
159
+ });
160
+ connectionRef.current = connection;
161
+ const remote = await connection.promise;
162
+ if (isCancelled) {
163
+ connection.destroy();
164
+ return;
202
165
  }
203
- switch (event.data.type) {
204
- case "IFRAME_READY":
205
- setIsIframeReady(true);
206
- break;
207
- case "RECEIVE_OIDC":
208
- if (typeof ((_b = event.data.payload) == null ? void 0 : _b.idToken) === "string") {
209
- const oidcToken = event.data.payload.idToken;
210
- hasRequestedOidcRef.current = false;
211
- onOidcReceived == null ? void 0 : onOidcReceived(oidcToken);
212
- } else {
213
- hasRequestedOidcRef.current = false;
214
- }
215
- break;
216
- case "AUTH_STATUS": {
217
- const newIsAuthenticated = !!event.data.isAuthenticated;
218
- const newUserId = (_d = (_c = event.data.user) == null ? void 0 : _c.sub) != null ? _d : null;
219
- const now = Date.now();
220
- if (now - lastAuthStateRef.current.lastUpdateTime < 500) {
221
- return;
222
- }
223
- const authStateChanged = lastAuthStateRef.current.isAuthenticated !== newIsAuthenticated || lastAuthStateRef.current.userId !== newUserId;
224
- if (authStateChanged) {
225
- setIsAuthenticated(newIsAuthenticated);
226
- if (event.data.user) {
227
- const userInfo = {
228
- email: event.data.user.email,
229
- sub: event.data.user.sub,
230
- configured_mfa: [],
231
- displayName: event.data.user.nickname || event.data.user.name || ((_e = event.data.user.email) == null ? void 0 : _e.split("@")[0]) || "User",
232
- rawUserData: event.data.user
233
- };
234
- setUser(userInfo);
235
- if (newIsAuthenticated && !cubistClient && !hasRequestedOidcRef.current) {
236
- hasRequestedOidcRef.current = true;
237
- sendMessage({ type: "GET_OIDC" });
238
- return;
239
- }
240
- } else {
241
- setUser(null);
242
- localStorage.removeItem(AUTH_TOKENS_KEY);
243
- localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
244
- sessionStorage.removeItem(OIDC_TOKEN_KEY);
245
- }
246
- lastAuthStateRef.current = {
247
- isAuthenticated: newIsAuthenticated,
248
- userId: newUserId,
249
- lastUpdateTime: now
250
- };
251
- if (newIsAuthenticated && event.data.user) {
252
- if (!hasRequestedOidcRef.current) {
253
- if (event.data.tokens) {
254
- localStorage.setItem(AUTH_TOKENS_KEY, JSON.stringify(event.data.tokens));
255
- }
256
- onAuthSuccess == null ? void 0 : onAuthSuccess();
257
- }
258
- }
259
- }
260
- if (event.data.orgConfig && onOrgConfigUpdate) {
261
- onOrgConfigUpdate(event.data.orgConfig);
262
- if (orgId) {
263
- try {
264
- const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
265
- const configWithTimestamp = {
266
- ...event.data.orgConfig,
267
- _timestamp: Date.now()
268
- };
269
- localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
270
- } catch (error) {
271
- }
272
- }
273
- }
274
- if (!hasRequestedOidcRef.current) {
275
- setIsLoading(false);
276
- }
277
- break;
278
- }
279
- case "REGISTER_SUCCESS": {
280
- const userId = (_f = event.data.payload) == null ? void 0 : _f.userId;
281
- if (userId) {
282
- localStorage.setItem(CUBIST_USER_ID_KEY, userId);
283
- if (!hasRequestedOidcRef.current) {
284
- hasRequestedOidcRef.current = true;
285
- sendMessage({ type: "GET_OIDC" });
286
- }
287
- }
288
- break;
166
+ console.log("[Penpal Parent] Connected to auth service");
167
+ isConnectedRef.current = true;
168
+ setAuthService(remote);
169
+ setIsConnected(true);
170
+ setIsIframeReady(true);
171
+ } catch (error) {
172
+ if (isCancelled) return;
173
+ console.error(`[Penpal Parent] Failed to connect (attempt ${attempt}):`, error);
174
+ if (attempt < maxAttempts) {
175
+ console.log(`[Penpal Parent] Retrying in 1 second...`);
176
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
177
+ if (!isCancelled) {
178
+ await setupConnection(attempt + 1, maxAttempts);
289
179
  }
290
- case "ERROR":
291
- if (event.data.error === "User not authenticated in iframe") {
292
- isHandlingMessageRef.current = false;
293
- return;
294
- }
295
- onAuthError == null ? void 0 : onAuthError(new Error((_g = event.data.error) != null ? _g : "Unknown error"));
296
- setIsLoading(false);
297
- break;
180
+ } else {
181
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to connect to auth service"));
298
182
  }
299
- } finally {
300
- isHandlingMessageRef.current = false;
301
183
  }
302
184
  };
303
- window.addEventListener("message", handleMessage);
304
- return () => window.removeEventListener("message", handleMessage);
305
- }, [
306
- authServiceUrl,
307
- onAuthError,
308
- onAuthSuccess,
309
- onOidcReceived,
310
- onOrgConfigUpdate,
311
- setIsAuthenticated,
312
- setIsIframeReady,
313
- setIsLoading,
314
- setUser,
315
- sendMessage,
316
- cubistClient,
317
- orgId,
318
- environment
319
- ]);
185
+ setupConnection();
186
+ return () => {
187
+ isCancelled = true;
188
+ };
189
+ }, [iframe, authServiceUrl]);
320
190
  useEffect(() => {
321
- if (isIframeReady && (iframe == null ? void 0 : iframe.contentWindow)) {
322
- sendMessage({
323
- type: "CHECK_AUTH_STATUS",
324
- payload: {
325
- orgId,
326
- environment
191
+ if (isConnected && authService && !hasCheckedAuthRef.current) {
192
+ hasCheckedAuthRef.current = true;
193
+ authService.checkAuthStatus(orgId, environment).then((status) => {
194
+ console.log("[Penpal Parent] Initial auth status:", status);
195
+ parentMethods.onAuthStatusChange(status);
196
+ if (status.isAuthenticated) {
197
+ return authService.getOidc();
327
198
  }
199
+ return null;
200
+ }).then((oidcResult) => {
201
+ if (oidcResult == null ? void 0 : oidcResult.idToken) {
202
+ onOidcReceived == null ? void 0 : onOidcReceived(oidcResult.idToken);
203
+ }
204
+ }).catch((error) => {
205
+ console.error("[Penpal Parent] Error checking auth status:", error);
206
+ setIsLoading(false);
328
207
  });
329
208
  }
330
- }, [isIframeReady, iframe, sendMessage, orgId, environment]);
209
+ }, [isConnected, authService, orgId, environment]);
210
+ const login = useCallback(async (params) => {
211
+ var _a;
212
+ if (!authService) {
213
+ console.warn("[Penpal] Cannot login - not connected");
214
+ return;
215
+ }
216
+ try {
217
+ const result = await authService.login(params || {});
218
+ setIsAuthenticated(true);
219
+ if (result.user) {
220
+ const userInfo = {
221
+ email: result.user.email,
222
+ sub: result.user.sub,
223
+ configured_mfa: [],
224
+ displayName: result.user.nickname || result.user.name || ((_a = result.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
225
+ rawUserData: result.user
226
+ };
227
+ setUser(userInfo);
228
+ }
229
+ if (result.accessToken) {
230
+ onOidcReceived == null ? void 0 : onOidcReceived(result.accessToken);
231
+ }
232
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
233
+ return result;
234
+ } catch (error) {
235
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Login failed"));
236
+ throw error;
237
+ }
238
+ }, [authService, setIsAuthenticated, setUser, onOidcReceived, onAuthSuccess, onAuthError]);
239
+ const signup = useCallback(async (email, password) => {
240
+ var _a;
241
+ if (!authService) {
242
+ console.warn("[Penpal] Cannot signup - not connected");
243
+ return;
244
+ }
245
+ try {
246
+ const result = await authService.signup({ email, password });
247
+ setIsAuthenticated(true);
248
+ if (result.user) {
249
+ const userInfo = {
250
+ email: result.user.email,
251
+ sub: result.user.sub,
252
+ configured_mfa: [],
253
+ displayName: result.user.nickname || result.user.name || ((_a = result.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
254
+ rawUserData: result.user
255
+ };
256
+ setUser(userInfo);
257
+ }
258
+ if (result.accessToken) {
259
+ onOidcReceived == null ? void 0 : onOidcReceived(result.accessToken);
260
+ }
261
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
262
+ return result;
263
+ } catch (error) {
264
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Signup failed"));
265
+ throw error;
266
+ }
267
+ }, [authService, setIsAuthenticated, setUser, onOidcReceived, onAuthSuccess, onAuthError]);
268
+ const logout = useCallback(async () => {
269
+ if (!authService) {
270
+ console.warn("[Penpal] Cannot logout - not connected");
271
+ return;
272
+ }
273
+ try {
274
+ await authService.logout();
275
+ setIsAuthenticated(false);
276
+ setUser(null);
277
+ localStorage.removeItem(AUTH_TOKENS_KEY);
278
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
279
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
280
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ID_TOKEN);
281
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.EXPIRES_AT);
282
+ localStorage.removeItem(CUBIST_USER_ID_KEY);
283
+ sessionStorage.removeItem(OIDC_TOKEN_KEY);
284
+ } catch (error) {
285
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Logout failed"));
286
+ throw error;
287
+ }
288
+ }, [authService, setIsAuthenticated, setUser, onAuthError]);
289
+ const getOidc = useCallback(async () => {
290
+ if (!authService) {
291
+ console.warn("[Penpal] Cannot get OIDC - not connected");
292
+ return;
293
+ }
294
+ try {
295
+ return await authService.getOidc();
296
+ } catch (error) {
297
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to get OIDC token"));
298
+ throw error;
299
+ }
300
+ }, [authService, onAuthError]);
301
+ const checkAuthStatus = useCallback(async () => {
302
+ if (!authService) {
303
+ console.warn("[Penpal] Cannot check auth status - not connected");
304
+ return;
305
+ }
306
+ try {
307
+ return await authService.checkAuthStatus(orgId, environment);
308
+ } catch (error) {
309
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to check auth status"));
310
+ throw error;
311
+ }
312
+ }, [authService, orgId, environment, onAuthError]);
331
313
  return {
332
- sendMessage
314
+ authService,
315
+ isConnected,
316
+ login,
317
+ signup,
318
+ logout,
319
+ getOidc,
320
+ checkAuthStatus
333
321
  };
334
322
  }
335
323
 
336
324
  // src/AuthModalContext.tsx
337
- import { createContext, useContext, useState as useState3, useCallback as useCallback2 } from "react";
325
+ import { createContext, useContext, useState as useState4, useCallback as useCallback3 } from "react";
338
326
  import { Dialog as Dialog2, DialogContent as DialogContent2, DialogTitle } from "@avalabs/core-k2-components";
339
327
 
340
328
  // src/components/Modal.tsx
341
- import { useState as useState2, useEffect as useEffect2, useRef as useRef2 } from "react";
329
+ import { useState as useState3, useRef as useRef2, useCallback as useCallback2, useEffect as useEffect2 } from "react";
342
330
  import { Dialog, DialogContent, IconButton as IconButton2, Stack as Stack3, XIcon } from "@avalabs/core-k2-components";
343
331
 
344
332
  // src/components/SignInContent.tsx
345
- import { useState } from "react";
333
+ import { useState as useState2 } from "react";
346
334
  import { Button, TextField, Typography as Typography2, Stack as Stack2, IconButton, Divider, GoogleIcon, AppleIcon, XTwitterIcon, FacebookIcon } from "@avalabs/core-k2-components";
347
335
 
348
336
  // src/components/PoweredByAvaCloud.tsx
@@ -372,10 +360,10 @@ function SignInContent({
372
360
  isSubmitting,
373
361
  socialLogins = ["google", "x", "apple"]
374
362
  }) {
375
- const [email, setEmail] = useState("");
376
- const [password, setPassword] = useState("");
377
- const [isPasswordStep, setIsPasswordStep] = useState(false);
378
- const [isSignupMode, setIsSignupMode] = useState(false);
363
+ const [email, setEmail] = useState2("");
364
+ const [password, setPassword] = useState2("");
365
+ const [isPasswordStep, setIsPasswordStep] = useState2(false);
366
+ const [isSignupMode, setIsSignupMode] = useState2(false);
379
367
  const providerConnectionMap = {
380
368
  "google": "google-oauth2",
381
369
  "x": "twitter",
@@ -949,123 +937,72 @@ function SignInContent({
949
937
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
950
938
  function LoginModal({ open, onClose }) {
951
939
  var _a;
952
- const { iframe, orgConfig, signup } = useAvaCloudWallet();
953
- const [isSubmitting, setIsSubmitting] = useState2(false);
954
- const [error, setError] = useState2("");
940
+ const { orgConfig, signup, login, isAuthenticated } = useAvaCloudWallet();
941
+ const [isSubmitting, setIsSubmitting] = useState3(false);
942
+ const [error, setError] = useState3("");
955
943
  const timeoutIdRef = useRef2(null);
956
- const signupInProgressRef = useRef2(false);
957
- const lastSignupAttemptRef = useRef2(0);
958
944
  const socialLogins = (_a = orgConfig == null ? void 0 : orgConfig.adminPortalSettings) == null ? void 0 : _a.socialLogins;
959
945
  useEffect2(() => {
960
- let requestInProgress = false;
961
- const handleMessage = (event) => {
962
- if (!event.data || typeof event.data.type !== "string") {
963
- return;
946
+ if (isAuthenticated && open) {
947
+ setIsSubmitting(false);
948
+ if (timeoutIdRef.current) {
949
+ clearTimeout(timeoutIdRef.current);
950
+ timeoutIdRef.current = null;
964
951
  }
965
- if (event.data.type === "ERROR") {
966
- if (event.data.payload === "User not authenticated in iframe") {
967
- return;
968
- }
969
- setError(event.data.payload);
970
- setIsSubmitting(false);
971
- signupInProgressRef.current = false;
972
- if (timeoutIdRef.current) {
973
- clearTimeout(timeoutIdRef.current);
974
- timeoutIdRef.current = null;
975
- }
976
- } else if (event.data.type === "AUTH_STATUS" && event.data.isAuthenticated) {
977
- setIsSubmitting(false);
978
- signupInProgressRef.current = false;
979
- requestInProgress = false;
980
- if (timeoutIdRef.current) {
981
- clearTimeout(timeoutIdRef.current);
982
- timeoutIdRef.current = null;
983
- }
984
- onClose();
985
- } else if (event.data.type === "RECEIVE_OIDC") {
986
- signupInProgressRef.current = false;
987
- requestInProgress = false;
952
+ onClose();
953
+ }
954
+ }, [isAuthenticated, open, onClose]);
955
+ useEffect2(() => {
956
+ if (!open) {
957
+ setIsSubmitting(false);
958
+ setError("");
959
+ if (timeoutIdRef.current) {
960
+ clearTimeout(timeoutIdRef.current);
961
+ timeoutIdRef.current = null;
988
962
  }
989
- };
990
- window.addEventListener("message", handleMessage);
963
+ }
964
+ }, [open]);
965
+ useEffect2(() => {
991
966
  return () => {
992
- window.removeEventListener("message", handleMessage);
993
967
  if (timeoutIdRef.current) {
994
968
  clearTimeout(timeoutIdRef.current);
995
969
  timeoutIdRef.current = null;
996
970
  }
997
971
  };
998
- }, [onClose]);
999
- const handleProviderLogin = (provider) => {
1000
- var _a2;
972
+ }, []);
973
+ const handleProviderLogin = useCallback2((provider) => {
1001
974
  setError("");
1002
- if (!iframe) {
1003
- setError("Authentication service not available");
1004
- return;
1005
- }
1006
- (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
1007
- type: "LOGIN_REQUEST",
1008
- connection: provider,
1009
- requestId: `login-${Date.now()}`
1010
- }, "*");
1011
- onClose();
1012
- };
1013
- const handleEmailLogin = (email, password) => {
1014
- var _a2;
975
+ setIsSubmitting(true);
976
+ login({ connection: provider });
977
+ }, [login]);
978
+ const handleEmailLogin = useCallback2((email, password) => {
1015
979
  setError("");
1016
980
  setIsSubmitting(true);
1017
- if (!iframe) {
1018
- setError("Authentication service not available");
1019
- setIsSubmitting(false);
1020
- return;
1021
- }
1022
981
  if (timeoutIdRef.current) {
1023
982
  clearTimeout(timeoutIdRef.current);
1024
983
  timeoutIdRef.current = null;
1025
984
  }
1026
- (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
1027
- type: "LOGIN_REQUEST",
1028
- email,
1029
- password,
1030
- requestId: `login-${Date.now()}`
1031
- }, "*");
985
+ login({ email, password });
1032
986
  timeoutIdRef.current = setTimeout(() => {
1033
987
  setError("Authentication service timed out");
1034
988
  setIsSubmitting(false);
1035
989
  timeoutIdRef.current = null;
1036
990
  }, 1e4);
1037
- };
1038
- const handleEmailSignup = (email, password) => {
1039
- if (signupInProgressRef.current) {
1040
- return;
1041
- }
1042
- const now = Date.now();
1043
- if (now - lastSignupAttemptRef.current < 2e3) {
1044
- return;
1045
- }
1046
- lastSignupAttemptRef.current = now;
991
+ }, [login]);
992
+ const handleEmailSignup = useCallback2((email, password) => {
1047
993
  setError("");
1048
994
  setIsSubmitting(true);
1049
- signupInProgressRef.current = true;
1050
995
  if (timeoutIdRef.current) {
1051
996
  clearTimeout(timeoutIdRef.current);
1052
997
  timeoutIdRef.current = null;
1053
998
  }
1054
- try {
1055
- signup(email, password);
1056
- } catch (error2) {
1057
- setError("Failed to initiate signup");
1058
- setIsSubmitting(false);
1059
- signupInProgressRef.current = false;
1060
- return;
1061
- }
999
+ signup(email, password);
1062
1000
  timeoutIdRef.current = setTimeout(() => {
1063
1001
  setError("Authentication service timed out");
1064
1002
  setIsSubmitting(false);
1065
- signupInProgressRef.current = false;
1066
1003
  timeoutIdRef.current = null;
1067
1004
  }, 1e4);
1068
- };
1005
+ }, [signup]);
1069
1006
  return /* @__PURE__ */ jsxs3(
1070
1007
  Dialog,
1071
1008
  {
@@ -1153,9 +1090,9 @@ function LoginModal({ open, onClose }) {
1153
1090
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1154
1091
  var AuthModalContext = createContext(void 0);
1155
1092
  function AuthModalProvider({ children }) {
1156
- const [isModalOpen, setIsModalOpen] = useState3(false);
1157
- const openLoginModal = useCallback2(() => setIsModalOpen(true), []);
1158
- const closeLoginModal = useCallback2(() => setIsModalOpen(false), []);
1093
+ const [isModalOpen, setIsModalOpen] = useState4(false);
1094
+ const openLoginModal = useCallback3(() => setIsModalOpen(true), []);
1095
+ const closeLoginModal = useCallback3(() => setIsModalOpen(false), []);
1159
1096
  return /* @__PURE__ */ jsxs4(AuthModalContext.Provider, { value: { openLoginModal, closeLoginModal, isModalOpen }, children: [
1160
1097
  children,
1161
1098
  /* @__PURE__ */ jsxs4(
@@ -1190,11 +1127,11 @@ function useAuthModal() {
1190
1127
  import { CubeSignerClient } from "@cubist-labs/cubesigner-sdk";
1191
1128
 
1192
1129
  // src/providers/ViemContext.tsx
1193
- import { createContext as createContext2, useContext as useContext2, useState as useState4, useEffect as useEffect3 } from "react";
1130
+ import { createContext as createContext2, useContext as useContext2, useState as useState5, useEffect as useEffect3 } from "react";
1194
1131
  import { createPublicClient, createWalletClient, http } from "viem";
1195
1132
 
1196
1133
  // src/hooks/useAuth.ts
1197
- import { useCallback as useCallback3 } from "react";
1134
+ import { useCallback as useCallback4 } from "react";
1198
1135
  function useAuth() {
1199
1136
  const {
1200
1137
  isAuthenticated,
@@ -1207,7 +1144,7 @@ function useAuth() {
1207
1144
  cubistError
1208
1145
  } = useAvaCloudWallet();
1209
1146
  const { openLoginModal } = useAuthModal();
1210
- const login = useCallback3(() => {
1147
+ const login = useCallback4(() => {
1211
1148
  openLoginModal();
1212
1149
  }, [openLoginModal]);
1213
1150
  return {
@@ -1228,10 +1165,10 @@ import { jsx as jsx5 } from "react/jsx-runtime";
1228
1165
  var ViemContext = createContext2(null);
1229
1166
  function ViemProvider({ children, rpcUrl, chainId, explorerUrl }) {
1230
1167
  var _a, _b;
1231
- const [publicClient, setPublicClient] = useState4(null);
1232
- const [walletClient, setWalletClient] = useState4(null);
1233
- const [isConnected, setIsConnected] = useState4(false);
1234
- const [error, setError] = useState4(null);
1168
+ const [publicClient, setPublicClient] = useState5(null);
1169
+ const [walletClient, setWalletClient] = useState5(null);
1170
+ const [isConnected, setIsConnected] = useState5(false);
1171
+ const [error, setError] = useState5(null);
1235
1172
  const { cubistClient, wallet: authWallet } = useAuth();
1236
1173
  useEffect3(() => {
1237
1174
  const initClient = async () => {
@@ -1397,11 +1334,11 @@ var GlacierApiClient = class {
1397
1334
  var glacierApi = new GlacierApiClient();
1398
1335
 
1399
1336
  // src/hooks/useChainId.ts
1400
- import { useState as useState5 } from "react";
1337
+ import { useState as useState6 } from "react";
1401
1338
  var CHAIN_ID_STORAGE_KEY = "avalanche-chain-id";
1402
1339
  var DEFAULT_CHAIN_ID = 43113;
1403
1340
  function useChainId() {
1404
- const [chainId, setChainIdState] = useState5(() => {
1341
+ const [chainId, setChainIdState] = useState6(() => {
1405
1342
  const storedChainId = localStorage.getItem(CHAIN_ID_STORAGE_KEY);
1406
1343
  return storedChainId ? Number.parseInt(storedChainId, 10) : DEFAULT_CHAIN_ID;
1407
1344
  });
@@ -1481,7 +1418,7 @@ function useERC1155Balances(address, chainId) {
1481
1418
 
1482
1419
  // src/providers/ThemeProvider.tsx
1483
1420
  import { ThemeProvider as K2ThemeProvider, createTheme } from "@avalabs/core-k2-components";
1484
- import { createContext as createContext3, useContext as useContext3, useState as useState6, useCallback as useCallback4, useEffect as useEffect4 } from "react";
1421
+ import { createContext as createContext3, useContext as useContext3, useState as useState7, useCallback as useCallback5, useEffect as useEffect4 } from "react";
1485
1422
  import { jsx as jsx6 } from "react/jsx-runtime";
1486
1423
  var ThemeContext = createContext3({
1487
1424
  isDarkMode: false,
@@ -1527,13 +1464,13 @@ var darkTheme = createTheme({
1527
1464
  }
1528
1465
  });
1529
1466
  function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1530
- const [isDarkMode, setIsDarkMode] = useState6(darkMode != null ? darkMode : false);
1467
+ const [isDarkMode, setIsDarkMode] = useState7(darkMode != null ? darkMode : false);
1531
1468
  useEffect4(() => {
1532
1469
  if (darkMode !== void 0 && darkMode !== isDarkMode) {
1533
1470
  setIsDarkMode(darkMode);
1534
1471
  }
1535
- }, [darkMode]);
1536
- const toggleTheme = useCallback4(() => {
1472
+ }, [darkMode, isDarkMode]);
1473
+ const toggleTheme = useCallback5(() => {
1537
1474
  const newDarkMode = !isDarkMode;
1538
1475
  setIsDarkMode(newDarkMode);
1539
1476
  onDarkModeChange == null ? void 0 : onDarkModeChange(newDarkMode);
@@ -1541,6 +1478,18 @@ function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1541
1478
  return /* @__PURE__ */ jsx6(ThemeContext.Provider, { value: { isDarkMode, toggleTheme }, children: /* @__PURE__ */ jsx6(K2ThemeProvider, { theme: isDarkMode ? darkTheme : lightTheme, children }) });
1542
1479
  }
1543
1480
 
1481
+ // src/constants/storage.ts
1482
+ var OIDC_TOKEN_KEY2 = "avacloud-auth-oidc-token";
1483
+ var AUTH_TOKENS_KEY2 = "auth_tokens";
1484
+ var AUTH0_STORAGE_KEYS2 = {
1485
+ IS_AUTHENTICATED: "auth0.is.authenticated",
1486
+ ACCESS_TOKEN: "auth0.access_token",
1487
+ ID_TOKEN: "auth0.id_token",
1488
+ EXPIRES_AT: "auth0.expires_at"
1489
+ };
1490
+ var CUBIST_USER_ID_KEY2 = "cubist_user_id";
1491
+ var ORG_CONFIG_CACHE_KEY2 = "avacloud-org-config-cache";
1492
+
1544
1493
  // src/AvaCloudWalletProvider.tsx
1545
1494
  import { Fragment, jsx as jsx7 } from "react/jsx-runtime";
1546
1495
  var AvaCloudWalletContext = createContext4(void 0);
@@ -1571,12 +1520,30 @@ function ViemProviderWrapper({ children, chainId }) {
1571
1520
  }
1572
1521
  );
1573
1522
  }
1523
+ function normalizeOrgConfig(config) {
1524
+ if (!config) {
1525
+ return null;
1526
+ }
1527
+ const typedConfig = config;
1528
+ const explicitWalletProvider = typeof typedConfig.walletProviderOrgID === "string" ? typedConfig.walletProviderOrgID.trim() : "";
1529
+ const cubistOrgId = typeof typedConfig.cubistOrgId === "string" ? typedConfig.cubistOrgId.trim() : "";
1530
+ const resolvedOrgId = explicitWalletProvider || cubistOrgId;
1531
+ if (!resolvedOrgId) {
1532
+ return typedConfig;
1533
+ }
1534
+ return {
1535
+ ...typedConfig,
1536
+ walletProviderOrgID: resolvedOrgId,
1537
+ cubistOrgId: cubistOrgId || resolvedOrgId
1538
+ };
1539
+ }
1574
1540
  function AvaCloudWalletProvider({
1575
1541
  children,
1576
1542
  orgId,
1577
1543
  chainId = 43113,
1578
1544
  darkMode = false,
1579
1545
  env = "production",
1546
+ authServiceUrl: customAuthServiceUrl,
1580
1547
  onAuthSuccess,
1581
1548
  onAuthError,
1582
1549
  onWalletUpdate
@@ -1585,24 +1552,40 @@ function AvaCloudWalletProvider({
1585
1552
  useEffect5(() => {
1586
1553
  setChainId(chainId);
1587
1554
  }, [chainId, setChainId]);
1588
- const authServiceUrl = env === "development" ? "http://localhost:3000" : env === "staging" ? "https://ac-auth-service-env-staging-ava-labs.vercel.app" : "https://ac-auth-service.vercel.app";
1555
+ const getAuthServiceUrl = () => {
1556
+ var _a;
1557
+ if (customAuthServiceUrl) {
1558
+ return customAuthServiceUrl;
1559
+ }
1560
+ if (typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.NEXT_PUBLIC_AUTH_SERVICE_URL)) {
1561
+ return process.env.NEXT_PUBLIC_AUTH_SERVICE_URL;
1562
+ }
1563
+ if (env === "development") {
1564
+ return "http://localhost:3000";
1565
+ } else if (env === "staging") {
1566
+ return "https://ac-auth-service-env-staging-ava-labs.vercel.app";
1567
+ } else {
1568
+ return "https://ac-auth-service.vercel.app";
1569
+ }
1570
+ };
1571
+ const authServiceUrl = getAuthServiceUrl();
1589
1572
  const environment = env;
1590
- const [isAuthenticated, setIsAuthenticated] = useState7(false);
1591
- const [isCubistLoading, setIsCubistLoading] = useState7(true);
1592
- const [isLoading, setIsLoading] = useState7(true);
1593
- const [user, setUser] = useState7(null);
1594
- const [wallet, setWallet] = useState7({ address: null });
1595
- const [orgConfig, setOrgConfig] = useState7(null);
1596
- const [iframe, setIframe] = useState7(null);
1597
- const [isIframeReady, setIsIframeReady] = useState7(false);
1598
- const [cubistClient, setCubistClient] = useState7(null);
1599
- const [cubistError, setCubistError] = useState7(null);
1600
- const [pendingOidcToken, setPendingOidcToken] = useState7(null);
1573
+ const [isAuthenticated, setIsAuthenticated] = useState8(false);
1574
+ const [isCubistLoading, setIsCubistLoading] = useState8(true);
1575
+ const [isLoading, setIsLoading] = useState8(true);
1576
+ const [user, setUser] = useState8(null);
1577
+ const [wallet, setWallet] = useState8({ address: null });
1578
+ const [orgConfig, setOrgConfig] = useState8(null);
1579
+ const [iframe, setIframe] = useState8(null);
1580
+ const [_isIframeReady, setIsIframeReady] = useState8(false);
1581
+ const [cubistClient, setCubistClient] = useState8(null);
1582
+ const [cubistError, setCubistError] = useState8(null);
1583
+ const [pendingOidcToken, setPendingOidcToken] = useState8(null);
1601
1584
  const iframeRef = useRef3(null);
1602
1585
  useEffect5(() => {
1603
1586
  setIsLoading(isCubistLoading || isAuthenticated && !wallet.address);
1604
1587
  }, [isCubistLoading, isAuthenticated, wallet.address]);
1605
- const getWalletInfo = useCallback5(async (client, sessionId) => {
1588
+ const getWalletInfo = useCallback6(async (client, sessionId) => {
1606
1589
  try {
1607
1590
  const sessionKeys = await client.sessionKeys();
1608
1591
  if (!sessionKeys.length) {
@@ -1623,7 +1606,7 @@ function AvaCloudWalletProvider({
1623
1606
  return null;
1624
1607
  }
1625
1608
  }, [orgConfig]);
1626
- const loginWithCubist = useCallback5(async (oidcToken) => {
1609
+ const loginWithCubist = useCallback6(async (oidcToken) => {
1627
1610
  if (!orgConfig || !orgConfig.walletProviderOrgID) {
1628
1611
  const error = new Error("Missing required walletProviderOrgID in organization configuration");
1629
1612
  setCubistError(error);
@@ -1641,7 +1624,7 @@ function AvaCloudWalletProvider({
1641
1624
  if (oidcToken) {
1642
1625
  accessToken = oidcToken;
1643
1626
  } else {
1644
- const tokens = localStorage.getItem(AUTH_TOKENS_KEY);
1627
+ const tokens = localStorage.getItem(AUTH_TOKENS_KEY2);
1645
1628
  if (!tokens) {
1646
1629
  throw new Error("No authentication tokens found in localStorage");
1647
1630
  }
@@ -1684,8 +1667,8 @@ function AvaCloudWalletProvider({
1684
1667
  });
1685
1668
  }
1686
1669
  } catch (error) {
1687
- localStorage.removeItem(AUTH_TOKENS_KEY);
1688
- localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1670
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
1671
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1689
1672
  setIsAuthenticated(false);
1690
1673
  setUser(null);
1691
1674
  setCubistClient(null);
@@ -1699,12 +1682,17 @@ function AvaCloudWalletProvider({
1699
1682
  setIsCubistLoading(false);
1700
1683
  }
1701
1684
  }, [wallet, onWalletUpdate, onAuthError, getWalletInfo, orgConfig, environment]);
1702
- const { sendMessage } = usePostMessage({
1685
+ const {
1686
+ authService,
1687
+ isConnected,
1688
+ login: penpalLogin,
1689
+ signup: penpalSignup,
1690
+ logout: penpalLogout
1691
+ } = usePenpalAuth({
1703
1692
  authServiceUrl,
1704
1693
  orgId,
1705
1694
  environment,
1706
1695
  iframe,
1707
- isIframeReady,
1708
1696
  onAuthSuccess: () => {
1709
1697
  if (user) {
1710
1698
  if (wallet.address) {
@@ -1714,8 +1702,7 @@ function AvaCloudWalletProvider({
1714
1702
  },
1715
1703
  onAuthError: (error) => {
1716
1704
  const errorMessage = (error == null ? void 0 : error.message) || "";
1717
- if (errorMessage === "User not authenticated in iframe" || errorMessage === "Unknown error" || // Generic error that often appears during signup
1718
- errorMessage.includes("OIDC user not found")) {
1705
+ if (errorMessage === "User not authenticated in iframe" || errorMessage === "Unknown error" || errorMessage.includes("OIDC user not found")) {
1719
1706
  return;
1720
1707
  }
1721
1708
  setIsCubistLoading(false);
@@ -1741,76 +1728,78 @@ function AvaCloudWalletProvider({
1741
1728
  };
1742
1729
  },
1743
1730
  onOrgConfigUpdate: (config) => {
1744
- setOrgConfig(config);
1731
+ setOrgConfig(normalizeOrgConfig(config));
1745
1732
  },
1746
1733
  setIsAuthenticated,
1747
1734
  setUser,
1748
- setIsLoading: (isLoading2) => {
1749
- setIsLoading(isLoading2);
1735
+ setIsLoading: (loading) => {
1736
+ setIsLoading(loading);
1750
1737
  },
1751
- setIsIframeReady,
1752
- wallet,
1753
- cubistClient
1738
+ setIsIframeReady
1754
1739
  });
1755
- const login = useCallback5(() => {
1756
- if (iframe == null ? void 0 : iframe.contentWindow) {
1757
- setIsCubistLoading(true);
1758
- sendMessage({ type: "LOGIN_REQUEST" });
1740
+ const login = useCallback6((params) => {
1741
+ if (isConnected) {
1742
+ const isEmailLogin = (params == null ? void 0 : params.email) && (params == null ? void 0 : params.password);
1743
+ if (isEmailLogin) {
1744
+ setIsCubistLoading(true);
1745
+ }
1746
+ penpalLogin(params).catch((error) => {
1747
+ setIsCubistLoading(false);
1748
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Login failed"));
1749
+ });
1759
1750
  }
1760
- }, [iframe, sendMessage]);
1761
- const signup = useCallback5((email, password) => {
1762
- if (iframe == null ? void 0 : iframe.contentWindow) {
1751
+ }, [isConnected, penpalLogin, onAuthError]);
1752
+ const signup = useCallback6((email, password) => {
1753
+ if (isConnected) {
1763
1754
  setIsCubistLoading(true);
1764
- sendMessage({
1765
- type: "SIGNUP_REQUEST",
1766
- payload: {
1767
- email,
1768
- password
1769
- },
1770
- requestId: `signup-${Date.now()}`
1755
+ penpalSignup(email, password).catch((error) => {
1756
+ setIsCubistLoading(false);
1757
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Signup failed"));
1771
1758
  });
1772
1759
  }
1773
- }, [iframe, sendMessage]);
1774
- const logout = useCallback5(() => {
1775
- sendMessage({ type: "LOGOUT_REQUEST" });
1760
+ }, [isConnected, penpalSignup, onAuthError]);
1761
+ const logout = useCallback6(() => {
1762
+ penpalLogout().catch((error) => {
1763
+ console.error("Logout error:", error);
1764
+ });
1776
1765
  setUser(null);
1777
1766
  setWallet({ address: null });
1778
1767
  setIsAuthenticated(false);
1779
- localStorage.removeItem(AUTH_TOKENS_KEY);
1780
- localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1781
- localStorage.removeItem(AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
1782
- localStorage.removeItem(AUTH0_STORAGE_KEYS.ID_TOKEN);
1783
- localStorage.removeItem(AUTH0_STORAGE_KEYS.EXPIRES_AT);
1784
- localStorage.removeItem(CUBIST_USER_ID_KEY);
1768
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
1769
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1770
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.ACCESS_TOKEN);
1771
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.ID_TOKEN);
1772
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.EXPIRES_AT);
1773
+ localStorage.removeItem(CUBIST_USER_ID_KEY2);
1785
1774
  if (orgId) {
1786
- const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${env}`;
1775
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${env}`;
1787
1776
  localStorage.removeItem(cachedConfigKey);
1788
1777
  }
1789
- sessionStorage.removeItem(OIDC_TOKEN_KEY);
1778
+ sessionStorage.removeItem(OIDC_TOKEN_KEY2);
1790
1779
  setCubistClient(null);
1791
1780
  setCubistError(null);
1792
1781
  setPendingOidcToken(null);
1793
- }, [sendMessage, orgId, env]);
1794
- const addAccount = useCallback5(async (accountIndex) => {
1782
+ }, [penpalLogout, orgId, env]);
1783
+ const addAccount = useCallback6(async (accountIndex) => {
1795
1784
  if (!isAuthenticated || !user || !wallet.mnemonicId) {
1796
1785
  throw new Error("User must be authenticated and have a wallet to add an account");
1797
1786
  }
1787
+ if (!authService) {
1788
+ throw new Error("Auth service not connected");
1789
+ }
1798
1790
  const path = getDerivationPath("EVM" /* EVM */, accountIndex);
1799
- sendMessage({
1800
- type: "ADD_ACCOUNT",
1801
- payload: {
1802
- accountIndex,
1803
- mnemonicId: wallet.mnemonicId,
1804
- derivationPath: path,
1805
- identityProof: {
1806
- email: user.email,
1807
- displayName: user.displayName,
1808
- sub: user.sub,
1809
- configured_mfa: user.configured_mfa
1810
- }
1791
+ await authService.addAccount({
1792
+ accountIndex,
1793
+ mnemonicId: wallet.mnemonicId,
1794
+ derivationPath: path,
1795
+ identityProof: {
1796
+ email: user.email,
1797
+ displayName: user.displayName,
1798
+ sub: user.sub,
1799
+ configured_mfa: user.configured_mfa
1811
1800
  }
1812
1801
  });
1813
- }, [sendMessage, isAuthenticated, user, wallet.mnemonicId]);
1802
+ }, [authService, isAuthenticated, user, wallet.mnemonicId]);
1814
1803
  useEffect5(() => {
1815
1804
  const hasOrgConfig = !!(orgConfig == null ? void 0 : orgConfig.walletProviderOrgID);
1816
1805
  const hasOidcToken = !!pendingOidcToken;
@@ -1860,20 +1849,20 @@ function AvaCloudWalletProvider({
1860
1849
  if (typeof window === "undefined") {
1861
1850
  return;
1862
1851
  }
1863
- const isAuthenticatedInStorage = localStorage.getItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED) === "true";
1852
+ const isAuthenticatedInStorage = localStorage.getItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED) === "true";
1864
1853
  if (!isAuthenticatedInStorage) {
1865
1854
  return;
1866
1855
  }
1867
- const existingOidcToken = sessionStorage.getItem(OIDC_TOKEN_KEY);
1856
+ const existingOidcToken = sessionStorage.getItem(OIDC_TOKEN_KEY2);
1868
1857
  if (existingOidcToken) {
1869
1858
  setPendingOidcToken(existingOidcToken);
1870
1859
  } else {
1871
1860
  try {
1872
- const tokensJson = localStorage.getItem(AUTH_TOKENS_KEY);
1861
+ const tokensJson = localStorage.getItem(AUTH_TOKENS_KEY2);
1873
1862
  if (tokensJson) {
1874
1863
  const tokens = JSON.parse(tokensJson);
1875
1864
  if (tokens.access_token) {
1876
- sessionStorage.setItem(OIDC_TOKEN_KEY, tokens.access_token);
1865
+ sessionStorage.setItem(OIDC_TOKEN_KEY2, tokens.access_token);
1877
1866
  setPendingOidcToken(tokens.access_token);
1878
1867
  }
1879
1868
  }
@@ -1911,7 +1900,7 @@ function useAvaCloudWallet() {
1911
1900
  }
1912
1901
 
1913
1902
  // src/components/LoginButton.tsx
1914
- import { useState as useState8 } from "react";
1903
+ import { useState as useState9 } from "react";
1915
1904
  import { Button as Button2, Dialog as Dialog3, DialogContent as DialogContent3, DialogTitle as DialogTitle2 } from "@avalabs/core-k2-components";
1916
1905
  import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1917
1906
  function LoginButton({
@@ -1920,7 +1909,7 @@ function LoginButton({
1920
1909
  ...props
1921
1910
  }) {
1922
1911
  const { isLoading } = useAvaCloudWallet();
1923
- const [isModalOpen, setIsModalOpen] = useState8(false);
1912
+ const [isModalOpen, setIsModalOpen] = useState9(false);
1924
1913
  const handleOpen = () => setIsModalOpen(true);
1925
1914
  const handleClose = () => setIsModalOpen(false);
1926
1915
  return /* @__PURE__ */ jsxs5(Fragment2, { children: [
@@ -1958,7 +1947,7 @@ function LoginButton({
1958
1947
  }
1959
1948
 
1960
1949
  // src/components/WalletButton.tsx
1961
- import { useState as useState16 } from "react";
1950
+ import { useState as useState17 } from "react";
1962
1951
  import {
1963
1952
  Button as Button8,
1964
1953
  Box as Box11,
@@ -1970,7 +1959,7 @@ import {
1970
1959
  } from "@avalabs/core-k2-components";
1971
1960
 
1972
1961
  // src/components/WalletCard.tsx
1973
- import { useState as useState15 } from "react";
1962
+ import { useState as useState16 } from "react";
1974
1963
  import {
1975
1964
  Typography as Typography10,
1976
1965
  Box as Box10,
@@ -1985,7 +1974,7 @@ import {
1985
1974
  } from "@avalabs/core-k2-components";
1986
1975
 
1987
1976
  // src/components/SendView.tsx
1988
- import { useState as useState11, useEffect as useEffect6 } from "react";
1977
+ import { useState as useState12, useEffect as useEffect6 } from "react";
1989
1978
  import {
1990
1979
  Box as Box3,
1991
1980
  Typography as Typography4,
@@ -2001,7 +1990,7 @@ import {
2001
1990
  import { Icon } from "@iconify/react";
2002
1991
 
2003
1992
  // src/hooks/useTransferTokens.ts
2004
- import { useCallback as useCallback6, useState as useState9 } from "react";
1993
+ import { useCallback as useCallback7, useState as useState10 } from "react";
2005
1994
  import { Secp256k1 } from "@cubist-labs/cubesigner-sdk";
2006
1995
  import { useQueryClient } from "@tanstack/react-query";
2007
1996
  import {
@@ -2014,7 +2003,7 @@ import {
2014
2003
  erc20Abi
2015
2004
  } from "viem";
2016
2005
  function useTransferTokens() {
2017
- const [state, setState] = useState9({
2006
+ const [state, setState] = useState10({
2018
2007
  isLoading: false,
2019
2008
  error: null,
2020
2009
  txHash: null,
@@ -2026,7 +2015,7 @@ function useTransferTokens() {
2026
2015
  const { wallet, cubistClient } = useAvaCloudWallet();
2027
2016
  const { publicClient } = useViem();
2028
2017
  const queryClient2 = useQueryClient();
2029
- const reset = useCallback6(() => {
2018
+ const reset = useCallback7(() => {
2030
2019
  setState({
2031
2020
  isLoading: false,
2032
2021
  error: null,
@@ -2037,7 +2026,7 @@ function useTransferTokens() {
2037
2026
  actualTotalFee: null
2038
2027
  });
2039
2028
  }, []);
2040
- const transfer = useCallback6(async (toAddress, amount) => {
2029
+ const transfer = useCallback7(async (toAddress, amount) => {
2041
2030
  var _a;
2042
2031
  if (!publicClient || !cubistClient || !(wallet == null ? void 0 : wallet.address)) {
2043
2032
  setState((prev) => ({
@@ -2123,7 +2112,7 @@ function useTransferTokens() {
2123
2112
  setState((prev) => ({ ...prev, isLoading: false }));
2124
2113
  }
2125
2114
  }, [publicClient, cubistClient, wallet == null ? void 0 : wallet.address, queryClient2]);
2126
- const transferERC20 = useCallback6(async (tokenAddress, toAddress, amount, decimals) => {
2115
+ const transferERC20 = useCallback7(async (tokenAddress, toAddress, amount, decimals) => {
2127
2116
  var _a;
2128
2117
  if (!publicClient || !cubistClient || !(wallet == null ? void 0 : wallet.address)) {
2129
2118
  setState((prev) => ({
@@ -2226,10 +2215,10 @@ function useTransferTokens() {
2226
2215
  }
2227
2216
 
2228
2217
  // src/hooks/useGasEstimation.ts
2229
- import { useCallback as useCallback7, useState as useState10 } from "react";
2218
+ import { useCallback as useCallback8, useState as useState11 } from "react";
2230
2219
  import { formatEther as formatEther2, parseEther as parseEther2 } from "viem";
2231
2220
  function useGasEstimation() {
2232
- const [state, setState] = useState10({
2221
+ const [state, setState] = useState11({
2233
2222
  isLoading: false,
2234
2223
  error: null,
2235
2224
  baseFee: null,
@@ -2238,7 +2227,7 @@ function useGasEstimation() {
2238
2227
  totalWithAmount: null
2239
2228
  });
2240
2229
  const { publicClient } = useViem();
2241
- const reset = useCallback7(() => {
2230
+ const reset = useCallback8(() => {
2242
2231
  setState({
2243
2232
  isLoading: false,
2244
2233
  error: null,
@@ -2248,7 +2237,7 @@ function useGasEstimation() {
2248
2237
  totalWithAmount: null
2249
2238
  });
2250
2239
  }, []);
2251
- const updateTotal = useCallback7((amount) => {
2240
+ const updateTotal = useCallback8((amount) => {
2252
2241
  if (!state.totalFee) return;
2253
2242
  const amountValue = Number.parseFloat(amount);
2254
2243
  if (Number.isNaN(amountValue)) return;
@@ -2258,7 +2247,7 @@ function useGasEstimation() {
2258
2247
  totalWithAmount: newTotal
2259
2248
  }));
2260
2249
  }, [state.totalFee]);
2261
- const estimateGas = useCallback7(async (toAddress, amount) => {
2250
+ const estimateGas = useCallback8(async (toAddress, amount) => {
2262
2251
  if (!publicClient) {
2263
2252
  setState((prev) => ({
2264
2253
  ...prev,
@@ -2532,7 +2521,7 @@ function SendFormView({
2532
2521
  const { data: tokenBalancesResponse } = useERC20Balances((wallet == null ? void 0 : wallet.address) || void 0, chainId == null ? void 0 : chainId.toString());
2533
2522
  const tokenBalances = tokenBalancesResponse;
2534
2523
  const { baseFee, priorityFee, totalFee, totalWithAmount, estimateGas, updateTotal } = useGasEstimation();
2535
- const [addressError, setAddressError] = useState11(null);
2524
+ const [addressError, setAddressError] = useState12(null);
2536
2525
  const handleRecipientChange = (value) => {
2537
2526
  if (value && !isAddress2(value)) {
2538
2527
  setAddressError("Invalid address format");
@@ -3060,9 +3049,9 @@ function FailureView({ recipient, amount, currencySymbol, error, onDone }) {
3060
3049
  function SendView({ onBack, onViewStateChange, selectedToken: initialToken }) {
3061
3050
  var _a;
3062
3051
  const { chainId } = useChainId();
3063
- const [recipient, setRecipient] = useState11("");
3064
- const [amount, setAmount] = useState11("");
3065
- const [selectedToken, setSelectedToken] = useState11(initialToken);
3052
+ const [recipient, setRecipient] = useState12("");
3053
+ const [amount, setAmount] = useState12("");
3054
+ const [selectedToken, setSelectedToken] = useState12(initialToken);
3066
3055
  const { transfer, transferERC20, error, isLoading, txHash, viewState, reset, actualBaseFee, actualPriorityFee, actualTotalFee } = useTransferTokens();
3067
3056
  const { data: blockchainInfo } = useBlockchain((chainId == null ? void 0 : chainId.toString()) || "");
3068
3057
  const { wallet } = useAvaCloudWallet();
@@ -3158,7 +3147,7 @@ function SendView({ onBack, onViewStateChange, selectedToken: initialToken }) {
3158
3147
  }
3159
3148
 
3160
3149
  // src/components/ReceiveView.tsx
3161
- import { useState as useState12 } from "react";
3150
+ import { useState as useState13 } from "react";
3162
3151
  import { QRCodeSVG } from "qrcode.react";
3163
3152
  import {
3164
3153
  Box as Box4,
@@ -3171,7 +3160,7 @@ import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
3171
3160
  function ReceiveView(_props) {
3172
3161
  const { wallet } = useAvaCloudWallet();
3173
3162
  const { chainId } = useChainId();
3174
- const [_copied, setCopied] = useState12(false);
3163
+ const [_copied, setCopied] = useState13(false);
3175
3164
  const theme = useTheme2();
3176
3165
  const { isDarkMode } = useThemeMode();
3177
3166
  if (!wallet.address) {
@@ -3251,7 +3240,7 @@ function ReceiveView(_props) {
3251
3240
  }
3252
3241
 
3253
3242
  // src/components/ExportView.tsx
3254
- import { useState as useState13 } from "react";
3243
+ import { useState as useState14, useCallback as useCallback9 } from "react";
3255
3244
  import {
3256
3245
  Box as Box5,
3257
3246
  Typography as Typography6,
@@ -3263,32 +3252,27 @@ import {
3263
3252
  } from "@avalabs/core-k2-components";
3264
3253
  import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
3265
3254
  function ExportView({ onBack }) {
3266
- const { wallet, iframe } = useAvaCloudWallet();
3267
- const [showKey, setShowKey] = useState13(false);
3268
- const [copied, setCopied] = useState13(false);
3269
- const [privateKey, setPrivateKey] = useState13(null);
3270
- const [error, setError] = useState13(null);
3271
- const handleExport = async () => {
3272
- if (!(iframe == null ? void 0 : iframe.contentWindow)) return;
3255
+ const { wallet } = useAvaCloudWallet();
3256
+ const [showKey, _setShowKey] = useState14(false);
3257
+ const [copied, setCopied] = useState14(false);
3258
+ const [privateKey, _setPrivateKey] = useState14(null);
3259
+ const [error, setError] = useState14(null);
3260
+ const [isLoading, setIsLoading] = useState14(false);
3261
+ const handleExport = useCallback9(async () => {
3262
+ if (!wallet.address) {
3263
+ setError("No wallet address available");
3264
+ return;
3265
+ }
3266
+ setIsLoading(true);
3267
+ setError(null);
3273
3268
  try {
3274
- iframe.contentWindow.postMessage({
3275
- type: "EXPORT_PRIVATE_KEY",
3276
- payload: {
3277
- address: wallet.address
3278
- }
3279
- }, "*");
3280
- const handleResponse = (event) => {
3281
- if (event.data.type === "EXPORT_PRIVATE_KEY_RESPONSE") {
3282
- setPrivateKey(event.data.payload.privateKey);
3283
- setShowKey(true);
3284
- window.removeEventListener("message", handleResponse);
3285
- }
3286
- };
3287
- window.addEventListener("message", handleResponse);
3269
+ setError("Private key export is not yet available. Please use the wallet provider directly.");
3288
3270
  } catch (err) {
3289
3271
  setError("Failed to export private key. Please try again.");
3272
+ } finally {
3273
+ setIsLoading(false);
3290
3274
  }
3291
- };
3275
+ }, [wallet.address]);
3292
3276
  const handleCopy = () => {
3293
3277
  if (privateKey) {
3294
3278
  navigator.clipboard.writeText(privateKey);
@@ -3309,8 +3293,9 @@ function ExportView({ onBack }) {
3309
3293
  variant: "contained",
3310
3294
  color: "warning",
3311
3295
  onClick: handleExport,
3296
+ disabled: isLoading,
3312
3297
  sx: { mb: 2 },
3313
- children: "Show Private Key"
3298
+ children: isLoading ? "Loading..." : "Show Private Key"
3314
3299
  }
3315
3300
  ) : /* @__PURE__ */ jsx13(Box5, { sx: { mb: 3 }, children: /* @__PURE__ */ jsxs9(Box5, { sx: {
3316
3301
  display: "flex",
@@ -3360,7 +3345,7 @@ function ExportView({ onBack }) {
3360
3345
  }
3361
3346
 
3362
3347
  // src/components/TokensView.tsx
3363
- import { useState as useState14 } from "react";
3348
+ import { useState as useState15 } from "react";
3364
3349
  import {
3365
3350
  Box as Box8,
3366
3351
  Tabs,
@@ -3760,7 +3745,7 @@ function NonFungibleList() {
3760
3745
  // src/components/TokensView.tsx
3761
3746
  import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
3762
3747
  function TokensView({ onSend }) {
3763
- const [activeTab, setActiveTab] = useState14("tokens");
3748
+ const [activeTab, setActiveTab] = useState15("tokens");
3764
3749
  const theme = useTheme3();
3765
3750
  const handleCopyAddress = (address) => {
3766
3751
  navigator.clipboard.writeText(address);
@@ -4000,8 +3985,8 @@ import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-r
4000
3985
  function WalletCard({ onClose }) {
4001
3986
  const { user, wallet, isAuthenticated } = useAvaCloudWallet();
4002
3987
  const { balance, isLoadingBalance, currencySymbol, blockchain } = useGlacier();
4003
- const [currentView, setCurrentView] = useState15("main");
4004
- const [selectedToken, setSelectedToken] = useState15();
3988
+ const [currentView, setCurrentView] = useState16("main");
3989
+ const [selectedToken, setSelectedToken] = useState16();
4005
3990
  const theme = useTheme4();
4006
3991
  if (!isAuthenticated || !user) return null;
4007
3992
  const handleCopy = (e) => {
@@ -4193,7 +4178,7 @@ function WalletButton({
4193
4178
  ...props
4194
4179
  }) {
4195
4180
  const { isLoading, isAuthenticated, wallet } = useAvaCloudWallet();
4196
- const [isModalOpen, setIsModalOpen] = useState16(false);
4181
+ const [isModalOpen, setIsModalOpen] = useState17(false);
4197
4182
  const theme = useTheme5();
4198
4183
  const { isDarkMode } = useThemeMode();
4199
4184
  const handleOpen = () => setIsModalOpen(true);
@@ -4277,134 +4262,422 @@ function WalletButton({
4277
4262
  },
4278
4263
  children: displayAddress
4279
4264
  }
4280
- ),
4281
- /* @__PURE__ */ jsx21(
4282
- IconButton9,
4283
- {
4284
- size: "small",
4285
- onClick: handleCopy,
4286
- sx: { color: "text.secondary" },
4287
- children: /* @__PURE__ */ jsx21(CopyIcon5, {})
4265
+ ),
4266
+ /* @__PURE__ */ jsx21(
4267
+ IconButton9,
4268
+ {
4269
+ size: "small",
4270
+ onClick: handleCopy,
4271
+ sx: { color: "text.secondary" },
4272
+ children: /* @__PURE__ */ jsx21(CopyIcon5, {})
4273
+ }
4274
+ )
4275
+ ] })
4276
+ ]
4277
+ }
4278
+ ),
4279
+ isModalOpen && /* @__PURE__ */ jsx21(WalletCard, { onClose: handleClose })
4280
+ ] });
4281
+ }
4282
+
4283
+ // src/components/WalletDisplay.tsx
4284
+ import { useState as useState18 } from "react";
4285
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
4286
+ function WalletDisplay({
4287
+ className = "",
4288
+ truncateAddress = true,
4289
+ showAddAccount = true
4290
+ }) {
4291
+ const { wallet, addAccount, isAuthenticated } = useAvaCloudWallet();
4292
+ const [isAdding, setIsAdding] = useState18(false);
4293
+ const [accountIndex, setAccountIndex] = useState18(0);
4294
+ if (!isAuthenticated || !wallet.address) {
4295
+ return null;
4296
+ }
4297
+ const displayAddress = truncateAddress ? `${wallet.address.slice(0, 6)}...${wallet.address.slice(-4)}` : wallet.address;
4298
+ const handleAddAccount = async () => {
4299
+ try {
4300
+ setIsAdding(true);
4301
+ await addAccount(accountIndex);
4302
+ setAccountIndex((prev) => prev + 1);
4303
+ } catch (error) {
4304
+ console.error("Failed to add account:", error);
4305
+ } finally {
4306
+ setIsAdding(false);
4307
+ }
4308
+ };
4309
+ return /* @__PURE__ */ jsxs18("div", { className: `space-y-4 ${className}`, children: [
4310
+ /* @__PURE__ */ jsxs18("div", { className: "bg-gray-50 rounded-lg p-4", children: [
4311
+ /* @__PURE__ */ jsx22("div", { className: "text-sm text-gray-500", children: "Wallet Address" }),
4312
+ /* @__PURE__ */ jsx22("div", { className: "mt-1 font-mono text-sm break-all", children: displayAddress })
4313
+ ] }),
4314
+ showAddAccount && /* @__PURE__ */ jsx22(
4315
+ "button",
4316
+ {
4317
+ type: "button",
4318
+ onClick: handleAddAccount,
4319
+ disabled: isAdding,
4320
+ className: "w-full inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed",
4321
+ children: isAdding ? "Adding Account..." : "Add Account"
4322
+ }
4323
+ )
4324
+ ] });
4325
+ }
4326
+
4327
+ // src/components/UserProfile.tsx
4328
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
4329
+ function UserProfile({
4330
+ className = "",
4331
+ showLogout = true
4332
+ }) {
4333
+ const { user, logout, isAuthenticated } = useAvaCloudWallet();
4334
+ if (!isAuthenticated || !user) {
4335
+ return null;
4336
+ }
4337
+ return /* @__PURE__ */ jsx23("div", { className: `space-y-4 ${className}`, children: /* @__PURE__ */ jsxs19("div", { className: "bg-white shadow rounded-lg p-6", children: [
4338
+ /* @__PURE__ */ jsx23("div", { className: "px-4 py-5 sm:px-6", children: /* @__PURE__ */ jsx23("h3", { className: "text-lg font-medium leading-6 text-gray-900", children: "User Profile" }) }),
4339
+ /* @__PURE__ */ jsx23("div", { className: "border-t border-gray-200", children: /* @__PURE__ */ jsxs19("dl", { children: [
4340
+ /* @__PURE__ */ jsxs19("div", { className: "bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", children: [
4341
+ /* @__PURE__ */ jsx23("dt", { className: "text-sm font-medium text-gray-500", children: "Display Name" }),
4342
+ /* @__PURE__ */ jsx23("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.displayName })
4343
+ ] }),
4344
+ user.email && /* @__PURE__ */ jsxs19("div", { className: "bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", children: [
4345
+ /* @__PURE__ */ jsx23("dt", { className: "text-sm font-medium text-gray-500", children: "Email address" }),
4346
+ /* @__PURE__ */ jsx23("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.email })
4347
+ ] }),
4348
+ user.configured_mfa && user.configured_mfa.length > 0 && /* @__PURE__ */ jsxs19("div", { children: [
4349
+ /* @__PURE__ */ jsx23("div", { className: "text-sm font-medium text-gray-500", children: "MFA Methods" }),
4350
+ /* @__PURE__ */ jsx23("div", { className: "mt-1 space-y-1", children: user.configured_mfa.map((method) => {
4351
+ const mfaMethod = typeof method === "string" ? { type: method } : method;
4352
+ return /* @__PURE__ */ jsx23(
4353
+ "div",
4354
+ {
4355
+ className: "text-sm text-gray-900",
4356
+ children: mfaMethod.type === "totp" ? "Authenticator App" : mfaMethod.name
4357
+ },
4358
+ mfaMethod.type === "fido" ? mfaMethod.id : `totp-${mfaMethod.type}`
4359
+ );
4360
+ }) })
4361
+ ] })
4362
+ ] }) }),
4363
+ showLogout && /* @__PURE__ */ jsx23("div", { className: "mt-6", children: /* @__PURE__ */ jsx23(
4364
+ "button",
4365
+ {
4366
+ type: "button",
4367
+ onClick: logout,
4368
+ className: "w-full inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500",
4369
+ children: "Sign Out"
4370
+ }
4371
+ ) })
4372
+ ] }) });
4373
+ }
4374
+
4375
+ // src/hooks/usePostMessage.ts
4376
+ import { useCallback as useCallback10, useEffect as useEffect7, useRef as useRef4 } from "react";
4377
+ var globalAuthState = {
4378
+ signupInProgress: false,
4379
+ loginInProgress: false,
4380
+ lastSignupTimestamp: 0,
4381
+ lastLoginTimestamp: 0,
4382
+ processingMessageIds: /* @__PURE__ */ new Set()
4383
+ };
4384
+ function cleanupProcessedMessageIds() {
4385
+ if (globalAuthState.processingMessageIds.size > 100) {
4386
+ const messageIds = Array.from(globalAuthState.processingMessageIds);
4387
+ globalAuthState.processingMessageIds = new Set(messageIds.slice(-50));
4388
+ }
4389
+ }
4390
+ function usePostMessage({
4391
+ authServiceUrl,
4392
+ orgId,
4393
+ environment,
4394
+ iframe,
4395
+ isIframeReady,
4396
+ onAuthSuccess,
4397
+ onAuthError,
4398
+ onOidcReceived,
4399
+ onOrgConfigUpdate,
4400
+ setIsAuthenticated,
4401
+ setUser,
4402
+ setIsLoading,
4403
+ setIsIframeReady,
4404
+ cubistClient
4405
+ }) {
4406
+ const lastAuthStateRef = useRef4({
4407
+ isAuthenticated: false,
4408
+ userId: null,
4409
+ lastUpdateTime: 0
4410
+ });
4411
+ const hasRequestedOidcRef = useRef4(false);
4412
+ const isHandlingMessageRef = useRef4(false);
4413
+ const hasLoadedCacheRef = useRef4(false);
4414
+ useEffect7(() => {
4415
+ if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
4416
+ hasLoadedCacheRef.current = true;
4417
+ try {
4418
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${environment}`;
4419
+ const cachedConfigJson = localStorage.getItem(cachedConfigKey);
4420
+ if (cachedConfigJson) {
4421
+ const cachedConfig = JSON.parse(cachedConfigJson);
4422
+ const timestamp = cachedConfig._timestamp || 0;
4423
+ const isExpired = Date.now() - timestamp > 30 * 60 * 1e3;
4424
+ if (!isExpired) {
4425
+ const { _timestamp, ...configWithoutTimestamp } = cachedConfig;
4426
+ onOrgConfigUpdate(configWithoutTimestamp);
4427
+ }
4428
+ }
4429
+ } catch (error) {
4430
+ }
4431
+ }
4432
+ }, [orgId, environment, onOrgConfigUpdate]);
4433
+ const sendMessage = useCallback10((message) => {
4434
+ if (iframe == null ? void 0 : iframe.contentWindow) {
4435
+ try {
4436
+ if (message.type === "SIGNUP_REQUEST") {
4437
+ if (globalAuthState.signupInProgress) {
4438
+ return;
4439
+ }
4440
+ const now = Date.now();
4441
+ if (now - globalAuthState.lastSignupTimestamp < 3e3) {
4442
+ return;
4443
+ }
4444
+ globalAuthState.signupInProgress = true;
4445
+ globalAuthState.lastSignupTimestamp = now;
4446
+ let finalMessage = message;
4447
+ if (!message.requestId) {
4448
+ finalMessage = {
4449
+ ...message,
4450
+ requestId: `signup-${now}`
4451
+ };
4452
+ }
4453
+ let messageToSend = finalMessage;
4454
+ if (finalMessage.payload && typeof finalMessage.payload.email === "string" && typeof finalMessage.payload.password === "string") {
4455
+ messageToSend = {
4456
+ type: "SIGNUP_REQUEST",
4457
+ email: finalMessage.payload.email,
4458
+ password: finalMessage.payload.password,
4459
+ requestId: finalMessage.requestId || `signup-${now}`
4460
+ };
4461
+ }
4462
+ if ("requestId" in messageToSend && messageToSend.requestId) {
4463
+ globalAuthState.processingMessageIds.add(messageToSend.requestId);
4464
+ }
4465
+ iframe.contentWindow.postMessage(messageToSend, authServiceUrl);
4466
+ return;
4467
+ }
4468
+ if (message.type === "LOGIN_REQUEST") {
4469
+ if (globalAuthState.loginInProgress) {
4470
+ return;
4471
+ }
4472
+ const now = Date.now();
4473
+ if (now - globalAuthState.lastLoginTimestamp < 3e3) {
4474
+ return;
4475
+ }
4476
+ globalAuthState.loginInProgress = true;
4477
+ globalAuthState.lastLoginTimestamp = now;
4478
+ let finalMessage = message;
4479
+ if (!message.requestId) {
4480
+ finalMessage = {
4481
+ ...message,
4482
+ requestId: `login-${now}`
4483
+ };
4484
+ }
4485
+ if (finalMessage.requestId) {
4486
+ globalAuthState.processingMessageIds.add(finalMessage.requestId);
4487
+ }
4488
+ iframe.contentWindow.postMessage(finalMessage, authServiceUrl);
4489
+ return;
4490
+ }
4491
+ iframe.contentWindow.postMessage(message, authServiceUrl);
4492
+ } catch (error) {
4493
+ if (message.type === "SIGNUP_REQUEST") {
4494
+ globalAuthState.signupInProgress = false;
4495
+ }
4496
+ if (message.type === "LOGIN_REQUEST") {
4497
+ globalAuthState.loginInProgress = false;
4498
+ }
4499
+ }
4500
+ }
4501
+ }, [iframe, authServiceUrl]);
4502
+ useEffect7(() => {
4503
+ const handleMessage = async (event) => {
4504
+ var _a, _b, _c, _d, _e, _f, _g;
4505
+ if (isHandlingMessageRef.current) {
4506
+ return;
4507
+ }
4508
+ if (event.origin !== new URL(authServiceUrl).origin) {
4509
+ return;
4510
+ }
4511
+ if (typeof ((_a = event.data) == null ? void 0 : _a.type) !== "string") {
4512
+ return;
4513
+ }
4514
+ if (event.data.requestId && globalAuthState.processingMessageIds.has(event.data.requestId)) {
4515
+ return;
4516
+ }
4517
+ try {
4518
+ isHandlingMessageRef.current = true;
4519
+ if (event.data.type === "ERROR") {
4520
+ globalAuthState.signupInProgress = false;
4521
+ globalAuthState.loginInProgress = false;
4522
+ } else if (event.data.type === "AUTH_STATUS" && event.data.isAuthenticated) {
4523
+ globalAuthState.signupInProgress = false;
4524
+ globalAuthState.loginInProgress = false;
4525
+ cleanupProcessedMessageIds();
4526
+ } else if (event.data.type === "RECEIVE_OIDC") {
4527
+ globalAuthState.signupInProgress = false;
4528
+ globalAuthState.loginInProgress = false;
4529
+ }
4530
+ switch (event.data.type) {
4531
+ case "IFRAME_READY":
4532
+ setIsIframeReady(true);
4533
+ break;
4534
+ case "RECEIVE_OIDC":
4535
+ if (typeof ((_b = event.data.payload) == null ? void 0 : _b.idToken) === "string") {
4536
+ const oidcToken = event.data.payload.idToken;
4537
+ hasRequestedOidcRef.current = false;
4538
+ onOidcReceived == null ? void 0 : onOidcReceived(oidcToken);
4539
+ } else {
4540
+ hasRequestedOidcRef.current = false;
4541
+ }
4542
+ break;
4543
+ case "AUTH_STATUS": {
4544
+ const newIsAuthenticated = !!event.data.isAuthenticated;
4545
+ const newUserId = (_d = (_c = event.data.user) == null ? void 0 : _c.sub) != null ? _d : null;
4546
+ const now = Date.now();
4547
+ if (now - lastAuthStateRef.current.lastUpdateTime < 500) {
4548
+ return;
4549
+ }
4550
+ const authStateChanged = lastAuthStateRef.current.isAuthenticated !== newIsAuthenticated || lastAuthStateRef.current.userId !== newUserId;
4551
+ if (authStateChanged) {
4552
+ setIsAuthenticated(newIsAuthenticated);
4553
+ if (event.data.user) {
4554
+ const userInfo = {
4555
+ email: event.data.user.email,
4556
+ sub: event.data.user.sub,
4557
+ configured_mfa: [],
4558
+ displayName: event.data.user.nickname || event.data.user.name || ((_e = event.data.user.email) == null ? void 0 : _e.split("@")[0]) || "User",
4559
+ rawUserData: event.data.user
4560
+ };
4561
+ setUser(userInfo);
4562
+ if (newIsAuthenticated && !cubistClient && !hasRequestedOidcRef.current) {
4563
+ hasRequestedOidcRef.current = true;
4564
+ sendMessage({ type: "GET_OIDC" });
4565
+ return;
4566
+ }
4567
+ } else {
4568
+ setUser(null);
4569
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
4570
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
4571
+ sessionStorage.removeItem(OIDC_TOKEN_KEY2);
4572
+ }
4573
+ lastAuthStateRef.current = {
4574
+ isAuthenticated: newIsAuthenticated,
4575
+ userId: newUserId,
4576
+ lastUpdateTime: now
4577
+ };
4578
+ if (newIsAuthenticated && event.data.user) {
4579
+ if (!hasRequestedOidcRef.current) {
4580
+ if (event.data.tokens) {
4581
+ localStorage.setItem(AUTH_TOKENS_KEY2, JSON.stringify(event.data.tokens));
4582
+ }
4583
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
4584
+ }
4288
4585
  }
4289
- )
4290
- ] })
4291
- ]
4586
+ }
4587
+ if (event.data.orgConfig && onOrgConfigUpdate) {
4588
+ onOrgConfigUpdate(event.data.orgConfig);
4589
+ if (orgId) {
4590
+ try {
4591
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${environment}`;
4592
+ const configWithTimestamp = {
4593
+ ...event.data.orgConfig,
4594
+ _timestamp: Date.now()
4595
+ };
4596
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
4597
+ } catch (error) {
4598
+ }
4599
+ }
4600
+ }
4601
+ if (!hasRequestedOidcRef.current) {
4602
+ setIsLoading(false);
4603
+ }
4604
+ break;
4605
+ }
4606
+ case "REGISTER_SUCCESS": {
4607
+ const userId = (_f = event.data.payload) == null ? void 0 : _f.userId;
4608
+ if (userId) {
4609
+ localStorage.setItem(CUBIST_USER_ID_KEY2, userId);
4610
+ if (!hasRequestedOidcRef.current) {
4611
+ hasRequestedOidcRef.current = true;
4612
+ sendMessage({ type: "GET_OIDC" });
4613
+ }
4614
+ }
4615
+ break;
4616
+ }
4617
+ case "ERROR":
4618
+ if (event.data.error === "User not authenticated in iframe") {
4619
+ isHandlingMessageRef.current = false;
4620
+ return;
4621
+ }
4622
+ onAuthError == null ? void 0 : onAuthError(new Error((_g = event.data.error) != null ? _g : "Unknown error"));
4623
+ setIsLoading(false);
4624
+ break;
4625
+ }
4626
+ } finally {
4627
+ isHandlingMessageRef.current = false;
4292
4628
  }
4293
- ),
4294
- isModalOpen && /* @__PURE__ */ jsx21(WalletCard, { onClose: handleClose })
4295
- ] });
4296
- }
4297
-
4298
- // src/components/WalletDisplay.tsx
4299
- import { useState as useState17 } from "react";
4300
- import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
4301
- function WalletDisplay({
4302
- className = "",
4303
- truncateAddress = true,
4304
- showAddAccount = true
4305
- }) {
4306
- const { wallet, addAccount, isAuthenticated } = useAvaCloudWallet();
4307
- const [isAdding, setIsAdding] = useState17(false);
4308
- const [accountIndex, setAccountIndex] = useState17(0);
4309
- if (!isAuthenticated || !wallet.address) {
4310
- return null;
4311
- }
4312
- const displayAddress = truncateAddress ? `${wallet.address.slice(0, 6)}...${wallet.address.slice(-4)}` : wallet.address;
4313
- const handleAddAccount = async () => {
4314
- try {
4315
- setIsAdding(true);
4316
- await addAccount(accountIndex);
4317
- setAccountIndex((prev) => prev + 1);
4318
- } catch (error) {
4319
- console.error("Failed to add account:", error);
4320
- } finally {
4321
- setIsAdding(false);
4629
+ };
4630
+ window.addEventListener("message", handleMessage);
4631
+ return () => window.removeEventListener("message", handleMessage);
4632
+ }, [
4633
+ authServiceUrl,
4634
+ onAuthError,
4635
+ onAuthSuccess,
4636
+ onOidcReceived,
4637
+ onOrgConfigUpdate,
4638
+ setIsAuthenticated,
4639
+ setIsIframeReady,
4640
+ setIsLoading,
4641
+ setUser,
4642
+ sendMessage,
4643
+ cubistClient,
4644
+ orgId,
4645
+ environment
4646
+ ]);
4647
+ useEffect7(() => {
4648
+ if (isIframeReady && (iframe == null ? void 0 : iframe.contentWindow)) {
4649
+ sendMessage({
4650
+ type: "CHECK_AUTH_STATUS",
4651
+ payload: {
4652
+ orgId,
4653
+ environment
4654
+ }
4655
+ });
4322
4656
  }
4657
+ }, [isIframeReady, iframe, sendMessage, orgId, environment]);
4658
+ return {
4659
+ sendMessage
4323
4660
  };
4324
- return /* @__PURE__ */ jsxs18("div", { className: `space-y-4 ${className}`, children: [
4325
- /* @__PURE__ */ jsxs18("div", { className: "bg-gray-50 rounded-lg p-4", children: [
4326
- /* @__PURE__ */ jsx22("div", { className: "text-sm text-gray-500", children: "Wallet Address" }),
4327
- /* @__PURE__ */ jsx22("div", { className: "mt-1 font-mono text-sm break-all", children: displayAddress })
4328
- ] }),
4329
- showAddAccount && /* @__PURE__ */ jsx22(
4330
- "button",
4331
- {
4332
- type: "button",
4333
- onClick: handleAddAccount,
4334
- disabled: isAdding,
4335
- className: "w-full inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed",
4336
- children: isAdding ? "Adding Account..." : "Add Account"
4337
- }
4338
- )
4339
- ] });
4340
- }
4341
-
4342
- // src/components/UserProfile.tsx
4343
- import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
4344
- function UserProfile({
4345
- className = "",
4346
- showLogout = true
4347
- }) {
4348
- const { user, logout, isAuthenticated } = useAvaCloudWallet();
4349
- if (!isAuthenticated || !user) {
4350
- return null;
4351
- }
4352
- return /* @__PURE__ */ jsx23("div", { className: `space-y-4 ${className}`, children: /* @__PURE__ */ jsxs19("div", { className: "bg-white shadow rounded-lg p-6", children: [
4353
- /* @__PURE__ */ jsx23("div", { className: "px-4 py-5 sm:px-6", children: /* @__PURE__ */ jsx23("h3", { className: "text-lg font-medium leading-6 text-gray-900", children: "User Profile" }) }),
4354
- /* @__PURE__ */ jsx23("div", { className: "border-t border-gray-200", children: /* @__PURE__ */ jsxs19("dl", { children: [
4355
- /* @__PURE__ */ jsxs19("div", { className: "bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", children: [
4356
- /* @__PURE__ */ jsx23("dt", { className: "text-sm font-medium text-gray-500", children: "Display Name" }),
4357
- /* @__PURE__ */ jsx23("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.displayName })
4358
- ] }),
4359
- user.email && /* @__PURE__ */ jsxs19("div", { className: "bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", children: [
4360
- /* @__PURE__ */ jsx23("dt", { className: "text-sm font-medium text-gray-500", children: "Email address" }),
4361
- /* @__PURE__ */ jsx23("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.email })
4362
- ] }),
4363
- user.configured_mfa && user.configured_mfa.length > 0 && /* @__PURE__ */ jsxs19("div", { children: [
4364
- /* @__PURE__ */ jsx23("div", { className: "text-sm font-medium text-gray-500", children: "MFA Methods" }),
4365
- /* @__PURE__ */ jsx23("div", { className: "mt-1 space-y-1", children: user.configured_mfa.map((method) => {
4366
- const mfaMethod = typeof method === "string" ? { type: method } : method;
4367
- return /* @__PURE__ */ jsx23(
4368
- "div",
4369
- {
4370
- className: "text-sm text-gray-900",
4371
- children: mfaMethod.type === "totp" ? "Authenticator App" : mfaMethod.name
4372
- },
4373
- mfaMethod.type === "fido" ? mfaMethod.id : `totp-${mfaMethod.type}`
4374
- );
4375
- }) })
4376
- ] })
4377
- ] }) }),
4378
- showLogout && /* @__PURE__ */ jsx23("div", { className: "mt-6", children: /* @__PURE__ */ jsx23(
4379
- "button",
4380
- {
4381
- type: "button",
4382
- onClick: logout,
4383
- className: "w-full inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500",
4384
- children: "Sign Out"
4385
- }
4386
- ) })
4387
- ] }) });
4388
4661
  }
4389
4662
 
4390
4663
  // src/hooks/useSignMessage.ts
4391
- import { useCallback as useCallback8, useState as useState18 } from "react";
4664
+ import { useCallback as useCallback11, useState as useState19 } from "react";
4392
4665
  import { Secp256k1 as Secp256k12 } from "@cubist-labs/cubesigner-sdk";
4393
4666
  function useSignMessage() {
4394
- const [state, setState] = useState18({
4667
+ const [state, setState] = useState19({
4395
4668
  isLoading: false,
4396
4669
  error: null,
4397
4670
  signature: null
4398
4671
  });
4399
4672
  const { wallet, cubistClient } = useAvaCloudWallet();
4400
- const reset = useCallback8(() => {
4673
+ const reset = useCallback11(() => {
4401
4674
  setState({
4402
4675
  isLoading: false,
4403
4676
  error: null,
4404
4677
  signature: null
4405
4678
  });
4406
4679
  }, []);
4407
- const signMessage = useCallback8(async (message) => {
4680
+ const signMessage = useCallback11(async (message) => {
4408
4681
  if (!cubistClient || !wallet.address) {
4409
4682
  setState((prev) => ({
4410
4683
  ...prev,
@@ -4441,10 +4714,11 @@ function useSignMessage() {
4441
4714
  }
4442
4715
 
4443
4716
  // src/hooks/useSignTransaction.ts
4444
- import { useCallback as useCallback9, useState as useState19 } from "react";
4717
+ import { useCallback as useCallback12, useState as useState20 } from "react";
4445
4718
  import { Secp256k1 as Secp256k13 } from "@cubist-labs/cubesigner-sdk";
4719
+ import { toHex } from "viem";
4446
4720
  function useSignTransaction() {
4447
- const [state, setState] = useState19({
4721
+ const [state, setState] = useState20({
4448
4722
  isLoading: false,
4449
4723
  error: null,
4450
4724
  signature: null,
@@ -4452,7 +4726,7 @@ function useSignTransaction() {
4452
4726
  });
4453
4727
  const { wallet, cubistClient } = useAvaCloudWallet();
4454
4728
  const { publicClient } = useViem();
4455
- const reset = useCallback9(() => {
4729
+ const reset = useCallback12(() => {
4456
4730
  setState({
4457
4731
  isLoading: false,
4458
4732
  error: null,
@@ -4460,8 +4734,7 @@ function useSignTransaction() {
4460
4734
  signedTransaction: null
4461
4735
  });
4462
4736
  }, []);
4463
- const signTransaction = useCallback9(async (transaction) => {
4464
- var _a, _b, _c, _d;
4737
+ const signTransaction = useCallback12(async (transaction) => {
4465
4738
  if (!(wallet == null ? void 0 : wallet.address)) {
4466
4739
  setState((prev) => ({
4467
4740
  ...prev,
@@ -4497,13 +4770,13 @@ function useSignTransaction() {
4497
4770
  chain_id: publicClient.chain.id,
4498
4771
  tx: {
4499
4772
  to: transaction.to || void 0,
4500
- value: (_a = transaction.value) == null ? void 0 : _a.toString(),
4773
+ value: transaction.value !== void 0 ? toHex(transaction.value) : void 0,
4501
4774
  data: transaction.data || "0x",
4502
- nonce: (_b = transaction.nonce) == null ? void 0 : _b.toString(),
4775
+ nonce: transaction.nonce !== void 0 ? toHex(transaction.nonce) : void 0,
4503
4776
  type: "0x2",
4504
4777
  // EIP-1559
4505
- maxFeePerGas: (_c = transaction.maxFeePerGas) == null ? void 0 : _c.toString(),
4506
- maxPriorityFeePerGas: (_d = transaction.maxPriorityFeePerGas) == null ? void 0 : _d.toString()
4778
+ maxFeePerGas: transaction.maxFeePerGas !== void 0 ? toHex(transaction.maxFeePerGas) : void 0,
4779
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas !== void 0 ? toHex(transaction.maxPriorityFeePerGas) : void 0
4507
4780
  }
4508
4781
  };
4509
4782
  const sig = await key.signEvm(signReq);
@@ -4529,11 +4802,11 @@ function useSignTransaction() {
4529
4802
  }
4530
4803
 
4531
4804
  // src/hooks/useUserWallets.ts
4532
- import { useCallback as useCallback10, useState as useState20 } from "react";
4805
+ import { useCallback as useCallback13, useState as useState21 } from "react";
4533
4806
  function useUserWallets() {
4534
- const [error, setError] = useState20(null);
4535
- const [isLoading, setIsLoading] = useState20(false);
4536
- const getWallets = useCallback10(async (client) => {
4807
+ const [error, setError] = useState21(null);
4808
+ const [isLoading, setIsLoading] = useState21(false);
4809
+ const getWallets = useCallback13(async (client) => {
4537
4810
  setIsLoading(true);
4538
4811
  setError(null);
4539
4812
  try {
@@ -4573,15 +4846,30 @@ function avaCloudWallet() {
4573
4846
  id: "avaCloudWallet",
4574
4847
  name: "AvaCloud Wallet",
4575
4848
  type: "injected",
4576
- async connect() {
4849
+ async connect(parameters) {
4850
+ const { withCapabilities } = parameters != null ? parameters : {};
4577
4851
  const { walletClient } = useViem();
4578
4852
  if (!walletClient) {
4579
4853
  throw new Error("AvaCloud Wallet not connected");
4580
4854
  }
4581
4855
  const accounts = await this.getAccounts();
4582
4856
  const chainId = await this.getChainId();
4857
+ if (withCapabilities) {
4858
+ const result = {
4859
+ accounts: accounts.map((address) => ({
4860
+ address,
4861
+ capabilities: {}
4862
+ })),
4863
+ chainId
4864
+ };
4865
+ config.emitter.emit("connect", { accounts, chainId });
4866
+ return result;
4867
+ }
4583
4868
  config.emitter.emit("connect", { accounts, chainId });
4584
- return { accounts, chainId };
4869
+ return {
4870
+ accounts,
4871
+ chainId
4872
+ };
4585
4873
  },
4586
4874
  async disconnect() {
4587
4875
  config.emitter.emit("disconnect");
@@ -4628,7 +4916,7 @@ function avaCloudWallet() {
4628
4916
  }
4629
4917
 
4630
4918
  // src/providers/GaslessProvider.tsx
4631
- import { createContext as createContext5, useContext as useContext5, useEffect as useEffect7, useState as useState21 } from "react";
4919
+ import { createContext as createContext5, useContext as useContext5, useEffect as useEffect8, useState as useState22 } from "react";
4632
4920
  import { jsx as jsx24 } from "react/jsx-runtime";
4633
4921
  function validateGaslessConfig(config) {
4634
4922
  if (!config || typeof config !== "object") {
@@ -4664,13 +4952,13 @@ function validateGaslessConfig(config) {
4664
4952
  }
4665
4953
  var GaslessContext = createContext5(null);
4666
4954
  function GaslessProvider({ children, config, fetchParams }) {
4667
- const [state, setState] = useState21({
4955
+ const [state, setState] = useState22({
4668
4956
  isLoading: false,
4669
4957
  error: null,
4670
4958
  config: null
4671
4959
  });
4672
4960
  const { authServiceUrl, environment } = useAvaCloudWallet();
4673
- useEffect7(() => {
4961
+ useEffect8(() => {
4674
4962
  if (config) {
4675
4963
  const validationError = validateGaslessConfig(config);
4676
4964
  if (validationError) {
@@ -4757,9 +5045,16 @@ function GaslessProvider({ children, config, fetchParams }) {
4757
5045
  }, [config, fetchParams, authServiceUrl, environment]);
4758
5046
  return /* @__PURE__ */ jsx24(GaslessContext.Provider, { value: state, children });
4759
5047
  }
5048
+ function useGaslessConfig() {
5049
+ const ctx = useContext5(GaslessContext);
5050
+ if (!ctx) {
5051
+ throw new Error("useGaslessConfig must be used within a GaslessProvider");
5052
+ }
5053
+ return ctx;
5054
+ }
4760
5055
 
4761
5056
  // src/hooks/useGaslessTransaction.ts
4762
- import { useCallback as useCallback11, useState as useState22 } from "react";
5057
+ import { useCallback as useCallback14, useState as useState23 } from "react";
4763
5058
  import * as ethers from "ethers";
4764
5059
  import axios from "axios";
4765
5060
  import { Secp256k1 as Secp256k14 } from "@cubist-labs/cubesigner-sdk";
@@ -4785,7 +5080,7 @@ var FORWARDER_GET_NONCE_ABI = [
4785
5080
  }
4786
5081
  ];
4787
5082
  function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContractAddress, abi: defaultAbi }) {
4788
- const [state, setState] = useState22({
5083
+ const [state, setState] = useState23({
4789
5084
  isLoading: false,
4790
5085
  error: null,
4791
5086
  txHash: null
@@ -4793,14 +5088,14 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4793
5088
  const config = gaslessConfig;
4794
5089
  const { wallet, cubistClient } = useAvaCloudWallet();
4795
5090
  useViem();
4796
- const reset = useCallback11(() => {
5091
+ const reset = useCallback14(() => {
4797
5092
  setState({
4798
5093
  isLoading: false,
4799
5094
  error: null,
4800
5095
  txHash: null
4801
5096
  });
4802
5097
  }, []);
4803
- const validateConfig = useCallback11((config2) => {
5098
+ const validateConfig = useCallback14((config2) => {
4804
5099
  if (!config2) {
4805
5100
  return "Gasless configuration is not available. Please ensure GaslessProvider is properly configured.";
4806
5101
  }
@@ -4834,7 +5129,7 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4834
5129
  }
4835
5130
  return null;
4836
5131
  }, []);
4837
- const sendGaslessTransaction = useCallback11(async ({
5132
+ const sendGaslessTransaction = useCallback14(async ({
4838
5133
  functionName,
4839
5134
  args = [],
4840
5135
  abi: overrideAbi,
@@ -4919,7 +5214,12 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4919
5214
  const suffixParts = config.suffix.match(/^(\w+)\s+(.+)\)$/);
4920
5215
  if (suffixParts) {
4921
5216
  const [, , suffixName] = suffixParts;
4922
- message[suffixName] = Buffer.from(config.suffix, "utf8");
5217
+ const encoder = new TextEncoder();
5218
+ const suffixBytes = encoder.encode(config.suffix);
5219
+ const paddedBytes = new Uint8Array(32);
5220
+ paddedBytes.set(suffixBytes.slice(0, 32));
5221
+ const hexString = Array.from(paddedBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
5222
+ message[suffixName] = "0x" + hexString;
4923
5223
  }
4924
5224
  }
4925
5225
  const domain = {
@@ -4928,12 +5228,22 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4928
5228
  chainId: (await provider.getNetwork()).chainId,
4929
5229
  verifyingContract: config.forwarderAddress
4930
5230
  };
4931
- const digest = ethers.utils._TypedDataEncoder.hash(domain, {
4932
- [config.requestType]: types[config.requestType]
4933
- }, message);
4934
5231
  const key = await cubistClient.org().getKeyByMaterialId(Secp256k14.Evm, wallet.address);
4935
- const sigResp = await key.signBlob({
4936
- message_base64: Buffer.from(digest.slice(2), "hex").toString("base64")
5232
+ const sigResp = await key.signEip712({
5233
+ chain_id: domain.chainId,
5234
+ typed_data: {
5235
+ domain: {
5236
+ name: domain.name,
5237
+ version: domain.version,
5238
+ chainId: `0x${domain.chainId.toString(16)}`,
5239
+ verifyingContract: domain.verifyingContract
5240
+ },
5241
+ primaryType: config.requestType,
5242
+ types: {
5243
+ [config.requestType]: types[config.requestType]
5244
+ },
5245
+ message
5246
+ }
4937
5247
  });
4938
5248
  const signatureData = sigResp.data().signature;
4939
5249
  const signature = signatureData.startsWith("0x") ? signatureData : `0x${signatureData}`;
@@ -5023,6 +5333,7 @@ export {
5023
5333
  useAvaCloudWallet,
5024
5334
  useBlockchain,
5025
5335
  useChainId,
5336
+ useGaslessConfig,
5026
5337
  useGaslessTransaction,
5027
5338
  useGlacier,
5028
5339
  usePostMessage,