@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.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,10 +31,11 @@ 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";
34
+ // src/hooks/usePenpalAuth.ts
35
+ import { useCallback, useEffect, useRef, useState } from "react";
36
+ import { connect, WindowMessenger } from "penpal";
36
37
 
37
- // src/constants/storage.ts
38
+ // ../avacloud-waas-common/dist/constants/storage.js
38
39
  var OIDC_TOKEN_KEY = "avacloud-auth-oidc-token";
39
40
  var AUTH_TOKENS_KEY = "auth_tokens";
40
41
  var AUTH0_STORAGE_KEYS = {
@@ -46,26 +47,12 @@ var AUTH0_STORAGE_KEYS = {
46
47
  var CUBIST_USER_ID_KEY = "cubist_user_id";
47
48
  var ORG_CONFIG_CACHE_KEY = "avacloud-org-config-cache";
48
49
 
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({
50
+ // src/hooks/usePenpalAuth.ts
51
+ function usePenpalAuth({
64
52
  authServiceUrl,
65
53
  orgId,
66
54
  environment,
67
55
  iframe,
68
- isIframeReady,
69
56
  onAuthSuccess,
70
57
  onAuthError,
71
58
  onOidcReceived,
@@ -73,16 +60,13 @@ function usePostMessage({
73
60
  setIsAuthenticated,
74
61
  setUser,
75
62
  setIsLoading,
76
- setIsIframeReady,
77
- cubistClient
63
+ setIsIframeReady
78
64
  }) {
79
- const lastAuthStateRef = useRef({
80
- isAuthenticated: false,
81
- userId: null,
82
- lastUpdateTime: 0
83
- });
84
- const hasRequestedOidcRef = useRef(false);
85
- const isHandlingMessageRef = useRef(false);
65
+ const connectionRef = useRef(null);
66
+ const [authService, setAuthService] = useState(null);
67
+ const [isConnected, setIsConnected] = useState(false);
68
+ const isConnectedRef = useRef(false);
69
+ const hasCheckedAuthRef = useRef(false);
86
70
  const hasLoadedCacheRef = useRef(false);
87
71
  useEffect(() => {
88
72
  if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
@@ -103,246 +87,263 @@ function usePostMessage({
103
87
  }
104
88
  }
105
89
  }, [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}`
90
+ const parentMethods = {
91
+ onReady: () => {
92
+ console.log("[Penpal Parent] Iframe is ready");
93
+ setIsIframeReady(true);
94
+ },
95
+ onAuthStatusChange: (status) => {
96
+ var _a;
97
+ console.log("[Penpal Parent] Auth status changed:", status);
98
+ setIsAuthenticated(status.isAuthenticated);
99
+ if (status.user) {
100
+ const userInfo = {
101
+ email: status.user.email,
102
+ sub: status.user.sub,
103
+ configured_mfa: [],
104
+ displayName: status.user.nickname || status.user.name || ((_a = status.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
105
+ rawUserData: status.user
106
+ };
107
+ setUser(userInfo);
108
+ } else {
109
+ setUser(null);
110
+ }
111
+ if (status.orgConfig) {
112
+ onOrgConfigUpdate == null ? void 0 : onOrgConfigUpdate(status.orgConfig);
113
+ if (orgId) {
114
+ try {
115
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
116
+ const configWithTimestamp = {
117
+ ...status.orgConfig,
118
+ _timestamp: Date.now()
156
119
  };
120
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
121
+ } catch (error) {
157
122
  }
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
123
  }
172
124
  }
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;
125
+ if (status.isAuthenticated) {
126
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
180
127
  }
181
- if (event.origin !== new URL(authServiceUrl).origin) {
128
+ setIsLoading(false);
129
+ },
130
+ onError: (error) => {
131
+ console.error("[Penpal Parent] Error from iframe:", error);
132
+ if (error.message === "User not authenticated in iframe" || error.message === "Unknown error" || error.message.includes("OIDC user not found")) {
182
133
  return;
183
134
  }
184
- if (typeof ((_a = event.data) == null ? void 0 : _a.type) !== "string") {
135
+ onAuthError == null ? void 0 : onAuthError(new Error(error.message));
136
+ setIsLoading(false);
137
+ },
138
+ onWalletUpdate: (wallet) => {
139
+ console.log("[Penpal Parent] Wallet update:", wallet);
140
+ }
141
+ };
142
+ useEffect(() => {
143
+ if (!(iframe == null ? void 0 : iframe.contentWindow)) {
144
+ return;
145
+ }
146
+ let isCancelled = false;
147
+ const setupConnection = async (attempt = 1, maxAttempts = 3) => {
148
+ if (isCancelled) return;
149
+ if (isConnectedRef.current && connectionRef.current) {
150
+ console.log("[Penpal Parent] Already connected, skipping setup");
185
151
  return;
186
152
  }
187
- if (event.data.requestId && globalAuthState.processingMessageIds.has(event.data.requestId)) {
188
- return;
153
+ console.log(`[Penpal Parent] Setting up connection to iframe (attempt ${attempt}/${maxAttempts})...`);
154
+ if (connectionRef.current) {
155
+ connectionRef.current.destroy();
156
+ connectionRef.current = null;
157
+ setAuthService(null);
158
+ setIsConnected(false);
159
+ isConnectedRef.current = false;
189
160
  }
190
161
  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;
162
+ const authServiceOrigin = new URL(authServiceUrl).origin;
163
+ const messenger = new WindowMessenger({
164
+ remoteWindow: iframe.contentWindow,
165
+ allowedOrigins: [authServiceOrigin]
166
+ });
167
+ const connection = connect({
168
+ messenger,
169
+ methods: parentMethods,
170
+ timeout: 1e4
171
+ // 10 second connection timeout per attempt
172
+ });
173
+ connectionRef.current = connection;
174
+ const remote = await connection.promise;
175
+ if (isCancelled) {
176
+ connection.destroy();
177
+ return;
202
178
  }
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;
179
+ console.log("[Penpal Parent] Connected to auth service");
180
+ isConnectedRef.current = true;
181
+ setAuthService(remote);
182
+ setIsConnected(true);
183
+ setIsIframeReady(true);
184
+ } catch (error) {
185
+ if (isCancelled) return;
186
+ console.error(`[Penpal Parent] Failed to connect (attempt ${attempt}):`, error);
187
+ if (attempt < maxAttempts) {
188
+ console.log(`[Penpal Parent] Retrying in 1 second...`);
189
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
190
+ if (!isCancelled) {
191
+ await setupConnection(attempt + 1, maxAttempts);
289
192
  }
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;
193
+ } else {
194
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to connect to auth service"));
298
195
  }
299
- } finally {
300
- isHandlingMessageRef.current = false;
301
196
  }
302
197
  };
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
- ]);
198
+ setupConnection();
199
+ return () => {
200
+ isCancelled = true;
201
+ };
202
+ }, [iframe, authServiceUrl]);
320
203
  useEffect(() => {
321
- if (isIframeReady && (iframe == null ? void 0 : iframe.contentWindow)) {
322
- sendMessage({
323
- type: "CHECK_AUTH_STATUS",
324
- payload: {
325
- orgId,
326
- environment
204
+ if (isConnected && authService && !hasCheckedAuthRef.current) {
205
+ hasCheckedAuthRef.current = true;
206
+ authService.checkAuthStatus(orgId, environment).then((status) => {
207
+ console.log("[Penpal Parent] Initial auth status:", status);
208
+ parentMethods.onAuthStatusChange(status);
209
+ if (status.isAuthenticated) {
210
+ return authService.getOidc();
211
+ }
212
+ return null;
213
+ }).then((oidcResult) => {
214
+ if (oidcResult == null ? void 0 : oidcResult.idToken) {
215
+ onOidcReceived == null ? void 0 : onOidcReceived(oidcResult.idToken);
327
216
  }
217
+ }).catch((error) => {
218
+ console.error("[Penpal Parent] Error checking auth status:", error);
219
+ setIsLoading(false);
328
220
  });
329
221
  }
330
- }, [isIframeReady, iframe, sendMessage, orgId, environment]);
222
+ }, [isConnected, authService, orgId, environment]);
223
+ const login = useCallback(async (params) => {
224
+ var _a;
225
+ if (!authService) {
226
+ console.warn("[Penpal] Cannot login - not connected");
227
+ return;
228
+ }
229
+ try {
230
+ const result = await authService.login(params || {});
231
+ setIsAuthenticated(true);
232
+ if (result.user) {
233
+ const userInfo = {
234
+ email: result.user.email,
235
+ sub: result.user.sub,
236
+ configured_mfa: [],
237
+ displayName: result.user.nickname || result.user.name || ((_a = result.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
238
+ rawUserData: result.user
239
+ };
240
+ setUser(userInfo);
241
+ }
242
+ if (result.accessToken) {
243
+ onOidcReceived == null ? void 0 : onOidcReceived(result.accessToken);
244
+ }
245
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
246
+ return result;
247
+ } catch (error) {
248
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Login failed"));
249
+ throw error;
250
+ }
251
+ }, [authService, setIsAuthenticated, setUser, onOidcReceived, onAuthSuccess, onAuthError]);
252
+ const signup = useCallback(async (email, password) => {
253
+ var _a;
254
+ if (!authService) {
255
+ console.warn("[Penpal] Cannot signup - not connected");
256
+ return;
257
+ }
258
+ try {
259
+ const result = await authService.signup({ email, password });
260
+ setIsAuthenticated(true);
261
+ if (result.user) {
262
+ const userInfo = {
263
+ email: result.user.email,
264
+ sub: result.user.sub,
265
+ configured_mfa: [],
266
+ displayName: result.user.nickname || result.user.name || ((_a = result.user.email) == null ? void 0 : _a.split("@")[0]) || "User",
267
+ rawUserData: result.user
268
+ };
269
+ setUser(userInfo);
270
+ }
271
+ if (result.accessToken) {
272
+ onOidcReceived == null ? void 0 : onOidcReceived(result.accessToken);
273
+ }
274
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
275
+ return result;
276
+ } catch (error) {
277
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Signup failed"));
278
+ throw error;
279
+ }
280
+ }, [authService, setIsAuthenticated, setUser, onOidcReceived, onAuthSuccess, onAuthError]);
281
+ const logout = useCallback(async () => {
282
+ if (!authService) {
283
+ console.warn("[Penpal] Cannot logout - not connected");
284
+ return;
285
+ }
286
+ try {
287
+ await authService.logout();
288
+ setIsAuthenticated(false);
289
+ setUser(null);
290
+ localStorage.removeItem(AUTH_TOKENS_KEY);
291
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
292
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
293
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ID_TOKEN);
294
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.EXPIRES_AT);
295
+ localStorage.removeItem(CUBIST_USER_ID_KEY);
296
+ sessionStorage.removeItem(OIDC_TOKEN_KEY);
297
+ } catch (error) {
298
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Logout failed"));
299
+ throw error;
300
+ }
301
+ }, [authService, setIsAuthenticated, setUser, onAuthError]);
302
+ const getOidc = useCallback(async () => {
303
+ if (!authService) {
304
+ console.warn("[Penpal] Cannot get OIDC - not connected");
305
+ return;
306
+ }
307
+ try {
308
+ return await authService.getOidc();
309
+ } catch (error) {
310
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to get OIDC token"));
311
+ throw error;
312
+ }
313
+ }, [authService, onAuthError]);
314
+ const checkAuthStatus = useCallback(async () => {
315
+ if (!authService) {
316
+ console.warn("[Penpal] Cannot check auth status - not connected");
317
+ return;
318
+ }
319
+ try {
320
+ return await authService.checkAuthStatus(orgId, environment);
321
+ } catch (error) {
322
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Failed to check auth status"));
323
+ throw error;
324
+ }
325
+ }, [authService, orgId, environment, onAuthError]);
331
326
  return {
332
- sendMessage
327
+ authService,
328
+ isConnected,
329
+ login,
330
+ signup,
331
+ logout,
332
+ getOidc,
333
+ checkAuthStatus
333
334
  };
334
335
  }
335
336
 
336
337
  // src/AuthModalContext.tsx
337
- import { createContext, useContext, useState as useState3, useCallback as useCallback2 } from "react";
338
+ import { createContext, useContext, useState as useState4, useCallback as useCallback3 } from "react";
338
339
  import { Dialog as Dialog2, DialogContent as DialogContent2, DialogTitle } from "@avalabs/core-k2-components";
339
340
 
340
341
  // src/components/Modal.tsx
341
- import { useState as useState2, useEffect as useEffect2, useRef as useRef2 } from "react";
342
+ import { useState as useState3, useRef as useRef2, useCallback as useCallback2, useEffect as useEffect2 } from "react";
342
343
  import { Dialog, DialogContent, IconButton as IconButton2, Stack as Stack3, XIcon } from "@avalabs/core-k2-components";
343
344
 
344
345
  // src/components/SignInContent.tsx
345
- import { useState } from "react";
346
+ import { useState as useState2 } from "react";
346
347
  import { Button, TextField, Typography as Typography2, Stack as Stack2, IconButton, Divider, GoogleIcon, AppleIcon, XTwitterIcon, FacebookIcon } from "@avalabs/core-k2-components";
347
348
 
348
349
  // src/components/PoweredByAvaCloud.tsx
@@ -372,10 +373,10 @@ function SignInContent({
372
373
  isSubmitting,
373
374
  socialLogins = ["google", "x", "apple"]
374
375
  }) {
375
- const [email, setEmail] = useState("");
376
- const [password, setPassword] = useState("");
377
- const [isPasswordStep, setIsPasswordStep] = useState(false);
378
- const [isSignupMode, setIsSignupMode] = useState(false);
376
+ const [email, setEmail] = useState2("");
377
+ const [password, setPassword] = useState2("");
378
+ const [isPasswordStep, setIsPasswordStep] = useState2(false);
379
+ const [isSignupMode, setIsSignupMode] = useState2(false);
379
380
  const providerConnectionMap = {
380
381
  "google": "google-oauth2",
381
382
  "x": "twitter",
@@ -949,123 +950,72 @@ function SignInContent({
949
950
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
950
951
  function LoginModal({ open, onClose }) {
951
952
  var _a;
952
- const { iframe, orgConfig, signup } = useAvaCloudWallet();
953
- const [isSubmitting, setIsSubmitting] = useState2(false);
954
- const [error, setError] = useState2("");
953
+ const { orgConfig, signup, login, isAuthenticated } = useAvaCloudWallet();
954
+ const [isSubmitting, setIsSubmitting] = useState3(false);
955
+ const [error, setError] = useState3("");
955
956
  const timeoutIdRef = useRef2(null);
956
- const signupInProgressRef = useRef2(false);
957
- const lastSignupAttemptRef = useRef2(0);
958
957
  const socialLogins = (_a = orgConfig == null ? void 0 : orgConfig.adminPortalSettings) == null ? void 0 : _a.socialLogins;
959
958
  useEffect2(() => {
960
- let requestInProgress = false;
961
- const handleMessage = (event) => {
962
- if (!event.data || typeof event.data.type !== "string") {
963
- return;
959
+ if (isAuthenticated && open) {
960
+ setIsSubmitting(false);
961
+ if (timeoutIdRef.current) {
962
+ clearTimeout(timeoutIdRef.current);
963
+ timeoutIdRef.current = null;
964
964
  }
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;
965
+ onClose();
966
+ }
967
+ }, [isAuthenticated, open, onClose]);
968
+ useEffect2(() => {
969
+ if (!open) {
970
+ setIsSubmitting(false);
971
+ setError("");
972
+ if (timeoutIdRef.current) {
973
+ clearTimeout(timeoutIdRef.current);
974
+ timeoutIdRef.current = null;
988
975
  }
989
- };
990
- window.addEventListener("message", handleMessage);
976
+ }
977
+ }, [open]);
978
+ useEffect2(() => {
991
979
  return () => {
992
- window.removeEventListener("message", handleMessage);
993
980
  if (timeoutIdRef.current) {
994
981
  clearTimeout(timeoutIdRef.current);
995
982
  timeoutIdRef.current = null;
996
983
  }
997
984
  };
998
- }, [onClose]);
999
- const handleProviderLogin = (provider) => {
1000
- var _a2;
985
+ }, []);
986
+ const handleProviderLogin = useCallback2((provider) => {
1001
987
  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;
988
+ setIsSubmitting(true);
989
+ login({ connection: provider });
990
+ }, [login]);
991
+ const handleEmailLogin = useCallback2((email, password) => {
1015
992
  setError("");
1016
993
  setIsSubmitting(true);
1017
- if (!iframe) {
1018
- setError("Authentication service not available");
1019
- setIsSubmitting(false);
1020
- return;
1021
- }
1022
994
  if (timeoutIdRef.current) {
1023
995
  clearTimeout(timeoutIdRef.current);
1024
996
  timeoutIdRef.current = null;
1025
997
  }
1026
- (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
1027
- type: "LOGIN_REQUEST",
1028
- email,
1029
- password,
1030
- requestId: `login-${Date.now()}`
1031
- }, "*");
998
+ login({ email, password });
1032
999
  timeoutIdRef.current = setTimeout(() => {
1033
1000
  setError("Authentication service timed out");
1034
1001
  setIsSubmitting(false);
1035
1002
  timeoutIdRef.current = null;
1036
1003
  }, 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;
1004
+ }, [login]);
1005
+ const handleEmailSignup = useCallback2((email, password) => {
1047
1006
  setError("");
1048
1007
  setIsSubmitting(true);
1049
- signupInProgressRef.current = true;
1050
1008
  if (timeoutIdRef.current) {
1051
1009
  clearTimeout(timeoutIdRef.current);
1052
1010
  timeoutIdRef.current = null;
1053
1011
  }
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
- }
1012
+ signup(email, password);
1062
1013
  timeoutIdRef.current = setTimeout(() => {
1063
1014
  setError("Authentication service timed out");
1064
1015
  setIsSubmitting(false);
1065
- signupInProgressRef.current = false;
1066
1016
  timeoutIdRef.current = null;
1067
1017
  }, 1e4);
1068
- };
1018
+ }, [signup]);
1069
1019
  return /* @__PURE__ */ jsxs3(
1070
1020
  Dialog,
1071
1021
  {
@@ -1153,9 +1103,9 @@ function LoginModal({ open, onClose }) {
1153
1103
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1154
1104
  var AuthModalContext = createContext(void 0);
1155
1105
  function AuthModalProvider({ children }) {
1156
- const [isModalOpen, setIsModalOpen] = useState3(false);
1157
- const openLoginModal = useCallback2(() => setIsModalOpen(true), []);
1158
- const closeLoginModal = useCallback2(() => setIsModalOpen(false), []);
1106
+ const [isModalOpen, setIsModalOpen] = useState4(false);
1107
+ const openLoginModal = useCallback3(() => setIsModalOpen(true), []);
1108
+ const closeLoginModal = useCallback3(() => setIsModalOpen(false), []);
1159
1109
  return /* @__PURE__ */ jsxs4(AuthModalContext.Provider, { value: { openLoginModal, closeLoginModal, isModalOpen }, children: [
1160
1110
  children,
1161
1111
  /* @__PURE__ */ jsxs4(
@@ -1190,11 +1140,11 @@ function useAuthModal() {
1190
1140
  import { CubeSignerClient } from "@cubist-labs/cubesigner-sdk";
1191
1141
 
1192
1142
  // src/providers/ViemContext.tsx
1193
- import { createContext as createContext2, useContext as useContext2, useState as useState4, useEffect as useEffect3 } from "react";
1143
+ import { createContext as createContext2, useContext as useContext2, useState as useState5, useEffect as useEffect3 } from "react";
1194
1144
  import { createPublicClient, createWalletClient, http } from "viem";
1195
1145
 
1196
1146
  // src/hooks/useAuth.ts
1197
- import { useCallback as useCallback3 } from "react";
1147
+ import { useCallback as useCallback4 } from "react";
1198
1148
  function useAuth() {
1199
1149
  const {
1200
1150
  isAuthenticated,
@@ -1207,7 +1157,7 @@ function useAuth() {
1207
1157
  cubistError
1208
1158
  } = useAvaCloudWallet();
1209
1159
  const { openLoginModal } = useAuthModal();
1210
- const login = useCallback3(() => {
1160
+ const login = useCallback4(() => {
1211
1161
  openLoginModal();
1212
1162
  }, [openLoginModal]);
1213
1163
  return {
@@ -1228,10 +1178,10 @@ import { jsx as jsx5 } from "react/jsx-runtime";
1228
1178
  var ViemContext = createContext2(null);
1229
1179
  function ViemProvider({ children, rpcUrl, chainId, explorerUrl }) {
1230
1180
  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);
1181
+ const [publicClient, setPublicClient] = useState5(null);
1182
+ const [walletClient, setWalletClient] = useState5(null);
1183
+ const [isConnected, setIsConnected] = useState5(false);
1184
+ const [error, setError] = useState5(null);
1235
1185
  const { cubistClient, wallet: authWallet } = useAuth();
1236
1186
  useEffect3(() => {
1237
1187
  const initClient = async () => {
@@ -1397,11 +1347,11 @@ var GlacierApiClient = class {
1397
1347
  var glacierApi = new GlacierApiClient();
1398
1348
 
1399
1349
  // src/hooks/useChainId.ts
1400
- import { useState as useState5 } from "react";
1350
+ import { useState as useState6 } from "react";
1401
1351
  var CHAIN_ID_STORAGE_KEY = "avalanche-chain-id";
1402
1352
  var DEFAULT_CHAIN_ID = 43113;
1403
1353
  function useChainId() {
1404
- const [chainId, setChainIdState] = useState5(() => {
1354
+ const [chainId, setChainIdState] = useState6(() => {
1405
1355
  const storedChainId = localStorage.getItem(CHAIN_ID_STORAGE_KEY);
1406
1356
  return storedChainId ? Number.parseInt(storedChainId, 10) : DEFAULT_CHAIN_ID;
1407
1357
  });
@@ -1481,7 +1431,7 @@ function useERC1155Balances(address, chainId) {
1481
1431
 
1482
1432
  // src/providers/ThemeProvider.tsx
1483
1433
  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";
1434
+ import { createContext as createContext3, useContext as useContext3, useState as useState7, useCallback as useCallback5, useEffect as useEffect4 } from "react";
1485
1435
  import { jsx as jsx6 } from "react/jsx-runtime";
1486
1436
  var ThemeContext = createContext3({
1487
1437
  isDarkMode: false,
@@ -1527,13 +1477,13 @@ var darkTheme = createTheme({
1527
1477
  }
1528
1478
  });
1529
1479
  function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1530
- const [isDarkMode, setIsDarkMode] = useState6(darkMode != null ? darkMode : false);
1480
+ const [isDarkMode, setIsDarkMode] = useState7(darkMode != null ? darkMode : false);
1531
1481
  useEffect4(() => {
1532
1482
  if (darkMode !== void 0 && darkMode !== isDarkMode) {
1533
1483
  setIsDarkMode(darkMode);
1534
1484
  }
1535
- }, [darkMode]);
1536
- const toggleTheme = useCallback4(() => {
1485
+ }, [darkMode, isDarkMode]);
1486
+ const toggleTheme = useCallback5(() => {
1537
1487
  const newDarkMode = !isDarkMode;
1538
1488
  setIsDarkMode(newDarkMode);
1539
1489
  onDarkModeChange == null ? void 0 : onDarkModeChange(newDarkMode);
@@ -1541,6 +1491,18 @@ function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1541
1491
  return /* @__PURE__ */ jsx6(ThemeContext.Provider, { value: { isDarkMode, toggleTheme }, children: /* @__PURE__ */ jsx6(K2ThemeProvider, { theme: isDarkMode ? darkTheme : lightTheme, children }) });
1542
1492
  }
1543
1493
 
1494
+ // src/constants/storage.ts
1495
+ var OIDC_TOKEN_KEY2 = "avacloud-auth-oidc-token";
1496
+ var AUTH_TOKENS_KEY2 = "auth_tokens";
1497
+ var AUTH0_STORAGE_KEYS2 = {
1498
+ IS_AUTHENTICATED: "auth0.is.authenticated",
1499
+ ACCESS_TOKEN: "auth0.access_token",
1500
+ ID_TOKEN: "auth0.id_token",
1501
+ EXPIRES_AT: "auth0.expires_at"
1502
+ };
1503
+ var CUBIST_USER_ID_KEY2 = "cubist_user_id";
1504
+ var ORG_CONFIG_CACHE_KEY2 = "avacloud-org-config-cache";
1505
+
1544
1506
  // src/AvaCloudWalletProvider.tsx
1545
1507
  import { Fragment, jsx as jsx7 } from "react/jsx-runtime";
1546
1508
  var AvaCloudWalletContext = createContext4(void 0);
@@ -1571,6 +1533,23 @@ function ViemProviderWrapper({ children, chainId }) {
1571
1533
  }
1572
1534
  );
1573
1535
  }
1536
+ function normalizeOrgConfig(config) {
1537
+ if (!config) {
1538
+ return null;
1539
+ }
1540
+ const typedConfig = config;
1541
+ const explicitWalletProvider = typeof typedConfig.walletProviderOrgID === "string" ? typedConfig.walletProviderOrgID.trim() : "";
1542
+ const cubistOrgId = typeof typedConfig.cubistOrgId === "string" ? typedConfig.cubistOrgId.trim() : "";
1543
+ const resolvedOrgId = explicitWalletProvider || cubistOrgId;
1544
+ if (!resolvedOrgId) {
1545
+ return typedConfig;
1546
+ }
1547
+ return {
1548
+ ...typedConfig,
1549
+ walletProviderOrgID: resolvedOrgId,
1550
+ cubistOrgId: cubistOrgId || resolvedOrgId
1551
+ };
1552
+ }
1574
1553
  function AvaCloudWalletProvider({
1575
1554
  children,
1576
1555
  orgId,
@@ -1604,22 +1583,22 @@ function AvaCloudWalletProvider({
1604
1583
  };
1605
1584
  const authServiceUrl = getAuthServiceUrl();
1606
1585
  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);
1586
+ const [isAuthenticated, setIsAuthenticated] = useState8(false);
1587
+ const [isCubistLoading, setIsCubistLoading] = useState8(true);
1588
+ const [isLoading, setIsLoading] = useState8(true);
1589
+ const [user, setUser] = useState8(null);
1590
+ const [wallet, setWallet] = useState8({ address: null });
1591
+ const [orgConfig, setOrgConfig] = useState8(null);
1592
+ const [iframe, setIframe] = useState8(null);
1593
+ const [_isIframeReady, setIsIframeReady] = useState8(false);
1594
+ const [cubistClient, setCubistClient] = useState8(null);
1595
+ const [cubistError, setCubistError] = useState8(null);
1596
+ const [pendingOidcToken, setPendingOidcToken] = useState8(null);
1618
1597
  const iframeRef = useRef3(null);
1619
1598
  useEffect5(() => {
1620
1599
  setIsLoading(isCubistLoading || isAuthenticated && !wallet.address);
1621
1600
  }, [isCubistLoading, isAuthenticated, wallet.address]);
1622
- const getWalletInfo = useCallback5(async (client, sessionId) => {
1601
+ const getWalletInfo = useCallback6(async (client, sessionId) => {
1623
1602
  try {
1624
1603
  const sessionKeys = await client.sessionKeys();
1625
1604
  if (!sessionKeys.length) {
@@ -1640,7 +1619,7 @@ function AvaCloudWalletProvider({
1640
1619
  return null;
1641
1620
  }
1642
1621
  }, [orgConfig]);
1643
- const loginWithCubist = useCallback5(async (oidcToken) => {
1622
+ const loginWithCubist = useCallback6(async (oidcToken) => {
1644
1623
  if (!orgConfig || !orgConfig.walletProviderOrgID) {
1645
1624
  const error = new Error("Missing required walletProviderOrgID in organization configuration");
1646
1625
  setCubistError(error);
@@ -1658,7 +1637,7 @@ function AvaCloudWalletProvider({
1658
1637
  if (oidcToken) {
1659
1638
  accessToken = oidcToken;
1660
1639
  } else {
1661
- const tokens = localStorage.getItem(AUTH_TOKENS_KEY);
1640
+ const tokens = localStorage.getItem(AUTH_TOKENS_KEY2);
1662
1641
  if (!tokens) {
1663
1642
  throw new Error("No authentication tokens found in localStorage");
1664
1643
  }
@@ -1701,8 +1680,8 @@ function AvaCloudWalletProvider({
1701
1680
  });
1702
1681
  }
1703
1682
  } catch (error) {
1704
- localStorage.removeItem(AUTH_TOKENS_KEY);
1705
- localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1683
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
1684
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1706
1685
  setIsAuthenticated(false);
1707
1686
  setUser(null);
1708
1687
  setCubistClient(null);
@@ -1716,12 +1695,17 @@ function AvaCloudWalletProvider({
1716
1695
  setIsCubistLoading(false);
1717
1696
  }
1718
1697
  }, [wallet, onWalletUpdate, onAuthError, getWalletInfo, orgConfig, environment]);
1719
- const { sendMessage } = usePostMessage({
1698
+ const {
1699
+ authService,
1700
+ isConnected,
1701
+ login: penpalLogin,
1702
+ signup: penpalSignup,
1703
+ logout: penpalLogout
1704
+ } = usePenpalAuth({
1720
1705
  authServiceUrl,
1721
1706
  orgId,
1722
1707
  environment,
1723
1708
  iframe,
1724
- isIframeReady,
1725
1709
  onAuthSuccess: () => {
1726
1710
  if (user) {
1727
1711
  if (wallet.address) {
@@ -1731,8 +1715,7 @@ function AvaCloudWalletProvider({
1731
1715
  },
1732
1716
  onAuthError: (error) => {
1733
1717
  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")) {
1718
+ if (errorMessage === "User not authenticated in iframe" || errorMessage === "Unknown error" || errorMessage.includes("OIDC user not found")) {
1736
1719
  return;
1737
1720
  }
1738
1721
  setIsCubistLoading(false);
@@ -1758,76 +1741,78 @@ function AvaCloudWalletProvider({
1758
1741
  };
1759
1742
  },
1760
1743
  onOrgConfigUpdate: (config) => {
1761
- setOrgConfig(config);
1744
+ setOrgConfig(normalizeOrgConfig(config));
1762
1745
  },
1763
1746
  setIsAuthenticated,
1764
1747
  setUser,
1765
- setIsLoading: (isLoading2) => {
1766
- setIsLoading(isLoading2);
1748
+ setIsLoading: (loading) => {
1749
+ setIsLoading(loading);
1767
1750
  },
1768
- setIsIframeReady,
1769
- wallet,
1770
- cubistClient
1751
+ setIsIframeReady
1771
1752
  });
1772
- const login = useCallback5(() => {
1773
- if (iframe == null ? void 0 : iframe.contentWindow) {
1774
- setIsCubistLoading(true);
1775
- sendMessage({ type: "LOGIN_REQUEST" });
1753
+ const login = useCallback6((params) => {
1754
+ if (isConnected) {
1755
+ const isEmailLogin = (params == null ? void 0 : params.email) && (params == null ? void 0 : params.password);
1756
+ if (isEmailLogin) {
1757
+ setIsCubistLoading(true);
1758
+ }
1759
+ penpalLogin(params).catch((error) => {
1760
+ setIsCubistLoading(false);
1761
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Login failed"));
1762
+ });
1776
1763
  }
1777
- }, [iframe, sendMessage]);
1778
- const signup = useCallback5((email, password) => {
1779
- if (iframe == null ? void 0 : iframe.contentWindow) {
1764
+ }, [isConnected, penpalLogin, onAuthError]);
1765
+ const signup = useCallback6((email, password) => {
1766
+ if (isConnected) {
1780
1767
  setIsCubistLoading(true);
1781
- sendMessage({
1782
- type: "SIGNUP_REQUEST",
1783
- payload: {
1784
- email,
1785
- password
1786
- },
1787
- requestId: `signup-${Date.now()}`
1768
+ penpalSignup(email, password).catch((error) => {
1769
+ setIsCubistLoading(false);
1770
+ onAuthError == null ? void 0 : onAuthError(error instanceof Error ? error : new Error("Signup failed"));
1788
1771
  });
1789
1772
  }
1790
- }, [iframe, sendMessage]);
1791
- const logout = useCallback5(() => {
1792
- sendMessage({ type: "LOGOUT_REQUEST" });
1773
+ }, [isConnected, penpalSignup, onAuthError]);
1774
+ const logout = useCallback6(() => {
1775
+ penpalLogout().catch((error) => {
1776
+ console.error("Logout error:", error);
1777
+ });
1793
1778
  setUser(null);
1794
1779
  setWallet({ address: null });
1795
1780
  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);
1781
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
1782
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1783
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.ACCESS_TOKEN);
1784
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.ID_TOKEN);
1785
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.EXPIRES_AT);
1786
+ localStorage.removeItem(CUBIST_USER_ID_KEY2);
1802
1787
  if (orgId) {
1803
- const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${env}`;
1788
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${env}`;
1804
1789
  localStorage.removeItem(cachedConfigKey);
1805
1790
  }
1806
- sessionStorage.removeItem(OIDC_TOKEN_KEY);
1791
+ sessionStorage.removeItem(OIDC_TOKEN_KEY2);
1807
1792
  setCubistClient(null);
1808
1793
  setCubistError(null);
1809
1794
  setPendingOidcToken(null);
1810
- }, [sendMessage, orgId, env]);
1811
- const addAccount = useCallback5(async (accountIndex) => {
1795
+ }, [penpalLogout, orgId, env]);
1796
+ const addAccount = useCallback6(async (accountIndex) => {
1812
1797
  if (!isAuthenticated || !user || !wallet.mnemonicId) {
1813
1798
  throw new Error("User must be authenticated and have a wallet to add an account");
1814
1799
  }
1800
+ if (!authService) {
1801
+ throw new Error("Auth service not connected");
1802
+ }
1815
1803
  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
- }
1804
+ await authService.addAccount({
1805
+ accountIndex,
1806
+ mnemonicId: wallet.mnemonicId,
1807
+ derivationPath: path,
1808
+ identityProof: {
1809
+ email: user.email,
1810
+ displayName: user.displayName,
1811
+ sub: user.sub,
1812
+ configured_mfa: user.configured_mfa
1828
1813
  }
1829
1814
  });
1830
- }, [sendMessage, isAuthenticated, user, wallet.mnemonicId]);
1815
+ }, [authService, isAuthenticated, user, wallet.mnemonicId]);
1831
1816
  useEffect5(() => {
1832
1817
  const hasOrgConfig = !!(orgConfig == null ? void 0 : orgConfig.walletProviderOrgID);
1833
1818
  const hasOidcToken = !!pendingOidcToken;
@@ -1877,20 +1862,20 @@ function AvaCloudWalletProvider({
1877
1862
  if (typeof window === "undefined") {
1878
1863
  return;
1879
1864
  }
1880
- const isAuthenticatedInStorage = localStorage.getItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED) === "true";
1865
+ const isAuthenticatedInStorage = localStorage.getItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED) === "true";
1881
1866
  if (!isAuthenticatedInStorage) {
1882
1867
  return;
1883
1868
  }
1884
- const existingOidcToken = sessionStorage.getItem(OIDC_TOKEN_KEY);
1869
+ const existingOidcToken = sessionStorage.getItem(OIDC_TOKEN_KEY2);
1885
1870
  if (existingOidcToken) {
1886
1871
  setPendingOidcToken(existingOidcToken);
1887
1872
  } else {
1888
1873
  try {
1889
- const tokensJson = localStorage.getItem(AUTH_TOKENS_KEY);
1874
+ const tokensJson = localStorage.getItem(AUTH_TOKENS_KEY2);
1890
1875
  if (tokensJson) {
1891
1876
  const tokens = JSON.parse(tokensJson);
1892
1877
  if (tokens.access_token) {
1893
- sessionStorage.setItem(OIDC_TOKEN_KEY, tokens.access_token);
1878
+ sessionStorage.setItem(OIDC_TOKEN_KEY2, tokens.access_token);
1894
1879
  setPendingOidcToken(tokens.access_token);
1895
1880
  }
1896
1881
  }
@@ -1928,7 +1913,7 @@ function useAvaCloudWallet() {
1928
1913
  }
1929
1914
 
1930
1915
  // src/components/LoginButton.tsx
1931
- import { useState as useState8 } from "react";
1916
+ import { useState as useState9 } from "react";
1932
1917
  import { Button as Button2, Dialog as Dialog3, DialogContent as DialogContent3, DialogTitle as DialogTitle2 } from "@avalabs/core-k2-components";
1933
1918
  import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1934
1919
  function LoginButton({
@@ -1937,7 +1922,7 @@ function LoginButton({
1937
1922
  ...props
1938
1923
  }) {
1939
1924
  const { isLoading } = useAvaCloudWallet();
1940
- const [isModalOpen, setIsModalOpen] = useState8(false);
1925
+ const [isModalOpen, setIsModalOpen] = useState9(false);
1941
1926
  const handleOpen = () => setIsModalOpen(true);
1942
1927
  const handleClose = () => setIsModalOpen(false);
1943
1928
  return /* @__PURE__ */ jsxs5(Fragment2, { children: [
@@ -1975,7 +1960,7 @@ function LoginButton({
1975
1960
  }
1976
1961
 
1977
1962
  // src/components/WalletButton.tsx
1978
- import { useState as useState16 } from "react";
1963
+ import { useState as useState17 } from "react";
1979
1964
  import {
1980
1965
  Button as Button8,
1981
1966
  Box as Box11,
@@ -1987,7 +1972,7 @@ import {
1987
1972
  } from "@avalabs/core-k2-components";
1988
1973
 
1989
1974
  // src/components/WalletCard.tsx
1990
- import { useState as useState15 } from "react";
1975
+ import { useState as useState16 } from "react";
1991
1976
  import {
1992
1977
  Typography as Typography10,
1993
1978
  Box as Box10,
@@ -2002,7 +1987,7 @@ import {
2002
1987
  } from "@avalabs/core-k2-components";
2003
1988
 
2004
1989
  // src/components/SendView.tsx
2005
- import { useState as useState11, useEffect as useEffect6 } from "react";
1990
+ import { useState as useState12, useEffect as useEffect6 } from "react";
2006
1991
  import {
2007
1992
  Box as Box3,
2008
1993
  Typography as Typography4,
@@ -2018,7 +2003,7 @@ import {
2018
2003
  import { Icon } from "@iconify/react";
2019
2004
 
2020
2005
  // src/hooks/useTransferTokens.ts
2021
- import { useCallback as useCallback6, useState as useState9 } from "react";
2006
+ import { useCallback as useCallback7, useState as useState10 } from "react";
2022
2007
  import { Secp256k1 } from "@cubist-labs/cubesigner-sdk";
2023
2008
  import { useQueryClient } from "@tanstack/react-query";
2024
2009
  import {
@@ -2031,7 +2016,7 @@ import {
2031
2016
  erc20Abi
2032
2017
  } from "viem";
2033
2018
  function useTransferTokens() {
2034
- const [state, setState] = useState9({
2019
+ const [state, setState] = useState10({
2035
2020
  isLoading: false,
2036
2021
  error: null,
2037
2022
  txHash: null,
@@ -2043,7 +2028,7 @@ function useTransferTokens() {
2043
2028
  const { wallet, cubistClient } = useAvaCloudWallet();
2044
2029
  const { publicClient } = useViem();
2045
2030
  const queryClient2 = useQueryClient();
2046
- const reset = useCallback6(() => {
2031
+ const reset = useCallback7(() => {
2047
2032
  setState({
2048
2033
  isLoading: false,
2049
2034
  error: null,
@@ -2054,7 +2039,7 @@ function useTransferTokens() {
2054
2039
  actualTotalFee: null
2055
2040
  });
2056
2041
  }, []);
2057
- const transfer = useCallback6(async (toAddress, amount) => {
2042
+ const transfer = useCallback7(async (toAddress, amount) => {
2058
2043
  var _a;
2059
2044
  if (!publicClient || !cubistClient || !(wallet == null ? void 0 : wallet.address)) {
2060
2045
  setState((prev) => ({
@@ -2140,7 +2125,7 @@ function useTransferTokens() {
2140
2125
  setState((prev) => ({ ...prev, isLoading: false }));
2141
2126
  }
2142
2127
  }, [publicClient, cubistClient, wallet == null ? void 0 : wallet.address, queryClient2]);
2143
- const transferERC20 = useCallback6(async (tokenAddress, toAddress, amount, decimals) => {
2128
+ const transferERC20 = useCallback7(async (tokenAddress, toAddress, amount, decimals) => {
2144
2129
  var _a;
2145
2130
  if (!publicClient || !cubistClient || !(wallet == null ? void 0 : wallet.address)) {
2146
2131
  setState((prev) => ({
@@ -2243,10 +2228,10 @@ function useTransferTokens() {
2243
2228
  }
2244
2229
 
2245
2230
  // src/hooks/useGasEstimation.ts
2246
- import { useCallback as useCallback7, useState as useState10 } from "react";
2231
+ import { useCallback as useCallback8, useState as useState11 } from "react";
2247
2232
  import { formatEther as formatEther2, parseEther as parseEther2 } from "viem";
2248
2233
  function useGasEstimation() {
2249
- const [state, setState] = useState10({
2234
+ const [state, setState] = useState11({
2250
2235
  isLoading: false,
2251
2236
  error: null,
2252
2237
  baseFee: null,
@@ -2255,7 +2240,7 @@ function useGasEstimation() {
2255
2240
  totalWithAmount: null
2256
2241
  });
2257
2242
  const { publicClient } = useViem();
2258
- const reset = useCallback7(() => {
2243
+ const reset = useCallback8(() => {
2259
2244
  setState({
2260
2245
  isLoading: false,
2261
2246
  error: null,
@@ -2265,7 +2250,7 @@ function useGasEstimation() {
2265
2250
  totalWithAmount: null
2266
2251
  });
2267
2252
  }, []);
2268
- const updateTotal = useCallback7((amount) => {
2253
+ const updateTotal = useCallback8((amount) => {
2269
2254
  if (!state.totalFee) return;
2270
2255
  const amountValue = Number.parseFloat(amount);
2271
2256
  if (Number.isNaN(amountValue)) return;
@@ -2275,7 +2260,7 @@ function useGasEstimation() {
2275
2260
  totalWithAmount: newTotal
2276
2261
  }));
2277
2262
  }, [state.totalFee]);
2278
- const estimateGas = useCallback7(async (toAddress, amount) => {
2263
+ const estimateGas = useCallback8(async (toAddress, amount) => {
2279
2264
  if (!publicClient) {
2280
2265
  setState((prev) => ({
2281
2266
  ...prev,
@@ -2549,7 +2534,7 @@ function SendFormView({
2549
2534
  const { data: tokenBalancesResponse } = useERC20Balances((wallet == null ? void 0 : wallet.address) || void 0, chainId == null ? void 0 : chainId.toString());
2550
2535
  const tokenBalances = tokenBalancesResponse;
2551
2536
  const { baseFee, priorityFee, totalFee, totalWithAmount, estimateGas, updateTotal } = useGasEstimation();
2552
- const [addressError, setAddressError] = useState11(null);
2537
+ const [addressError, setAddressError] = useState12(null);
2553
2538
  const handleRecipientChange = (value) => {
2554
2539
  if (value && !isAddress2(value)) {
2555
2540
  setAddressError("Invalid address format");
@@ -3077,9 +3062,9 @@ function FailureView({ recipient, amount, currencySymbol, error, onDone }) {
3077
3062
  function SendView({ onBack, onViewStateChange, selectedToken: initialToken }) {
3078
3063
  var _a;
3079
3064
  const { chainId } = useChainId();
3080
- const [recipient, setRecipient] = useState11("");
3081
- const [amount, setAmount] = useState11("");
3082
- const [selectedToken, setSelectedToken] = useState11(initialToken);
3065
+ const [recipient, setRecipient] = useState12("");
3066
+ const [amount, setAmount] = useState12("");
3067
+ const [selectedToken, setSelectedToken] = useState12(initialToken);
3083
3068
  const { transfer, transferERC20, error, isLoading, txHash, viewState, reset, actualBaseFee, actualPriorityFee, actualTotalFee } = useTransferTokens();
3084
3069
  const { data: blockchainInfo } = useBlockchain((chainId == null ? void 0 : chainId.toString()) || "");
3085
3070
  const { wallet } = useAvaCloudWallet();
@@ -3175,7 +3160,7 @@ function SendView({ onBack, onViewStateChange, selectedToken: initialToken }) {
3175
3160
  }
3176
3161
 
3177
3162
  // src/components/ReceiveView.tsx
3178
- import { useState as useState12 } from "react";
3163
+ import { useState as useState13 } from "react";
3179
3164
  import { QRCodeSVG } from "qrcode.react";
3180
3165
  import {
3181
3166
  Box as Box4,
@@ -3188,7 +3173,7 @@ import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
3188
3173
  function ReceiveView(_props) {
3189
3174
  const { wallet } = useAvaCloudWallet();
3190
3175
  const { chainId } = useChainId();
3191
- const [_copied, setCopied] = useState12(false);
3176
+ const [_copied, setCopied] = useState13(false);
3192
3177
  const theme = useTheme2();
3193
3178
  const { isDarkMode } = useThemeMode();
3194
3179
  if (!wallet.address) {
@@ -3268,7 +3253,7 @@ function ReceiveView(_props) {
3268
3253
  }
3269
3254
 
3270
3255
  // src/components/ExportView.tsx
3271
- import { useState as useState13 } from "react";
3256
+ import { useState as useState14, useCallback as useCallback9 } from "react";
3272
3257
  import {
3273
3258
  Box as Box5,
3274
3259
  Typography as Typography6,
@@ -3280,32 +3265,27 @@ import {
3280
3265
  } from "@avalabs/core-k2-components";
3281
3266
  import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
3282
3267
  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;
3268
+ const { wallet } = useAvaCloudWallet();
3269
+ const [showKey, _setShowKey] = useState14(false);
3270
+ const [copied, setCopied] = useState14(false);
3271
+ const [privateKey, _setPrivateKey] = useState14(null);
3272
+ const [error, setError] = useState14(null);
3273
+ const [isLoading, setIsLoading] = useState14(false);
3274
+ const handleExport = useCallback9(async () => {
3275
+ if (!wallet.address) {
3276
+ setError("No wallet address available");
3277
+ return;
3278
+ }
3279
+ setIsLoading(true);
3280
+ setError(null);
3290
3281
  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);
3282
+ setError("Private key export is not yet available. Please use the wallet provider directly.");
3305
3283
  } catch (err) {
3306
3284
  setError("Failed to export private key. Please try again.");
3285
+ } finally {
3286
+ setIsLoading(false);
3307
3287
  }
3308
- };
3288
+ }, [wallet.address]);
3309
3289
  const handleCopy = () => {
3310
3290
  if (privateKey) {
3311
3291
  navigator.clipboard.writeText(privateKey);
@@ -3326,8 +3306,9 @@ function ExportView({ onBack }) {
3326
3306
  variant: "contained",
3327
3307
  color: "warning",
3328
3308
  onClick: handleExport,
3309
+ disabled: isLoading,
3329
3310
  sx: { mb: 2 },
3330
- children: "Show Private Key"
3311
+ children: isLoading ? "Loading..." : "Show Private Key"
3331
3312
  }
3332
3313
  ) : /* @__PURE__ */ jsx13(Box5, { sx: { mb: 3 }, children: /* @__PURE__ */ jsxs9(Box5, { sx: {
3333
3314
  display: "flex",
@@ -3377,7 +3358,7 @@ function ExportView({ onBack }) {
3377
3358
  }
3378
3359
 
3379
3360
  // src/components/TokensView.tsx
3380
- import { useState as useState14 } from "react";
3361
+ import { useState as useState15 } from "react";
3381
3362
  import {
3382
3363
  Box as Box8,
3383
3364
  Tabs,
@@ -3777,7 +3758,7 @@ function NonFungibleList() {
3777
3758
  // src/components/TokensView.tsx
3778
3759
  import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
3779
3760
  function TokensView({ onSend }) {
3780
- const [activeTab, setActiveTab] = useState14("tokens");
3761
+ const [activeTab, setActiveTab] = useState15("tokens");
3781
3762
  const theme = useTheme3();
3782
3763
  const handleCopyAddress = (address) => {
3783
3764
  navigator.clipboard.writeText(address);
@@ -4017,8 +3998,8 @@ import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs16 } from "react/jsx-r
4017
3998
  function WalletCard({ onClose }) {
4018
3999
  const { user, wallet, isAuthenticated } = useAvaCloudWallet();
4019
4000
  const { balance, isLoadingBalance, currencySymbol, blockchain } = useGlacier();
4020
- const [currentView, setCurrentView] = useState15("main");
4021
- const [selectedToken, setSelectedToken] = useState15();
4001
+ const [currentView, setCurrentView] = useState16("main");
4002
+ const [selectedToken, setSelectedToken] = useState16();
4022
4003
  const theme = useTheme4();
4023
4004
  if (!isAuthenticated || !user) return null;
4024
4005
  const handleCopy = (e) => {
@@ -4210,7 +4191,7 @@ function WalletButton({
4210
4191
  ...props
4211
4192
  }) {
4212
4193
  const { isLoading, isAuthenticated, wallet } = useAvaCloudWallet();
4213
- const [isModalOpen, setIsModalOpen] = useState16(false);
4194
+ const [isModalOpen, setIsModalOpen] = useState17(false);
4214
4195
  const theme = useTheme5();
4215
4196
  const { isDarkMode } = useThemeMode();
4216
4197
  const handleOpen = () => setIsModalOpen(true);
@@ -4294,134 +4275,422 @@ function WalletButton({
4294
4275
  },
4295
4276
  children: displayAddress
4296
4277
  }
4297
- ),
4298
- /* @__PURE__ */ jsx21(
4299
- IconButton9,
4300
- {
4301
- size: "small",
4302
- onClick: handleCopy,
4303
- sx: { color: "text.secondary" },
4304
- children: /* @__PURE__ */ jsx21(CopyIcon5, {})
4278
+ ),
4279
+ /* @__PURE__ */ jsx21(
4280
+ IconButton9,
4281
+ {
4282
+ size: "small",
4283
+ onClick: handleCopy,
4284
+ sx: { color: "text.secondary" },
4285
+ children: /* @__PURE__ */ jsx21(CopyIcon5, {})
4286
+ }
4287
+ )
4288
+ ] })
4289
+ ]
4290
+ }
4291
+ ),
4292
+ isModalOpen && /* @__PURE__ */ jsx21(WalletCard, { onClose: handleClose })
4293
+ ] });
4294
+ }
4295
+
4296
+ // src/components/WalletDisplay.tsx
4297
+ import { useState as useState18 } from "react";
4298
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
4299
+ function WalletDisplay({
4300
+ className = "",
4301
+ truncateAddress = true,
4302
+ showAddAccount = true
4303
+ }) {
4304
+ const { wallet, addAccount, isAuthenticated } = useAvaCloudWallet();
4305
+ const [isAdding, setIsAdding] = useState18(false);
4306
+ const [accountIndex, setAccountIndex] = useState18(0);
4307
+ if (!isAuthenticated || !wallet.address) {
4308
+ return null;
4309
+ }
4310
+ const displayAddress = truncateAddress ? `${wallet.address.slice(0, 6)}...${wallet.address.slice(-4)}` : wallet.address;
4311
+ const handleAddAccount = async () => {
4312
+ try {
4313
+ setIsAdding(true);
4314
+ await addAccount(accountIndex);
4315
+ setAccountIndex((prev) => prev + 1);
4316
+ } catch (error) {
4317
+ console.error("Failed to add account:", error);
4318
+ } finally {
4319
+ setIsAdding(false);
4320
+ }
4321
+ };
4322
+ return /* @__PURE__ */ jsxs18("div", { className: `space-y-4 ${className}`, children: [
4323
+ /* @__PURE__ */ jsxs18("div", { className: "bg-gray-50 rounded-lg p-4", children: [
4324
+ /* @__PURE__ */ jsx22("div", { className: "text-sm text-gray-500", children: "Wallet Address" }),
4325
+ /* @__PURE__ */ jsx22("div", { className: "mt-1 font-mono text-sm break-all", children: displayAddress })
4326
+ ] }),
4327
+ showAddAccount && /* @__PURE__ */ jsx22(
4328
+ "button",
4329
+ {
4330
+ type: "button",
4331
+ onClick: handleAddAccount,
4332
+ disabled: isAdding,
4333
+ 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",
4334
+ children: isAdding ? "Adding Account..." : "Add Account"
4335
+ }
4336
+ )
4337
+ ] });
4338
+ }
4339
+
4340
+ // src/components/UserProfile.tsx
4341
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
4342
+ function UserProfile({
4343
+ className = "",
4344
+ showLogout = true
4345
+ }) {
4346
+ const { user, logout, isAuthenticated } = useAvaCloudWallet();
4347
+ if (!isAuthenticated || !user) {
4348
+ return null;
4349
+ }
4350
+ return /* @__PURE__ */ jsx23("div", { className: `space-y-4 ${className}`, children: /* @__PURE__ */ jsxs19("div", { className: "bg-white shadow rounded-lg p-6", children: [
4351
+ /* @__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" }) }),
4352
+ /* @__PURE__ */ jsx23("div", { className: "border-t border-gray-200", children: /* @__PURE__ */ jsxs19("dl", { children: [
4353
+ /* @__PURE__ */ jsxs19("div", { className: "bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6", children: [
4354
+ /* @__PURE__ */ jsx23("dt", { className: "text-sm font-medium text-gray-500", children: "Display Name" }),
4355
+ /* @__PURE__ */ jsx23("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.displayName })
4356
+ ] }),
4357
+ 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: [
4358
+ /* @__PURE__ */ jsx23("dt", { className: "text-sm font-medium text-gray-500", children: "Email address" }),
4359
+ /* @__PURE__ */ jsx23("dd", { className: "mt-1 text-sm text-gray-900 sm:col-span-2", children: user.email })
4360
+ ] }),
4361
+ user.configured_mfa && user.configured_mfa.length > 0 && /* @__PURE__ */ jsxs19("div", { children: [
4362
+ /* @__PURE__ */ jsx23("div", { className: "text-sm font-medium text-gray-500", children: "MFA Methods" }),
4363
+ /* @__PURE__ */ jsx23("div", { className: "mt-1 space-y-1", children: user.configured_mfa.map((method) => {
4364
+ const mfaMethod = typeof method === "string" ? { type: method } : method;
4365
+ return /* @__PURE__ */ jsx23(
4366
+ "div",
4367
+ {
4368
+ className: "text-sm text-gray-900",
4369
+ children: mfaMethod.type === "totp" ? "Authenticator App" : mfaMethod.name
4370
+ },
4371
+ mfaMethod.type === "fido" ? mfaMethod.id : `totp-${mfaMethod.type}`
4372
+ );
4373
+ }) })
4374
+ ] })
4375
+ ] }) }),
4376
+ showLogout && /* @__PURE__ */ jsx23("div", { className: "mt-6", children: /* @__PURE__ */ jsx23(
4377
+ "button",
4378
+ {
4379
+ type: "button",
4380
+ onClick: logout,
4381
+ 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",
4382
+ children: "Sign Out"
4383
+ }
4384
+ ) })
4385
+ ] }) });
4386
+ }
4387
+
4388
+ // src/hooks/usePostMessage.ts
4389
+ import { useCallback as useCallback10, useEffect as useEffect7, useRef as useRef4 } from "react";
4390
+ var globalAuthState = {
4391
+ signupInProgress: false,
4392
+ loginInProgress: false,
4393
+ lastSignupTimestamp: 0,
4394
+ lastLoginTimestamp: 0,
4395
+ processingMessageIds: /* @__PURE__ */ new Set()
4396
+ };
4397
+ function cleanupProcessedMessageIds() {
4398
+ if (globalAuthState.processingMessageIds.size > 100) {
4399
+ const messageIds = Array.from(globalAuthState.processingMessageIds);
4400
+ globalAuthState.processingMessageIds = new Set(messageIds.slice(-50));
4401
+ }
4402
+ }
4403
+ function usePostMessage({
4404
+ authServiceUrl,
4405
+ orgId,
4406
+ environment,
4407
+ iframe,
4408
+ isIframeReady,
4409
+ onAuthSuccess,
4410
+ onAuthError,
4411
+ onOidcReceived,
4412
+ onOrgConfigUpdate,
4413
+ setIsAuthenticated,
4414
+ setUser,
4415
+ setIsLoading,
4416
+ setIsIframeReady,
4417
+ cubistClient
4418
+ }) {
4419
+ const lastAuthStateRef = useRef4({
4420
+ isAuthenticated: false,
4421
+ userId: null,
4422
+ lastUpdateTime: 0
4423
+ });
4424
+ const hasRequestedOidcRef = useRef4(false);
4425
+ const isHandlingMessageRef = useRef4(false);
4426
+ const hasLoadedCacheRef = useRef4(false);
4427
+ useEffect7(() => {
4428
+ if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
4429
+ hasLoadedCacheRef.current = true;
4430
+ try {
4431
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${environment}`;
4432
+ const cachedConfigJson = localStorage.getItem(cachedConfigKey);
4433
+ if (cachedConfigJson) {
4434
+ const cachedConfig = JSON.parse(cachedConfigJson);
4435
+ const timestamp = cachedConfig._timestamp || 0;
4436
+ const isExpired = Date.now() - timestamp > 30 * 60 * 1e3;
4437
+ if (!isExpired) {
4438
+ const { _timestamp, ...configWithoutTimestamp } = cachedConfig;
4439
+ onOrgConfigUpdate(configWithoutTimestamp);
4440
+ }
4441
+ }
4442
+ } catch (error) {
4443
+ }
4444
+ }
4445
+ }, [orgId, environment, onOrgConfigUpdate]);
4446
+ const sendMessage = useCallback10((message) => {
4447
+ if (iframe == null ? void 0 : iframe.contentWindow) {
4448
+ try {
4449
+ if (message.type === "SIGNUP_REQUEST") {
4450
+ if (globalAuthState.signupInProgress) {
4451
+ return;
4452
+ }
4453
+ const now = Date.now();
4454
+ if (now - globalAuthState.lastSignupTimestamp < 3e3) {
4455
+ return;
4456
+ }
4457
+ globalAuthState.signupInProgress = true;
4458
+ globalAuthState.lastSignupTimestamp = now;
4459
+ let finalMessage = message;
4460
+ if (!message.requestId) {
4461
+ finalMessage = {
4462
+ ...message,
4463
+ requestId: `signup-${now}`
4464
+ };
4465
+ }
4466
+ let messageToSend = finalMessage;
4467
+ if (finalMessage.payload && typeof finalMessage.payload.email === "string" && typeof finalMessage.payload.password === "string") {
4468
+ messageToSend = {
4469
+ type: "SIGNUP_REQUEST",
4470
+ email: finalMessage.payload.email,
4471
+ password: finalMessage.payload.password,
4472
+ requestId: finalMessage.requestId || `signup-${now}`
4473
+ };
4474
+ }
4475
+ if ("requestId" in messageToSend && messageToSend.requestId) {
4476
+ globalAuthState.processingMessageIds.add(messageToSend.requestId);
4477
+ }
4478
+ iframe.contentWindow.postMessage(messageToSend, authServiceUrl);
4479
+ return;
4480
+ }
4481
+ if (message.type === "LOGIN_REQUEST") {
4482
+ if (globalAuthState.loginInProgress) {
4483
+ return;
4484
+ }
4485
+ const now = Date.now();
4486
+ if (now - globalAuthState.lastLoginTimestamp < 3e3) {
4487
+ return;
4488
+ }
4489
+ globalAuthState.loginInProgress = true;
4490
+ globalAuthState.lastLoginTimestamp = now;
4491
+ let finalMessage = message;
4492
+ if (!message.requestId) {
4493
+ finalMessage = {
4494
+ ...message,
4495
+ requestId: `login-${now}`
4496
+ };
4497
+ }
4498
+ if (finalMessage.requestId) {
4499
+ globalAuthState.processingMessageIds.add(finalMessage.requestId);
4500
+ }
4501
+ iframe.contentWindow.postMessage(finalMessage, authServiceUrl);
4502
+ return;
4503
+ }
4504
+ iframe.contentWindow.postMessage(message, authServiceUrl);
4505
+ } catch (error) {
4506
+ if (message.type === "SIGNUP_REQUEST") {
4507
+ globalAuthState.signupInProgress = false;
4508
+ }
4509
+ if (message.type === "LOGIN_REQUEST") {
4510
+ globalAuthState.loginInProgress = false;
4511
+ }
4512
+ }
4513
+ }
4514
+ }, [iframe, authServiceUrl]);
4515
+ useEffect7(() => {
4516
+ const handleMessage = async (event) => {
4517
+ var _a, _b, _c, _d, _e, _f, _g;
4518
+ if (isHandlingMessageRef.current) {
4519
+ return;
4520
+ }
4521
+ if (event.origin !== new URL(authServiceUrl).origin) {
4522
+ return;
4523
+ }
4524
+ if (typeof ((_a = event.data) == null ? void 0 : _a.type) !== "string") {
4525
+ return;
4526
+ }
4527
+ if (event.data.requestId && globalAuthState.processingMessageIds.has(event.data.requestId)) {
4528
+ return;
4529
+ }
4530
+ try {
4531
+ isHandlingMessageRef.current = true;
4532
+ if (event.data.type === "ERROR") {
4533
+ globalAuthState.signupInProgress = false;
4534
+ globalAuthState.loginInProgress = false;
4535
+ } else if (event.data.type === "AUTH_STATUS" && event.data.isAuthenticated) {
4536
+ globalAuthState.signupInProgress = false;
4537
+ globalAuthState.loginInProgress = false;
4538
+ cleanupProcessedMessageIds();
4539
+ } else if (event.data.type === "RECEIVE_OIDC") {
4540
+ globalAuthState.signupInProgress = false;
4541
+ globalAuthState.loginInProgress = false;
4542
+ }
4543
+ switch (event.data.type) {
4544
+ case "IFRAME_READY":
4545
+ setIsIframeReady(true);
4546
+ break;
4547
+ case "RECEIVE_OIDC":
4548
+ if (typeof ((_b = event.data.payload) == null ? void 0 : _b.idToken) === "string") {
4549
+ const oidcToken = event.data.payload.idToken;
4550
+ hasRequestedOidcRef.current = false;
4551
+ onOidcReceived == null ? void 0 : onOidcReceived(oidcToken);
4552
+ } else {
4553
+ hasRequestedOidcRef.current = false;
4554
+ }
4555
+ break;
4556
+ case "AUTH_STATUS": {
4557
+ const newIsAuthenticated = !!event.data.isAuthenticated;
4558
+ const newUserId = (_d = (_c = event.data.user) == null ? void 0 : _c.sub) != null ? _d : null;
4559
+ const now = Date.now();
4560
+ if (now - lastAuthStateRef.current.lastUpdateTime < 500) {
4561
+ return;
4562
+ }
4563
+ const authStateChanged = lastAuthStateRef.current.isAuthenticated !== newIsAuthenticated || lastAuthStateRef.current.userId !== newUserId;
4564
+ if (authStateChanged) {
4565
+ setIsAuthenticated(newIsAuthenticated);
4566
+ if (event.data.user) {
4567
+ const userInfo = {
4568
+ email: event.data.user.email,
4569
+ sub: event.data.user.sub,
4570
+ configured_mfa: [],
4571
+ displayName: event.data.user.nickname || event.data.user.name || ((_e = event.data.user.email) == null ? void 0 : _e.split("@")[0]) || "User",
4572
+ rawUserData: event.data.user
4573
+ };
4574
+ setUser(userInfo);
4575
+ if (newIsAuthenticated && !cubistClient && !hasRequestedOidcRef.current) {
4576
+ hasRequestedOidcRef.current = true;
4577
+ sendMessage({ type: "GET_OIDC" });
4578
+ return;
4579
+ }
4580
+ } else {
4581
+ setUser(null);
4582
+ localStorage.removeItem(AUTH_TOKENS_KEY2);
4583
+ localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
4584
+ sessionStorage.removeItem(OIDC_TOKEN_KEY2);
4585
+ }
4586
+ lastAuthStateRef.current = {
4587
+ isAuthenticated: newIsAuthenticated,
4588
+ userId: newUserId,
4589
+ lastUpdateTime: now
4590
+ };
4591
+ if (newIsAuthenticated && event.data.user) {
4592
+ if (!hasRequestedOidcRef.current) {
4593
+ if (event.data.tokens) {
4594
+ localStorage.setItem(AUTH_TOKENS_KEY2, JSON.stringify(event.data.tokens));
4595
+ }
4596
+ onAuthSuccess == null ? void 0 : onAuthSuccess();
4597
+ }
4305
4598
  }
4306
- )
4307
- ] })
4308
- ]
4599
+ }
4600
+ if (event.data.orgConfig && onOrgConfigUpdate) {
4601
+ onOrgConfigUpdate(event.data.orgConfig);
4602
+ if (orgId) {
4603
+ try {
4604
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY2}-${orgId}-${environment}`;
4605
+ const configWithTimestamp = {
4606
+ ...event.data.orgConfig,
4607
+ _timestamp: Date.now()
4608
+ };
4609
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
4610
+ } catch (error) {
4611
+ }
4612
+ }
4613
+ }
4614
+ if (!hasRequestedOidcRef.current) {
4615
+ setIsLoading(false);
4616
+ }
4617
+ break;
4618
+ }
4619
+ case "REGISTER_SUCCESS": {
4620
+ const userId = (_f = event.data.payload) == null ? void 0 : _f.userId;
4621
+ if (userId) {
4622
+ localStorage.setItem(CUBIST_USER_ID_KEY2, userId);
4623
+ if (!hasRequestedOidcRef.current) {
4624
+ hasRequestedOidcRef.current = true;
4625
+ sendMessage({ type: "GET_OIDC" });
4626
+ }
4627
+ }
4628
+ break;
4629
+ }
4630
+ case "ERROR":
4631
+ if (event.data.error === "User not authenticated in iframe") {
4632
+ isHandlingMessageRef.current = false;
4633
+ return;
4634
+ }
4635
+ onAuthError == null ? void 0 : onAuthError(new Error((_g = event.data.error) != null ? _g : "Unknown error"));
4636
+ setIsLoading(false);
4637
+ break;
4638
+ }
4639
+ } finally {
4640
+ isHandlingMessageRef.current = false;
4309
4641
  }
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);
4642
+ };
4643
+ window.addEventListener("message", handleMessage);
4644
+ return () => window.removeEventListener("message", handleMessage);
4645
+ }, [
4646
+ authServiceUrl,
4647
+ onAuthError,
4648
+ onAuthSuccess,
4649
+ onOidcReceived,
4650
+ onOrgConfigUpdate,
4651
+ setIsAuthenticated,
4652
+ setIsIframeReady,
4653
+ setIsLoading,
4654
+ setUser,
4655
+ sendMessage,
4656
+ cubistClient,
4657
+ orgId,
4658
+ environment
4659
+ ]);
4660
+ useEffect7(() => {
4661
+ if (isIframeReady && (iframe == null ? void 0 : iframe.contentWindow)) {
4662
+ sendMessage({
4663
+ type: "CHECK_AUTH_STATUS",
4664
+ payload: {
4665
+ orgId,
4666
+ environment
4667
+ }
4668
+ });
4339
4669
  }
4670
+ }, [isIframeReady, iframe, sendMessage, orgId, environment]);
4671
+ return {
4672
+ sendMessage
4340
4673
  };
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
4674
  }
4406
4675
 
4407
4676
  // src/hooks/useSignMessage.ts
4408
- import { useCallback as useCallback8, useState as useState18 } from "react";
4677
+ import { useCallback as useCallback11, useState as useState19 } from "react";
4409
4678
  import { Secp256k1 as Secp256k12 } from "@cubist-labs/cubesigner-sdk";
4410
4679
  function useSignMessage() {
4411
- const [state, setState] = useState18({
4680
+ const [state, setState] = useState19({
4412
4681
  isLoading: false,
4413
4682
  error: null,
4414
4683
  signature: null
4415
4684
  });
4416
4685
  const { wallet, cubistClient } = useAvaCloudWallet();
4417
- const reset = useCallback8(() => {
4686
+ const reset = useCallback11(() => {
4418
4687
  setState({
4419
4688
  isLoading: false,
4420
4689
  error: null,
4421
4690
  signature: null
4422
4691
  });
4423
4692
  }, []);
4424
- const signMessage = useCallback8(async (message) => {
4693
+ const signMessage = useCallback11(async (message) => {
4425
4694
  if (!cubistClient || !wallet.address) {
4426
4695
  setState((prev) => ({
4427
4696
  ...prev,
@@ -4458,10 +4727,11 @@ function useSignMessage() {
4458
4727
  }
4459
4728
 
4460
4729
  // src/hooks/useSignTransaction.ts
4461
- import { useCallback as useCallback9, useState as useState19 } from "react";
4730
+ import { useCallback as useCallback12, useState as useState20 } from "react";
4462
4731
  import { Secp256k1 as Secp256k13 } from "@cubist-labs/cubesigner-sdk";
4732
+ import { toHex } from "viem";
4463
4733
  function useSignTransaction() {
4464
- const [state, setState] = useState19({
4734
+ const [state, setState] = useState20({
4465
4735
  isLoading: false,
4466
4736
  error: null,
4467
4737
  signature: null,
@@ -4469,7 +4739,7 @@ function useSignTransaction() {
4469
4739
  });
4470
4740
  const { wallet, cubistClient } = useAvaCloudWallet();
4471
4741
  const { publicClient } = useViem();
4472
- const reset = useCallback9(() => {
4742
+ const reset = useCallback12(() => {
4473
4743
  setState({
4474
4744
  isLoading: false,
4475
4745
  error: null,
@@ -4477,8 +4747,7 @@ function useSignTransaction() {
4477
4747
  signedTransaction: null
4478
4748
  });
4479
4749
  }, []);
4480
- const signTransaction = useCallback9(async (transaction) => {
4481
- var _a, _b, _c, _d;
4750
+ const signTransaction = useCallback12(async (transaction) => {
4482
4751
  if (!(wallet == null ? void 0 : wallet.address)) {
4483
4752
  setState((prev) => ({
4484
4753
  ...prev,
@@ -4514,13 +4783,13 @@ function useSignTransaction() {
4514
4783
  chain_id: publicClient.chain.id,
4515
4784
  tx: {
4516
4785
  to: transaction.to || void 0,
4517
- value: (_a = transaction.value) == null ? void 0 : _a.toString(),
4786
+ value: transaction.value !== void 0 ? toHex(transaction.value) : void 0,
4518
4787
  data: transaction.data || "0x",
4519
- nonce: (_b = transaction.nonce) == null ? void 0 : _b.toString(),
4788
+ nonce: transaction.nonce !== void 0 ? toHex(transaction.nonce) : void 0,
4520
4789
  type: "0x2",
4521
4790
  // EIP-1559
4522
- maxFeePerGas: (_c = transaction.maxFeePerGas) == null ? void 0 : _c.toString(),
4523
- maxPriorityFeePerGas: (_d = transaction.maxPriorityFeePerGas) == null ? void 0 : _d.toString()
4791
+ maxFeePerGas: transaction.maxFeePerGas !== void 0 ? toHex(transaction.maxFeePerGas) : void 0,
4792
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas !== void 0 ? toHex(transaction.maxPriorityFeePerGas) : void 0
4524
4793
  }
4525
4794
  };
4526
4795
  const sig = await key.signEvm(signReq);
@@ -4546,11 +4815,11 @@ function useSignTransaction() {
4546
4815
  }
4547
4816
 
4548
4817
  // src/hooks/useUserWallets.ts
4549
- import { useCallback as useCallback10, useState as useState20 } from "react";
4818
+ import { useCallback as useCallback13, useState as useState21 } from "react";
4550
4819
  function useUserWallets() {
4551
- const [error, setError] = useState20(null);
4552
- const [isLoading, setIsLoading] = useState20(false);
4553
- const getWallets = useCallback10(async (client) => {
4820
+ const [error, setError] = useState21(null);
4821
+ const [isLoading, setIsLoading] = useState21(false);
4822
+ const getWallets = useCallback13(async (client) => {
4554
4823
  setIsLoading(true);
4555
4824
  setError(null);
4556
4825
  try {
@@ -4590,15 +4859,30 @@ function avaCloudWallet() {
4590
4859
  id: "avaCloudWallet",
4591
4860
  name: "AvaCloud Wallet",
4592
4861
  type: "injected",
4593
- async connect() {
4862
+ async connect(parameters) {
4863
+ const { withCapabilities } = parameters != null ? parameters : {};
4594
4864
  const { walletClient } = useViem();
4595
4865
  if (!walletClient) {
4596
4866
  throw new Error("AvaCloud Wallet not connected");
4597
4867
  }
4598
4868
  const accounts = await this.getAccounts();
4599
4869
  const chainId = await this.getChainId();
4870
+ if (withCapabilities) {
4871
+ const result = {
4872
+ accounts: accounts.map((address) => ({
4873
+ address,
4874
+ capabilities: {}
4875
+ })),
4876
+ chainId
4877
+ };
4878
+ config.emitter.emit("connect", { accounts, chainId });
4879
+ return result;
4880
+ }
4600
4881
  config.emitter.emit("connect", { accounts, chainId });
4601
- return { accounts, chainId };
4882
+ return {
4883
+ accounts,
4884
+ chainId
4885
+ };
4602
4886
  },
4603
4887
  async disconnect() {
4604
4888
  config.emitter.emit("disconnect");
@@ -4645,7 +4929,7 @@ function avaCloudWallet() {
4645
4929
  }
4646
4930
 
4647
4931
  // src/providers/GaslessProvider.tsx
4648
- import { createContext as createContext5, useContext as useContext5, useEffect as useEffect7, useState as useState21 } from "react";
4932
+ import { createContext as createContext5, useContext as useContext5, useEffect as useEffect8, useState as useState22 } from "react";
4649
4933
  import { jsx as jsx24 } from "react/jsx-runtime";
4650
4934
  function validateGaslessConfig(config) {
4651
4935
  if (!config || typeof config !== "object") {
@@ -4681,13 +4965,13 @@ function validateGaslessConfig(config) {
4681
4965
  }
4682
4966
  var GaslessContext = createContext5(null);
4683
4967
  function GaslessProvider({ children, config, fetchParams }) {
4684
- const [state, setState] = useState21({
4968
+ const [state, setState] = useState22({
4685
4969
  isLoading: false,
4686
4970
  error: null,
4687
4971
  config: null
4688
4972
  });
4689
4973
  const { authServiceUrl, environment } = useAvaCloudWallet();
4690
- useEffect7(() => {
4974
+ useEffect8(() => {
4691
4975
  if (config) {
4692
4976
  const validationError = validateGaslessConfig(config);
4693
4977
  if (validationError) {
@@ -4774,9 +5058,16 @@ function GaslessProvider({ children, config, fetchParams }) {
4774
5058
  }, [config, fetchParams, authServiceUrl, environment]);
4775
5059
  return /* @__PURE__ */ jsx24(GaslessContext.Provider, { value: state, children });
4776
5060
  }
5061
+ function useGaslessConfig() {
5062
+ const ctx = useContext5(GaslessContext);
5063
+ if (!ctx) {
5064
+ throw new Error("useGaslessConfig must be used within a GaslessProvider");
5065
+ }
5066
+ return ctx;
5067
+ }
4777
5068
 
4778
5069
  // src/hooks/useGaslessTransaction.ts
4779
- import { useCallback as useCallback11, useState as useState22 } from "react";
5070
+ import { useCallback as useCallback14, useState as useState23 } from "react";
4780
5071
  import * as ethers from "ethers";
4781
5072
  import axios from "axios";
4782
5073
  import { Secp256k1 as Secp256k14 } from "@cubist-labs/cubesigner-sdk";
@@ -4802,7 +5093,7 @@ var FORWARDER_GET_NONCE_ABI = [
4802
5093
  }
4803
5094
  ];
4804
5095
  function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContractAddress, abi: defaultAbi }) {
4805
- const [state, setState] = useState22({
5096
+ const [state, setState] = useState23({
4806
5097
  isLoading: false,
4807
5098
  error: null,
4808
5099
  txHash: null
@@ -4810,14 +5101,14 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4810
5101
  const config = gaslessConfig;
4811
5102
  const { wallet, cubistClient } = useAvaCloudWallet();
4812
5103
  useViem();
4813
- const reset = useCallback11(() => {
5104
+ const reset = useCallback14(() => {
4814
5105
  setState({
4815
5106
  isLoading: false,
4816
5107
  error: null,
4817
5108
  txHash: null
4818
5109
  });
4819
5110
  }, []);
4820
- const validateConfig = useCallback11((config2) => {
5111
+ const validateConfig = useCallback14((config2) => {
4821
5112
  if (!config2) {
4822
5113
  return "Gasless configuration is not available. Please ensure GaslessProvider is properly configured.";
4823
5114
  }
@@ -4851,7 +5142,7 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4851
5142
  }
4852
5143
  return null;
4853
5144
  }, []);
4854
- const sendGaslessTransaction = useCallback11(async ({
5145
+ const sendGaslessTransaction = useCallback14(async ({
4855
5146
  functionName,
4856
5147
  args = [],
4857
5148
  abi: overrideAbi,
@@ -4936,7 +5227,12 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4936
5227
  const suffixParts = config.suffix.match(/^(\w+)\s+(.+)\)$/);
4937
5228
  if (suffixParts) {
4938
5229
  const [, , suffixName] = suffixParts;
4939
- message[suffixName] = Buffer.from(config.suffix, "utf8");
5230
+ const encoder = new TextEncoder();
5231
+ const suffixBytes = encoder.encode(config.suffix);
5232
+ const paddedBytes = new Uint8Array(32);
5233
+ paddedBytes.set(suffixBytes.slice(0, 32));
5234
+ const hexString = Array.from(paddedBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
5235
+ message[suffixName] = "0x" + hexString;
4940
5236
  }
4941
5237
  }
4942
5238
  const domain = {
@@ -4945,12 +5241,22 @@ function useGaslessTransaction({ gaslessConfig, contractAddress: defaultContract
4945
5241
  chainId: (await provider.getNetwork()).chainId,
4946
5242
  verifyingContract: config.forwarderAddress
4947
5243
  };
4948
- const digest = ethers.utils._TypedDataEncoder.hash(domain, {
4949
- [config.requestType]: types[config.requestType]
4950
- }, message);
4951
5244
  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")
5245
+ const sigResp = await key.signEip712({
5246
+ chain_id: domain.chainId,
5247
+ typed_data: {
5248
+ domain: {
5249
+ name: domain.name,
5250
+ version: domain.version,
5251
+ chainId: `0x${domain.chainId.toString(16)}`,
5252
+ verifyingContract: domain.verifyingContract
5253
+ },
5254
+ primaryType: config.requestType,
5255
+ types: {
5256
+ [config.requestType]: types[config.requestType]
5257
+ },
5258
+ message
5259
+ }
4954
5260
  });
4955
5261
  const signatureData = sigResp.data().signature;
4956
5262
  const signature = signatureData.startsWith("0x") ? signatureData : `0x${signatureData}`;
@@ -5040,6 +5346,7 @@ export {
5040
5346
  useAvaCloudWallet,
5041
5347
  useBlockchain,
5042
5348
  useChainId,
5349
+ useGaslessConfig,
5043
5350
  useGaslessTransaction,
5044
5351
  useGlacier,
5045
5352
  usePostMessage,