@avalabs/avacloud-waas-react 1.3.1 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,10 +93,11 @@ 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");
98
+ var import_penpal = require("penpal");
97
99
 
98
- // src/constants/storage.ts
100
+ // ../avacloud-waas-common/dist/constants/storage.js
99
101
  var OIDC_TOKEN_KEY = "avacloud-auth-oidc-token";
100
102
  var AUTH_TOKENS_KEY = "auth_tokens";
101
103
  var AUTH0_STORAGE_KEYS = {
@@ -107,26 +109,12 @@ var AUTH0_STORAGE_KEYS = {
107
109
  var CUBIST_USER_ID_KEY = "cubist_user_id";
108
110
  var ORG_CONFIG_CACHE_KEY = "avacloud-org-config-cache";
109
111
 
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({
112
+ // src/hooks/usePenpalAuth.ts
113
+ function usePenpalAuth({
125
114
  authServiceUrl,
126
115
  orgId,
127
116
  environment,
128
117
  iframe,
129
- isIframeReady,
130
118
  onAuthSuccess,
131
119
  onAuthError,
132
120
  onOidcReceived,
@@ -134,16 +122,13 @@ function usePostMessage({
134
122
  setIsAuthenticated,
135
123
  setUser,
136
124
  setIsLoading,
137
- setIsIframeReady,
138
- cubistClient
125
+ setIsIframeReady
139
126
  }) {
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);
127
+ const connectionRef = (0, import_react.useRef)(null);
128
+ const [authService, setAuthService] = (0, import_react.useState)(null);
129
+ const [isConnected, setIsConnected] = (0, import_react.useState)(false);
130
+ const isConnectedRef = (0, import_react.useRef)(false);
131
+ const hasCheckedAuthRef = (0, import_react.useRef)(false);
147
132
  const hasLoadedCacheRef = (0, import_react.useRef)(false);
148
133
  (0, import_react.useEffect)(() => {
149
134
  if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
@@ -164,233 +149,250 @@ function usePostMessage({
164
149
  }
165
150
  }
166
151
  }, [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}`
152
+ const parentMethods = {
153
+ onReady: () => {
154
+ console.log("[Penpal Parent] Iframe is ready");
155
+ setIsIframeReady(true);
156
+ },
157
+ onAuthStatusChange: (status) => {
158
+ var _a;
159
+ console.log("[Penpal Parent] Auth status changed:", status);
160
+ setIsAuthenticated(status.isAuthenticated);
161
+ if (status.user) {
162
+ const userInfo = {
163
+ email: status.user.email,
164
+ sub: status.user.sub,
165
+ configured_mfa: [],
166
+ displayName: status.user.nickname || status.user.name || ((_a = status.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
167
+ rawUserData: status.user
168
+ };
169
+ setUser(userInfo);
170
+ } else {
171
+ setUser(null);
172
+ }
173
+ if (status.orgConfig) {
174
+ onOrgConfigUpdate == null ? void 0 : onOrgConfigUpdate(status.orgConfig);
175
+ if (orgId) {
176
+ try {
177
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
178
+ const configWithTimestamp = {
179
+ ...status.orgConfig,
180
+ _timestamp: Date.now()
217
181
  };
182
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
183
+ } catch (error) {
218
184
  }
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
185
  }
233
186
  }
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;
187
+ if (status.isAuthenticated) {
188
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
241
189
  }
242
- if (event.origin !== new URL(authServiceUrl).origin) {
190
+ setIsLoading(false);
191
+ },
192
+ onError: (error) => {
193
+ console.error("[Penpal Parent] Error from iframe:", error);
194
+ if (error.message === "User not authenticated in iframe" || error.message === "Unknown error" || error.message.includes("OIDC user not found")) {
243
195
  return;
244
196
  }
245
- if (typeof ((_a = event.data) == null ? void 0 : _a.type) !== "string") {
197
+ onAuthError == null ? void 0 : onAuthError(new Error(error.message));
198
+ setIsLoading(false);
199
+ },
200
+ onWalletUpdate: (wallet) => {
201
+ console.log("[Penpal Parent] Wallet update:", wallet);
202
+ }
203
+ };
204
+ (0, import_react.useEffect)(() => {
205
+ if (!(iframe == null ? void 0 : iframe.contentWindow)) {
206
+ return;
207
+ }
208
+ let isCancelled = false;
209
+ const setupConnection = async (attempt = 1, maxAttempts = 3) => {
210
+ if (isCancelled) return;
211
+ if (isConnectedRef.current && connectionRef.current) {
212
+ console.log("[Penpal Parent] Already connected, skipping setup");
246
213
  return;
247
214
  }
248
- if (event.data.requestId && globalAuthState.processingMessageIds.has(event.data.requestId)) {
249
- return;
215
+ console.log(`[Penpal Parent] Setting up connection to iframe (attempt ${attempt}/${maxAttempts})...`);
216
+ if (connectionRef.current) {
217
+ connectionRef.current.destroy();
218
+ connectionRef.current = null;
219
+ setAuthService(null);
220
+ setIsConnected(false);
221
+ isConnectedRef.current = false;
250
222
  }
251
223
  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;
224
+ const authServiceOrigin = new URL(authServiceUrl).origin;
225
+ const messenger = new import_penpal.WindowMessenger({
226
+ remoteWindow: iframe.contentWindow,
227
+ allowedOrigins: [authServiceOrigin]
228
+ });
229
+ const connection = (0, import_penpal.connect)({
230
+ messenger,
231
+ methods: parentMethods,
232
+ timeout: 1e4
233
+ // 10 second connection timeout per attempt
234
+ });
235
+ connectionRef.current = connection;
236
+ const remote = await connection.promise;
237
+ if (isCancelled) {
238
+ connection.destroy();
239
+ return;
263
240
  }
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;
241
+ console.log("[Penpal Parent] Connected to auth service");
242
+ isConnectedRef.current = true;
243
+ setAuthService(remote);
244
+ setIsConnected(true);
245
+ setIsIframeReady(true);
246
+ } catch (error) {
247
+ if (isCancelled) return;
248
+ console.error(`[Penpal Parent] Failed to connect (attempt ${attempt}):`, error);
249
+ if (attempt < maxAttempts) {
250
+ console.log(`[Penpal Parent] Retrying in 1 second...`);
251
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
252
+ if (!isCancelled) {
253
+ await setupConnection(attempt + 1, maxAttempts);
350
254
  }
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;
255
+ } else {
256
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to connect to auth service"));
359
257
  }
360
- } finally {
361
- isHandlingMessageRef.current = false;
362
258
  }
363
259
  };
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
- ]);
260
+ setupConnection();
261
+ return () => {
262
+ isCancelled = true;
263
+ };
264
+ }, [iframe, authServiceUrl]);
381
265
  (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
266
+ if (isConnected && authService && !hasCheckedAuthRef.current) {
267
+ hasCheckedAuthRef.current = true;
268
+ authService.checkAuthStatus(orgId, environment).then((status) => {
269
+ console.log("[Penpal Parent] Initial auth status:", status);
270
+ parentMethods.onAuthStatusChange(status);
271
+ if (status.isAuthenticated) {
272
+ return authService.getOidc();
273
+ }
274
+ return null;
275
+ }).then((oidcResult) => {
276
+ if (oidcResult == null ? void 0 : oidcResult.idToken) {
277
+ onOidcReceived == null ? void 0 : onOidcReceived(oidcResult.idToken);
388
278
  }
279
+ }).catch((error) => {
280
+ console.error("[Penpal Parent] Error checking auth status:", error);
281
+ setIsLoading(false);
389
282
  });
390
283
  }
391
- }, [isIframeReady, iframe, sendMessage, orgId, environment]);
284
+ }, [isConnected, authService, orgId, environment]);
285
+ const login = (0, import_react.useCallback)(async (params) => {
286
+ var _a;
287
+ if (!authService) {
288
+ console.warn("[Penpal] Cannot login - not connected");
289
+ return;
290
+ }
291
+ try {
292
+ const result = await authService.login(params || {});
293
+ setIsAuthenticated(true);
294
+ if (result.user) {
295
+ const userInfo = {
296
+ email: result.user.email,
297
+ sub: result.user.sub,
298
+ configured_mfa: [],
299
+ displayName: result.user.nickname || result.user.name || ((_a = result.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
300
+ rawUserData: result.user
301
+ };
302
+ setUser(userInfo);
303
+ }
304
+ if (result.accessToken) {
305
+ onOidcReceived == null ? void 0 : onOidcReceived(result.accessToken);
306
+ }
307
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
308
+ return result;
309
+ } catch (error) {
310
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Login failed"));
311
+ throw error;
312
+ }
313
+ }, [authService, setIsAuthenticated, setUser, onOidcReceived, onAuthSuccess, onAuthError]);
314
+ const signup = (0, import_react.useCallback)(async (email, password) => {
315
+ var _a;
316
+ if (!authService) {
317
+ console.warn("[Penpal] Cannot signup - not connected");
318
+ return;
319
+ }
320
+ try {
321
+ const result = await authService.signup({ email, password });
322
+ setIsAuthenticated(true);
323
+ if (result.user) {
324
+ const userInfo = {
325
+ email: result.user.email,
326
+ sub: result.user.sub,
327
+ configured_mfa: [],
328
+ displayName: result.user.nickname || result.user.name || ((_a = result.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
329
+ rawUserData: result.user
330
+ };
331
+ setUser(userInfo);
332
+ }
333
+ if (result.accessToken) {
334
+ onOidcReceived == null ? void 0 : onOidcReceived(result.accessToken);
335
+ }
336
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
337
+ return result;
338
+ } catch (error) {
339
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Signup failed"));
340
+ throw error;
341
+ }
342
+ }, [authService, setIsAuthenticated, setUser, onOidcReceived, onAuthSuccess, onAuthError]);
343
+ const logout = (0, import_react.useCallback)(async () => {
344
+ if (!authService) {
345
+ console.warn("[Penpal] Cannot logout - not connected");
346
+ return;
347
+ }
348
+ try {
349
+ await authService.logout();
350
+ setIsAuthenticated(false);
351
+ setUser(null);
352
+ localStorage.removeItem(AUTH_TOKENS_KEY);
353
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
354
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
355
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ID_TOKEN);
356
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.EXPIRES_AT);
357
+ localStorage.removeItem(CUBIST_USER_ID_KEY);
358
+ sessionStorage.removeItem(OIDC_TOKEN_KEY);
359
+ } catch (error) {
360
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Logout failed"));
361
+ throw error;
362
+ }
363
+ }, [authService, setIsAuthenticated, setUser, onAuthError]);
364
+ const getOidc = (0, import_react.useCallback)(async () => {
365
+ if (!authService) {
366
+ console.warn("[Penpal] Cannot get OIDC - not connected");
367
+ return;
368
+ }
369
+ try {
370
+ return await authService.getOidc();
371
+ } catch (error) {
372
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to get OIDC token"));
373
+ throw error;
374
+ }
375
+ }, [authService, onAuthError]);
376
+ const checkAuthStatus = (0, import_react.useCallback)(async () => {
377
+ if (!authService) {
378
+ console.warn("[Penpal] Cannot check auth status - not connected");
379
+ return;
380
+ }
381
+ try {
382
+ return await authService.checkAuthStatus(orgId, environment);
383
+ } catch (error) {
384
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to check auth status"));
385
+ throw error;
386
+ }
387
+ }, [authService, orgId, environment, onAuthError]);
392
388
  return {
393
- sendMessage
389
+ authService,
390
+ isConnected,
391
+ login,
392
+ signup,
393
+ logout,
394
+ getOidc,
395
+ checkAuthStatus
394
396
  };
395
397
  }
396
398
 
@@ -1010,123 +1012,72 @@ function SignInContent({
1010
1012
  var import_jsx_runtime3 = require("react/jsx-runtime");
1011
1013
  function LoginModal({ open, onClose }) {
1012
1014
  var _a;
1013
- const { iframe, orgConfig, signup } = useAvaCloudWallet();
1015
+ const { orgConfig, signup, login, isAuthenticated } = useAvaCloudWallet();
1014
1016
  const [isSubmitting, setIsSubmitting] = (0, import_react3.useState)(false);
1015
1017
  const [error, setError] = (0, import_react3.useState)("");
1016
1018
  const timeoutIdRef = (0, import_react3.useRef)(null);
1017
- const signupInProgressRef = (0, import_react3.useRef)(false);
1018
- const lastSignupAttemptRef = (0, import_react3.useRef)(0);
1019
1019
  const socialLogins = (_a = orgConfig == null ? void 0 : orgConfig.adminPortalSettings) == null ? void 0 : _a.socialLogins;
1020
1020
  (0, import_react3.useEffect)(() => {
1021
- let requestInProgress = false;
1022
- const handleMessage = (event) => {
1023
- if (!event.data || typeof event.data.type !== "string") {
1024
- return;
1021
+ if (isAuthenticated && open) {
1022
+ setIsSubmitting(false);
1023
+ if (timeoutIdRef.current) {
1024
+ clearTimeout(timeoutIdRef.current);
1025
+ timeoutIdRef.current = null;
1025
1026
  }
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;
1027
+ onClose();
1028
+ }
1029
+ }, [isAuthenticated, open, onClose]);
1030
+ (0, import_react3.useEffect)(() => {
1031
+ if (!open) {
1032
+ setIsSubmitting(false);
1033
+ setError("");
1034
+ if (timeoutIdRef.current) {
1035
+ clearTimeout(timeoutIdRef.current);
1036
+ timeoutIdRef.current = null;
1049
1037
  }
1050
- };
1051
- window.addEventListener("message", handleMessage);
1038
+ }
1039
+ }, [open]);
1040
+ (0, import_react3.useEffect)(() => {
1052
1041
  return () => {
1053
- window.removeEventListener("message", handleMessage);
1054
1042
  if (timeoutIdRef.current) {
1055
1043
  clearTimeout(timeoutIdRef.current);
1056
1044
  timeoutIdRef.current = null;
1057
1045
  }
1058
1046
  };
1059
- }, [onClose]);
1060
- const handleProviderLogin = (provider) => {
1061
- var _a2;
1047
+ }, []);
1048
+ const handleProviderLogin = (0, import_react3.useCallback)((provider) => {
1062
1049
  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;
1050
+ setIsSubmitting(true);
1051
+ login({ connection: provider });
1052
+ }, [login]);
1053
+ const handleEmailLogin = (0, import_react3.useCallback)((email, password) => {
1076
1054
  setError("");
1077
1055
  setIsSubmitting(true);
1078
- if (!iframe) {
1079
- setError("Authentication service not available");
1080
- setIsSubmitting(false);
1081
- return;
1082
- }
1083
1056
  if (timeoutIdRef.current) {
1084
1057
  clearTimeout(timeoutIdRef.current);
1085
1058
  timeoutIdRef.current = null;
1086
1059
  }
1087
- (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
1088
- type: "LOGIN_REQUEST",
1089
- email,
1090
- password,
1091
- requestId: `login-${Date.now()}`
1092
- }, "*");
1060
+ login({ email, password });
1093
1061
  timeoutIdRef.current = setTimeout(() => {
1094
1062
  setError("Authentication service timed out");
1095
1063
  setIsSubmitting(false);
1096
1064
  timeoutIdRef.current = null;
1097
1065
  }, 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;
1066
+ }, [login]);
1067
+ const handleEmailSignup = (0, import_react3.useCallback)((email, password) => {
1108
1068
  setError("");
1109
1069
  setIsSubmitting(true);
1110
- signupInProgressRef.current = true;
1111
1070
  if (timeoutIdRef.current) {
1112
1071
  clearTimeout(timeoutIdRef.current);
1113
1072
  timeoutIdRef.current = null;
1114
1073
  }
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
- }
1074
+ signup(email, password);
1123
1075
  timeoutIdRef.current = setTimeout(() => {
1124
1076
  setError("Authentication service timed out");
1125
1077
  setIsSubmitting(false);
1126
- signupInProgressRef.current = false;
1127
1078
  timeoutIdRef.current = null;
1128
1079
  }, 1e4);
1129
- };
1080
+ }, [signup]);
1130
1081
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1131
1082
  import_core_k2_components3.Dialog,
1132
1083
  {
@@ -1593,7 +1544,7 @@ function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1593
1544
  if (darkMode !== void 0 && darkMode !== isDarkMode) {
1594
1545
  setIsDarkMode(darkMode);
1595
1546
  }
1596
- }, [darkMode]);
1547
+ }, [darkMode, isDarkMode]);
1597
1548
  const toggleTheme = (0, import_react8.useCallback)(() => {
1598
1549
  const newDarkMode = !isDarkMode;
1599
1550
  setIsDarkMode(newDarkMode);
@@ -1602,6 +1553,18 @@ function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1602
1553
  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
1554
  }
1604
1555
 
1556
+ // src/constants/storage.ts
1557
+ var OIDC_TOKEN_KEY2 = "avacloud-auth-oidc-token";
1558
+ var AUTH_TOKENS_KEY2 = "auth_tokens";
1559
+ var AUTH0_STORAGE_KEYS2 = {
1560
+ IS_AUTHENTICATED: "auth0.is.authenticated",
1561
+ ACCESS_TOKEN: "auth0.access_token",
1562
+ ID_TOKEN: "auth0.id_token",
1563
+ EXPIRES_AT: "auth0.expires_at"
1564
+ };
1565
+ var CUBIST_USER_ID_KEY2 = "cubist_user_id";
1566
+ var ORG_CONFIG_CACHE_KEY2 = "avacloud-org-config-cache";
1567
+
1605
1568
  // src/AvaCloudWalletProvider.tsx
1606
1569
  var import_jsx_runtime7 = require("react/jsx-runtime");
1607
1570
  var AvaCloudWalletContext = (0, import_react9.createContext)(void 0);
@@ -1632,6 +1595,23 @@ function ViemProviderWrapper({ children, chainId }) {
1632
1595
  }
1633
1596
  );
1634
1597
  }
1598
+ function normalizeOrgConfig(config) {
1599
+ if (!config) {
1600
+ return null;
1601
+ }
1602
+ const typedConfig = config;
1603
+ const explicitWalletProvider = typeof typedConfig.walletProviderOrgID === "string" ? typedConfig.walletProviderOrgID.trim() : "";
1604
+ const cubistOrgId = typeof typedConfig.cubistOrgId === "string" ? typedConfig.cubistOrgId.trim() : "";
1605
+ const resolvedOrgId = explicitWalletProvider || cubistOrgId;
1606
+ if (!resolvedOrgId) {
1607
+ return typedConfig;
1608
+ }
1609
+ return {
1610
+ ...typedConfig,
1611
+ walletProviderOrgID: resolvedOrgId,
1612
+ cubistOrgId: cubistOrgId || resolvedOrgId
1613
+ };
1614
+ }
1635
1615
  function AvaCloudWalletProvider({
1636
1616
  children,
1637
1617
  orgId,
@@ -1672,7 +1652,7 @@ function AvaCloudWalletProvider({
1672
1652
  const [wallet, setWallet] = (0, import_react9.useState)({ address: null });
1673
1653
  const [orgConfig, setOrgConfig] = (0, import_react9.useState)(null);
1674
1654
  const [iframe, setIframe] = (0, import_react9.useState)(null);
1675
- const [isIframeReady, setIsIframeReady] = (0, import_react9.useState)(false);
1655
+ const [_isIframeReady, setIsIframeReady] = (0, import_react9.useState)(false);
1676
1656
  const [cubistClient, setCubistClient] = (0, import_react9.useState)(null);
1677
1657
  const [cubistError, setCubistError] = (0, import_react9.useState)(null);
1678
1658
  const [pendingOidcToken, setPendingOidcToken] = (0, import_react9.useState)(null);
@@ -1719,7 +1699,7 @@ function AvaCloudWalletProvider({
1719
1699
  if (oidcToken) {
1720
1700
  accessToken = oidcToken;
1721
1701
  } else {
1722
- const tokens = localStorage.getItem(AUTH_TOKENS_KEY);
1702
+ const tokens = localStorage.getItem(AUTH_TOKENS_KEY2);
1723
1703
  if (!tokens) {
1724
1704
  throw new Error("No authentication tokens found in localStorage");
1725
1705
  }
@@ -1762,8 +1742,8 @@ function AvaCloudWalletProvider({
1762
1742
  });
1763
1743
  }
1764
1744
  } catch (error) {
1765
- localStorage.removeItem(AUTH_TOKENS_KEY);
1766
- localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1745
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
1746
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1767
1747
  setIsAuthenticated(false);
1768
1748
  setUser(null);
1769
1749
  setCubistClient(null);
@@ -1777,12 +1757,17 @@ function AvaCloudWalletProvider({
1777
1757
  setIsCubistLoading(false);
1778
1758
  }
1779
1759
  }, [wallet, onWalletUpdate, onAuthError, getWalletInfo, orgConfig, environment]);
1780
- const { sendMessage } = usePostMessage({
1760
+ const {
1761
+ authService,
1762
+ isConnected,
1763
+ login: penpalLogin,
1764
+ signup: penpalSignup,
1765
+ logout: penpalLogout
1766
+ } = usePenpalAuth({
1781
1767
  authServiceUrl,
1782
1768
  orgId,
1783
1769
  environment,
1784
1770
  iframe,
1785
- isIframeReady,
1786
1771
  onAuthSuccess: () => {
1787
1772
  if (user) {
1788
1773
  if (wallet.address) {
@@ -1792,8 +1777,7 @@ function AvaCloudWalletProvider({
1792
1777
  },
1793
1778
  onAuthError: (error) => {
1794
1779
  const errorMessage = (error == null ? void 0 : error.message) || "";
1795
- if (errorMessage === "User not authenticated in iframe" || errorMessage === "Unknown error" || // Generic error that often appears during signup
1796
- errorMessage.includes("OIDC user not found")) {
1780
+ if (errorMessage === "User not authenticated in iframe" || errorMessage === "Unknown error" || errorMessage.includes("OIDC user not found")) {
1797
1781
  return;
1798
1782
  }
1799
1783
  setIsCubistLoading(false);
@@ -1819,76 +1803,78 @@ function AvaCloudWalletProvider({
1819
1803
  };
1820
1804
  },
1821
1805
  onOrgConfigUpdate: (config) => {
1822
- setOrgConfig(config);
1806
+ setOrgConfig(normalizeOrgConfig(config));
1823
1807
  },
1824
1808
  setIsAuthenticated,
1825
1809
  setUser,
1826
- setIsLoading: (isLoading2) => {
1827
- setIsLoading(isLoading2);
1810
+ setIsLoading: (loading) => {
1811
+ setIsLoading(loading);
1828
1812
  },
1829
- setIsIframeReady,
1830
- wallet,
1831
- cubistClient
1813
+ setIsIframeReady
1832
1814
  });
1833
- const login = (0, import_react9.useCallback)(() => {
1834
- if (iframe == null ? void 0 : iframe.contentWindow) {
1835
- setIsCubistLoading(true);
1836
- sendMessage({ type: "LOGIN_REQUEST" });
1815
+ const login = (0, import_react9.useCallback)((params) => {
1816
+ if (isConnected) {
1817
+ const isEmailLogin = (params == null ? void 0 : params.email) && (params == null ? void 0 : params.password);
1818
+ if (isEmailLogin) {
1819
+ setIsCubistLoading(true);
1820
+ }
1821
+ penpalLogin(params).catch((error) => {
1822
+ setIsCubistLoading(false);
1823
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Login failed"));
1824
+ });
1837
1825
  }
1838
- }, [iframe, sendMessage]);
1826
+ }, [isConnected, penpalLogin, onAuthError]);
1839
1827
  const signup = (0, import_react9.useCallback)((email, password) => {
1840
- if (iframe == null ? void 0 : iframe.contentWindow) {
1828
+ if (isConnected) {
1841
1829
  setIsCubistLoading(true);
1842
- sendMessage({
1843
- type: "SIGNUP_REQUEST",
1844
- payload: {
1845
- email,
1846
- password
1847
- },
1848
- requestId: `signup-${Date.now()}`
1830
+ penpalSignup(email, password).catch((error) => {
1831
+ setIsCubistLoading(false);
1832
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Signup failed"));
1849
1833
  });
1850
1834
  }
1851
- }, [iframe, sendMessage]);
1835
+ }, [isConnected, penpalSignup, onAuthError]);
1852
1836
  const logout = (0, import_react9.useCallback)(() => {
1853
- sendMessage({ type: "LOGOUT_REQUEST" });
1837
+ penpalLogout().catch((error) => {
1838
+ console.error("Logout error:", error);
1839
+ });
1854
1840
  setUser(null);
1855
1841
  setWallet({ address: null });
1856
1842
  setIsAuthenticated(false);
1857
- localStorage.removeItem(AUTH_TOKENS_KEY);
1858
- localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1859
- localStorage.removeItem(AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
1860
- localStorage.removeItem(AUTH0_STORAGE_KEYS.ID_TOKEN);
1861
- localStorage.removeItem(AUTH0_STORAGE_KEYS.EXPIRES_AT);
1862
- localStorage.removeItem(CUBIST_USER_ID_KEY);
1843
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
1844
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1845
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.ACCESS_TOKEN);
1846
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.ID_TOKEN);
1847
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.EXPIRES_AT);
1848
+ localStorage.removeItem(CUBIST_USER_ID_KEY2);
1863
1849
  if (orgId) {
1864
- const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${env}`;
1850
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${env}`;
1865
1851
  localStorage.removeItem(cachedConfigKey);
1866
1852
  }
1867
- sessionStorage.removeItem(OIDC_TOKEN_KEY);
1853
+ sessionStorage.removeItem(OIDC_TOKEN_KEY2);
1868
1854
  setCubistClient(null);
1869
1855
  setCubistError(null);
1870
1856
  setPendingOidcToken(null);
1871
- }, [sendMessage, orgId, env]);
1857
+ }, [penpalLogout, orgId, env]);
1872
1858
  const addAccount = (0, import_react9.useCallback)(async (accountIndex) => {
1873
1859
  if (!isAuthenticated || !user || !wallet.mnemonicId) {
1874
1860
  throw new Error("User must be authenticated and have a wallet to add an account");
1875
1861
  }
1862
+ if (!authService) {
1863
+ throw new Error("Auth service not connected");
1864
+ }
1876
1865
  const path = getDerivationPath("EVM" /* EVM */, accountIndex);
1877
- sendMessage({
1878
- type: "ADD_ACCOUNT",
1879
- payload: {
1880
- accountIndex,
1881
- mnemonicId: wallet.mnemonicId,
1882
- derivationPath: path,
1883
- identityProof: {
1884
- email: user.email,
1885
- displayName: user.displayName,
1886
- sub: user.sub,
1887
- configured_mfa: user.configured_mfa
1888
- }
1866
+ await authService.addAccount({
1867
+ accountIndex,
1868
+ mnemonicId: wallet.mnemonicId,
1869
+ derivationPath: path,
1870
+ identityProof: {
1871
+ email: user.email,
1872
+ displayName: user.displayName,
1873
+ sub: user.sub,
1874
+ configured_mfa: user.configured_mfa
1889
1875
  }
1890
1876
  });
1891
- }, [sendMessage, isAuthenticated, user, wallet.mnemonicId]);
1877
+ }, [authService, isAuthenticated, user, wallet.mnemonicId]);
1892
1878
  (0, import_react9.useEffect)(() => {
1893
1879
  const hasOrgConfig = !!(orgConfig == null ? void 0 : orgConfig.walletProviderOrgID);
1894
1880
  const hasOidcToken = !!pendingOidcToken;
@@ -1938,20 +1924,20 @@ function AvaCloudWalletProvider({
1938
1924
  if (typeof window === "undefined") {
1939
1925
  return;
1940
1926
  }
1941
- const isAuthenticatedInStorage = localStorage.getItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED) === "true";
1927
+ const isAuthenticatedInStorage = localStorage.getItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED) === "true";
1942
1928
  if (!isAuthenticatedInStorage) {
1943
1929
  return;
1944
1930
  }
1945
- const existingOidcToken = sessionStorage.getItem(OIDC_TOKEN_KEY);
1931
+ const existingOidcToken = sessionStorage.getItem(OIDC_TOKEN_KEY2);
1946
1932
  if (existingOidcToken) {
1947
1933
  setPendingOidcToken(existingOidcToken);
1948
1934
  } else {
1949
1935
  try {
1950
- const tokensJson = localStorage.getItem(AUTH_TOKENS_KEY);
1936
+ const tokensJson = localStorage.getItem(AUTH_TOKENS_KEY2);
1951
1937
  if (tokensJson) {
1952
1938
  const tokens = JSON.parse(tokensJson);
1953
1939
  if (tokens.access_token) {
1954
- sessionStorage.setItem(OIDC_TOKEN_KEY, tokens.access_token);
1940
+ sessionStorage.setItem(OIDC_TOKEN_KEY2, tokens.access_token);
1955
1941
  setPendingOidcToken(tokens.access_token);
1956
1942
  }
1957
1943
  }
@@ -3287,32 +3273,27 @@ var import_react16 = require("react");
3287
3273
  var import_core_k2_components11 = require("@avalabs/core-k2-components");
3288
3274
  var import_jsx_runtime13 = require("react/jsx-runtime");
3289
3275
  function ExportView({ onBack }) {
3290
- const { wallet, iframe } = useAvaCloudWallet();
3291
- const [showKey, setShowKey] = (0, import_react16.useState)(false);
3276
+ const { wallet } = useAvaCloudWallet();
3277
+ const [showKey, _setShowKey] = (0, import_react16.useState)(false);
3292
3278
  const [copied, setCopied] = (0, import_react16.useState)(false);
3293
- const [privateKey, setPrivateKey] = (0, import_react16.useState)(null);
3279
+ const [privateKey, _setPrivateKey] = (0, import_react16.useState)(null);
3294
3280
  const [error, setError] = (0, import_react16.useState)(null);
3295
- const handleExport = async () => {
3296
- if (!(iframe == null ? void 0 : iframe.contentWindow)) return;
3297
- try {
3298
- iframe.contentWindow.postMessage({
3299
- type: "EXPORT_PRIVATE_KEY",
3300
- payload: {
3301
- address: wallet.address
3302
- }
3303
- }, "*");
3304
- const handleResponse = (event) => {
3305
- if (event.data.type === "EXPORT_PRIVATE_KEY_RESPONSE") {
3306
- setPrivateKey(event.data.payload.privateKey);
3307
- setShowKey(true);
3308
- window.removeEventListener("message", handleResponse);
3309
- }
3310
- };
3311
- window.addEventListener("message", handleResponse);
3281
+ const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
3282
+ const handleExport = (0, import_react16.useCallback)(async () => {
3283
+ if (!wallet.address) {
3284
+ setError("No wallet address available");
3285
+ return;
3286
+ }
3287
+ setIsLoading(true);
3288
+ setError(null);
3289
+ try {
3290
+ setError("Private key export is not yet available. Please use the wallet provider directly.");
3312
3291
  } catch (err) {
3313
3292
  setError("Failed to export private key. Please try again.");
3293
+ } finally {
3294
+ setIsLoading(false);
3314
3295
  }
3315
- };
3296
+ }, [wallet.address]);
3316
3297
  const handleCopy = () => {
3317
3298
  if (privateKey) {
3318
3299
  navigator.clipboard.writeText(privateKey);
@@ -3333,8 +3314,9 @@ function ExportView({ onBack }) {
3333
3314
  variant: "contained",
3334
3315
  color: "warning",
3335
3316
  onClick: handleExport,
3317
+ disabled: isLoading,
3336
3318
  sx: { mb: 2 },
3337
- children: "Show Private Key"
3319
+ children: isLoading ? "Loading..." : "Show Private Key"
3338
3320
  }
3339
3321
  ) : /* @__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: {
3340
3322
  display: "flex",
@@ -4277,134 +4259,422 @@ function WalletButton({
4277
4259
  },
4278
4260
  children: displayAddress
4279
4261
  }
4280
- ),
4281
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4282
- import_core_k2_components19.IconButton,
4283
- {
4284
- size: "small",
4285
- onClick: handleCopy,
4286
- sx: { color: "text.secondary" },
4287
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core_k2_components19.CopyIcon, {})
4262
+ ),
4263
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4264
+ import_core_k2_components19.IconButton,
4265
+ {
4266
+ size: "small",
4267
+ onClick: handleCopy,
4268
+ sx: { color: "text.secondary" },
4269
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core_k2_components19.CopyIcon, {})
4270
+ }
4271
+ )
4272
+ ] })
4273
+ ]
4274
+ }
4275
+ ),
4276
+ isModalOpen && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(WalletCard, { onClose: handleClose })
4277
+ ] });
4278
+ }
4279
+
4280
+ // src/components/WalletDisplay.tsx
4281
+ var import_react23 = require("react");
4282
+ var import_jsx_runtime22 = require("react/jsx-runtime");
4283
+ function WalletDisplay({
4284
+ className = "",
4285
+ truncateAddress = true,
4286
+ showAddAccount = true
4287
+ }) {
4288
+ const { wallet, addAccount, isAuthenticated } = useAvaCloudWallet();
4289
+ const [isAdding, setIsAdding] = (0, import_react23.useState)(false);
4290
+ const [accountIndex, setAccountIndex] = (0, import_react23.useState)(0);
4291
+ if (!isAuthenticated || !wallet.address) {
4292
+ return null;
4293
+ }
4294
+ const displayAddress = truncateAddress ? `${wallet.address.slice(0, 6)}...${wallet.address.slice(-4)}` : wallet.address;
4295
+ const handleAddAccount = async () => {
4296
+ try {
4297
+ setIsAdding(true);
4298
+ await addAccount(accountIndex);
4299
+ setAccountIndex((prev) => prev + 1);
4300
+ } catch (error) {
4301
+ console.error("Failed to add account:", error);
4302
+ } finally {
4303
+ setIsAdding(false);
4304
+ }
4305
+ };
4306
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `space-y-4 ${className}`, children: [
4307
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "bg-gray-50 rounded-lg p-4", children: [
4308
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-sm text-gray-500", children: "Wallet Address" }),
4309
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-1 font-mono text-sm break-all", children: displayAddress })
4310
+ ] }),
4311
+ showAddAccount && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4312
+ "button",
4313
+ {
4314
+ type: "button",
4315
+ onClick: handleAddAccount,
4316
+ disabled: isAdding,
4317
+ 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",
4318
+ children: isAdding ? "Adding Account..." : "Add Account"
4319
+ }
4320
+ )
4321
+ ] });
4322
+ }
4323
+
4324
+ // src/components/UserProfile.tsx
4325
+ var import_jsx_runtime23 = require("react/jsx-runtime");
4326
+ function UserProfile({
4327
+ className = "",
4328
+ showLogout = true
4329
+ }) {
4330
+ const { user, logout, isAuthenticated } = useAvaCloudWallet();
4331
+ if (!isAuthenticated || !user) {
4332
+ return null;
4333
+ }
4334
+ 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: [
4335
+ /* @__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" }) }),
4336
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "border-t border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("dl", { children: [
4337
+ /* @__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: [
4338
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { className: "text-sm font-medium text-gray-500", children: "Display Name" }),
4339
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.displayName })
4340
+ ] }),
4341
+ 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: [
4342
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { className: "text-sm font-medium text-gray-500", children: "Email address" }),
4343
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.email })
4344
+ ] }),
4345
+ user.configured_mfa && user.configured_mfa.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
4346
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-sm font-medium text-gray-500", children: "MFA Methods" }),
4347
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-1 space-y-1", children: user.configured_mfa.map((method) => {
4348
+ const mfaMethod = typeof method === "string" ? { type: method } : method;
4349
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4350
+ "div",
4351
+ {
4352
+ className: "text-sm text-gray-900",
4353
+ children: mfaMethod.type === "totp" ? "Authenticator App" : mfaMethod.name
4354
+ },
4355
+ mfaMethod.type === "fido" ? mfaMethod.id : `totp-${mfaMethod.type}`
4356
+ );
4357
+ }) })
4358
+ ] })
4359
+ ] }) }),
4360
+ showLogout && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4361
+ "button",
4362
+ {
4363
+ type: "button",
4364
+ onClick: logout,
4365
+ 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",
4366
+ children: "Sign Out"
4367
+ }
4368
+ ) })
4369
+ ] }) });
4370
+ }
4371
+
4372
+ // src/hooks/usePostMessage.ts
4373
+ var import_react24 = require("react");
4374
+ var globalAuthState = {
4375
+ signupInProgress: false,
4376
+ loginInProgress: false,
4377
+ lastSignupTimestamp: 0,
4378
+ lastLoginTimestamp: 0,
4379
+ processingMessageIds: /* @__PURE__ */ new Set()
4380
+ };
4381
+ function cleanupProcessedMessageIds() {
4382
+ if (globalAuthState.processingMessageIds.size > 100) {
4383
+ const messageIds = Array.from(globalAuthState.processingMessageIds);
4384
+ globalAuthState.processingMessageIds = new Set(messageIds.slice(-50));
4385
+ }
4386
+ }
4387
+ function usePostMessage({
4388
+ authServiceUrl,
4389
+ orgId,
4390
+ environment,
4391
+ iframe,
4392
+ isIframeReady,
4393
+ onAuthSuccess,
4394
+ onAuthError,
4395
+ onOidcReceived,
4396
+ onOrgConfigUpdate,
4397
+ setIsAuthenticated,
4398
+ setUser,
4399
+ setIsLoading,
4400
+ setIsIframeReady,
4401
+ cubistClient
4402
+ }) {
4403
+ const lastAuthStateRef = (0, import_react24.useRef)({
4404
+ isAuthenticated: false,
4405
+ userId: null,
4406
+ lastUpdateTime: 0
4407
+ });
4408
+ const hasRequestedOidcRef = (0, import_react24.useRef)(false);
4409
+ const isHandlingMessageRef = (0, import_react24.useRef)(false);
4410
+ const hasLoadedCacheRef = (0, import_react24.useRef)(false);
4411
+ (0, import_react24.useEffect)(() => {
4412
+ if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
4413
+ hasLoadedCacheRef.current = true;
4414
+ try {
4415
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${environment}`;
4416
+ const cachedConfigJson = localStorage.getItem(cachedConfigKey);
4417
+ if (cachedConfigJson) {
4418
+ const cachedConfig = JSON.parse(cachedConfigJson);
4419
+ const timestamp = cachedConfig._timestamp || 0;
4420
+ const isExpired = Date.now() - timestamp > 30 * 60 * 1e3;
4421
+ if (!isExpired) {
4422
+ const { _timestamp, ...configWithoutTimestamp } = cachedConfig;
4423
+ onOrgConfigUpdate(configWithoutTimestamp);
4424
+ }
4425
+ }
4426
+ } catch (error) {
4427
+ }
4428
+ }
4429
+ }, [orgId, environment, onOrgConfigUpdate]);
4430
+ const sendMessage = (0, import_react24.useCallback)((message) => {
4431
+ if (iframe == null ? void 0 : iframe.contentWindow) {
4432
+ try {
4433
+ if (message.type === "SIGNUP_REQUEST") {
4434
+ if (globalAuthState.signupInProgress) {
4435
+ return;
4436
+ }
4437
+ const now = Date.now();
4438
+ if (now - globalAuthState.lastSignupTimestamp < 3e3) {
4439
+ return;
4440
+ }
4441
+ globalAuthState.signupInProgress = true;
4442
+ globalAuthState.lastSignupTimestamp = now;
4443
+ let finalMessage = message;
4444
+ if (!message.requestId) {
4445
+ finalMessage = {
4446
+ ...message,
4447
+ requestId: `signup-${now}`
4448
+ };
4449
+ }
4450
+ let messageToSend = finalMessage;
4451
+ if (finalMessage.payload && typeof finalMessage.payload.email === "string" && typeof finalMessage.payload.password === "string") {
4452
+ messageToSend = {
4453
+ type: "SIGNUP_REQUEST",
4454
+ email: finalMessage.payload.email,
4455
+ password: finalMessage.payload.password,
4456
+ requestId: finalMessage.requestId || `signup-${now}`
4457
+ };
4458
+ }
4459
+ if ("requestId" in messageToSend && messageToSend.requestId) {
4460
+ globalAuthState.processingMessageIds.add(messageToSend.requestId);
4461
+ }
4462
+ iframe.contentWindow.postMessage(messageToSend, authServiceUrl);
4463
+ return;
4464
+ }
4465
+ if (message.type === "LOGIN_REQUEST") {
4466
+ if (globalAuthState.loginInProgress) {
4467
+ return;
4468
+ }
4469
+ const now = Date.now();
4470
+ if (now - globalAuthState.lastLoginTimestamp < 3e3) {
4471
+ return;
4472
+ }
4473
+ globalAuthState.loginInProgress = true;
4474
+ globalAuthState.lastLoginTimestamp = now;
4475
+ let finalMessage = message;
4476
+ if (!message.requestId) {
4477
+ finalMessage = {
4478
+ ...message,
4479
+ requestId: `login-${now}`
4480
+ };
4481
+ }
4482
+ if (finalMessage.requestId) {
4483
+ globalAuthState.processingMessageIds.add(finalMessage.requestId);
4484
+ }
4485
+ iframe.contentWindow.postMessage(finalMessage, authServiceUrl);
4486
+ return;
4487
+ }
4488
+ iframe.contentWindow.postMessage(message, authServiceUrl);
4489
+ } catch (error) {
4490
+ if (message.type === "SIGNUP_REQUEST") {
4491
+ globalAuthState.signupInProgress = false;
4492
+ }
4493
+ if (message.type === "LOGIN_REQUEST") {
4494
+ globalAuthState.loginInProgress = false;
4495
+ }
4496
+ }
4497
+ }
4498
+ }, [iframe, authServiceUrl]);
4499
+ (0, import_react24.useEffect)(() => {
4500
+ const handleMessage = async (event) => {
4501
+ var _a, _b, _c, _d, _e, _f, _g;
4502
+ if (isHandlingMessageRef.current) {
4503
+ return;
4504
+ }
4505
+ if (event.origin !== new URL(authServiceUrl).origin) {
4506
+ return;
4507
+ }
4508
+ if (typeof ((_a = event.data) == null ? void 0 : _a.type) !== "string") {
4509
+ return;
4510
+ }
4511
+ if (event.data.requestId && globalAuthState.processingMessageIds.has(event.data.requestId)) {
4512
+ return;
4513
+ }
4514
+ try {
4515
+ isHandlingMessageRef.current = true;
4516
+ if (event.data.type === "ERROR") {
4517
+ globalAuthState.signupInProgress = false;
4518
+ globalAuthState.loginInProgress = false;
4519
+ } else if (event.data.type === "AUTH_STATUS" && event.data.isAuthenticated) {
4520
+ globalAuthState.signupInProgress = false;
4521
+ globalAuthState.loginInProgress = false;
4522
+ cleanupProcessedMessageIds();
4523
+ } else if (event.data.type === "RECEIVE_OIDC") {
4524
+ globalAuthState.signupInProgress = false;
4525
+ globalAuthState.loginInProgress = false;
4526
+ }
4527
+ switch (event.data.type) {
4528
+ case "IFRAME_READY":
4529
+ setIsIframeReady(true);
4530
+ break;
4531
+ case "RECEIVE_OIDC":
4532
+ if (typeof ((_b = event.data.payload) == null ? void 0 : _b.idToken) === "string") {
4533
+ const oidcToken = event.data.payload.idToken;
4534
+ hasRequestedOidcRef.current = false;
4535
+ onOidcReceived == null ? void 0 : onOidcReceived(oidcToken);
4536
+ } else {
4537
+ hasRequestedOidcRef.current = false;
4538
+ }
4539
+ break;
4540
+ case "AUTH_STATUS": {
4541
+ const newIsAuthenticated = !!event.data.isAuthenticated;
4542
+ const newUserId = (_d = (_c = event.data.user) == null ? void 0 : _c.sub) != null ? _d : null;
4543
+ const now = Date.now();
4544
+ if (now - lastAuthStateRef.current.lastUpdateTime < 500) {
4545
+ return;
4546
+ }
4547
+ const authStateChanged = lastAuthStateRef.current.isAuthenticated !== newIsAuthenticated || lastAuthStateRef.current.userId !== newUserId;
4548
+ if (authStateChanged) {
4549
+ setIsAuthenticated(newIsAuthenticated);
4550
+ if (event.data.user) {
4551
+ const userInfo = {
4552
+ email: event.data.user.email,
4553
+ sub: event.data.user.sub,
4554
+ configured_mfa: [],
4555
+ displayName: event.data.user.nickname || event.data.user.name || ((_e = event.data.user.email) == null ? void 0 : _e.split("@")[0]) || "User",
4556
+ rawUserData: event.data.user
4557
+ };
4558
+ setUser(userInfo);
4559
+ if (newIsAuthenticated && !cubistClient && !hasRequestedOidcRef.current) {
4560
+ hasRequestedOidcRef.current = true;
4561
+ sendMessage({ type: "GET_OIDC" });
4562
+ return;
4563
+ }
4564
+ } else {
4565
+ setUser(null);
4566
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
4567
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
4568
+ sessionStorage.removeItem(OIDC_TOKEN_KEY2);
4569
+ }
4570
+ lastAuthStateRef.current = {
4571
+ isAuthenticated: newIsAuthenticated,
4572
+ userId: newUserId,
4573
+ lastUpdateTime: now
4574
+ };
4575
+ if (newIsAuthenticated && event.data.user) {
4576
+ if (!hasRequestedOidcRef.current) {
4577
+ if (event.data.tokens) {
4578
+ localStorage.setItem(AUTH_TOKENS_KEY2, JSON.stringify(event.data.tokens));
4579
+ }
4580
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
4581
+ }
4288
4582
  }
4289
- )
4290
- ] })
4291
- ]
4583
+ }
4584
+ if (event.data.orgConfig && onOrgConfigUpdate) {
4585
+ onOrgConfigUpdate(event.data.orgConfig);
4586
+ if (orgId) {
4587
+ try {
4588
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${environment}`;
4589
+ const configWithTimestamp = {
4590
+ ...event.data.orgConfig,
4591
+ _timestamp: Date.now()
4592
+ };
4593
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
4594
+ } catch (error) {
4595
+ }
4596
+ }
4597
+ }
4598
+ if (!hasRequestedOidcRef.current) {
4599
+ setIsLoading(false);
4600
+ }
4601
+ break;
4602
+ }
4603
+ case "REGISTER_SUCCESS": {
4604
+ const userId = (_f = event.data.payload) == null ? void 0 : _f.userId;
4605
+ if (userId) {
4606
+ localStorage.setItem(CUBIST_USER_ID_KEY2, userId);
4607
+ if (!hasRequestedOidcRef.current) {
4608
+ hasRequestedOidcRef.current = true;
4609
+ sendMessage({ type: "GET_OIDC" });
4610
+ }
4611
+ }
4612
+ break;
4613
+ }
4614
+ case "ERROR":
4615
+ if (event.data.error === "User not authenticated in iframe") {
4616
+ isHandlingMessageRef.current = false;
4617
+ return;
4618
+ }
4619
+ onAuthError == null ? void 0 : onAuthError(new Error((_g = event.data.error) != null ? _g : "Unknown error"));
4620
+ setIsLoading(false);
4621
+ break;
4622
+ }
4623
+ } finally {
4624
+ isHandlingMessageRef.current = false;
4292
4625
  }
4293
- ),
4294
- isModalOpen && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(WalletCard, { onClose: handleClose })
4295
- ] });
4296
- }
4297
-
4298
- // src/components/WalletDisplay.tsx
4299
- var import_react23 = require("react");
4300
- var import_jsx_runtime22 = require("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] = (0, import_react23.useState)(false);
4308
- const [accountIndex, setAccountIndex] = (0, import_react23.useState)(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);
4626
+ };
4627
+ window.addEventListener("message", handleMessage);
4628
+ return () => window.removeEventListener("message", handleMessage);
4629
+ }, [
4630
+ authServiceUrl,
4631
+ onAuthError,
4632
+ onAuthSuccess,
4633
+ onOidcReceived,
4634
+ onOrgConfigUpdate,
4635
+ setIsAuthenticated,
4636
+ setIsIframeReady,
4637
+ setIsLoading,
4638
+ setUser,
4639
+ sendMessage,
4640
+ cubistClient,
4641
+ orgId,
4642
+ environment
4643
+ ]);
4644
+ (0, import_react24.useEffect)(() => {
4645
+ if (isIframeReady && (iframe == null ? void 0 : iframe.contentWindow)) {
4646
+ sendMessage({
4647
+ type: "CHECK_AUTH_STATUS",
4648
+ payload: {
4649
+ orgId,
4650
+ environment
4651
+ }
4652
+ });
4322
4653
  }
4654
+ }, [isIframeReady, iframe, sendMessage, orgId, environment]);
4655
+ return {
4656
+ sendMessage
4323
4657
  };
4324
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `space-y-4 ${className}`, children: [
4325
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "bg-gray-50 rounded-lg p-4", children: [
4326
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-sm text-gray-500", children: "Wallet Address" }),
4327
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mt-1 font-mono text-sm break-all", children: displayAddress })
4328
- ] }),
4329
- showAddAccount && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
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
- var import_jsx_runtime23 = require("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__ */ (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: [
4353
- /* @__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" }) }),
4354
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "border-t border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("dl", { children: [
4355
- /* @__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: [
4356
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { className: "text-sm font-medium text-gray-500", children: "Display Name" }),
4357
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.displayName })
4358
- ] }),
4359
- 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: [
4360
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("dt", { className: "text-sm font-medium text-gray-500", children: "Email address" }),
4361
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsxs)("div", { children: [
4364
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-sm font-medium text-gray-500", children: "MFA Methods" }),
4365
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsx)(
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__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-6", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
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
4658
  }
4389
4659
 
4390
4660
  // src/hooks/useSignMessage.ts
4391
- var import_react24 = require("react");
4661
+ var import_react25 = require("react");
4392
4662
  var import_cubesigner_sdk4 = require("@cubist-labs/cubesigner-sdk");
4393
4663
  function useSignMessage() {
4394
- const [state, setState] = (0, import_react24.useState)({
4664
+ const [state, setState] = (0, import_react25.useState)({
4395
4665
  isLoading: false,
4396
4666
  error: null,
4397
4667
  signature: null
4398
4668
  });
4399
4669
  const { wallet, cubistClient } = useAvaCloudWallet();
4400
- const reset = (0, import_react24.useCallback)(() => {
4670
+ const reset = (0, import_react25.useCallback)(() => {
4401
4671
  setState({
4402
4672
  isLoading: false,
4403
4673
  error: null,
4404
4674
  signature: null
4405
4675
  });
4406
4676
  }, []);
4407
- const signMessage = (0, import_react24.useCallback)(async (message) => {
4677
+ const signMessage = (0, import_react25.useCallback)(async (message) => {
4408
4678
  if (!cubistClient || !wallet.address) {
4409
4679
  setState((prev) => ({
4410
4680
  ...prev,
@@ -4441,10 +4711,11 @@ function useSignMessage() {
4441
4711
  }
4442
4712
 
4443
4713
  // src/hooks/useSignTransaction.ts
4444
- var import_react25 = require("react");
4714
+ var import_react26 = require("react");
4445
4715
  var import_cubesigner_sdk5 = require("@cubist-labs/cubesigner-sdk");
4716
+ var import_viem5 = require("viem");
4446
4717
  function useSignTransaction() {
4447
- const [state, setState] = (0, import_react25.useState)({
4718
+ const [state, setState] = (0, import_react26.useState)({
4448
4719
  isLoading: false,
4449
4720
  error: null,
4450
4721
  signature: null,
@@ -4452,7 +4723,7 @@ function useSignTransaction() {
4452
4723
  });
4453
4724
  const { wallet, cubistClient } = useAvaCloudWallet();
4454
4725
  const { publicClient } = useViem();
4455
- const reset = (0, import_react25.useCallback)(() => {
4726
+ const reset = (0, import_react26.useCallback)(() => {
4456
4727
  setState({
4457
4728
  isLoading: false,
4458
4729
  error: null,
@@ -4460,8 +4731,7 @@ function useSignTransaction() {
4460
4731
  signedTransaction: null
4461
4732
  });
4462
4733
  }, []);
4463
- const signTransaction = (0, import_react25.useCallback)(async (transaction) => {
4464
- var _a, _b, _c, _d;
4734
+ const signTransaction = (0, import_react26.useCallback)(async (transaction) => {
4465
4735
  if (!(wallet == null ? void 0 : wallet.address)) {
4466
4736
  setState((prev) => ({
4467
4737
  ...prev,
@@ -4497,13 +4767,13 @@ function useSignTransaction() {
4497
4767
  chain_id: publicClient.chain.id,
4498
4768
  tx: {
4499
4769
  to: transaction.to || void 0,
4500
- value: (_a = transaction.value) == null ? void 0 : _a.toString(),
4770
+ value: transaction.value !== void 0 ? (0, import_viem5.toHex)(transaction.value) : void 0,
4501
4771
  data: transaction.data || "0x",
4502
- nonce: (_b = transaction.nonce) == null ? void 0 : _b.toString(),
4772
+ nonce: transaction.nonce !== void 0 ? (0, import_viem5.toHex)(transaction.nonce) : void 0,
4503
4773
  type: "0x2",
4504
4774
  // EIP-1559
4505
- maxFeePerGas: (_c = transaction.maxFeePerGas) == null ? void 0 : _c.toString(),
4506
- maxPriorityFeePerGas: (_d = transaction.maxPriorityFeePerGas) == null ? void 0 : _d.toString()
4775
+ maxFeePerGas: transaction.maxFeePerGas !== void 0 ? (0, import_viem5.toHex)(transaction.maxFeePerGas) : void 0,
4776
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas !== void 0 ? (0, import_viem5.toHex)(transaction.maxPriorityFeePerGas) : void 0
4507
4777
  }
4508
4778
  };
4509
4779
  const sig = await key.signEvm(signReq);
@@ -4529,11 +4799,11 @@ function useSignTransaction() {
4529
4799
  }
4530
4800
 
4531
4801
  // src/hooks/useUserWallets.ts
4532
- var import_react26 = require("react");
4802
+ var import_react27 = require("react");
4533
4803
  function useUserWallets() {
4534
- const [error, setError] = (0, import_react26.useState)(null);
4535
- const [isLoading, setIsLoading] = (0, import_react26.useState)(false);
4536
- const getWallets = (0, import_react26.useCallback)(async (client) => {
4804
+ const [error, setError] = (0, import_react27.useState)(null);
4805
+ const [isLoading, setIsLoading] = (0, import_react27.useState)(false);
4806
+ const getWallets = (0, import_react27.useCallback)(async (client) => {
4537
4807
  setIsLoading(true);
4538
4808
  setError(null);
4539
4809
  try {
@@ -4563,21 +4833,36 @@ function useUserWallets() {
4563
4833
 
4564
4834
  // src/wagmi/connector.ts
4565
4835
  var import_core = require("@wagmi/core");
4566
- var import_viem5 = require("viem");
4836
+ var import_viem6 = require("viem");
4567
4837
  function avaCloudWallet() {
4568
4838
  return (0, import_core.createConnector)((config) => ({
4569
4839
  id: "avaCloudWallet",
4570
4840
  name: "AvaCloud Wallet",
4571
4841
  type: "injected",
4572
- async connect() {
4842
+ async connect(parameters) {
4843
+ const { withCapabilities } = parameters != null ? parameters : {};
4573
4844
  const { walletClient } = useViem();
4574
4845
  if (!walletClient) {
4575
4846
  throw new Error("AvaCloud Wallet not connected");
4576
4847
  }
4577
4848
  const accounts = await this.getAccounts();
4578
4849
  const chainId = await this.getChainId();
4850
+ if (withCapabilities) {
4851
+ const result = {
4852
+ accounts: accounts.map((address) => ({
4853
+ address,
4854
+ capabilities: {}
4855
+ })),
4856
+ chainId
4857
+ };
4858
+ config.emitter.emit("connect", { accounts, chainId });
4859
+ return result;
4860
+ }
4579
4861
  config.emitter.emit("connect", { accounts, chainId });
4580
- return { accounts, chainId };
4862
+ return {
4863
+ accounts,
4864
+ chainId
4865
+ };
4581
4866
  },
4582
4867
  async disconnect() {
4583
4868
  config.emitter.emit("disconnect");
@@ -4609,7 +4894,7 @@ function avaCloudWallet() {
4609
4894
  this.disconnect();
4610
4895
  } else {
4611
4896
  config.emitter.emit("change", {
4612
- accounts: accounts.map((x) => (0, import_viem5.getAddress)(x))
4897
+ accounts: accounts.map((x) => (0, import_viem6.getAddress)(x))
4613
4898
  });
4614
4899
  }
4615
4900
  },
@@ -4624,7 +4909,7 @@ function avaCloudWallet() {
4624
4909
  }
4625
4910
 
4626
4911
  // src/providers/GaslessProvider.tsx
4627
- var import_react27 = require("react");
4912
+ var import_react28 = require("react");
4628
4913
  var import_jsx_runtime24 = require("react/jsx-runtime");
4629
4914
  function validateGaslessConfig(config) {
4630
4915
  if (!config || typeof config !== "object") {
@@ -4658,15 +4943,15 @@ function validateGaslessConfig(config) {
4658
4943
  }
4659
4944
  return null;
4660
4945
  }
4661
- var GaslessContext = (0, import_react27.createContext)(null);
4946
+ var GaslessContext = (0, import_react28.createContext)(null);
4662
4947
  function GaslessProvider({ children, config, fetchParams }) {
4663
- const [state, setState] = (0, import_react27.useState)({
4948
+ const [state, setState] = (0, import_react28.useState)({
4664
4949
  isLoading: false,
4665
4950
  error: null,
4666
4951
  config: null
4667
4952
  });
4668
4953
  const { authServiceUrl, environment } = useAvaCloudWallet();
4669
- (0, import_react27.useEffect)(() => {
4954
+ (0, import_react28.useEffect)(() => {
4670
4955
  if (config) {
4671
4956
  const validationError = validateGaslessConfig(config);
4672
4957
  if (validationError) {
@@ -4753,9 +5038,16 @@ function GaslessProvider({ children, config, fetchParams }) {
4753
5038
  }, [config, fetchParams, authServiceUrl, environment]);
4754
5039
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(GaslessContext.Provider, { value: state, children });
4755
5040
  }
5041
+ function useGaslessConfig() {
5042
+ const ctx = (0, import_react28.useContext)(GaslessContext);
5043
+ if (!ctx) {
5044
+ throw new Error("useGaslessConfig must be used within a GaslessProvider");
5045
+ }
5046
+ return ctx;
5047
+ }
4756
5048
 
4757
5049
  // src/hooks/useGaslessTransaction.ts
4758
- var import_react28 = require("react");
5050
+ var import_react29 = require("react");
4759
5051
  var ethers = __toESM(require("ethers"));
4760
5052
  var import_axios = __toESM(require("axios"));
4761
5053
  var import_cubesigner_sdk6 = require("@cubist-labs/cubesigner-sdk");
@@ -4781,7 +5073,7 @@ var FORWARDER_GET_NONCE_ABI = [
4781
5073
  }
4782
5074
  ];
4783
5075
  function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContractAddress, abi: defaultAbi }) {
4784
- const [state, setState] = (0, import_react28.useState)({
5076
+ const [state, setState] = (0, import_react29.useState)({
4785
5077
  isLoading: false,
4786
5078
  error: null,
4787
5079
  txHash: null
@@ -4789,14 +5081,14 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4789
5081
  const config = gaslessConfig;
4790
5082
  const { wallet, cubistClient } = useAvaCloudWallet();
4791
5083
  useViem();
4792
- const reset = (0, import_react28.useCallback)(() => {
5084
+ const reset = (0, import_react29.useCallback)(() => {
4793
5085
  setState({
4794
5086
  isLoading: false,
4795
5087
  error: null,
4796
5088
  txHash: null
4797
5089
  });
4798
5090
  }, []);
4799
- const validateConfig = (0, import_react28.useCallback)((config2) => {
5091
+ const validateConfig = (0, import_react29.useCallback)((config2) => {
4800
5092
  if (!config2) {
4801
5093
  return "Gasless configuration is not available. Please ensure GaslessProvider is properly configured.";
4802
5094
  }
@@ -4830,7 +5122,7 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4830
5122
  }
4831
5123
  return null;
4832
5124
  }, []);
4833
- const sendGaslessTransaction = (0, import_react28.useCallback)(async ({
5125
+ const sendGaslessTransaction = (0, import_react29.useCallback)(async ({
4834
5126
  functionName,
4835
5127
  args = [],
4836
5128
  abi: overrideAbi,
@@ -4915,7 +5207,12 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4915
5207
  const suffixParts = config.suffix.match(/^(\w+)\s+(.+)\)$/);
4916
5208
  if (suffixParts) {
4917
5209
  const [, , suffixName] = suffixParts;
4918
- message[suffixName] = Buffer.from(config.suffix, "utf8");
5210
+ const encoder = new TextEncoder();
5211
+ const suffixBytes = encoder.encode(config.suffix);
5212
+ const paddedBytes = new Uint8Array(32);
5213
+ paddedBytes.set(suffixBytes.slice(0, 32));
5214
+ const hexString = Array.from(paddedBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
5215
+ message[suffixName] = "0x" + hexString;
4919
5216
  }
4920
5217
  }
4921
5218
  const domain = {
@@ -4924,12 +5221,22 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4924
5221
  chainId: (await provider.getNetwork()).chainId,
4925
5222
  verifyingContract: config.forwarderAddress
4926
5223
  };
4927
- const digest = ethers.utils._TypedDataEncoder.hash(domain, {
4928
- [config.requestType]: types[config.requestType]
4929
- }, message);
4930
5224
  const key = await cubistClient.org().getKeyByMaterialId(import_cubesigner_sdk6.Secp256k1.Evm, wallet.address);
4931
- const sigResp = await key.signBlob({
4932
- message_base64: Buffer.from(digest.slice(2), "hex").toString("base64")
5225
+ const sigResp = await key.signEip712({
5226
+ chain_id: domain.chainId,
5227
+ typed_data: {
5228
+ domain: {
5229
+ name: domain.name,
5230
+ version: domain.version,
5231
+ chainId: `0x${domain.chainId.toString(16)}`,
5232
+ verifyingContract: domain.verifyingContract
5233
+ },
5234
+ primaryType: config.requestType,
5235
+ types: {
5236
+ [config.requestType]: types[config.requestType]
5237
+ },
5238
+ message
5239
+ }
4933
5240
  });
4934
5241
  const signatureData = sigResp.data().signature;
4935
5242
  const signature = signatureData.startsWith("0x") ? signatureData : `0x${signatureData}`;
@@ -5020,6 +5327,7 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
5020
5327
  useAvaCloudWallet,
5021
5328
  useBlockchain,
5022
5329
  useChainId,
5330
+ useGaslessConfig,
5023
5331
  useGaslessTransaction,
5024
5332
  useGlacier,
5025
5333
  usePostMessage,