@avalabs/avacloud-waas-react 1.0.1 → 1.0.3

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @avalabs/avacloud-waas-react
2
2
 
3
- Official React SDK for AvaCloud Authentication and wallet integration. This library provides a seamless way to integrate AvaCloud authentication and wallet functionality into your React applications.
3
+ Official React SDK for AvaCloud Wallet-as-a-Service (WaaS) integration. This library provides a seamless way to integrate AvaCloud wallet functionality into your React applications.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@avalabs/avacloud-waas-react.svg)](https://www.npmjs.com/package/@avalabs/avacloud-waas-react)
6
6
  [![License](https://img.shields.io/npm/l/@avalabs/avacloud-waas-react.svg)](https://github.com/ava-labs/avacloud-waas-react/blob/main/LICENSE)
@@ -38,7 +38,7 @@ function App() {
38
38
  }
39
39
  ```
40
40
 
41
- Use the authentication hooks and components in your application:
41
+ Use the wallet hooks and components in your application:
42
42
 
43
43
  ```tsx
44
44
  import { useAvaCloudWallet, LoginButton, WalletDisplay } from '@avalabs/avacloud-waas-react';
@@ -69,11 +69,11 @@ function YourComponent() {
69
69
 
70
70
  ### AvaCloudWalletProvider
71
71
 
72
- The main provider component that wraps your application and provides authentication context.
72
+ The main provider component that wraps your application and provides wallet context.
73
73
 
74
74
  ```tsx
75
75
  <AvaCloudWalletProvider
76
- authServiceUrl="https://auth.avacloud.io"
76
+ orgId="your-avacloud-org-id" // Required
77
77
  chainId={43113}
78
78
  darkMode={false}
79
79
  onAuthSuccess={(user) => console.log('Auth success', user)}
@@ -88,7 +88,8 @@ The main provider component that wraps your application and provides authenticat
88
88
 
89
89
  | Prop | Type | Description |
90
90
  |------|------|-------------|
91
- | `authServiceUrl` | `string` | URL of the AvaCloud authentication service |
91
+ | `orgId` | `string` | Required AvaCloud organization ID |
92
+ | `authServiceUrl` | `string` | (Optional) URL of the AvaCloud authentication service. Defaults to AvaCloud's production auth service. |
92
93
  | `chainId` | `number` | (Optional) EVM chain ID to use (defaults to Avalanche Fuji Testnet - 43113) |
93
94
  | `darkMode` | `boolean` | (Optional) Whether to use dark mode for UI components |
94
95
  | `onAuthSuccess` | `(user: Auth0User) => void` | (Optional) Callback called when authentication is successful |
@@ -111,7 +112,7 @@ The main provider component that wraps your application and provides authenticat
111
112
 
112
113
  ### useAvaCloudWallet
113
114
 
114
- The main hook for accessing authentication state and methods.
115
+ The main hook for accessing wallet state and methods.
115
116
 
116
117
  ```tsx
117
118
  const {
@@ -192,6 +193,22 @@ const handleTransfer = async () => {
192
193
  };
193
194
  ```
194
195
 
196
+ ### useUserWallets
197
+
198
+ Hook for accessing and managing user wallets.
199
+
200
+ ```tsx
201
+ const { wallets, isLoading, error } = useUserWallets();
202
+ ```
203
+
204
+ ### useChainId
205
+
206
+ Hook for accessing and setting the current chain ID.
207
+
208
+ ```tsx
209
+ const { chainId, setChainId } = useChainId();
210
+ ```
211
+
195
212
  ## Advanced Usage
196
213
 
197
214
  ### Theme Customization
@@ -261,7 +278,7 @@ MIT © [Ava Labs, Inc.](https://github.com/ava-labs)
261
278
 
262
279
  ## Using the AvaCloud Organization ID
263
280
 
264
- The `AvaCloudWalletProvider` requires an AvaCloud organization ID (`orgId`). This will be used to fetch the organization configuration from the AvaCloud API, which includes the mapping to the appropriate Cubist organization ID used for wallet operations.
281
+ The `AvaCloudWalletProvider` requires an AvaCloud organization ID (`orgId`). This is used to fetch the organization configuration from the AvaCloud API, which includes the mapping to the appropriate wallet service organization ID used for wallet operations.
265
282
 
266
283
  ```jsx
267
284
  import { AvaCloudWalletProvider } from '@avalabs/avacloud-waas-react';
@@ -269,7 +286,6 @@ import { AvaCloudWalletProvider } from '@avalabs/avacloud-waas-react';
269
286
  function App() {
270
287
  return (
271
288
  <AvaCloudWalletProvider
272
- authServiceUrl="https://ac-auth-service.vercel.app/"
273
289
  orgId="your-avacloud-org-id" // Required AvaCloud organization ID
274
290
  >
275
291
  <YourApp />
@@ -281,7 +297,7 @@ function App() {
281
297
  When provided, the `orgId` will be used to:
282
298
 
283
299
  1. Fetch the organization configuration from the AvaCloud API
284
- 2. Map to a Cubist organization ID as specified in the configuration
285
- 3. Use the mapped ID for Cubist authentication and wallet operations
300
+ 2. Map to the appropriate wallet service organization ID
301
+ 3. Use the mapped ID for wallet operations
286
302
 
287
- This enables organizations to have their AvaCloud identity seamlessly map to their Cubist wallets.
303
+ This enables organizations to have their AvaCloud identity seamlessly map to their WaaS wallets.
package/dist/index.d.mts CHANGED
@@ -1,7 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as _cubist_labs_cubesigner_sdk from '@cubist-labs/cubesigner-sdk';
3
3
  import { IdentityProof, CubeSignerClient } from '@cubist-labs/cubesigner-sdk';
4
- import { QueryClient } from '@tanstack/react-query';
5
4
  import { PropsWithChildren, ButtonHTMLAttributes } from 'react';
6
5
  import { ButtonProps } from '@avalabs/core-k2-components';
7
6
  import { Hex, TransactionRequest, Signature, Hash } from 'viem';
@@ -64,6 +63,44 @@ interface Auth0User$1 {
64
63
  [key: string]: unknown;
65
64
  }
66
65
 
66
+ /**
67
+ * Organization configuration types
68
+ */
69
+ /**
70
+ * Admin portal settings within organization configuration
71
+ */
72
+ interface AdminPortalSettings {
73
+ /**
74
+ * Array of enabled social login providers
75
+ * Possible values: 'google', 'facebook', 'x', 'twitter', 'apple'
76
+ * Note: Some providers like 'facebook' may be in development and not fully supported
77
+ */
78
+ socialLogins?: string[];
79
+ [key: string]: unknown;
80
+ }
81
+ /**
82
+ * Organization configuration interface
83
+ */
84
+ interface OrgConfig {
85
+ /** Primary key of the organization */
86
+ PKey?: string;
87
+ /** Secondary key of the organization */
88
+ SKey?: string;
89
+ /** Organization ID */
90
+ orgID?: string;
91
+ /** Wallet provider organization ID used for Cubist */
92
+ walletProviderOrgID?: string;
93
+ /** Admin portal settings */
94
+ adminPortalSettings?: AdminPortalSettings;
95
+ /** Allowed origins for CORS */
96
+ originAllowlist?: string[];
97
+ /** Timestamp when the config was created */
98
+ createdAt?: number;
99
+ /** Timestamp when the config was last updated */
100
+ updatedAt?: number;
101
+ [key: string]: unknown;
102
+ }
103
+
67
104
  /**
68
105
  * Authentication message payload structure
69
106
  */
@@ -114,6 +151,12 @@ declare enum VM {
114
151
  PVM = "PVM"
115
152
  }
116
153
 
154
+ type QueryClient = {
155
+ invalidateQueries: (options: {
156
+ queryKey: string[];
157
+ }) => void;
158
+ };
159
+
117
160
  /**
118
161
  * Possible AvaCloud environments
119
162
  */
@@ -240,7 +283,7 @@ type AuthMessage = IframeReadyMessage | CheckAuthStatusMessage | AuthStatusMessa
240
283
  */
241
284
  interface AvaCloudWalletProviderProps {
242
285
  children: React.ReactNode;
243
- authServiceUrl: string;
286
+ authServiceUrl?: string;
244
287
  orgId: string;
245
288
  chainId?: number;
246
289
  darkMode?: boolean;
@@ -257,7 +300,7 @@ interface AvaCloudWalletContextType {
257
300
  isLoading: boolean;
258
301
  user: UserInfo | null;
259
302
  wallet: WalletInfo;
260
- orgConfig: Record<string, unknown> | null;
303
+ orgConfig: OrgConfig | null;
261
304
  logout: () => void;
262
305
  loginWithCubist: (oidcToken?: string) => Promise<void>;
263
306
  cubistClient: CubeSignerClient | null;
@@ -470,4 +513,4 @@ interface UseUserWalletsResult {
470
513
  }
471
514
  declare function useUserWallets(): UseUserWalletsResult;
472
515
 
473
- export { type AddAccountMessage, type Auth0User, type AuthMessage, type AuthMessagePayload, type AuthStateUpdateMessage, type AuthStatusMessage, type AvaCloudEnvironment, type AvaCloudWalletContextType, AvaCloudWalletProvider, type AvaCloudWalletProviderProps, type BaseAuthMessage, type CheckAuthStatusMessage, type CubistWalletInfo, type ErrorMessage, ExportView, type GetOidcMessage, type IframeReadyMessage, LoginButton, type LoginRequestMessage, type LogoutRequestMessage, type MessageType, type ReceiveOidcMessage, ReceiveView, type RegisterMessage, type RegisterPayload, type RegisterSuccessMessage, SendView, ThemeProvider, TokensView, type UserInfo, UserProfile, VM, WalletButton, WalletCard, WalletDisplay, type WalletInfo, type WalletKeysErrorMessage, type WalletKeysUpdateMessage, useAuth, useAvaCloudWallet, useChainId, usePostMessage, useSignMessage, useSignTransaction, useThemeMode, useTransferTokens, useUserWallets };
516
+ export { type AddAccountMessage, type AdminPortalSettings, type Auth0User, type AuthMessage, type AuthMessagePayload, type AuthStateUpdateMessage, type AuthStatusMessage, type AvaCloudEnvironment, type AvaCloudWalletContextType, AvaCloudWalletProvider, type AvaCloudWalletProviderProps, type BaseAuthMessage, type CheckAuthStatusMessage, type CubistWalletInfo, type ErrorMessage, ExportView, type GetOidcMessage, type IframeReadyMessage, LoginButton, type LoginRequestMessage, type LogoutRequestMessage, type MessageType, type OrgConfig, type ReceiveOidcMessage, ReceiveView, type RegisterMessage, type RegisterPayload, type RegisterSuccessMessage, SendView, ThemeProvider, TokensView, type UserInfo, UserProfile, VM, WalletButton, WalletCard, WalletDisplay, type WalletInfo, type WalletKeysErrorMessage, type WalletKeysUpdateMessage, useAuth, useAvaCloudWallet, useChainId, usePostMessage, useSignMessage, useSignTransaction, useThemeMode, useTransferTokens, useUserWallets };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as _cubist_labs_cubesigner_sdk from '@cubist-labs/cubesigner-sdk';
3
3
  import { IdentityProof, CubeSignerClient } from '@cubist-labs/cubesigner-sdk';
4
- import { QueryClient } from '@tanstack/react-query';
5
4
  import { PropsWithChildren, ButtonHTMLAttributes } from 'react';
6
5
  import { ButtonProps } from '@avalabs/core-k2-components';
7
6
  import { Hex, TransactionRequest, Signature, Hash } from 'viem';
@@ -64,6 +63,44 @@ interface Auth0User$1 {
64
63
  [key: string]: unknown;
65
64
  }
66
65
 
66
+ /**
67
+ * Organization configuration types
68
+ */
69
+ /**
70
+ * Admin portal settings within organization configuration
71
+ */
72
+ interface AdminPortalSettings {
73
+ /**
74
+ * Array of enabled social login providers
75
+ * Possible values: 'google', 'facebook', 'x', 'twitter', 'apple'
76
+ * Note: Some providers like 'facebook' may be in development and not fully supported
77
+ */
78
+ socialLogins?: string[];
79
+ [key: string]: unknown;
80
+ }
81
+ /**
82
+ * Organization configuration interface
83
+ */
84
+ interface OrgConfig {
85
+ /** Primary key of the organization */
86
+ PKey?: string;
87
+ /** Secondary key of the organization */
88
+ SKey?: string;
89
+ /** Organization ID */
90
+ orgID?: string;
91
+ /** Wallet provider organization ID used for Cubist */
92
+ walletProviderOrgID?: string;
93
+ /** Admin portal settings */
94
+ adminPortalSettings?: AdminPortalSettings;
95
+ /** Allowed origins for CORS */
96
+ originAllowlist?: string[];
97
+ /** Timestamp when the config was created */
98
+ createdAt?: number;
99
+ /** Timestamp when the config was last updated */
100
+ updatedAt?: number;
101
+ [key: string]: unknown;
102
+ }
103
+
67
104
  /**
68
105
  * Authentication message payload structure
69
106
  */
@@ -114,6 +151,12 @@ declare enum VM {
114
151
  PVM = "PVM"
115
152
  }
116
153
 
154
+ type QueryClient = {
155
+ invalidateQueries: (options: {
156
+ queryKey: string[];
157
+ }) => void;
158
+ };
159
+
117
160
  /**
118
161
  * Possible AvaCloud environments
119
162
  */
@@ -240,7 +283,7 @@ type AuthMessage = IframeReadyMessage | CheckAuthStatusMessage | AuthStatusMessa
240
283
  */
241
284
  interface AvaCloudWalletProviderProps {
242
285
  children: React.ReactNode;
243
- authServiceUrl: string;
286
+ authServiceUrl?: string;
244
287
  orgId: string;
245
288
  chainId?: number;
246
289
  darkMode?: boolean;
@@ -257,7 +300,7 @@ interface AvaCloudWalletContextType {
257
300
  isLoading: boolean;
258
301
  user: UserInfo | null;
259
302
  wallet: WalletInfo;
260
- orgConfig: Record<string, unknown> | null;
303
+ orgConfig: OrgConfig | null;
261
304
  logout: () => void;
262
305
  loginWithCubist: (oidcToken?: string) => Promise<void>;
263
306
  cubistClient: CubeSignerClient | null;
@@ -470,4 +513,4 @@ interface UseUserWalletsResult {
470
513
  }
471
514
  declare function useUserWallets(): UseUserWalletsResult;
472
515
 
473
- export { type AddAccountMessage, type Auth0User, type AuthMessage, type AuthMessagePayload, type AuthStateUpdateMessage, type AuthStatusMessage, type AvaCloudEnvironment, type AvaCloudWalletContextType, AvaCloudWalletProvider, type AvaCloudWalletProviderProps, type BaseAuthMessage, type CheckAuthStatusMessage, type CubistWalletInfo, type ErrorMessage, ExportView, type GetOidcMessage, type IframeReadyMessage, LoginButton, type LoginRequestMessage, type LogoutRequestMessage, type MessageType, type ReceiveOidcMessage, ReceiveView, type RegisterMessage, type RegisterPayload, type RegisterSuccessMessage, SendView, ThemeProvider, TokensView, type UserInfo, UserProfile, VM, WalletButton, WalletCard, WalletDisplay, type WalletInfo, type WalletKeysErrorMessage, type WalletKeysUpdateMessage, useAuth, useAvaCloudWallet, useChainId, usePostMessage, useSignMessage, useSignTransaction, useThemeMode, useTransferTokens, useUserWallets };
516
+ export { type AddAccountMessage, type AdminPortalSettings, type Auth0User, type AuthMessage, type AuthMessagePayload, type AuthStateUpdateMessage, type AuthStatusMessage, type AvaCloudEnvironment, type AvaCloudWalletContextType, AvaCloudWalletProvider, type AvaCloudWalletProviderProps, type BaseAuthMessage, type CheckAuthStatusMessage, type CubistWalletInfo, type ErrorMessage, ExportView, type GetOidcMessage, type IframeReadyMessage, LoginButton, type LoginRequestMessage, type LogoutRequestMessage, type MessageType, type OrgConfig, type ReceiveOidcMessage, ReceiveView, type RegisterMessage, type RegisterPayload, type RegisterSuccessMessage, SendView, ThemeProvider, TokensView, type UserInfo, UserProfile, VM, WalletButton, WalletCard, WalletDisplay, type WalletInfo, type WalletKeysErrorMessage, type WalletKeysUpdateMessage, useAuth, useAvaCloudWallet, useChainId, usePostMessage, useSignMessage, useSignTransaction, useThemeMode, useTransferTokens, useUserWallets };
package/dist/index.js CHANGED
@@ -79,7 +79,20 @@ function getDerivationPath(vm, accountIndex) {
79
79
 
80
80
  // src/hooks/usePostMessage.ts
81
81
  var import_react = require("react");
82
- var import_waas_common = require("@avacloud/waas-common");
82
+
83
+ // src/constants/storage.ts
84
+ var OIDC_TOKEN_KEY = "avacloud-auth-oidc-token";
85
+ var AUTH_TOKENS_KEY = "auth_tokens";
86
+ var AUTH0_STORAGE_KEYS = {
87
+ IS_AUTHENTICATED: "auth0.is.authenticated",
88
+ ACCESS_TOKEN: "auth0.access_token",
89
+ ID_TOKEN: "auth0.id_token",
90
+ EXPIRES_AT: "auth0.expires_at"
91
+ };
92
+ var CUBIST_USER_ID_KEY = "cubist_user_id";
93
+ var ORG_CONFIG_CACHE_KEY = "avacloud-org-config-cache";
94
+
95
+ // src/hooks/usePostMessage.ts
83
96
  function usePostMessage({
84
97
  authServiceUrl,
85
98
  orgId,
@@ -103,6 +116,30 @@ function usePostMessage({
103
116
  });
104
117
  const hasRequestedOidcRef = (0, import_react.useRef)(false);
105
118
  const isHandlingMessageRef = (0, import_react.useRef)(false);
119
+ const hasLoadedCacheRef = (0, import_react.useRef)(false);
120
+ (0, import_react.useEffect)(() => {
121
+ if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
122
+ hasLoadedCacheRef.current = true;
123
+ try {
124
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
125
+ const cachedConfigJson = localStorage.getItem(cachedConfigKey);
126
+ if (cachedConfigJson) {
127
+ const cachedConfig = JSON.parse(cachedConfigJson);
128
+ const timestamp = cachedConfig._timestamp || 0;
129
+ const isExpired = Date.now() - timestamp > 30 * 60 * 1e3;
130
+ if (!isExpired) {
131
+ const { _timestamp, ...configWithoutTimestamp } = cachedConfig;
132
+ console.log("Using cached org config:", configWithoutTimestamp);
133
+ onOrgConfigUpdate(configWithoutTimestamp);
134
+ } else {
135
+ console.log("Cached org config expired, will fetch fresh data");
136
+ }
137
+ }
138
+ } catch (error) {
139
+ console.error("Error loading cached org config:", error);
140
+ }
141
+ }
142
+ }, [orgId, environment, onOrgConfigUpdate]);
106
143
  const sendMessage = (0, import_react.useCallback)((message) => {
107
144
  if (iframe == null ? void 0 : iframe.contentWindow) {
108
145
  try {
@@ -178,9 +215,9 @@ function usePostMessage({
178
215
  }
179
216
  } else {
180
217
  setUser(null);
181
- localStorage.removeItem(import_waas_common.AUTH_TOKENS_KEY);
182
- localStorage.removeItem(import_waas_common.AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
183
- sessionStorage.removeItem(import_waas_common.OIDC_TOKEN_KEY);
218
+ localStorage.removeItem(AUTH_TOKENS_KEY);
219
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
220
+ sessionStorage.removeItem(OIDC_TOKEN_KEY);
184
221
  }
185
222
  lastAuthStateRef.current = {
186
223
  isAuthenticated: newIsAuthenticated,
@@ -190,7 +227,7 @@ function usePostMessage({
190
227
  if (newIsAuthenticated && event.data.user) {
191
228
  if (!hasRequestedOidcRef.current) {
192
229
  if (event.data.tokens) {
193
- localStorage.setItem(import_waas_common.AUTH_TOKENS_KEY, JSON.stringify(event.data.tokens));
230
+ localStorage.setItem(AUTH_TOKENS_KEY, JSON.stringify(event.data.tokens));
194
231
  }
195
232
  onAuthSuccess == null ? void 0 : onAuthSuccess();
196
233
  }
@@ -199,6 +236,19 @@ function usePostMessage({
199
236
  if (event.data.orgConfig && onOrgConfigUpdate) {
200
237
  console.log("Received organization config:", event.data.orgConfig);
201
238
  onOrgConfigUpdate(event.data.orgConfig);
239
+ if (orgId) {
240
+ try {
241
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
242
+ const configWithTimestamp = {
243
+ ...event.data.orgConfig,
244
+ _timestamp: Date.now()
245
+ };
246
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
247
+ console.log("Cached organization config for future use");
248
+ } catch (error) {
249
+ console.error("Error caching org config:", error);
250
+ }
251
+ }
202
252
  }
203
253
  if (!hasRequestedOidcRef.current) {
204
254
  setIsLoading(false);
@@ -209,7 +259,7 @@ function usePostMessage({
209
259
  console.log("Registration successful:", event.data.payload);
210
260
  const userId = (_f = event.data.payload) == null ? void 0 : _f.userId;
211
261
  if (userId) {
212
- localStorage.setItem(import_waas_common.CUBIST_USER_ID_KEY, userId);
262
+ localStorage.setItem(CUBIST_USER_ID_KEY, userId);
213
263
  if (!hasRequestedOidcRef.current) {
214
264
  console.log("Registration complete, sending GET_OIDC message");
215
265
  hasRequestedOidcRef.current = true;
@@ -241,7 +291,9 @@ function usePostMessage({
241
291
  setIsLoading,
242
292
  setUser,
243
293
  sendMessage,
244
- cubistClient
294
+ cubistClient,
295
+ orgId,
296
+ environment
245
297
  ]);
246
298
  (0, import_react.useEffect)(() => {
247
299
  if (isIframeReady && (iframe == null ? void 0 : iframe.contentWindow)) {
@@ -287,11 +339,70 @@ function PoweredByAvaCloud() {
287
339
 
288
340
  // src/components/SignInContent.tsx
289
341
  var import_jsx_runtime2 = require("react/jsx-runtime");
290
- function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
342
+ function SignInContent({
343
+ onEmailLogin,
344
+ onProviderLogin,
345
+ error,
346
+ isSubmitting,
347
+ socialLogins = ["google", "x", "apple"]
348
+ }) {
291
349
  const [email, setEmail] = (0, import_react2.useState)("");
292
350
  const [password, setPassword] = (0, import_react2.useState)("");
293
351
  const [isPasswordStep, setIsPasswordStep] = (0, import_react2.useState)(false);
294
- const theme = (0, import_core_k2_components2.useTheme)();
352
+ const providerConnectionMap = {
353
+ "google": "google-oauth2",
354
+ "x": "twitter",
355
+ "twitter": "twitter",
356
+ "facebook": "facebook",
357
+ "apple": "apple"
358
+ };
359
+ const renderSocialLoginButton = (loginType) => {
360
+ if (!providerConnectionMap[loginType]) return null;
361
+ const connectionName = providerConnectionMap[loginType];
362
+ let LoginIcon;
363
+ switch (loginType) {
364
+ case "google":
365
+ LoginIcon = import_core_k2_components2.GoogleIcon;
366
+ break;
367
+ case "x":
368
+ case "twitter":
369
+ LoginIcon = import_core_k2_components2.XTwitterIcon;
370
+ break;
371
+ case "facebook":
372
+ LoginIcon = import_core_k2_components2.FacebookIcon;
373
+ break;
374
+ case "apple":
375
+ LoginIcon = import_core_k2_components2.AppleIcon;
376
+ break;
377
+ default:
378
+ return null;
379
+ }
380
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
381
+ import_core_k2_components2.IconButton,
382
+ {
383
+ color: "default",
384
+ variant: "contained",
385
+ onClick: () => onProviderLogin(connectionName),
386
+ disabled: isSubmitting,
387
+ sx: {
388
+ display: "flex",
389
+ padding: "16px",
390
+ alignItems: "center",
391
+ gap: "8px",
392
+ borderRadius: "8px",
393
+ background: "rgba(0, 0, 0, 0.02)",
394
+ boxShadow: "2px 1px 4px 0px rgba(0, 0, 0, 0.20)",
395
+ width: 72,
396
+ height: 72,
397
+ "&:hover": {
398
+ background: "rgba(0, 0, 0, 0.04)"
399
+ }
400
+ },
401
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LoginIcon, { sx: { width: 24, height: 24 } })
402
+ },
403
+ loginType
404
+ );
405
+ };
295
406
  const handleEmailSubmit = (e) => {
296
407
  e.preventDefault();
297
408
  if (!email) return;
@@ -307,7 +418,7 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
307
418
  };
308
419
  const titleTypography = {
309
420
  alignSelf: "stretch",
310
- color: (theme2) => theme2.palette.mode === "dark" ? "#FFFFFF" : "rgba(0, 0, 0, 0.80)",
421
+ color: (theme) => theme.palette.mode === "dark" ? "#FFFFFF" : "rgba(0, 0, 0, 0.80)",
311
422
  fontFamily: "Inter",
312
423
  fontSize: "16px",
313
424
  fontStyle: "normal",
@@ -332,7 +443,7 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
332
443
  helperText: error,
333
444
  sx: {
334
445
  "& .MuiOutlinedInput-root": {
335
- backgroundColor: (theme2) => theme2.palette.mode === "dark" ? "rgba(255, 255, 255, 0.05)" : "grey.50"
446
+ backgroundColor: (theme) => theme.palette.mode === "dark" ? "rgba(255, 255, 255, 0.05)" : "grey.50"
336
447
  }
337
448
  }
338
449
  }
@@ -466,80 +577,7 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
466
577
  }
467
578
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_core_k2_components2.Stack, { gap: 3, children: [
468
579
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core_k2_components2.Typography, { variant: "h6", sx: titleTypography, children: "Sign in with" }),
469
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_core_k2_components2.Stack, { direction: "row", spacing: 3, sx: { justifyContent: "center" }, children: [
470
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
471
- import_core_k2_components2.IconButton,
472
- {
473
- color: "default",
474
- variant: "contained",
475
- onClick: () => onProviderLogin("google-oauth2"),
476
- disabled: isSubmitting,
477
- sx: {
478
- display: "flex",
479
- padding: "16px",
480
- alignItems: "center",
481
- gap: "8px",
482
- borderRadius: "8px",
483
- background: "rgba(0, 0, 0, 0.02)",
484
- boxShadow: "2px 1px 4px 0px rgba(0, 0, 0, 0.20)",
485
- width: 72,
486
- height: 72,
487
- "&:hover": {
488
- background: "rgba(0, 0, 0, 0.04)"
489
- }
490
- },
491
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core_k2_components2.GoogleColorIcon, { sx: { width: 24, height: 24 } })
492
- }
493
- ),
494
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
495
- import_core_k2_components2.IconButton,
496
- {
497
- color: "default",
498
- variant: "contained",
499
- onClick: () => onProviderLogin("twitter"),
500
- disabled: isSubmitting,
501
- sx: {
502
- display: "flex",
503
- padding: "16px",
504
- alignItems: "center",
505
- gap: "8px",
506
- borderRadius: "8px",
507
- background: "rgba(0, 0, 0, 0.02)",
508
- boxShadow: "2px 1px 4px 0px rgba(0, 0, 0, 0.20)",
509
- width: 72,
510
- height: 72,
511
- "&:hover": {
512
- background: "rgba(0, 0, 0, 0.04)"
513
- }
514
- },
515
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core_k2_components2.XTwitterIcon, { sx: { width: 24, height: 24 } })
516
- }
517
- ),
518
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
519
- import_core_k2_components2.IconButton,
520
- {
521
- color: "default",
522
- variant: "contained",
523
- onClick: () => onProviderLogin("apple"),
524
- disabled: isSubmitting,
525
- sx: {
526
- display: "flex",
527
- padding: "16px",
528
- alignItems: "center",
529
- gap: "8px",
530
- borderRadius: "8px",
531
- background: "rgba(0, 0, 0, 0.02)",
532
- boxShadow: "2px 1px 4px 0px rgba(0, 0, 0, 0.20)",
533
- width: 72,
534
- height: 72,
535
- "&:hover": {
536
- background: "rgba(0, 0, 0, 0.04)"
537
- }
538
- },
539
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core_k2_components2.AppleIcon, { sx: { width: 24, height: 24 } })
540
- }
541
- )
542
- ] }),
580
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core_k2_components2.Stack, { direction: "row", spacing: 3, sx: { justifyContent: "center" }, children: socialLogins.map((loginType) => renderSocialLoginButton(loginType)) }),
543
581
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core_k2_components2.Divider, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core_k2_components2.Typography, { variant: "body2", color: "text.secondary", children: "or" }) }),
544
582
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("form", { onSubmit: handleEmailSubmit, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_core_k2_components2.Stack, { gap: 2, children: [
545
583
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -556,7 +594,7 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
556
594
  helperText: error,
557
595
  sx: {
558
596
  "& .MuiOutlinedInput-root": {
559
- backgroundColor: (theme2) => theme2.palette.mode === "dark" ? "rgba(255, 255, 255, 0.05)" : "grey.50"
597
+ backgroundColor: (theme) => theme.palette.mode === "dark" ? "rgba(255, 255, 255, 0.05)" : "grey.50"
560
598
  }
561
599
  }
562
600
  }
@@ -659,9 +697,11 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
659
697
  // src/components/Modal.tsx
660
698
  var import_jsx_runtime3 = require("react/jsx-runtime");
661
699
  function LoginModal({ open, onClose }) {
662
- const { iframe } = useAvaCloudWallet();
700
+ var _a;
701
+ const { iframe, orgConfig } = useAvaCloudWallet();
663
702
  const [isSubmitting, setIsSubmitting] = (0, import_react3.useState)(false);
664
703
  const [error, setError] = (0, import_react3.useState)("");
704
+ const socialLogins = (_a = orgConfig == null ? void 0 : orgConfig.adminPortalSettings) == null ? void 0 : _a.socialLogins;
665
705
  (0, import_react3.useEffect)(() => {
666
706
  const handleMessage = (event) => {
667
707
  if (event.data.type === "ERROR") {
@@ -676,11 +716,11 @@ function LoginModal({ open, onClose }) {
676
716
  return () => window.removeEventListener("message", handleMessage);
677
717
  }, [onClose]);
678
718
  const handleProviderLogin = (provider) => {
679
- var _a;
719
+ var _a2;
680
720
  setError("");
681
721
  if (iframe) {
682
722
  console.log(`Sending LOGIN_REQUEST to auth service iframe with ${provider} connection`);
683
- (_a = iframe.contentWindow) == null ? void 0 : _a.postMessage({
723
+ (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
684
724
  type: "LOGIN_REQUEST",
685
725
  connection: provider
686
726
  }, "*");
@@ -691,12 +731,12 @@ function LoginModal({ open, onClose }) {
691
731
  }
692
732
  };
693
733
  const handleEmailLogin = (email, password) => {
694
- var _a;
734
+ var _a2;
695
735
  setError("");
696
736
  setIsSubmitting(true);
697
737
  if (iframe) {
698
738
  console.log("Sending email/password LOGIN_REQUEST to auth service iframe");
699
- (_a = iframe.contentWindow) == null ? void 0 : _a.postMessage({
739
+ (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
700
740
  type: "LOGIN_REQUEST",
701
741
  email,
702
742
  password
@@ -780,7 +820,8 @@ function LoginModal({ open, onClose }) {
780
820
  onEmailLogin: handleEmailLogin,
781
821
  onProviderLogin: handleProviderLogin,
782
822
  error,
783
- isSubmitting
823
+ isSubmitting,
824
+ socialLogins
784
825
  }
785
826
  ) })
786
827
  ]
@@ -1181,7 +1222,6 @@ function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1181
1222
  }
1182
1223
 
1183
1224
  // src/AvaCloudWalletProvider.tsx
1184
- var import_waas_common2 = require("@avacloud/waas-common");
1185
1225
  var import_jsx_runtime7 = require("react/jsx-runtime");
1186
1226
  var AvaCloudWalletContext = (0, import_react9.createContext)(void 0);
1187
1227
  var queryClient = new import_react_query2.QueryClient({
@@ -1284,7 +1324,7 @@ function AvaCloudWalletProvider({
1284
1324
  accessToken = oidcToken;
1285
1325
  } else {
1286
1326
  console.log("[loginWithCubist] Attempting to get OIDC token from localStorage.");
1287
- const tokens = localStorage.getItem(import_waas_common2.AUTH_TOKENS_KEY);
1327
+ const tokens = localStorage.getItem(AUTH_TOKENS_KEY);
1288
1328
  if (!tokens) {
1289
1329
  throw new Error("No authentication tokens found in localStorage");
1290
1330
  }
@@ -1340,8 +1380,8 @@ function AvaCloudWalletProvider({
1340
1380
  }
1341
1381
  } catch (error) {
1342
1382
  console.error("[loginWithCubist] Error during Cubist session creation/wallet info:", error);
1343
- localStorage.removeItem(import_waas_common2.AUTH_TOKENS_KEY);
1344
- localStorage.removeItem(import_waas_common2.AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1383
+ localStorage.removeItem(AUTH_TOKENS_KEY);
1384
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1345
1385
  setIsAuthenticated(false);
1346
1386
  setUser(null);
1347
1387
  setCubistClient(null);
@@ -1435,17 +1475,21 @@ function AvaCloudWalletProvider({
1435
1475
  setUser(null);
1436
1476
  setWallet({ address: null });
1437
1477
  setIsAuthenticated(false);
1438
- localStorage.removeItem(import_waas_common2.AUTH_TOKENS_KEY);
1439
- localStorage.removeItem(import_waas_common2.AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1440
- localStorage.removeItem(import_waas_common2.AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
1441
- localStorage.removeItem(import_waas_common2.AUTH0_STORAGE_KEYS.ID_TOKEN);
1442
- localStorage.removeItem(import_waas_common2.AUTH0_STORAGE_KEYS.EXPIRES_AT);
1443
- localStorage.removeItem(import_waas_common2.CUBIST_USER_ID_KEY);
1444
- sessionStorage.removeItem(import_waas_common2.OIDC_TOKEN_KEY);
1478
+ localStorage.removeItem(AUTH_TOKENS_KEY);
1479
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1480
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
1481
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ID_TOKEN);
1482
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.EXPIRES_AT);
1483
+ localStorage.removeItem(CUBIST_USER_ID_KEY);
1484
+ if (orgId) {
1485
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
1486
+ localStorage.removeItem(cachedConfigKey);
1487
+ }
1488
+ sessionStorage.removeItem(OIDC_TOKEN_KEY);
1445
1489
  setCubistClient(null);
1446
1490
  setCubistError(null);
1447
1491
  setPendingOidcToken(null);
1448
- }, [sendMessage]);
1492
+ }, [sendMessage, orgId, environment]);
1449
1493
  const addAccount = (0, import_react9.useCallback)(async (accountIndex) => {
1450
1494
  console.log("[addAccount] Called with accountIndex:", accountIndex);
1451
1495
  if (!isAuthenticated || !user || !wallet.mnemonicId) {
package/dist/index.mjs CHANGED
@@ -33,7 +33,20 @@ function getDerivationPath(vm, accountIndex) {
33
33
 
34
34
  // src/hooks/usePostMessage.ts
35
35
  import { useCallback, useEffect, useRef } from "react";
36
- import { AUTH_TOKENS_KEY, OIDC_TOKEN_KEY, AUTH0_STORAGE_KEYS, CUBIST_USER_ID_KEY } from "@avacloud/waas-common";
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
37
50
  function usePostMessage({
38
51
  authServiceUrl,
39
52
  orgId,
@@ -57,6 +70,30 @@ function usePostMessage({
57
70
  });
58
71
  const hasRequestedOidcRef = useRef(false);
59
72
  const isHandlingMessageRef = useRef(false);
73
+ const hasLoadedCacheRef = useRef(false);
74
+ useEffect(() => {
75
+ if (orgId && onOrgConfigUpdate && !hasLoadedCacheRef.current) {
76
+ hasLoadedCacheRef.current = true;
77
+ try {
78
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
79
+ const cachedConfigJson = localStorage.getItem(cachedConfigKey);
80
+ if (cachedConfigJson) {
81
+ const cachedConfig = JSON.parse(cachedConfigJson);
82
+ const timestamp = cachedConfig._timestamp || 0;
83
+ const isExpired = Date.now() - timestamp > 30 * 60 * 1e3;
84
+ if (!isExpired) {
85
+ const { _timestamp, ...configWithoutTimestamp } = cachedConfig;
86
+ console.log("Using cached org config:", configWithoutTimestamp);
87
+ onOrgConfigUpdate(configWithoutTimestamp);
88
+ } else {
89
+ console.log("Cached org config expired, will fetch fresh data");
90
+ }
91
+ }
92
+ } catch (error) {
93
+ console.error("Error loading cached org config:", error);
94
+ }
95
+ }
96
+ }, [orgId, environment, onOrgConfigUpdate]);
60
97
  const sendMessage = useCallback((message) => {
61
98
  if (iframe == null ? void 0 : iframe.contentWindow) {
62
99
  try {
@@ -153,6 +190,19 @@ function usePostMessage({
153
190
  if (event.data.orgConfig && onOrgConfigUpdate) {
154
191
  console.log("Received organization config:", event.data.orgConfig);
155
192
  onOrgConfigUpdate(event.data.orgConfig);
193
+ if (orgId) {
194
+ try {
195
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
196
+ const configWithTimestamp = {
197
+ ...event.data.orgConfig,
198
+ _timestamp: Date.now()
199
+ };
200
+ localStorage.setItem(cachedConfigKey, JSON.stringify(configWithTimestamp));
201
+ console.log("Cached organization config for future use");
202
+ } catch (error) {
203
+ console.error("Error caching org config:", error);
204
+ }
205
+ }
156
206
  }
157
207
  if (!hasRequestedOidcRef.current) {
158
208
  setIsLoading(false);
@@ -195,7 +245,9 @@ function usePostMessage({
195
245
  setIsLoading,
196
246
  setUser,
197
247
  sendMessage,
198
- cubistClient
248
+ cubistClient,
249
+ orgId,
250
+ environment
199
251
  ]);
200
252
  useEffect(() => {
201
253
  if (isIframeReady && (iframe == null ? void 0 : iframe.contentWindow)) {
@@ -224,7 +276,7 @@ import { Dialog, DialogContent, IconButton as IconButton2, Stack as Stack3, XIco
224
276
 
225
277
  // src/components/SignInContent.tsx
226
278
  import { useState } from "react";
227
- import { Button, TextField, Typography as Typography2, Stack as Stack2, IconButton, Divider, GoogleColorIcon, AppleIcon, XTwitterIcon, useTheme } from "@avalabs/core-k2-components";
279
+ import { Button, TextField, Typography as Typography2, Stack as Stack2, IconButton, Divider, GoogleIcon, AppleIcon, XTwitterIcon, FacebookIcon } from "@avalabs/core-k2-components";
228
280
 
229
281
  // src/components/PoweredByAvaCloud.tsx
230
282
  import { Stack, Typography, AvaCloudConnectIcon } from "@avalabs/core-k2-components";
@@ -241,11 +293,70 @@ function PoweredByAvaCloud() {
241
293
 
242
294
  // src/components/SignInContent.tsx
243
295
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
244
- function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
296
+ function SignInContent({
297
+ onEmailLogin,
298
+ onProviderLogin,
299
+ error,
300
+ isSubmitting,
301
+ socialLogins = ["google", "x", "apple"]
302
+ }) {
245
303
  const [email, setEmail] = useState("");
246
304
  const [password, setPassword] = useState("");
247
305
  const [isPasswordStep, setIsPasswordStep] = useState(false);
248
- const theme = useTheme();
306
+ const providerConnectionMap = {
307
+ "google": "google-oauth2",
308
+ "x": "twitter",
309
+ "twitter": "twitter",
310
+ "facebook": "facebook",
311
+ "apple": "apple"
312
+ };
313
+ const renderSocialLoginButton = (loginType) => {
314
+ if (!providerConnectionMap[loginType]) return null;
315
+ const connectionName = providerConnectionMap[loginType];
316
+ let LoginIcon;
317
+ switch (loginType) {
318
+ case "google":
319
+ LoginIcon = GoogleIcon;
320
+ break;
321
+ case "x":
322
+ case "twitter":
323
+ LoginIcon = XTwitterIcon;
324
+ break;
325
+ case "facebook":
326
+ LoginIcon = FacebookIcon;
327
+ break;
328
+ case "apple":
329
+ LoginIcon = AppleIcon;
330
+ break;
331
+ default:
332
+ return null;
333
+ }
334
+ return /* @__PURE__ */ jsx2(
335
+ IconButton,
336
+ {
337
+ color: "default",
338
+ variant: "contained",
339
+ onClick: () => onProviderLogin(connectionName),
340
+ disabled: isSubmitting,
341
+ sx: {
342
+ display: "flex",
343
+ padding: "16px",
344
+ alignItems: "center",
345
+ gap: "8px",
346
+ borderRadius: "8px",
347
+ background: "rgba(0, 0, 0, 0.02)",
348
+ boxShadow: "2px 1px 4px 0px rgba(0, 0, 0, 0.20)",
349
+ width: 72,
350
+ height: 72,
351
+ "&:hover": {
352
+ background: "rgba(0, 0, 0, 0.04)"
353
+ }
354
+ },
355
+ children: /* @__PURE__ */ jsx2(LoginIcon, { sx: { width: 24, height: 24 } })
356
+ },
357
+ loginType
358
+ );
359
+ };
249
360
  const handleEmailSubmit = (e) => {
250
361
  e.preventDefault();
251
362
  if (!email) return;
@@ -261,7 +372,7 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
261
372
  };
262
373
  const titleTypography = {
263
374
  alignSelf: "stretch",
264
- color: (theme2) => theme2.palette.mode === "dark" ? "#FFFFFF" : "rgba(0, 0, 0, 0.80)",
375
+ color: (theme) => theme.palette.mode === "dark" ? "#FFFFFF" : "rgba(0, 0, 0, 0.80)",
265
376
  fontFamily: "Inter",
266
377
  fontSize: "16px",
267
378
  fontStyle: "normal",
@@ -286,7 +397,7 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
286
397
  helperText: error,
287
398
  sx: {
288
399
  "& .MuiOutlinedInput-root": {
289
- backgroundColor: (theme2) => theme2.palette.mode === "dark" ? "rgba(255, 255, 255, 0.05)" : "grey.50"
400
+ backgroundColor: (theme) => theme.palette.mode === "dark" ? "rgba(255, 255, 255, 0.05)" : "grey.50"
290
401
  }
291
402
  }
292
403
  }
@@ -420,80 +531,7 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
420
531
  }
421
532
  return /* @__PURE__ */ jsxs2(Stack2, { gap: 3, children: [
422
533
  /* @__PURE__ */ jsx2(Typography2, { variant: "h6", sx: titleTypography, children: "Sign in with" }),
423
- /* @__PURE__ */ jsxs2(Stack2, { direction: "row", spacing: 3, sx: { justifyContent: "center" }, children: [
424
- /* @__PURE__ */ jsx2(
425
- IconButton,
426
- {
427
- color: "default",
428
- variant: "contained",
429
- onClick: () => onProviderLogin("google-oauth2"),
430
- disabled: isSubmitting,
431
- sx: {
432
- display: "flex",
433
- padding: "16px",
434
- alignItems: "center",
435
- gap: "8px",
436
- borderRadius: "8px",
437
- background: "rgba(0, 0, 0, 0.02)",
438
- boxShadow: "2px 1px 4px 0px rgba(0, 0, 0, 0.20)",
439
- width: 72,
440
- height: 72,
441
- "&:hover": {
442
- background: "rgba(0, 0, 0, 0.04)"
443
- }
444
- },
445
- children: /* @__PURE__ */ jsx2(GoogleColorIcon, { sx: { width: 24, height: 24 } })
446
- }
447
- ),
448
- /* @__PURE__ */ jsx2(
449
- IconButton,
450
- {
451
- color: "default",
452
- variant: "contained",
453
- onClick: () => onProviderLogin("twitter"),
454
- disabled: isSubmitting,
455
- sx: {
456
- display: "flex",
457
- padding: "16px",
458
- alignItems: "center",
459
- gap: "8px",
460
- borderRadius: "8px",
461
- background: "rgba(0, 0, 0, 0.02)",
462
- boxShadow: "2px 1px 4px 0px rgba(0, 0, 0, 0.20)",
463
- width: 72,
464
- height: 72,
465
- "&:hover": {
466
- background: "rgba(0, 0, 0, 0.04)"
467
- }
468
- },
469
- children: /* @__PURE__ */ jsx2(XTwitterIcon, { sx: { width: 24, height: 24 } })
470
- }
471
- ),
472
- /* @__PURE__ */ jsx2(
473
- IconButton,
474
- {
475
- color: "default",
476
- variant: "contained",
477
- onClick: () => onProviderLogin("apple"),
478
- disabled: isSubmitting,
479
- sx: {
480
- display: "flex",
481
- padding: "16px",
482
- alignItems: "center",
483
- gap: "8px",
484
- borderRadius: "8px",
485
- background: "rgba(0, 0, 0, 0.02)",
486
- boxShadow: "2px 1px 4px 0px rgba(0, 0, 0, 0.20)",
487
- width: 72,
488
- height: 72,
489
- "&:hover": {
490
- background: "rgba(0, 0, 0, 0.04)"
491
- }
492
- },
493
- children: /* @__PURE__ */ jsx2(AppleIcon, { sx: { width: 24, height: 24 } })
494
- }
495
- )
496
- ] }),
534
+ /* @__PURE__ */ jsx2(Stack2, { direction: "row", spacing: 3, sx: { justifyContent: "center" }, children: socialLogins.map((loginType) => renderSocialLoginButton(loginType)) }),
497
535
  /* @__PURE__ */ jsx2(Divider, { children: /* @__PURE__ */ jsx2(Typography2, { variant: "body2", color: "text.secondary", children: "or" }) }),
498
536
  /* @__PURE__ */ jsx2("form", { onSubmit: handleEmailSubmit, children: /* @__PURE__ */ jsxs2(Stack2, { gap: 2, children: [
499
537
  /* @__PURE__ */ jsx2(
@@ -510,7 +548,7 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
510
548
  helperText: error,
511
549
  sx: {
512
550
  "& .MuiOutlinedInput-root": {
513
- backgroundColor: (theme2) => theme2.palette.mode === "dark" ? "rgba(255, 255, 255, 0.05)" : "grey.50"
551
+ backgroundColor: (theme) => theme.palette.mode === "dark" ? "rgba(255, 255, 255, 0.05)" : "grey.50"
514
552
  }
515
553
  }
516
554
  }
@@ -613,9 +651,11 @@ function SignInContent({ onEmailLogin, onProviderLogin, error, isSubmitting }) {
613
651
  // src/components/Modal.tsx
614
652
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
615
653
  function LoginModal({ open, onClose }) {
616
- const { iframe } = useAvaCloudWallet();
654
+ var _a;
655
+ const { iframe, orgConfig } = useAvaCloudWallet();
617
656
  const [isSubmitting, setIsSubmitting] = useState2(false);
618
657
  const [error, setError] = useState2("");
658
+ const socialLogins = (_a = orgConfig == null ? void 0 : orgConfig.adminPortalSettings) == null ? void 0 : _a.socialLogins;
619
659
  useEffect2(() => {
620
660
  const handleMessage = (event) => {
621
661
  if (event.data.type === "ERROR") {
@@ -630,11 +670,11 @@ function LoginModal({ open, onClose }) {
630
670
  return () => window.removeEventListener("message", handleMessage);
631
671
  }, [onClose]);
632
672
  const handleProviderLogin = (provider) => {
633
- var _a;
673
+ var _a2;
634
674
  setError("");
635
675
  if (iframe) {
636
676
  console.log(`Sending LOGIN_REQUEST to auth service iframe with ${provider} connection`);
637
- (_a = iframe.contentWindow) == null ? void 0 : _a.postMessage({
677
+ (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
638
678
  type: "LOGIN_REQUEST",
639
679
  connection: provider
640
680
  }, "*");
@@ -645,12 +685,12 @@ function LoginModal({ open, onClose }) {
645
685
  }
646
686
  };
647
687
  const handleEmailLogin = (email, password) => {
648
- var _a;
688
+ var _a2;
649
689
  setError("");
650
690
  setIsSubmitting(true);
651
691
  if (iframe) {
652
692
  console.log("Sending email/password LOGIN_REQUEST to auth service iframe");
653
- (_a = iframe.contentWindow) == null ? void 0 : _a.postMessage({
693
+ (_a2 = iframe.contentWindow) == null ? void 0 : _a2.postMessage({
654
694
  type: "LOGIN_REQUEST",
655
695
  email,
656
696
  password
@@ -734,7 +774,8 @@ function LoginModal({ open, onClose }) {
734
774
  onEmailLogin: handleEmailLogin,
735
775
  onProviderLogin: handleProviderLogin,
736
776
  error,
737
- isSubmitting
777
+ isSubmitting,
778
+ socialLogins
738
779
  }
739
780
  ) })
740
781
  ]
@@ -1135,7 +1176,6 @@ function ThemeProvider({ children, darkMode, onDarkModeChange }) {
1135
1176
  }
1136
1177
 
1137
1178
  // src/AvaCloudWalletProvider.tsx
1138
- import { AUTH_TOKENS_KEY as AUTH_TOKENS_KEY2, OIDC_TOKEN_KEY as OIDC_TOKEN_KEY2, AUTH0_STORAGE_KEYS as AUTH0_STORAGE_KEYS2, CUBIST_USER_ID_KEY as CUBIST_USER_ID_KEY2 } from "@avacloud/waas-common";
1139
1179
  import { Fragment, jsx as jsx7 } from "react/jsx-runtime";
1140
1180
  var AvaCloudWalletContext = createContext4(void 0);
1141
1181
  var queryClient = new QueryClient({
@@ -1238,7 +1278,7 @@ function AvaCloudWalletProvider({
1238
1278
  accessToken = oidcToken;
1239
1279
  } else {
1240
1280
  console.log("[loginWithCubist] Attempting to get OIDC token from localStorage.");
1241
- const tokens = localStorage.getItem(AUTH_TOKENS_KEY2);
1281
+ const tokens = localStorage.getItem(AUTH_TOKENS_KEY);
1242
1282
  if (!tokens) {
1243
1283
  throw new Error("No authentication tokens found in localStorage");
1244
1284
  }
@@ -1294,8 +1334,8 @@ function AvaCloudWalletProvider({
1294
1334
  }
1295
1335
  } catch (error) {
1296
1336
  console.error("[loginWithCubist] Error during Cubist session creation/wallet info:", error);
1297
- localStorage.removeItem(AUTH_TOKENS_KEY2);
1298
- localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1337
+ localStorage.removeItem(AUTH_TOKENS_KEY);
1338
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1299
1339
  setIsAuthenticated(false);
1300
1340
  setUser(null);
1301
1341
  setCubistClient(null);
@@ -1389,17 +1429,21 @@ function AvaCloudWalletProvider({
1389
1429
  setUser(null);
1390
1430
  setWallet({ address: null });
1391
1431
  setIsAuthenticated(false);
1392
- localStorage.removeItem(AUTH_TOKENS_KEY2);
1393
- localStorage.removeItem(AUTH0_STORAGE_KEYS2.IS_AUTHENTICATED);
1394
- localStorage.removeItem(AUTH0_STORAGE_KEYS2.ACCESS_TOKEN);
1395
- localStorage.removeItem(AUTH0_STORAGE_KEYS2.ID_TOKEN);
1396
- localStorage.removeItem(AUTH0_STORAGE_KEYS2.EXPIRES_AT);
1397
- localStorage.removeItem(CUBIST_USER_ID_KEY2);
1398
- sessionStorage.removeItem(OIDC_TOKEN_KEY2);
1432
+ localStorage.removeItem(AUTH_TOKENS_KEY);
1433
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.IS_AUTHENTICATED);
1434
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ACCESS_TOKEN);
1435
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.ID_TOKEN);
1436
+ localStorage.removeItem(AUTH0_STORAGE_KEYS.EXPIRES_AT);
1437
+ localStorage.removeItem(CUBIST_USER_ID_KEY);
1438
+ if (orgId) {
1439
+ const cachedConfigKey = `${ORG_CONFIG_CACHE_KEY}-${orgId}-${environment}`;
1440
+ localStorage.removeItem(cachedConfigKey);
1441
+ }
1442
+ sessionStorage.removeItem(OIDC_TOKEN_KEY);
1399
1443
  setCubistClient(null);
1400
1444
  setCubistError(null);
1401
1445
  setPendingOidcToken(null);
1402
- }, [sendMessage]);
1446
+ }, [sendMessage, orgId, environment]);
1403
1447
  const addAccount = useCallback5(async (accountIndex) => {
1404
1448
  console.log("[addAccount] Called with accountIndex:", accountIndex);
1405
1449
  if (!isAuthenticated || !user || !wallet.mnemonicId) {
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avalabs/avacloud-waas-react",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "React SDK for AvaCloud Wallet as a Service",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -8,7 +8,8 @@
8
8
  "sideEffects": false,
9
9
  "license": "MIT",
10
10
  "files": [
11
- "dist/**"
11
+ "dist/**",
12
+ "public/**"
12
13
  ],
13
14
  "devDependencies": {
14
15
  "@iconify/types": "^2.0.0",
@@ -30,8 +31,7 @@
30
31
  "@tanstack/react-query": "^5.64.2",
31
32
  "lottie-react": "^2.4.0",
32
33
  "qrcode.react": "^3.1.0",
33
- "viem": "^2.5.0",
34
- "@avacloud/waas-common": "0.1.0"
34
+ "viem": "^2.5.0"
35
35
  },
36
36
  "keywords": [
37
37
  "avalanche",
@@ -52,7 +52,7 @@
52
52
  "homepage": "https://github.com/ava-labs/avacloud-auth-react#readme",
53
53
  "author": "Ava Labs, Inc.",
54
54
  "scripts": {
55
- "build": "tsup src/index.ts --format esm,cjs --dts --external react",
55
+ "build": "tsup src/index.ts --format esm,cjs --dts --external react && cp -r public dist/",
56
56
  "dev": "tsup src/index.ts --format esm,cjs --watch --dts --external react",
57
57
  "lint": "eslint \"src/**/*.ts*\"",
58
58
  "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist"
Binary file