@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.js CHANGED
@@ -48,6 +48,7 @@ __export(index_exports, {
48
48
  useAvaCloudWallet: () => useAvaCloudWallet,
49
49
  useBlockchain: () => useBlockchain,
50
50
  useChainId: () => useChainId,
51
+ useGaslessConfig: () => useGaslessConfig,
51
52
  useGaslessTransaction: () => useGaslessTransaction,
52
53
  useGlacier: () => useGlacier,
53
54
  usePostMessage: () => usePostMessage,
@@ -92,41 +93,15 @@ function getDerivationPath(vm, accountIndex) {
92
93
  return `m/44'/${coinIndex}'/0'/0/${accountIndex}`;
93
94
  }
94
95
 
95
- // src/hooks/usePostMessage.ts
96
+ // src/hooks/usePenpalAuth.ts
96
97
  var import_react = require("react");
97
-
98
- // src/constants/storage.ts
99
- var OIDC_TOKEN_KEY = "avacloud-auth-oidc-token";
100
- var AUTH_TOKENS_KEY = "auth_tokens";
101
- var AUTH0_STORAGE_KEYS = {
102
- IS_AUTHENTICATED: "auth0.is.authenticated",
103
- ACCESS_TOKEN: "auth0.access_token",
104
- ID_TOKEN: "auth0.id_token",
105
- EXPIRES_AT: "auth0.expires_at"
106
- };
107
- var CUBIST_USER_ID_KEY = "cubist_user_id";
108
- var ORG_CONFIG_CACHE_KEY = "avacloud-org-config-cache";
109
-
110
- // src/hooks/usePostMessage.ts
111
- var globalAuthState = {
112
- signupInProgress: false,
113
- loginInProgress: false,
114
- lastSignupTimestamp: 0,
115
- lastLoginTimestamp: 0,
116
- processingMessageIds: /* @__PURE__ */ new Set()
117
- };
118
- function cleanupProcessedMessageIds() {
119
- if (globalAuthState.processingMessageIds.size > 100) {
120
- const messageIds = Array.from(globalAuthState.processingMessageIds);
121
- globalAuthState.processingMessageIds = new Set(messageIds.slice(-50));
122
- }
123
- }
124
- function usePostMessage({
98
+ var import_penpal = require("penpal");
99
+ var import_waas_common = require("@avacloud/waas-common");
100
+ function usePenpalAuth({
125
101
  authServiceUrl,
126
102
  orgId,
127
103
  environment,
128
104
  iframe,
129
- isIframeReady,
130
105
  onAuthSuccess,
131
106
  onAuthError,
132
107
  onOidcReceived,
@@ -134,22 +109,19 @@ function usePostMessage({
134
109
  setIsAuthenticated,
135
110
  setUser,
136
111
  setIsLoading,
137
- setIsIframeReady,
138
- cubistClient
112
+ setIsIframeReady
139
113
  }) {
140
- const lastAuthStateRef = (0, import_react.useRef)({
141
- isAuthenticated: false,
142
- userId: null,
143
- lastUpdateTime: 0
144
- });
145
- const hasRequestedOidcRef = (0, import_react.useRef)(false);
146
- const isHandlingMessageRef = (0, import_react.useRef)(false);
114
+ const connectionRef = (0, import_react.useRef)(null);
115
+ const [authService, setAuthService] = (0, import_react.useState)(null);
116
+ const [isConnected, setIsConnected] = (0, import_react.useState)(false);
117
+ const isConnectedRef = (0, import_react.useRef)(false);
118
+ const hasCheckedAuthRef = (0, import_react.useRef)(false);
147
119
  const hasLoadedCacheRef = (0, import_react.useRef)(false);
148
120
  (0, import_react.useEffect)(() => {
149
121
  if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
150
122
  hasLoadedCacheRef.current = true;
151
123
  try {
152
- const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
124
+ const cachedConfigKey = `${import_waas_common.ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
153
125
  const cachedConfigJson = localStorage.getItem(cachedConfigKey);
154
126
  if (cachedConfigJson) {
155
127
  const cachedConfig = JSON.parse(cachedConfigJson);
@@ -164,233 +136,250 @@ function usePostMessage({
164
136
  }
165
137
  }
166
138
  }, [orgId, environment, onOrgConfigUpdate]);
167
- const sendMessage = (0, import_react.useCallback)((message) => {
168
- if (iframe == null ? void 0 : iframe.contentWindow) {
169
- try {
170
- if (message.type === "SIGNUP_REQUEST") {
171
- if (globalAuthState.signupInProgress) {
172
- return;
173
- }
174
- const now = Date.now();
175
- if (now - globalAuthState.lastSignupTimestamp < 3e3) {
176
- return;
177
- }
178
- globalAuthState.signupInProgress = true;
179
- globalAuthState.lastSignupTimestamp = now;
180
- let finalMessage = message;
181
- if (!message.requestId) {
182
- finalMessage = {
183
- ...message,
184
- requestId: `signup-${now}`
185
- };
186
- }
187
- let messageToSend = finalMessage;
188
- if (finalMessage.payload && typeof finalMessage.payload.email === "string" && typeof finalMessage.payload.password === "string") {
189
- messageToSend = {
190
- type: "SIGNUP_REQUEST",
191
- email: finalMessage.payload.email,
192
- password: finalMessage.payload.password,
193
- requestId: finalMessage.requestId || `signup-${now}`
194
- };
195
- }
196
- if ("requestId" in messageToSend && messageToSend.requestId) {
197
- globalAuthState.processingMessageIds.add(messageToSend.requestId);
198
- }
199
- iframe.contentWindow.postMessage(messageToSend, authServiceUrl);
200
- return;
201
- }
202
- if (message.type === "LOGIN_REQUEST") {
203
- if (globalAuthState.loginInProgress) {
204
- return;
205
- }
206
- const now = Date.now();
207
- if (now - globalAuthState.lastLoginTimestamp < 3e3) {
208
- return;
209
- }
210
- globalAuthState.loginInProgress = true;
211
- globalAuthState.lastLoginTimestamp = now;
212
- let finalMessage = message;
213
- if (!message.requestId) {
214
- finalMessage = {
215
- ...message,
216
- requestId: `login-${now}`
139
+ const parentMethods = {
140
+ onReady: () => {
141
+ console.log("[Penpal Parent] Iframe is ready");
142
+ setIsIframeReady(true);
143
+ },
144
+ onAuthStatusChange: (status) => {
145
+ var _a;
146
+ console.log("[Penpal Parent] Auth status changed:", status);
147
+ setIsAuthenticated(status.isAuthenticated);
148
+ if (status.user) {
149
+ const userInfo = {
150
+ email: status.user.email,
151
+ sub: status.user.sub,
152
+ configured_mfa: [],
153
+ displayName: status.user.nickname || status.user.name || ((_a = status.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
154
+ rawUserData: status.user
155
+ };
156
+ setUser(userInfo);
157
+ } else {
158
+ setUser(null);
159
+ }
160
+ if (status.orgConfig) {
161
+ onOrgConfigUpdate == null ? void 0 : onOrgConfigUpdate(status.orgConfig);
162
+ if (orgId) {
163
+ try {
164
+ const cachedConfigKey = `${import_waas_common.ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
165
+ const configWithTimestamp = {
166
+ ...status.orgConfig,
167
+ _timestamp: Date.now()
217
168
  };
169
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
170
+ } catch (error) {
218
171
  }
219
- if (finalMessage.requestId) {
220
- globalAuthState.processingMessageIds.add(finalMessage.requestId);
221
- }
222
- iframe.contentWindow.postMessage(finalMessage, authServiceUrl);
223
- return;
224
- }
225
- iframe.contentWindow.postMessage(message, authServiceUrl);
226
- } catch (error) {
227
- if (message.type === "SIGNUP_REQUEST") {
228
- globalAuthState.signupInProgress = false;
229
- }
230
- if (message.type === "LOGIN_REQUEST") {
231
- globalAuthState.loginInProgress = false;
232
172
  }
233
173
  }
234
- }
235
- }, [iframe, authServiceUrl]);
236
- (0, import_react.useEffect)(() => {
237
- const handleMessage = async (event) => {
238
- var _a, _b, _c, _d, _e, _f, _g;
239
- if (isHandlingMessageRef.current) {
240
- return;
174
+ if (status.isAuthenticated) {
175
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
241
176
  }
242
- if (event.origin !== new URL(authServiceUrl).origin) {
177
+ setIsLoading(false);
178
+ },
179
+ onError: (error) => {
180
+ console.error("[Penpal Parent] Error from iframe:", error);
181
+ if (error.message === "User not authenticated in iframe" || error.message === "Unknown error" || error.message.includes("OIDC user not found")) {
243
182
  return;
244
183
  }
245
- if (typeof ((_a = event.data) == null ? void 0 : _a.type) !== "string") {
184
+ onAuthError == null ? void 0 : onAuthError(new Error(error.message));
185
+ setIsLoading(false);
186
+ },
187
+ onWalletUpdate: (wallet) => {
188
+ console.log("[Penpal Parent] Wallet update:", wallet);
189
+ }
190
+ };
191
+ (0, import_react.useEffect)(() => {
192
+ if (!(iframe == null ? void 0 : iframe.contentWindow)) {
193
+ return;
194
+ }
195
+ let isCancelled = false;
196
+ const setupConnection = async (attempt = 1, maxAttempts = 3) => {
197
+ if (isCancelled) return;
198
+ if (isConnectedRef.current && connectionRef.current) {
199
+ console.log("[Penpal Parent] Already connected, skipping setup");
246
200
  return;
247
201
  }
248
- if (event.data.requestId && globalAuthState.processingMessageIds.has(event.data.requestId)) {
249
- return;
202
+ console.log(`[Penpal Parent] Setting up connection to iframe (attempt ${attempt}/${maxAttempts})...`);
203
+ if (connectionRef.current) {
204
+ connectionRef.current.destroy();
205
+ connectionRef.current = null;
206
+ setAuthService(null);
207
+ setIsConnected(false);
208
+ isConnectedRef.current = false;
250
209
  }
251
210
  try {
252
- isHandlingMessageRef.current = true;
253
- if (event.data.type === "ERROR") {
254
- globalAuthState.signupInProgress = false;
255
- globalAuthState.loginInProgress = false;
256
- } else if (event.data.type === "AUTH_STATUS" && event.data.isAuthenticated) {
257
- globalAuthState.signupInProgress = false;
258
- globalAuthState.loginInProgress = false;
259
- cleanupProcessedMessageIds();
260
- } else if (event.data.type === "RECEIVE_OIDC") {
261
- globalAuthState.signupInProgress = false;
262
- globalAuthState.loginInProgress = false;
211
+ const authServiceOrigin = new URL(authServiceUrl).origin;
212
+ const messenger = new import_penpal.WindowMessenger({
213
+ remoteWindow: iframe.contentWindow,
214
+ allowedOrigins: [authServiceOrigin]
215
+ });
216
+ const connection = (0, import_penpal.connect)({
217
+ messenger,
218
+ methods: parentMethods,
219
+ timeout: 1e4
220
+ // 10 second connection timeout per attempt
221
+ });
222
+ connectionRef.current = connection;
223
+ const remote = await connection.promise;
224
+ if (isCancelled) {
225
+ connection.destroy();
226
+ return;
263
227
  }
264
- switch (event.data.type) {
265
- case "IFRAME_READY":
266
- setIsIframeReady(true);
267
- break;
268
- case "RECEIVE_OIDC":
269
- if (typeof ((_b = event.data.payload) == null ? void 0 : _b.idToken) === "string") {
270
- const oidcToken = event.data.payload.idToken;
271
- hasRequestedOidcRef.current = false;
272
- onOidcReceived == null ? void 0 : onOidcReceived(oidcToken);
273
- } else {
274
- hasRequestedOidcRef.current = false;
275
- }
276
- break;
277
- case "AUTH_STATUS": {
278
- const newIsAuthenticated = !!event.data.isAuthenticated;
279
- const newUserId = (_d = (_c = event.data.user) == null ? void 0 : _c.sub) != null ? _d : null;
280
- const now = Date.now();
281
- if (now - lastAuthStateRef.current.lastUpdateTime < 500) {
282
- return;
283
- }
284
- const authStateChanged = lastAuthStateRef.current.isAuthenticated !== newIsAuthenticated || lastAuthStateRef.current.userId !== newUserId;
285
- if (authStateChanged) {
286
- setIsAuthenticated(newIsAuthenticated);
287
- if (event.data.user) {
288
- const userInfo = {
289
- email: event.data.user.email,
290
- sub: event.data.user.sub,
291
- configured_mfa: [],
292
- displayName: event.data.user.nickname || event.data.user.name || ((_e = event.data.user.email) == null ? void 0 : _e.split("@")[0]) || "User",
293
- rawUserData: event.data.user
294
- };
295
- setUser(userInfo);
296
- if (newIsAuthenticated && !cubistClient && !hasRequestedOidcRef.current) {
297
- hasRequestedOidcRef.current = true;
298
- sendMessage({ type: "GET_OIDC" });
299
- return;
300
- }
301
- } else {
302
- setUser(null);
303
- localStorage.removeItem(AUTH_TOKENS_KEY);
304
- localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
305
- sessionStorage.removeItem(OIDC_TOKEN_KEY);
306
- }
307
- lastAuthStateRef.current = {
308
- isAuthenticated: newIsAuthenticated,
309
- userId: newUserId,
310
- lastUpdateTime: now
311
- };
312
- if (newIsAuthenticated && event.data.user) {
313
- if (!hasRequestedOidcRef.current) {
314
- if (event.data.tokens) {
315
- localStorage.setItem(AUTH_TOKENS_KEY, JSON.stringify(event.data.tokens));
316
- }
317
- onAuthSuccess == null ? void 0 : onAuthSuccess();
318
- }
319
- }
320
- }
321
- if (event.data.orgConfig && onOrgConfigUpdate) {
322
- onOrgConfigUpdate(event.data.orgConfig);
323
- if (orgId) {
324
- try {
325
- const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
326
- const configWithTimestamp = {
327
- ...event.data.orgConfig,
328
- _timestamp: Date.now()
329
- };
330
- localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
331
- } catch (error) {
332
- }
333
- }
334
- }
335
- if (!hasRequestedOidcRef.current) {
336
- setIsLoading(false);
337
- }
338
- break;
339
- }
340
- case "REGISTER_SUCCESS": {
341
- const userId = (_f = event.data.payload) == null ? void 0 : _f.userId;
342
- if (userId) {
343
- localStorage.setItem(CUBIST_USER_ID_KEY, userId);
344
- if (!hasRequestedOidcRef.current) {
345
- hasRequestedOidcRef.current = true;
346
- sendMessage({ type: "GET_OIDC" });
347
- }
348
- }
349
- break;
228
+ console.log("[Penpal Parent] Connected to auth service");
229
+ isConnectedRef.current = true;
230
+ setAuthService(remote);
231
+ setIsConnected(true);
232
+ setIsIframeReady(true);
233
+ } catch (error) {
234
+ if (isCancelled) return;
235
+ console.error(`[Penpal Parent] Failed to connect (attempt ${attempt}):`, error);
236
+ if (attempt < maxAttempts) {
237
+ console.log(`[Penpal Parent] Retrying in 1 second...`);
238
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
239
+ if (!isCancelled) {
240
+ await setupConnection(attempt + 1, maxAttempts);
350
241
  }
351
- case "ERROR":
352
- if (event.data.error === "User not authenticated in iframe") {
353
- isHandlingMessageRef.current = false;
354
- return;
355
- }
356
- onAuthError == null ? void 0 : onAuthError(new Error((_g = event.data.error) != null ? _g : "Unknown error"));
357
- setIsLoading(false);
358
- break;
242
+ } else {
243
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to connect to auth service"));
359
244
  }
360
- } finally {
361
- isHandlingMessageRef.current = false;
362
245
  }
363
246
  };
364
- window.addEventListener("message", handleMessage);
365
- return () => window.removeEventListener("message", handleMessage);
366
- }, [
367
- authServiceUrl,
368
- onAuthError,
369
- onAuthSuccess,
370
- onOidcReceived,
371
- onOrgConfigUpdate,
372
- setIsAuthenticated,
373
- setIsIframeReady,
374
- setIsLoading,
375
- setUser,
376
- sendMessage,
377
- cubistClient,
378
- orgId,
379
- environment
380
- ]);
247
+ setupConnection();
248
+ return () => {
249
+ isCancelled = true;
250
+ };
251
+ }, [iframe, authServiceUrl]);
381
252
  (0, import_react.useEffect)(() => {
382
- if (isIframeReady && (iframe == null ? void 0 : iframe.contentWindow)) {
383
- sendMessage({
384
- type: "CHECK_AUTH_STATUS",
385
- payload: {
386
- orgId,
387
- environment
253
+ if (isConnected && authService && !hasCheckedAuthRef.current) {
254
+ hasCheckedAuthRef.current = true;
255
+ authService.checkAuthStatus(orgId, environment).then((status) => {
256
+ console.log("[Penpal Parent] Initial auth status:", status);
257
+ parentMethods.onAuthStatusChange(status);
258
+ if (status.isAuthenticated) {
259
+ return authService.getOidc();
388
260
  }
261
+ return null;
262
+ }).then((oidcResult) => {
263
+ if (oidcResult == null ? void 0 : oidcResult.idToken) {
264
+ onOidcReceived == null ? void 0 : onOidcReceived(oidcResult.idToken);
265
+ }
266
+ }).catch((error) => {
267
+ console.error("[Penpal Parent] Error checking auth status:", error);
268
+ setIsLoading(false);
389
269
  });
390
270
  }
391
- }, [isIframeReady, iframe, sendMessage, orgId, environment]);
271
+ }, [isConnected, authService, orgId, environment]);
272
+ const login = (0, import_react.useCallback)(async (params) => {
273
+ var _a;
274
+ if (!authService) {
275
+ console.warn("[Penpal] Cannot login - not connected");
276
+ return;
277
+ }
278
+ try {
279
+ const result = await authService.login(params || {});
280
+ setIsAuthenticated(true);
281
+ if (result.user) {
282
+ const userInfo = {
283
+ email: result.user.email,
284
+ sub: result.user.sub,
285
+ configured_mfa: [],
286
+ displayName: result.user.nickname || result.user.name || ((_a = result.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
287
+ rawUserData: result.user
288
+ };
289
+ setUser(userInfo);
290
+ }
291
+ if (result.accessToken) {
292
+ onOidcReceived == null ? void 0 : onOidcReceived(result.accessToken);
293
+ }
294
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
295
+ return result;
296
+ } catch (error) {
297
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Login failed"));
298
+ throw error;
299
+ }
300
+ }, [authService, setIsAuthenticated, setUser, onOidcReceived, onAuthSuccess, onAuthError]);
301
+ const signup = (0, import_react.useCallback)(async (email, password) => {
302
+ var _a;
303
+ if (!authService) {
304
+ console.warn("[Penpal] Cannot signup - not connected");
305
+ return;
306
+ }
307
+ try {
308
+ const result = await authService.signup({ email, password });
309
+ setIsAuthenticated(true);
310
+ if (result.user) {
311
+ const userInfo = {
312
+ email: result.user.email,
313
+ sub: result.user.sub,
314
+ configured_mfa: [],
315
+ displayName: result.user.nickname || result.user.name || ((_a = result.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
316
+ rawUserData: result.user
317
+ };
318
+ setUser(userInfo);
319
+ }
320
+ if (result.accessToken) {
321
+ onOidcReceived == null ? void 0 : onOidcReceived(result.accessToken);
322
+ }
323
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
324
+ return result;
325
+ } catch (error) {
326
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Signup failed"));
327
+ throw error;
328
+ }
329
+ }, [authService, setIsAuthenticated, setUser, onOidcReceived, onAuthSuccess, onAuthError]);
330
+ const logout = (0, import_react.useCallback)(async () => {
331
+ if (!authService) {
332
+ console.warn("[Penpal] Cannot logout - not connected");
333
+ return;
334
+ }
335
+ try {
336
+ await authService.logout();
337
+ setIsAuthenticated(false);
338
+ setUser(null);
339
+ localStorage.removeItem(import_waas_common.AUTH_TOKENS_KEY);
340
+ localStorage.removeItem(import_waas_common.AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
341
+ localStorage.removeItem(import_waas_common.AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
342
+ localStorage.removeItem(import_waas_common.AUTH0_STORAGE_KEYS.ID_TOKEN);
343
+ localStorage.removeItem(import_waas_common.AUTH0_STORAGE_KEYS.EXPIRES_AT);
344
+ localStorage.removeItem(import_waas_common.CUBIST_USER_ID_KEY);
345
+ sessionStorage.removeItem(import_waas_common.OIDC_TOKEN_KEY);
346
+ } catch (error) {
347
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Logout failed"));
348
+ throw error;
349
+ }
350
+ }, [authService, setIsAuthenticated, setUser, onAuthError]);
351
+ const getOidc = (0, import_react.useCallback)(async () => {
352
+ if (!authService) {
353
+ console.warn("[Penpal] Cannot get OIDC - not connected");
354
+ return;
355
+ }
356
+ try {
357
+ return await authService.getOidc();
358
+ } catch (error) {
359
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to get OIDC token"));
360
+ throw error;
361
+ }
362
+ }, [authService, onAuthError]);
363
+ const checkAuthStatus = (0, import_react.useCallback)(async () => {
364
+ if (!authService) {
365
+ console.warn("[Penpal] Cannot check auth status - not connected");
366
+ return;
367
+ }
368
+ try {
369
+ return await authService.checkAuthStatus(orgId, environment);
370
+ } catch (error) {
371
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to check auth status"));
372
+ throw error;
373
+ }
374
+ }, [authService, orgId, environment, onAuthError]);
392
375
  return {
393
- sendMessage
376
+ authService,
377
+ isConnected,
378
+ login,
379
+ signup,
380
+ logout,
381
+ getOidc,
382
+ checkAuthStatus
394
383
  };
395
384
  }
396
385
 
@@ -1010,123 +999,72 @@ function SignInContent({
1010
999
  var import_jsx_runtime3 = require("react/jsx-runtime");
1011
1000
  function LoginModal({ open, onClose }) {
1012
1001
  var _a;
1013
- const { iframe, orgConfig, signup } = useAvaCloudWallet();
1002
+ const { orgConfig, signup, login, isAuthenticated } = useAvaCloudWallet();
1014
1003
  const [isSubmitting, setIsSubmitting] = (0, import_react3.useState)(false);
1015
1004
  const [error, setError] = (0, import_react3.useState)("");
1016
1005
  const timeoutIdRef = (0, import_react3.useRef)(null);
1017
- const signupInProgressRef = (0, import_react3.useRef)(false);
1018
- const lastSignupAttemptRef = (0, import_react3.useRef)(0);
1019
1006
  const socialLogins = (_a = orgConfig == null ? void 0 : orgConfig.adminPortalSettings) == null ? void 0 : _a.socialLogins;
1020
1007
  (0, import_react3.useEffect)(() => {
1021
- let requestInProgress = false;
1022
- const handleMessage = (event) => {
1023
- if (!event.data || typeof event.data.type !== "string") {
1024
- return;
1008
+ if (isAuthenticated && open) {
1009
+ setIsSubmitting(false);
1010
+ if (timeoutIdRef.current) {
1011
+ clearTimeout(timeoutIdRef.current);
1012
+ timeoutIdRef.current = null;
1025
1013
  }
1026
- if (event.data.type === "ERROR") {
1027
- if (event.data.payload === "User not authenticated in iframe") {
1028
- return;
1029
- }
1030
- setError(event.data.payload);
1031
- setIsSubmitting(false);
1032
- signupInProgressRef.current = false;
1033
- if (timeoutIdRef.current) {
1034
- clearTimeout(timeoutIdRef.current);
1035
- timeoutIdRef.current = null;
1036
- }
1037
- } else if (event.data.type === "AUTH_STATUS" && event.data.isAuthenticated) {
1038
- setIsSubmitting(false);
1039
- signupInProgressRef.current = false;
1040
- requestInProgress = false;
1041
- if (timeoutIdRef.current) {
1042
- clearTimeout(timeoutIdRef.current);
1043
- timeoutIdRef.current = null;
1044
- }
1045
- onClose();
1046
- } else if (event.data.type === "RECEIVE_OIDC") {
1047
- signupInProgressRef.current = false;
1048
- requestInProgress = false;
1014
+ onClose();
1015
+ }
1016
+ }, [isAuthenticated, open, onClose]);
1017
+ (0, import_react3.useEffect)(() => {
1018
+ if (!open) {
1019
+ setIsSubmitting(false);
1020
+ setError("");
1021
+ if (timeoutIdRef.current) {
1022
+ clearTimeout(timeoutIdRef.current);
1023
+ timeoutIdRef.current = null;
1049
1024
  }
1050
- };
1051
- window.addEventListener("message", handleMessage);
1025
+ }
1026
+ }, [open]);
1027
+ (0, import_react3.useEffect)(() => {
1052
1028
  return () => {
1053
- window.removeEventListener("message", handleMessage);
1054
1029
  if (timeoutIdRef.current) {
1055
1030
  clearTimeout(timeoutIdRef.current);
1056
1031
  timeoutIdRef.current = null;
1057
1032
  }
1058
1033
  };
1059
- }, [onClose]);
1060
- const handleProviderLogin = (provider) => {
1061
- var _a2;
1034
+ }, []);
1035
+ const handleProviderLogin = (0, import_react3.useCallback)((provider) => {
1062
1036
  setError("");
1063
- if (!iframe) {
1064
- setError("Authentication service not available");
1065
- return;
1066
- }
1067
- (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
1068
- type: "LOGIN_REQUEST",
1069
- connection: provider,
1070
- requestId: `login-${Date.now()}`
1071
- }, "*");
1072
- onClose();
1073
- };
1074
- const handleEmailLogin = (email, password) => {
1075
- var _a2;
1037
+ setIsSubmitting(true);
1038
+ login({ connection: provider });
1039
+ }, [login]);
1040
+ const handleEmailLogin = (0, import_react3.useCallback)((email, password) => {
1076
1041
  setError("");
1077
1042
  setIsSubmitting(true);
1078
- if (!iframe) {
1079
- setError("Authentication service not available");
1080
- setIsSubmitting(false);
1081
- return;
1082
- }
1083
1043
  if (timeoutIdRef.current) {
1084
1044
  clearTimeout(timeoutIdRef.current);
1085
1045
  timeoutIdRef.current = null;
1086
1046
  }
1087
- (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
1088
- type: "LOGIN_REQUEST",
1089
- email,
1090
- password,
1091
- requestId: `login-${Date.now()}`
1092
- }, "*");
1047
+ login({ email, password });
1093
1048
  timeoutIdRef.current = setTimeout(() => {
1094
1049
  setError("Authentication service timed out");
1095
1050
  setIsSubmitting(false);
1096
1051
  timeoutIdRef.current = null;
1097
1052
  }, 1e4);
1098
- };
1099
- const handleEmailSignup = (email, password) => {
1100
- if (signupInProgressRef.current) {
1101
- return;
1102
- }
1103
- const now = Date.now();
1104
- if (now - lastSignupAttemptRef.current < 2e3) {
1105
- return;
1106
- }
1107
- lastSignupAttemptRef.current = now;
1053
+ }, [login]);
1054
+ const handleEmailSignup = (0, import_react3.useCallback)((email, password) => {
1108
1055
  setError("");
1109
1056
  setIsSubmitting(true);
1110
- signupInProgressRef.current = true;
1111
1057
  if (timeoutIdRef.current) {
1112
1058
  clearTimeout(timeoutIdRef.current);
1113
1059
  timeoutIdRef.current = null;
1114
1060
  }
1115
- try {
1116
- signup(email, password);
1117
- } catch (error2) {
1118
- setError("Failed to initiate signup");
1119
- setIsSubmitting(false);
1120
- signupInProgressRef.current = false;
1121
- return;
1122
- }
1061
+ signup(email, password);
1123
1062
  timeoutIdRef.current = setTimeout(() => {
1124
1063
  setError("Authentication service timed out");
1125
1064
  setIsSubmitting(false);
1126
- signupInProgressRef.current = false;
1127
1065
  timeoutIdRef.current = null;
1128
1066
  }, 1e4);
1129
- };
1067
+ }, [signup]);
1130
1068
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1131
1069
  import_core_k2_components3.Dialog,
1132
1070
  {
@@ -1593,7 +1531,7 @@ function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1593
1531
  if (darkMode !== void 0 && darkMode !== isDarkMode) {
1594
1532
  setIsDarkMode(darkMode);
1595
1533
  }
1596
- }, [darkMode]);
1534
+ }, [darkMode, isDarkMode]);
1597
1535
  const toggleTheme = (0, import_react8.useCallback)(() => {
1598
1536
  const newDarkMode = !isDarkMode;
1599
1537
  setIsDarkMode(newDarkMode);
@@ -1602,6 +1540,18 @@ function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1602
1540
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ThemeContext.Provider, { value: { isDarkMode, toggleTheme }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_core_k2_components5.ThemeProvider, { theme: isDarkMode ? darkTheme : lightTheme, children }) });
1603
1541
  }
1604
1542
 
1543
+ // src/constants/storage.ts
1544
+ var OIDC_TOKEN_KEY2 = "avacloud-auth-oidc-token";
1545
+ var AUTH_TOKENS_KEY2 = "auth_tokens";
1546
+ var AUTH0_STORAGE_KEYS2 = {
1547
+ IS_AUTHENTICATED: "auth0.is.authenticated",
1548
+ ACCESS_TOKEN: "auth0.access_token",
1549
+ ID_TOKEN: "auth0.id_token",
1550
+ EXPIRES_AT: "auth0.expires_at"
1551
+ };
1552
+ var CUBIST_USER_ID_KEY2 = "cubist_user_id";
1553
+ var ORG_CONFIG_CACHE_KEY2 = "avacloud-org-config-cache";
1554
+
1605
1555
  // src/AvaCloudWalletProvider.tsx
1606
1556
  var import_jsx_runtime7 = require("react/jsx-runtime");
1607
1557
  var AvaCloudWalletContext = (0, import_react9.createContext)(void 0);
@@ -1632,12 +1582,30 @@ function ViemProviderWrapper({ children, chainId }) {
1632
1582
  }
1633
1583
  );
1634
1584
  }
1585
+ function normalizeOrgConfig(config) {
1586
+ if (!config) {
1587
+ return null;
1588
+ }
1589
+ const typedConfig = config;
1590
+ const explicitWalletProvider = typeof typedConfig.walletProviderOrgID === "string" ? typedConfig.walletProviderOrgID.trim() : "";
1591
+ const cubistOrgId = typeof typedConfig.cubistOrgId === "string" ? typedConfig.cubistOrgId.trim() : "";
1592
+ const resolvedOrgId = explicitWalletProvider || cubistOrgId;
1593
+ if (!resolvedOrgId) {
1594
+ return typedConfig;
1595
+ }
1596
+ return {
1597
+ ...typedConfig,
1598
+ walletProviderOrgID: resolvedOrgId,
1599
+ cubistOrgId: cubistOrgId || resolvedOrgId
1600
+ };
1601
+ }
1635
1602
  function AvaCloudWalletProvider({
1636
1603
  children,
1637
1604
  orgId,
1638
1605
  chainId = 43113,
1639
1606
  darkMode = false,
1640
1607
  env = "production",
1608
+ authServiceUrl: customAuthServiceUrl,
1641
1609
  onAuthSuccess,
1642
1610
  onAuthError,
1643
1611
  onWalletUpdate
@@ -1646,7 +1614,23 @@ function AvaCloudWalletProvider({
1646
1614
  (0, import_react9.useEffect)(() => {
1647
1615
  setChainId(chainId);
1648
1616
  }, [chainId, setChainId]);
1649
- 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";
1617
+ const getAuthServiceUrl = () => {
1618
+ var _a;
1619
+ if (customAuthServiceUrl) {
1620
+ return customAuthServiceUrl;
1621
+ }
1622
+ if (typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.NEXT_PUBLIC_AUTH_SERVICE_URL)) {
1623
+ return process.env.NEXT_PUBLIC_AUTH_SERVICE_URL;
1624
+ }
1625
+ if (env === "development") {
1626
+ return "http://localhost:3000";
1627
+ } else if (env === "staging") {
1628
+ return "https://ac-auth-service-env-staging-ava-labs.vercel.app";
1629
+ } else {
1630
+ return "https://ac-auth-service.vercel.app";
1631
+ }
1632
+ };
1633
+ const authServiceUrl = getAuthServiceUrl();
1650
1634
  const environment = env;
1651
1635
  const [isAuthenticated, setIsAuthenticated] = (0, import_react9.useState)(false);
1652
1636
  const [isCubistLoading, setIsCubistLoading] = (0, import_react9.useState)(true);
@@ -1655,7 +1639,7 @@ function AvaCloudWalletProvider({
1655
1639
  const [wallet, setWallet] = (0, import_react9.useState)({ address: null });
1656
1640
  const [orgConfig, setOrgConfig] = (0, import_react9.useState)(null);
1657
1641
  const [iframe, setIframe] = (0, import_react9.useState)(null);
1658
- const [isIframeReady, setIsIframeReady] = (0, import_react9.useState)(false);
1642
+ const [_isIframeReady, setIsIframeReady] = (0, import_react9.useState)(false);
1659
1643
  const [cubistClient, setCubistClient] = (0, import_react9.useState)(null);
1660
1644
  const [cubistError, setCubistError] = (0, import_react9.useState)(null);
1661
1645
  const [pendingOidcToken, setPendingOidcToken] = (0, import_react9.useState)(null);
@@ -1702,7 +1686,7 @@ function AvaCloudWalletProvider({
1702
1686
  if (oidcToken) {
1703
1687
  accessToken = oidcToken;
1704
1688
  } else {
1705
- const tokens = localStorage.getItem(AUTH_TOKENS_KEY);
1689
+ const tokens = localStorage.getItem(AUTH_TOKENS_KEY2);
1706
1690
  if (!tokens) {
1707
1691
  throw new Error("No authentication tokens found in localStorage");
1708
1692
  }
@@ -1745,8 +1729,8 @@ function AvaCloudWalletProvider({
1745
1729
  });
1746
1730
  }
1747
1731
  } catch (error) {
1748
- localStorage.removeItem(AUTH_TOKENS_KEY);
1749
- localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1732
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
1733
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1750
1734
  setIsAuthenticated(false);
1751
1735
  setUser(null);
1752
1736
  setCubistClient(null);
@@ -1760,12 +1744,17 @@ function AvaCloudWalletProvider({
1760
1744
  setIsCubistLoading(false);
1761
1745
  }
1762
1746
  }, [wallet, onWalletUpdate, onAuthError, getWalletInfo, orgConfig, environment]);
1763
- const { sendMessage } = usePostMessage({
1747
+ const {
1748
+ authService,
1749
+ isConnected,
1750
+ login: penpalLogin,
1751
+ signup: penpalSignup,
1752
+ logout: penpalLogout
1753
+ } = usePenpalAuth({
1764
1754
  authServiceUrl,
1765
1755
  orgId,
1766
1756
  environment,
1767
1757
  iframe,
1768
- isIframeReady,
1769
1758
  onAuthSuccess: () => {
1770
1759
  if (user) {
1771
1760
  if (wallet.address) {
@@ -1775,8 +1764,7 @@ function AvaCloudWalletProvider({
1775
1764
  },
1776
1765
  onAuthError: (error) => {
1777
1766
  const errorMessage = (error == null ? void 0 : error.message) || "";
1778
- if (errorMessage === "User not authenticated in iframe" || errorMessage === "Unknown error" || // Generic error that often appears during signup
1779
- errorMessage.includes("OIDC user not found")) {
1767
+ if (errorMessage === "User not authenticated in iframe" || errorMessage === "Unknown error" || errorMessage.includes("OIDC user not found")) {
1780
1768
  return;
1781
1769
  }
1782
1770
  setIsCubistLoading(false);
@@ -1802,76 +1790,78 @@ function AvaCloudWalletProvider({
1802
1790
  };
1803
1791
  },
1804
1792
  onOrgConfigUpdate: (config) => {
1805
- setOrgConfig(config);
1793
+ setOrgConfig(normalizeOrgConfig(config));
1806
1794
  },
1807
1795
  setIsAuthenticated,
1808
1796
  setUser,
1809
- setIsLoading: (isLoading2) => {
1810
- setIsLoading(isLoading2);
1797
+ setIsLoading: (loading) => {
1798
+ setIsLoading(loading);
1811
1799
  },
1812
- setIsIframeReady,
1813
- wallet,
1814
- cubistClient
1800
+ setIsIframeReady
1815
1801
  });
1816
- const login = (0, import_react9.useCallback)(() => {
1817
- if (iframe == null ? void 0 : iframe.contentWindow) {
1818
- setIsCubistLoading(true);
1819
- sendMessage({ type: "LOGIN_REQUEST" });
1802
+ const login = (0, import_react9.useCallback)((params) => {
1803
+ if (isConnected) {
1804
+ const isEmailLogin = (params == null ? void 0 : params.email) && (params == null ? void 0 : params.password);
1805
+ if (isEmailLogin) {
1806
+ setIsCubistLoading(true);
1807
+ }
1808
+ penpalLogin(params).catch((error) => {
1809
+ setIsCubistLoading(false);
1810
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Login failed"));
1811
+ });
1820
1812
  }
1821
- }, [iframe, sendMessage]);
1813
+ }, [isConnected, penpalLogin, onAuthError]);
1822
1814
  const signup = (0, import_react9.useCallback)((email, password) => {
1823
- if (iframe == null ? void 0 : iframe.contentWindow) {
1815
+ if (isConnected) {
1824
1816
  setIsCubistLoading(true);
1825
- sendMessage({
1826
- type: "SIGNUP_REQUEST",
1827
- payload: {
1828
- email,
1829
- password
1830
- },
1831
- requestId: `signup-${Date.now()}`
1817
+ penpalSignup(email, password).catch((error) => {
1818
+ setIsCubistLoading(false);
1819
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Signup failed"));
1832
1820
  });
1833
1821
  }
1834
- }, [iframe, sendMessage]);
1822
+ }, [isConnected, penpalSignup, onAuthError]);
1835
1823
  const logout = (0, import_react9.useCallback)(() => {
1836
- sendMessage({ type: "LOGOUT_REQUEST" });
1824
+ penpalLogout().catch((error) => {
1825
+ console.error("Logout error:", error);
1826
+ });
1837
1827
  setUser(null);
1838
1828
  setWallet({ address: null });
1839
1829
  setIsAuthenticated(false);
1840
- localStorage.removeItem(AUTH_TOKENS_KEY);
1841
- localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1842
- localStorage.removeItem(AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
1843
- localStorage.removeItem(AUTH0_STORAGE_KEYS.ID_TOKEN);
1844
- localStorage.removeItem(AUTH0_STORAGE_KEYS.EXPIRES_AT);
1845
- localStorage.removeItem(CUBIST_USER_ID_KEY);
1830
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
1831
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1832
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.ACCESS_TOKEN);
1833
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.ID_TOKEN);
1834
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.EXPIRES_AT);
1835
+ localStorage.removeItem(CUBIST_USER_ID_KEY2);
1846
1836
  if (orgId) {
1847
- const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${env}`;
1837
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${env}`;
1848
1838
  localStorage.removeItem(cachedConfigKey);
1849
1839
  }
1850
- sessionStorage.removeItem(OIDC_TOKEN_KEY);
1840
+ sessionStorage.removeItem(OIDC_TOKEN_KEY2);
1851
1841
  setCubistClient(null);
1852
1842
  setCubistError(null);
1853
1843
  setPendingOidcToken(null);
1854
- }, [sendMessage, orgId, env]);
1844
+ }, [penpalLogout, orgId, env]);
1855
1845
  const addAccount = (0, import_react9.useCallback)(async (accountIndex) => {
1856
1846
  if (!isAuthenticated || !user || !wallet.mnemonicId) {
1857
1847
  throw new Error("User must be authenticated and have a wallet to add an account");
1858
1848
  }
1849
+ if (!authService) {
1850
+ throw new Error("Auth service not connected");
1851
+ }
1859
1852
  const path = getDerivationPath("EVM" /* EVM */, accountIndex);
1860
- sendMessage({
1861
- type: "ADD_ACCOUNT",
1862
- payload: {
1863
- accountIndex,
1864
- mnemonicId: wallet.mnemonicId,
1865
- derivationPath: path,
1866
- identityProof: {
1867
- email: user.email,
1868
- displayName: user.displayName,
1869
- sub: user.sub,
1870
- configured_mfa: user.configured_mfa
1871
- }
1853
+ await authService.addAccount({
1854
+ accountIndex,
1855
+ mnemonicId: wallet.mnemonicId,
1856
+ derivationPath: path,
1857
+ identityProof: {
1858
+ email: user.email,
1859
+ displayName: user.displayName,
1860
+ sub: user.sub,
1861
+ configured_mfa: user.configured_mfa
1872
1862
  }
1873
1863
  });
1874
- }, [sendMessage, isAuthenticated, user, wallet.mnemonicId]);
1864
+ }, [authService, isAuthenticated, user, wallet.mnemonicId]);
1875
1865
  (0, import_react9.useEffect)(() => {
1876
1866
  const hasOrgConfig = !!(orgConfig == null ? void 0 : orgConfig.walletProviderOrgID);
1877
1867
  const hasOidcToken = !!pendingOidcToken;
@@ -1921,20 +1911,20 @@ function AvaCloudWalletProvider({
1921
1911
  if (typeof window === "undefined") {
1922
1912
  return;
1923
1913
  }
1924
- const isAuthenticatedInStorage = localStorage.getItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED) === "true";
1914
+ const isAuthenticatedInStorage = localStorage.getItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED) === "true";
1925
1915
  if (!isAuthenticatedInStorage) {
1926
1916
  return;
1927
1917
  }
1928
- const existingOidcToken = sessionStorage.getItem(OIDC_TOKEN_KEY);
1918
+ const existingOidcToken = sessionStorage.getItem(OIDC_TOKEN_KEY2);
1929
1919
  if (existingOidcToken) {
1930
1920
  setPendingOidcToken(existingOidcToken);
1931
1921
  } else {
1932
1922
  try {
1933
- const tokensJson = localStorage.getItem(AUTH_TOKENS_KEY);
1923
+ const tokensJson = localStorage.getItem(AUTH_TOKENS_KEY2);
1934
1924
  if (tokensJson) {
1935
1925
  const tokens = JSON.parse(tokensJson);
1936
1926
  if (tokens.access_token) {
1937
- sessionStorage.setItem(OIDC_TOKEN_KEY, tokens.access_token);
1927
+ sessionStorage.setItem(OIDC_TOKEN_KEY2, tokens.access_token);
1938
1928
  setPendingOidcToken(tokens.access_token);
1939
1929
  }
1940
1930
  }
@@ -3270,32 +3260,27 @@ var import_react16 = require("react");
3270
3260
  var import_core_k2_components11 = require("@avalabs/core-k2-components");
3271
3261
  var import_jsx_runtime13 = require("react/jsx-runtime");
3272
3262
  function ExportView({ onBack }) {
3273
- const { wallet, iframe } = useAvaCloudWallet();
3274
- const [showKey, setShowKey] = (0, import_react16.useState)(false);
3263
+ const { wallet } = useAvaCloudWallet();
3264
+ const [showKey, _setShowKey] = (0, import_react16.useState)(false);
3275
3265
  const [copied, setCopied] = (0, import_react16.useState)(false);
3276
- const [privateKey, setPrivateKey] = (0, import_react16.useState)(null);
3266
+ const [privateKey, _setPrivateKey] = (0, import_react16.useState)(null);
3277
3267
  const [error, setError] = (0, import_react16.useState)(null);
3278
- const handleExport = async () => {
3279
- if (!(iframe == null ? void 0 : iframe.contentWindow)) return;
3280
- try {
3281
- iframe.contentWindow.postMessage({
3282
- type: "EXPORT_PRIVATE_KEY",
3283
- payload: {
3284
- address: wallet.address
3285
- }
3286
- }, "*");
3287
- const handleResponse = (event) => {
3288
- if (event.data.type === "EXPORT_PRIVATE_KEY_RESPONSE") {
3289
- setPrivateKey(event.data.payload.privateKey);
3290
- setShowKey(true);
3291
- window.removeEventListener("message", handleResponse);
3292
- }
3293
- };
3294
- window.addEventListener("message", handleResponse);
3268
+ const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
3269
+ const handleExport = (0, import_react16.useCallback)(async () => {
3270
+ if (!wallet.address) {
3271
+ setError("No wallet address available");
3272
+ return;
3273
+ }
3274
+ setIsLoading(true);
3275
+ setError(null);
3276
+ try {
3277
+ setError("Private key export is not yet available. Please use the wallet provider directly.");
3295
3278
  } catch (err) {
3296
3279
  setError("Failed to export private key. Please try again.");
3280
+ } finally {
3281
+ setIsLoading(false);
3297
3282
  }
3298
- };
3283
+ }, [wallet.address]);
3299
3284
  const handleCopy = () => {
3300
3285
  if (privateKey) {
3301
3286
  navigator.clipboard.writeText(privateKey);
@@ -3316,8 +3301,9 @@ function ExportView({ onBack }) {
3316
3301
  variant: "contained",
3317
3302
  color: "warning",
3318
3303
  onClick: handleExport,
3304
+ disabled: isLoading,
3319
3305
  sx: { mb: 2 },
3320
- children: "Show Private Key"
3306
+ children: isLoading ? "Loading..." : "Show Private Key"
3321
3307
  }
3322
3308
  ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_core_k2_components11.Box, { sx: { mb: 3 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_core_k2_components11.Box, { sx: {
3323
3309
  display: "flex",
@@ -4260,134 +4246,422 @@ function WalletButton({
4260
4246
  },
4261
4247
  children: displayAddress
4262
4248
  }
4263
- ),
4264
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4265
- import_core_k2_components19.IconButton,
4266
- {
4267
- size: "small",
4268
- onClick: handleCopy,
4269
- sx: { color: "text.secondary" },
4270
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core_k2_components19.CopyIcon, {})
4249
+ ),
4250
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4251
+ import_core_k2_components19.IconButton,
4252
+ {
4253
+ size: "small",
4254
+ onClick: handleCopy,
4255
+ sx: { color: "text.secondary" },
4256
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core_k2_components19.CopyIcon, {})
4257
+ }
4258
+ )
4259
+ ] })
4260
+ ]
4261
+ }
4262
+ ),
4263
+ isModalOpen && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(WalletCard, { onClose: handleClose })
4264
+ ] });
4265
+ }
4266
+
4267
+ // src/components/WalletDisplay.tsx
4268
+ var import_react23 = require("react");
4269
+ var import_jsx_runtime22 = require("react/jsx-runtime");
4270
+ function WalletDisplay({
4271
+ className = "",
4272
+ truncateAddress = true,
4273
+ showAddAccount = true
4274
+ }) {
4275
+ const { wallet, addAccount, isAuthenticated } = useAvaCloudWallet();
4276
+ const [isAdding, setIsAdding] = (0, import_react23.useState)(false);
4277
+ const [accountIndex, setAccountIndex] = (0, import_react23.useState)(0);
4278
+ if (!isAuthenticated || !wallet.address) {
4279
+ return null;
4280
+ }
4281
+ const displayAddress = truncateAddress ? `${wallet.address.slice(0, 6)}...${wallet.address.slice(-4)}` : wallet.address;
4282
+ const handleAddAccount = async () => {
4283
+ try {
4284
+ setIsAdding(true);
4285
+ await addAccount(accountIndex);
4286
+ setAccountIndex((prev) => prev + 1);
4287
+ } catch (error) {
4288
+ console.error("Failed to add account:", error);
4289
+ } finally {
4290
+ setIsAdding(false);
4291
+ }
4292
+ };
4293
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `space-y-4 ${className}`, children: [
4294
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "bg-gray-50 rounded-lg p-4", children: [
4295
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-sm text-gray-500", children: "Wallet Address" }),
4296
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-1 font-mono text-sm break-all", children: displayAddress })
4297
+ ] }),
4298
+ showAddAccount && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4299
+ "button",
4300
+ {
4301
+ type: "button",
4302
+ onClick: handleAddAccount,
4303
+ disabled: isAdding,
4304
+ 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",
4305
+ children: isAdding ? "Adding Account..." : "Add Account"
4306
+ }
4307
+ )
4308
+ ] });
4309
+ }
4310
+
4311
+ // src/components/UserProfile.tsx
4312
+ var import_jsx_runtime23 = require("react/jsx-runtime");
4313
+ function UserProfile({
4314
+ className = "",
4315
+ showLogout = true
4316
+ }) {
4317
+ const { user, logout, isAuthenticated } = useAvaCloudWallet();
4318
+ if (!isAuthenticated || !user) {
4319
+ return null;
4320
+ }
4321
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: `space-y-4 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "bg-white shadow rounded-lg p-6", children: [
4322
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-4 py-5 sm:px-6", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-lg font-medium leading-6 text-gray-900", children: "User Profile" }) }),
4323
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "border-t border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("dl", { children: [
4324
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", children: [
4325
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { className: "text-sm font-medium text-gray-500", children: "Display Name" }),
4326
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.displayName })
4327
+ ] }),
4328
+ user.email && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", children: [
4329
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { className: "text-sm font-medium text-gray-500", children: "Email address" }),
4330
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.email })
4331
+ ] }),
4332
+ user.configured_mfa && user.configured_mfa.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
4333
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-sm font-medium text-gray-500", children: "MFA Methods" }),
4334
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-1 space-y-1", children: user.configured_mfa.map((method) => {
4335
+ const mfaMethod = typeof method === "string" ? { type: method } : method;
4336
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4337
+ "div",
4338
+ {
4339
+ className: "text-sm text-gray-900",
4340
+ children: mfaMethod.type === "totp" ? "Authenticator App" : mfaMethod.name
4341
+ },
4342
+ mfaMethod.type === "fido" ? mfaMethod.id : `totp-${mfaMethod.type}`
4343
+ );
4344
+ }) })
4345
+ ] })
4346
+ ] }) }),
4347
+ showLogout && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4348
+ "button",
4349
+ {
4350
+ type: "button",
4351
+ onClick: logout,
4352
+ 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",
4353
+ children: "Sign Out"
4354
+ }
4355
+ ) })
4356
+ ] }) });
4357
+ }
4358
+
4359
+ // src/hooks/usePostMessage.ts
4360
+ var import_react24 = require("react");
4361
+ var globalAuthState = {
4362
+ signupInProgress: false,
4363
+ loginInProgress: false,
4364
+ lastSignupTimestamp: 0,
4365
+ lastLoginTimestamp: 0,
4366
+ processingMessageIds: /* @__PURE__ */ new Set()
4367
+ };
4368
+ function cleanupProcessedMessageIds() {
4369
+ if (globalAuthState.processingMessageIds.size > 100) {
4370
+ const messageIds = Array.from(globalAuthState.processingMessageIds);
4371
+ globalAuthState.processingMessageIds = new Set(messageIds.slice(-50));
4372
+ }
4373
+ }
4374
+ function usePostMessage({
4375
+ authServiceUrl,
4376
+ orgId,
4377
+ environment,
4378
+ iframe,
4379
+ isIframeReady,
4380
+ onAuthSuccess,
4381
+ onAuthError,
4382
+ onOidcReceived,
4383
+ onOrgConfigUpdate,
4384
+ setIsAuthenticated,
4385
+ setUser,
4386
+ setIsLoading,
4387
+ setIsIframeReady,
4388
+ cubistClient
4389
+ }) {
4390
+ const lastAuthStateRef = (0, import_react24.useRef)({
4391
+ isAuthenticated: false,
4392
+ userId: null,
4393
+ lastUpdateTime: 0
4394
+ });
4395
+ const hasRequestedOidcRef = (0, import_react24.useRef)(false);
4396
+ const isHandlingMessageRef = (0, import_react24.useRef)(false);
4397
+ const hasLoadedCacheRef = (0, import_react24.useRef)(false);
4398
+ (0, import_react24.useEffect)(() => {
4399
+ if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
4400
+ hasLoadedCacheRef.current = true;
4401
+ try {
4402
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${environment}`;
4403
+ const cachedConfigJson = localStorage.getItem(cachedConfigKey);
4404
+ if (cachedConfigJson) {
4405
+ const cachedConfig = JSON.parse(cachedConfigJson);
4406
+ const timestamp = cachedConfig._timestamp || 0;
4407
+ const isExpired = Date.now() - timestamp > 30 * 60 * 1e3;
4408
+ if (!isExpired) {
4409
+ const { _timestamp, ...configWithoutTimestamp } = cachedConfig;
4410
+ onOrgConfigUpdate(configWithoutTimestamp);
4411
+ }
4412
+ }
4413
+ } catch (error) {
4414
+ }
4415
+ }
4416
+ }, [orgId, environment, onOrgConfigUpdate]);
4417
+ const sendMessage = (0, import_react24.useCallback)((message) => {
4418
+ if (iframe == null ? void 0 : iframe.contentWindow) {
4419
+ try {
4420
+ if (message.type === "SIGNUP_REQUEST") {
4421
+ if (globalAuthState.signupInProgress) {
4422
+ return;
4423
+ }
4424
+ const now = Date.now();
4425
+ if (now - globalAuthState.lastSignupTimestamp < 3e3) {
4426
+ return;
4427
+ }
4428
+ globalAuthState.signupInProgress = true;
4429
+ globalAuthState.lastSignupTimestamp = now;
4430
+ let finalMessage = message;
4431
+ if (!message.requestId) {
4432
+ finalMessage = {
4433
+ ...message,
4434
+ requestId: `signup-${now}`
4435
+ };
4436
+ }
4437
+ let messageToSend = finalMessage;
4438
+ if (finalMessage.payload && typeof finalMessage.payload.email === "string" && typeof finalMessage.payload.password === "string") {
4439
+ messageToSend = {
4440
+ type: "SIGNUP_REQUEST",
4441
+ email: finalMessage.payload.email,
4442
+ password: finalMessage.payload.password,
4443
+ requestId: finalMessage.requestId || `signup-${now}`
4444
+ };
4445
+ }
4446
+ if ("requestId" in messageToSend && messageToSend.requestId) {
4447
+ globalAuthState.processingMessageIds.add(messageToSend.requestId);
4448
+ }
4449
+ iframe.contentWindow.postMessage(messageToSend, authServiceUrl);
4450
+ return;
4451
+ }
4452
+ if (message.type === "LOGIN_REQUEST") {
4453
+ if (globalAuthState.loginInProgress) {
4454
+ return;
4455
+ }
4456
+ const now = Date.now();
4457
+ if (now - globalAuthState.lastLoginTimestamp < 3e3) {
4458
+ return;
4459
+ }
4460
+ globalAuthState.loginInProgress = true;
4461
+ globalAuthState.lastLoginTimestamp = now;
4462
+ let finalMessage = message;
4463
+ if (!message.requestId) {
4464
+ finalMessage = {
4465
+ ...message,
4466
+ requestId: `login-${now}`
4467
+ };
4468
+ }
4469
+ if (finalMessage.requestId) {
4470
+ globalAuthState.processingMessageIds.add(finalMessage.requestId);
4471
+ }
4472
+ iframe.contentWindow.postMessage(finalMessage, authServiceUrl);
4473
+ return;
4474
+ }
4475
+ iframe.contentWindow.postMessage(message, authServiceUrl);
4476
+ } catch (error) {
4477
+ if (message.type === "SIGNUP_REQUEST") {
4478
+ globalAuthState.signupInProgress = false;
4479
+ }
4480
+ if (message.type === "LOGIN_REQUEST") {
4481
+ globalAuthState.loginInProgress = false;
4482
+ }
4483
+ }
4484
+ }
4485
+ }, [iframe, authServiceUrl]);
4486
+ (0, import_react24.useEffect)(() => {
4487
+ const handleMessage = async (event) => {
4488
+ var _a, _b, _c, _d, _e, _f, _g;
4489
+ if (isHandlingMessageRef.current) {
4490
+ return;
4491
+ }
4492
+ if (event.origin !== new URL(authServiceUrl).origin) {
4493
+ return;
4494
+ }
4495
+ if (typeof ((_a = event.data) == null ? void 0 : _a.type) !== "string") {
4496
+ return;
4497
+ }
4498
+ if (event.data.requestId && globalAuthState.processingMessageIds.has(event.data.requestId)) {
4499
+ return;
4500
+ }
4501
+ try {
4502
+ isHandlingMessageRef.current = true;
4503
+ if (event.data.type === "ERROR") {
4504
+ globalAuthState.signupInProgress = false;
4505
+ globalAuthState.loginInProgress = false;
4506
+ } else if (event.data.type === "AUTH_STATUS" && event.data.isAuthenticated) {
4507
+ globalAuthState.signupInProgress = false;
4508
+ globalAuthState.loginInProgress = false;
4509
+ cleanupProcessedMessageIds();
4510
+ } else if (event.data.type === "RECEIVE_OIDC") {
4511
+ globalAuthState.signupInProgress = false;
4512
+ globalAuthState.loginInProgress = false;
4513
+ }
4514
+ switch (event.data.type) {
4515
+ case "IFRAME_READY":
4516
+ setIsIframeReady(true);
4517
+ break;
4518
+ case "RECEIVE_OIDC":
4519
+ if (typeof ((_b = event.data.payload) == null ? void 0 : _b.idToken) === "string") {
4520
+ const oidcToken = event.data.payload.idToken;
4521
+ hasRequestedOidcRef.current = false;
4522
+ onOidcReceived == null ? void 0 : onOidcReceived(oidcToken);
4523
+ } else {
4524
+ hasRequestedOidcRef.current = false;
4525
+ }
4526
+ break;
4527
+ case "AUTH_STATUS": {
4528
+ const newIsAuthenticated = !!event.data.isAuthenticated;
4529
+ const newUserId = (_d = (_c = event.data.user) == null ? void 0 : _c.sub) != null ? _d : null;
4530
+ const now = Date.now();
4531
+ if (now - lastAuthStateRef.current.lastUpdateTime < 500) {
4532
+ return;
4533
+ }
4534
+ const authStateChanged = lastAuthStateRef.current.isAuthenticated !== newIsAuthenticated || lastAuthStateRef.current.userId !== newUserId;
4535
+ if (authStateChanged) {
4536
+ setIsAuthenticated(newIsAuthenticated);
4537
+ if (event.data.user) {
4538
+ const userInfo = {
4539
+ email: event.data.user.email,
4540
+ sub: event.data.user.sub,
4541
+ configured_mfa: [],
4542
+ displayName: event.data.user.nickname || event.data.user.name || ((_e = event.data.user.email) == null ? void 0 : _e.split("@")[0]) || "User",
4543
+ rawUserData: event.data.user
4544
+ };
4545
+ setUser(userInfo);
4546
+ if (newIsAuthenticated && !cubistClient && !hasRequestedOidcRef.current) {
4547
+ hasRequestedOidcRef.current = true;
4548
+ sendMessage({ type: "GET_OIDC" });
4549
+ return;
4550
+ }
4551
+ } else {
4552
+ setUser(null);
4553
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
4554
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
4555
+ sessionStorage.removeItem(OIDC_TOKEN_KEY2);
4556
+ }
4557
+ lastAuthStateRef.current = {
4558
+ isAuthenticated: newIsAuthenticated,
4559
+ userId: newUserId,
4560
+ lastUpdateTime: now
4561
+ };
4562
+ if (newIsAuthenticated && event.data.user) {
4563
+ if (!hasRequestedOidcRef.current) {
4564
+ if (event.data.tokens) {
4565
+ localStorage.setItem(AUTH_TOKENS_KEY2, JSON.stringify(event.data.tokens));
4566
+ }
4567
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
4568
+ }
4271
4569
  }
4272
- )
4273
- ] })
4274
- ]
4570
+ }
4571
+ if (event.data.orgConfig && onOrgConfigUpdate) {
4572
+ onOrgConfigUpdate(event.data.orgConfig);
4573
+ if (orgId) {
4574
+ try {
4575
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${environment}`;
4576
+ const configWithTimestamp = {
4577
+ ...event.data.orgConfig,
4578
+ _timestamp: Date.now()
4579
+ };
4580
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
4581
+ } catch (error) {
4582
+ }
4583
+ }
4584
+ }
4585
+ if (!hasRequestedOidcRef.current) {
4586
+ setIsLoading(false);
4587
+ }
4588
+ break;
4589
+ }
4590
+ case "REGISTER_SUCCESS": {
4591
+ const userId = (_f = event.data.payload) == null ? void 0 : _f.userId;
4592
+ if (userId) {
4593
+ localStorage.setItem(CUBIST_USER_ID_KEY2, userId);
4594
+ if (!hasRequestedOidcRef.current) {
4595
+ hasRequestedOidcRef.current = true;
4596
+ sendMessage({ type: "GET_OIDC" });
4597
+ }
4598
+ }
4599
+ break;
4600
+ }
4601
+ case "ERROR":
4602
+ if (event.data.error === "User not authenticated in iframe") {
4603
+ isHandlingMessageRef.current = false;
4604
+ return;
4605
+ }
4606
+ onAuthError == null ? void 0 : onAuthError(new Error((_g = event.data.error) != null ? _g : "Unknown error"));
4607
+ setIsLoading(false);
4608
+ break;
4609
+ }
4610
+ } finally {
4611
+ isHandlingMessageRef.current = false;
4275
4612
  }
4276
- ),
4277
- isModalOpen && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(WalletCard, { onClose: handleClose })
4278
- ] });
4279
- }
4280
-
4281
- // src/components/WalletDisplay.tsx
4282
- var import_react23 = require("react");
4283
- var import_jsx_runtime22 = require("react/jsx-runtime");
4284
- function WalletDisplay({
4285
- className = "",
4286
- truncateAddress = true,
4287
- showAddAccount = true
4288
- }) {
4289
- const { wallet, addAccount, isAuthenticated } = useAvaCloudWallet();
4290
- const [isAdding, setIsAdding] = (0, import_react23.useState)(false);
4291
- const [accountIndex, setAccountIndex] = (0, import_react23.useState)(0);
4292
- if (!isAuthenticated || !wallet.address) {
4293
- return null;
4294
- }
4295
- const displayAddress = truncateAddress ? `${wallet.address.slice(0, 6)}...${wallet.address.slice(-4)}` : wallet.address;
4296
- const handleAddAccount = async () => {
4297
- try {
4298
- setIsAdding(true);
4299
- await addAccount(accountIndex);
4300
- setAccountIndex((prev) => prev + 1);
4301
- } catch (error) {
4302
- console.error("Failed to add account:", error);
4303
- } finally {
4304
- setIsAdding(false);
4613
+ };
4614
+ window.addEventListener("message", handleMessage);
4615
+ return () => window.removeEventListener("message", handleMessage);
4616
+ }, [
4617
+ authServiceUrl,
4618
+ onAuthError,
4619
+ onAuthSuccess,
4620
+ onOidcReceived,
4621
+ onOrgConfigUpdate,
4622
+ setIsAuthenticated,
4623
+ setIsIframeReady,
4624
+ setIsLoading,
4625
+ setUser,
4626
+ sendMessage,
4627
+ cubistClient,
4628
+ orgId,
4629
+ environment
4630
+ ]);
4631
+ (0, import_react24.useEffect)(() => {
4632
+ if (isIframeReady && (iframe == null ? void 0 : iframe.contentWindow)) {
4633
+ sendMessage({
4634
+ type: "CHECK_AUTH_STATUS",
4635
+ payload: {
4636
+ orgId,
4637
+ environment
4638
+ }
4639
+ });
4305
4640
  }
4641
+ }, [isIframeReady, iframe, sendMessage, orgId, environment]);
4642
+ return {
4643
+ sendMessage
4306
4644
  };
4307
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `space-y-4 ${className}`, children: [
4308
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "bg-gray-50 rounded-lg p-4", children: [
4309
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-sm text-gray-500", children: "Wallet Address" }),
4310
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-1 font-mono text-sm break-all", children: displayAddress })
4311
- ] }),
4312
- showAddAccount && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4313
- "button",
4314
- {
4315
- type: "button",
4316
- onClick: handleAddAccount,
4317
- disabled: isAdding,
4318
- 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",
4319
- children: isAdding ? "Adding Account..." : "Add Account"
4320
- }
4321
- )
4322
- ] });
4323
- }
4324
-
4325
- // src/components/UserProfile.tsx
4326
- var import_jsx_runtime23 = require("react/jsx-runtime");
4327
- function UserProfile({
4328
- className = "",
4329
- showLogout = true
4330
- }) {
4331
- const { user, logout, isAuthenticated } = useAvaCloudWallet();
4332
- if (!isAuthenticated || !user) {
4333
- return null;
4334
- }
4335
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: `space-y-4 ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "bg-white shadow rounded-lg p-6", children: [
4336
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-4 py-5 sm:px-6", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-lg font-medium leading-6 text-gray-900", children: "User Profile" }) }),
4337
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "border-t border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("dl", { children: [
4338
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", children: [
4339
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { className: "text-sm font-medium text-gray-500", children: "Display Name" }),
4340
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.displayName })
4341
- ] }),
4342
- user.email && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", children: [
4343
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { className: "text-sm font-medium text-gray-500", children: "Email address" }),
4344
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.email })
4345
- ] }),
4346
- user.configured_mfa && user.configured_mfa.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
4347
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-sm font-medium text-gray-500", children: "MFA Methods" }),
4348
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-1 space-y-1", children: user.configured_mfa.map((method) => {
4349
- const mfaMethod = typeof method === "string" ? { type: method } : method;
4350
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4351
- "div",
4352
- {
4353
- className: "text-sm text-gray-900",
4354
- children: mfaMethod.type === "totp" ? "Authenticator App" : mfaMethod.name
4355
- },
4356
- mfaMethod.type === "fido" ? mfaMethod.id : `totp-${mfaMethod.type}`
4357
- );
4358
- }) })
4359
- ] })
4360
- ] }) }),
4361
- showLogout && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4362
- "button",
4363
- {
4364
- type: "button",
4365
- onClick: logout,
4366
- 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",
4367
- children: "Sign Out"
4368
- }
4369
- ) })
4370
- ] }) });
4371
4645
  }
4372
4646
 
4373
4647
  // src/hooks/useSignMessage.ts
4374
- var import_react24 = require("react");
4648
+ var import_react25 = require("react");
4375
4649
  var import_cubesigner_sdk4 = require("@cubist-labs/cubesigner-sdk");
4376
4650
  function useSignMessage() {
4377
- const [state, setState] = (0, import_react24.useState)({
4651
+ const [state, setState] = (0, import_react25.useState)({
4378
4652
  isLoading: false,
4379
4653
  error: null,
4380
4654
  signature: null
4381
4655
  });
4382
4656
  const { wallet, cubistClient } = useAvaCloudWallet();
4383
- const reset = (0, import_react24.useCallback)(() => {
4657
+ const reset = (0, import_react25.useCallback)(() => {
4384
4658
  setState({
4385
4659
  isLoading: false,
4386
4660
  error: null,
4387
4661
  signature: null
4388
4662
  });
4389
4663
  }, []);
4390
- const signMessage = (0, import_react24.useCallback)(async (message) => {
4664
+ const signMessage = (0, import_react25.useCallback)(async (message) => {
4391
4665
  if (!cubistClient || !wallet.address) {
4392
4666
  setState((prev) => ({
4393
4667
  ...prev,
@@ -4424,10 +4698,11 @@ function useSignMessage() {
4424
4698
  }
4425
4699
 
4426
4700
  // src/hooks/useSignTransaction.ts
4427
- var import_react25 = require("react");
4701
+ var import_react26 = require("react");
4428
4702
  var import_cubesigner_sdk5 = require("@cubist-labs/cubesigner-sdk");
4703
+ var import_viem5 = require("viem");
4429
4704
  function useSignTransaction() {
4430
- const [state, setState] = (0, import_react25.useState)({
4705
+ const [state, setState] = (0, import_react26.useState)({
4431
4706
  isLoading: false,
4432
4707
  error: null,
4433
4708
  signature: null,
@@ -4435,7 +4710,7 @@ function useSignTransaction() {
4435
4710
  });
4436
4711
  const { wallet, cubistClient } = useAvaCloudWallet();
4437
4712
  const { publicClient } = useViem();
4438
- const reset = (0, import_react25.useCallback)(() => {
4713
+ const reset = (0, import_react26.useCallback)(() => {
4439
4714
  setState({
4440
4715
  isLoading: false,
4441
4716
  error: null,
@@ -4443,8 +4718,7 @@ function useSignTransaction() {
4443
4718
  signedTransaction: null
4444
4719
  });
4445
4720
  }, []);
4446
- const signTransaction = (0, import_react25.useCallback)(async (transaction) => {
4447
- var _a, _b, _c, _d;
4721
+ const signTransaction = (0, import_react26.useCallback)(async (transaction) => {
4448
4722
  if (!(wallet == null ? void 0 : wallet.address)) {
4449
4723
  setState((prev) => ({
4450
4724
  ...prev,
@@ -4480,13 +4754,13 @@ function useSignTransaction() {
4480
4754
  chain_id: publicClient.chain.id,
4481
4755
  tx: {
4482
4756
  to: transaction.to || void 0,
4483
- value: (_a = transaction.value) == null ? void 0 : _a.toString(),
4757
+ value: transaction.value !== void 0 ? (0, import_viem5.toHex)(transaction.value) : void 0,
4484
4758
  data: transaction.data || "0x",
4485
- nonce: (_b = transaction.nonce) == null ? void 0 : _b.toString(),
4759
+ nonce: transaction.nonce !== void 0 ? (0, import_viem5.toHex)(transaction.nonce) : void 0,
4486
4760
  type: "0x2",
4487
4761
  // EIP-1559
4488
- maxFeePerGas: (_c = transaction.maxFeePerGas) == null ? void 0 : _c.toString(),
4489
- maxPriorityFeePerGas: (_d = transaction.maxPriorityFeePerGas) == null ? void 0 : _d.toString()
4762
+ maxFeePerGas: transaction.maxFeePerGas !== void 0 ? (0, import_viem5.toHex)(transaction.maxFeePerGas) : void 0,
4763
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas !== void 0 ? (0, import_viem5.toHex)(transaction.maxPriorityFeePerGas) : void 0
4490
4764
  }
4491
4765
  };
4492
4766
  const sig = await key.signEvm(signReq);
@@ -4512,11 +4786,11 @@ function useSignTransaction() {
4512
4786
  }
4513
4787
 
4514
4788
  // src/hooks/useUserWallets.ts
4515
- var import_react26 = require("react");
4789
+ var import_react27 = require("react");
4516
4790
  function useUserWallets() {
4517
- const [error, setError] = (0, import_react26.useState)(null);
4518
- const [isLoading, setIsLoading] = (0, import_react26.useState)(false);
4519
- const getWallets = (0, import_react26.useCallback)(async (client) => {
4791
+ const [error, setError] = (0, import_react27.useState)(null);
4792
+ const [isLoading, setIsLoading] = (0, import_react27.useState)(false);
4793
+ const getWallets = (0, import_react27.useCallback)(async (client) => {
4520
4794
  setIsLoading(true);
4521
4795
  setError(null);
4522
4796
  try {
@@ -4546,21 +4820,36 @@ function useUserWallets() {
4546
4820
 
4547
4821
  // src/wagmi/connector.ts
4548
4822
  var import_core = require("@wagmi/core");
4549
- var import_viem5 = require("viem");
4823
+ var import_viem6 = require("viem");
4550
4824
  function avaCloudWallet() {
4551
4825
  return (0, import_core.createConnector)((config) => ({
4552
4826
  id: "avaCloudWallet",
4553
4827
  name: "AvaCloud Wallet",
4554
4828
  type: "injected",
4555
- async connect() {
4829
+ async connect(parameters) {
4830
+ const { withCapabilities } = parameters != null ? parameters : {};
4556
4831
  const { walletClient } = useViem();
4557
4832
  if (!walletClient) {
4558
4833
  throw new Error("AvaCloud Wallet not connected");
4559
4834
  }
4560
4835
  const accounts = await this.getAccounts();
4561
4836
  const chainId = await this.getChainId();
4837
+ if (withCapabilities) {
4838
+ const result = {
4839
+ accounts: accounts.map((address) => ({
4840
+ address,
4841
+ capabilities: {}
4842
+ })),
4843
+ chainId
4844
+ };
4845
+ config.emitter.emit("connect", { accounts, chainId });
4846
+ return result;
4847
+ }
4562
4848
  config.emitter.emit("connect", { accounts, chainId });
4563
- return { accounts, chainId };
4849
+ return {
4850
+ accounts,
4851
+ chainId
4852
+ };
4564
4853
  },
4565
4854
  async disconnect() {
4566
4855
  config.emitter.emit("disconnect");
@@ -4592,7 +4881,7 @@ function avaCloudWallet() {
4592
4881
  this.disconnect();
4593
4882
  } else {
4594
4883
  config.emitter.emit("change", {
4595
- accounts: accounts.map((x) => (0, import_viem5.getAddress)(x))
4884
+ accounts: accounts.map((x) => (0, import_viem6.getAddress)(x))
4596
4885
  });
4597
4886
  }
4598
4887
  },
@@ -4607,7 +4896,7 @@ function avaCloudWallet() {
4607
4896
  }
4608
4897
 
4609
4898
  // src/providers/GaslessProvider.tsx
4610
- var import_react27 = require("react");
4899
+ var import_react28 = require("react");
4611
4900
  var import_jsx_runtime24 = require("react/jsx-runtime");
4612
4901
  function validateGaslessConfig(config) {
4613
4902
  if (!config || typeof config !== "object") {
@@ -4641,15 +4930,15 @@ function validateGaslessConfig(config) {
4641
4930
  }
4642
4931
  return null;
4643
4932
  }
4644
- var GaslessContext = (0, import_react27.createContext)(null);
4933
+ var GaslessContext = (0, import_react28.createContext)(null);
4645
4934
  function GaslessProvider({ children, config, fetchParams }) {
4646
- const [state, setState] = (0, import_react27.useState)({
4935
+ const [state, setState] = (0, import_react28.useState)({
4647
4936
  isLoading: false,
4648
4937
  error: null,
4649
4938
  config: null
4650
4939
  });
4651
4940
  const { authServiceUrl, environment } = useAvaCloudWallet();
4652
- (0, import_react27.useEffect)(() => {
4941
+ (0, import_react28.useEffect)(() => {
4653
4942
  if (config) {
4654
4943
  const validationError = validateGaslessConfig(config);
4655
4944
  if (validationError) {
@@ -4736,9 +5025,16 @@ function GaslessProvider({ children, config, fetchParams }) {
4736
5025
  }, [config, fetchParams, authServiceUrl, environment]);
4737
5026
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GaslessContext.Provider, { value: state, children });
4738
5027
  }
5028
+ function useGaslessConfig() {
5029
+ const ctx = (0, import_react28.useContext)(GaslessContext);
5030
+ if (!ctx) {
5031
+ throw new Error("useGaslessConfig must be used within a GaslessProvider");
5032
+ }
5033
+ return ctx;
5034
+ }
4739
5035
 
4740
5036
  // src/hooks/useGaslessTransaction.ts
4741
- var import_react28 = require("react");
5037
+ var import_react29 = require("react");
4742
5038
  var ethers = __toESM(require("ethers"));
4743
5039
  var import_axios = __toESM(require("axios"));
4744
5040
  var import_cubesigner_sdk6 = require("@cubist-labs/cubesigner-sdk");
@@ -4764,7 +5060,7 @@ var FORWARDER_GET_NONCE_ABI = [
4764
5060
  }
4765
5061
  ];
4766
5062
  function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContractAddress, abi: defaultAbi }) {
4767
- const [state, setState] = (0, import_react28.useState)({
5063
+ const [state, setState] = (0, import_react29.useState)({
4768
5064
  isLoading: false,
4769
5065
  error: null,
4770
5066
  txHash: null
@@ -4772,14 +5068,14 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4772
5068
  const config = gaslessConfig;
4773
5069
  const { wallet, cubistClient } = useAvaCloudWallet();
4774
5070
  useViem();
4775
- const reset = (0, import_react28.useCallback)(() => {
5071
+ const reset = (0, import_react29.useCallback)(() => {
4776
5072
  setState({
4777
5073
  isLoading: false,
4778
5074
  error: null,
4779
5075
  txHash: null
4780
5076
  });
4781
5077
  }, []);
4782
- const validateConfig = (0, import_react28.useCallback)((config2) => {
5078
+ const validateConfig = (0, import_react29.useCallback)((config2) => {
4783
5079
  if (!config2) {
4784
5080
  return "Gasless configuration is not available. Please ensure GaslessProvider is properly configured.";
4785
5081
  }
@@ -4813,7 +5109,7 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4813
5109
  }
4814
5110
  return null;
4815
5111
  }, []);
4816
- const sendGaslessTransaction = (0, import_react28.useCallback)(async ({
5112
+ const sendGaslessTransaction = (0, import_react29.useCallback)(async ({
4817
5113
  functionName,
4818
5114
  args = [],
4819
5115
  abi: overrideAbi,
@@ -4898,7 +5194,12 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4898
5194
  const suffixParts = config.suffix.match(/^(\w+)\s+(.+)\)$/);
4899
5195
  if (suffixParts) {
4900
5196
  const [, , suffixName] = suffixParts;
4901
- message[suffixName] = Buffer.from(config.suffix, "utf8");
5197
+ const encoder = new TextEncoder();
5198
+ const suffixBytes = encoder.encode(config.suffix);
5199
+ const paddedBytes = new Uint8Array(32);
5200
+ paddedBytes.set(suffixBytes.slice(0, 32));
5201
+ const hexString = Array.from(paddedBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
5202
+ message[suffixName] = "0x" + hexString;
4902
5203
  }
4903
5204
  }
4904
5205
  const domain = {
@@ -4907,12 +5208,22 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4907
5208
  chainId: (await provider.getNetwork()).chainId,
4908
5209
  verifyingContract: config.forwarderAddress
4909
5210
  };
4910
- const digest = ethers.utils._TypedDataEncoder.hash(domain, {
4911
- [config.requestType]: types[config.requestType]
4912
- }, message);
4913
5211
  const key = await cubistClient.org().getKeyByMaterialId(import_cubesigner_sdk6.Secp256k1.Evm, wallet.address);
4914
- const sigResp = await key.signBlob({
4915
- message_base64: Buffer.from(digest.slice(2), "hex").toString("base64")
5212
+ const sigResp = await key.signEip712({
5213
+ chain_id: domain.chainId,
5214
+ typed_data: {
5215
+ domain: {
5216
+ name: domain.name,
5217
+ version: domain.version,
5218
+ chainId: `0x${domain.chainId.toString(16)}`,
5219
+ verifyingContract: domain.verifyingContract
5220
+ },
5221
+ primaryType: config.requestType,
5222
+ types: {
5223
+ [config.requestType]: types[config.requestType]
5224
+ },
5225
+ message
5226
+ }
4916
5227
  });
4917
5228
  const signatureData = sigResp.data().signature;
4918
5229
  const signature = signatureData.startsWith("0x") ? signatureData : `0x${signatureData}`;
@@ -5003,6 +5314,7 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
5003
5314
  useAvaCloudWallet,
5004
5315
  useBlockchain,
5005
5316
  useChainId,
5317
+ useGaslessConfig,
5006
5318
  useGaslessTransaction,
5007
5319
  useGlacier,
5008
5320
  usePostMessage,