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