@embarkai/ui-kit 0.1.6 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -150,7 +150,9 @@ var init_initial = __esm({
150
150
  enabled: false,
151
151
  supportedChains: [1, 137, 56],
152
152
  requireSignature: true,
153
- walletConnectProjectId: void 0
153
+ walletConnectProjectId: void 0,
154
+ mode: "linked",
155
+ allowedWallets: void 0
154
156
  },
155
157
  // preferedColorMode: 'light', // undefined means 'auto'
156
158
  ui: {
@@ -15468,7 +15470,7 @@ var init_package = __esm({
15468
15470
  "package.json"() {
15469
15471
  package_default = {
15470
15472
  name: "@embarkai/ui-kit",
15471
- version: "0.1.6",
15473
+ version: "0.2.1",
15472
15474
  description: "React UI components and hooks for EmbarkAI authentication and Account Abstraction",
15473
15475
  type: "module",
15474
15476
  main: "./dist/index.cjs",
@@ -16175,21 +16177,71 @@ async function unlinkWallet(address) {
16175
16177
  throw new Error(errorData.message || `Failed to unlink wallet: ${response.statusText}`);
16176
16178
  }
16177
16179
  }
16178
- function createSignatureMessage(address, nonce) {
16180
+ async function fetchProjectName(projectId) {
16181
+ const now = Date.now();
16182
+ if (metadataCache && now - metadataCache.timestamp < METADATA_CACHE_TTL) {
16183
+ return metadataCache.data.name;
16184
+ }
16185
+ try {
16186
+ const response = await fetch(`${METADATA_API_URL}/${projectId}/metadata`);
16187
+ if (!response.ok) return "EmbarkAI";
16188
+ const metadata = await response.json();
16189
+ metadataCache = { data: metadata, timestamp: now };
16190
+ return metadata.name;
16191
+ } catch {
16192
+ return "EmbarkAI";
16193
+ }
16194
+ }
16195
+ function createSignatureMessage(address, projectName, nonce) {
16179
16196
  const timestamp = Date.now();
16180
16197
  const nonceValue = nonce || Math.random().toString(36).substring(2, 15);
16181
- return `EmbarkAI Wallet Link
16198
+ return `${projectName} Wallet Link
16182
16199
 
16183
16200
  Address: ${address}
16184
16201
  Nonce: ${nonceValue}
16185
16202
  Timestamp: ${timestamp}
16186
16203
 
16187
- Sign this message to link your wallet to EmbarkAI Wallet`;
16204
+ Sign this message to link your wallet to ${projectName} Wallet`;
16188
16205
  }
16206
+ var METADATA_API_URL, METADATA_CACHE_TTL, metadataCache;
16189
16207
  var init_wallet = __esm({
16190
16208
  "src/internal/auth/providers/wallet.ts"() {
16191
16209
  init_auth();
16192
16210
  init_types();
16211
+ METADATA_API_URL = "https://dashboard.lumiapassport.com/api/public/project";
16212
+ METADATA_CACHE_TTL = 36e5;
16213
+ metadataCache = null;
16214
+ }
16215
+ });
16216
+
16217
+ // src/internal/stores/useExternalWalletStore.ts
16218
+ import { create as create7 } from "zustand";
16219
+ var useExternalWalletStore;
16220
+ var init_useExternalWalletStore = __esm({
16221
+ "src/internal/stores/useExternalWalletStore.ts"() {
16222
+ useExternalWalletStore = create7((set) => ({
16223
+ configMode: "linked",
16224
+ activeMode: "linked",
16225
+ externalAddress: null,
16226
+ externalChainId: null,
16227
+ isExternalConnected: false,
16228
+ connectorName: null,
16229
+ setConfigMode: (mode) => set({ configMode: mode }),
16230
+ setActiveMode: (mode) => set({ activeMode: mode }),
16231
+ setExternalWallet: ({ address, chainId, connectorName }) => set({
16232
+ externalAddress: address,
16233
+ externalChainId: chainId,
16234
+ isExternalConnected: true,
16235
+ connectorName
16236
+ }),
16237
+ clearExternalWallet: () => set({
16238
+ externalAddress: null,
16239
+ externalChainId: null,
16240
+ isExternalConnected: false,
16241
+ connectorName: null
16242
+ }),
16243
+ setExternalChainId: (chainId) => set({ externalChainId: chainId })
16244
+ }));
16193
16245
  }
16194
16246
  });
16195
16247
 
@@ -16213,6 +16265,10 @@ function WalletConnectHandler() {
16213
16265
  const setManageWalletLinkError = useManageWalletStore((st) => st.setLinkError);
16214
16266
  const setLinkIsLoading = useManageWalletStore((st) => st.setLinkIsLoading);
16215
16267
  const setProviderType = useManageWalletStore((st) => st.setProviderType);
16268
+ const providerConfig = useProviderConfig().config.current;
16269
+ const walletMode = providerConfig?.wallet?.mode || "linked";
16270
+ const projectId = providerConfig?.projectId;
16271
+ const setExternalWallet = useExternalWalletStore((st) => st.setExternalWallet);
16216
16272
  const onLinkingComplete = useCallback23(
16217
16273
  async (success) => {
16218
16274
  setIsWalletLinking(false);
@@ -16243,24 +16299,42 @@ function WalletConnectHandler() {
16243
16299
  const [hasStartedLinking, setHasStartedLinking] = React8.useState(false);
16244
16300
  useEffect36(() => {
16245
16301
  if (isWalletLinking && !hasStartedLinking) {
16302
+ console.log("[WalletConnectHandler] Starting wallet link flow:", {
16303
+ isConnected,
16304
+ openConnectModal: typeof openConnectModal,
16305
+ walletMode
16306
+ });
16246
16307
  setHasStartedLinking(true);
16247
16308
  setProviderType(null);
16248
16309
  if (isConnected) {
16249
16310
  disconnect();
16250
16311
  setTimeout(() => {
16251
16312
  setPage(null);
16252
- openConnectModal();
16313
+ if (openConnectModal) {
16314
+ openConnectModal();
16315
+ } else {
16316
+ console.error("[WalletConnectHandler] openConnectModal is undefined!");
16317
+ setIsWalletLinking(false);
16318
+ setHasStartedLinking(false);
16319
+ }
16253
16320
  }, 500);
16254
16321
  } else {
16255
16322
  setPage(null);
16256
- openConnectModal();
16323
+ if (openConnectModal) {
16324
+ openConnectModal();
16325
+ } else {
16326
+ console.error("[WalletConnectHandler] openConnectModal is undefined!");
16327
+ setIsWalletLinking(false);
16328
+ setHasStartedLinking(false);
16329
+ }
16257
16330
  }
16258
16331
  }
16259
16332
  if (!isWalletLinking && hasStartedLinking) {
16260
16333
  setHasStartedLinking(false);
16261
- if (isConnected) disconnect();
16334
+ const shouldKeepConnected = walletMode === "direct" || walletMode === "both";
16335
+ if (isConnected && !shouldKeepConnected) disconnect();
16262
16336
  }
16263
- }, [isWalletLinking, hasStartedLinking, isConnected, openConnectModal, disconnect, setPage, setProviderType]);
16337
+ }, [isWalletLinking, hasStartedLinking, isConnected, openConnectModal, disconnect, setPage, setProviderType, walletMode]);
16264
16338
  useEffect36(() => {
16265
16339
  if (hasStartedLinking && !connectModalOpen && !isConnected && isWalletLinking) {
16266
16340
  console.log("[WalletConnectHandler] Modal closed without connecting");
@@ -16268,6 +16342,16 @@ function WalletConnectHandler() {
16268
16342
  setHasStartedLinking(false);
16269
16343
  }
16270
16344
  }, [connectModalOpen, hasStartedLinking, isConnected, isWalletLinking]);
16345
+ useEffect36(() => {
16346
+ if (isWalletLinking) {
16347
+ const timeout = setTimeout(() => {
16348
+ console.warn("[WalletConnectHandler] Wallet linking timed out, resetting state");
16349
+ setIsWalletLinking(false);
16350
+ setHasStartedLinking(false);
16351
+ }, 12e4);
16352
+ return () => clearTimeout(timeout);
16353
+ }
16354
+ }, [isWalletLinking, setIsWalletLinking]);
16271
16355
  const { mutate: handleWalletSign, isPending: isWalletSigning } = useMutation16({
16272
16356
  mutationFn: async (payload) => {
16273
16357
  const { chainId, signingWalletAddress } = payload;
@@ -16285,7 +16369,8 @@ function WalletConnectHandler() {
16285
16369
  return;
16286
16370
  }
16287
16371
  setLinkIsLoading(true);
16288
- const message = createSignatureMessage(signingWalletAddress);
16372
+ const projectName = projectId ? await fetchProjectName(projectId) : "EmbarkAI";
16373
+ const message = createSignatureMessage(signingWalletAddress, projectName);
16289
16374
  const signature = await signMessageAsync({ message, account: signingWalletAddress });
16290
16375
  if (!signature) {
16291
16376
  throw new Error("Failed to get signature");
@@ -16303,7 +16388,16 @@ function WalletConnectHandler() {
16303
16388
  });
16304
16389
  },
16305
16390
  onSuccess: () => {
16306
- disconnect();
16391
+ const shouldKeepConnected = walletMode === "direct" || walletMode === "both";
16392
+ if (shouldKeepConnected && walletAddress && chain?.id && connector) {
16393
+ setExternalWallet({
16394
+ address: walletAddress,
16395
+ chainId: chain.id,
16396
+ connectorName: connector.name || "Unknown Wallet"
16397
+ });
16398
+ } else {
16399
+ disconnect();
16400
+ }
16307
16401
  setHasStartedLinking(false);
16308
16402
  onLinkingComplete(true);
16309
16403
  setLinkIsLoading(false);
@@ -16343,6 +16437,17 @@ function WalletConnectHandler() {
16343
16437
  handleWalletSign({ chainId: chain.id, signingWalletAddress: walletAddress });
16344
16438
  }
16345
16439
  }, [chain, isConnected, walletAddress, isWalletLinking, hasStartedLinking]);
16440
+ useEffect36(() => {
16441
+ if (isConnected && !chain?.id && isWalletLinking && hasStartedLinking && !connectModalOpen && !isWalletSigning) {
16442
+ const timeout = setTimeout(() => {
16443
+ console.warn("[WalletConnectHandler] Wallet connected but chain info missing, resetting");
16444
+ onLinkingComplete(false);
16445
+ setHasStartedLinking(false);
16446
+ disconnect();
16447
+ }, 5e3);
16448
+ return () => clearTimeout(timeout);
16449
+ }
16450
+ }, [isConnected, chain?.id, isWalletLinking, hasStartedLinking, connectModalOpen, isWalletSigning, onLinkingComplete, disconnect]);
16346
16451
  return null;
16347
16452
  }
16348
16453
  var init_WalletConnectHandler = __esm({
@@ -16353,10 +16458,67 @@ var init_WalletConnectHandler = __esm({
16353
16458
  init_wallet();
16354
16459
  init_AuthMenu2();
16355
16460
  init_useLayoutDataStore();
16461
+ init_useExternalWalletStore();
16356
16462
  init_ManageWalletMenu();
16357
16463
  }
16358
16464
  });
16359
16465
 
16466
+ // src/internal/components/DirectWalletHandler.tsx
16467
+ import { useEffect as useEffect37 } from "react";
16468
+ import { useAccount as useAccount2 } from "wagmi";
16469
+ function DirectWalletHandler() {
16470
+ const walletMode = useProviderConfig().config.current?.wallet?.mode || "linked";
16471
+ const { address, isConnected, chain, connector } = useAccount2();
16472
+ const isExternalConnected = useExternalWalletStore((st) => st.isExternalConnected);
16473
+ const externalAddress = useExternalWalletStore((st) => st.externalAddress);
16474
+ const setExternalWallet = useExternalWalletStore((st) => st.setExternalWallet);
16475
+ const clearExternalWallet = useExternalWalletStore((st) => st.clearExternalWallet);
16476
+ const setExternalChainId = useExternalWalletStore((st) => st.setExternalChainId);
16477
+ const setConfigMode = useExternalWalletStore((st) => st.setConfigMode);
16478
+ const setActiveMode = useExternalWalletStore((st) => st.setActiveMode);
16479
+ useEffect37(() => {
16480
+ setConfigMode(walletMode);
16481
+ if (walletMode !== "both") {
16482
+ setActiveMode(walletMode);
16483
+ }
16484
+ }, [walletMode, setConfigMode, setActiveMode]);
16485
+ useEffect37(() => {
16486
+ if (isConnected && address && !isExternalConnected && connector) {
16487
+ setExternalWallet({
16488
+ address,
16489
+ chainId: chain?.id || 1,
16490
+ connectorName: connector.name || "Unknown Wallet"
16491
+ });
16492
+ }
16493
+ }, [isConnected, address, isExternalConnected, connector, chain?.id, setExternalWallet]);
16494
+ useEffect37(() => {
16495
+ if (isExternalConnected && !isConnected) {
16496
+ clearExternalWallet();
16497
+ }
16498
+ }, [isConnected, isExternalConnected, clearExternalWallet]);
16499
+ useEffect37(() => {
16500
+ if (isExternalConnected && isConnected && chain?.id) {
16501
+ setExternalChainId(chain.id);
16502
+ }
16503
+ }, [chain?.id, isConnected, isExternalConnected, setExternalChainId]);
16504
+ useEffect37(() => {
16505
+ if (isExternalConnected && isConnected && address && address !== externalAddress && connector) {
16506
+ setExternalWallet({
16507
+ address,
16508
+ chainId: chain?.id || 1,
16509
+ connectorName: connector.name || "Unknown Wallet"
16510
+ });
16511
+ }
16512
+ }, [address, isConnected, isExternalConnected, externalAddress, chain?.id, connector, setExternalWallet]);
16513
+ return null;
16514
+ }
16515
+ var init_DirectWalletHandler = __esm({
16516
+ "src/internal/components/DirectWalletHandler.tsx"() {
16517
+ init_ProviderContext();
16518
+ init_useExternalWalletStore();
16519
+ }
16520
+ });
16521
+
16360
16522
  // src/context/SessionContext.tsx
16361
16523
  import {
16362
16524
  createBundlerClientForChain,
@@ -16366,7 +16528,7 @@ import {
16366
16528
  getViemChain as getViemChain2
16367
16529
  } from "@embarkai/core/read";
16368
16530
  import { Fragment as Fragment39 } from "react";
16369
- import { create as create7 } from "zustand";
16531
+ import { create as create8 } from "zustand";
16370
16532
  import { persist } from "zustand/middleware";
16371
16533
  import { jsx as jsx93, jsxs as jsxs83 } from "react/jsx-runtime";
16372
16534
  function getChainParams(chainCfg) {
@@ -16389,6 +16551,7 @@ function SessionProvider({ children }) {
16389
16551
  return /* @__PURE__ */ jsxs83(Fragment39, { children: [
16390
16552
  children,
16391
16553
  config.current?.wallet?.enabled && /* @__PURE__ */ jsx93(WalletConnectHandler, {}),
16554
+ config.current?.wallet?.enabled && (config.current?.wallet?.mode === "direct" || config.current?.wallet?.mode === "both") && /* @__PURE__ */ jsx93(DirectWalletHandler, {}),
16392
16555
  /* @__PURE__ */ jsx93(BalanceFeedProvider, {}),
16393
16556
  /* @__PURE__ */ jsx93(ChainSync, {}),
16394
16557
  /* @__PURE__ */ jsx93(
@@ -16408,8 +16571,9 @@ var init_SessionContext = __esm({
16408
16571
  init_Dialog2();
16409
16572
  init_TssManager();
16410
16573
  init_WalletConnectHandler();
16574
+ init_DirectWalletHandler();
16411
16575
  init_ProviderContext();
16412
- useSession = create7()(
16576
+ useSession = create8()(
16413
16577
  persist(
16414
16578
  (set) => ({
16415
16579
  isLoading: false,
@@ -17463,6 +17627,7 @@ __export(auth_exports, {
17463
17627
  deriveDemoPrivateKey: () => deriveDemoPrivateKey,
17464
17628
  ensureKeyshare: () => ensureKeyshare,
17465
17629
  ensureValidToken: () => ensureValidToken,
17630
+ fetchProjectName: () => fetchProjectName,
17466
17631
  formatDate: () => formatDate,
17467
17632
  getKeyshareInfo: () => getKeyshareInfo,
17468
17633
  getLinkedProviders: () => getLinkedProviders,
@@ -18745,27 +18910,45 @@ var init_iframe_manager = __esm({
18745
18910
  // src/config/rainbowkit.ts
18746
18911
  import { lumiaMainnetChain as lumiaMainnetChain2, lumiaTestnetChain as lumiaTestnetChain2 } from "@embarkai/core/read";
18747
18912
  import { getDefaultConfig } from "@rainbow-me/rainbowkit";
18913
+ import {
18914
+ coinbaseWallet,
18915
+ metaMaskWallet,
18916
+ rainbowWallet,
18917
+ walletConnectWallet
18918
+ } from "@rainbow-me/rainbowkit/wallets";
18748
18919
  import { arbitrum, avalanche, base, bsc, mainnet, optimism, polygon, zora } from "wagmi/chains";
18749
- var getProjectId, createRainbowConfig, rainbowConfig, rainbowTheme;
18920
+ var getProjectId, WALLET_MAP, createRainbowConfig, rainbowConfig, rainbowTheme;
18750
18921
  var init_rainbowkit = __esm({
18751
18922
  "src/config/rainbowkit.ts"() {
18752
18923
  getProjectId = (configProjectId) => {
18753
- if (configProjectId) {
18754
- return configProjectId;
18755
- }
18924
+ if (configProjectId) return configProjectId;
18756
18925
  if (typeof window !== "undefined") {
18757
18926
  return window.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID || window.VITE_WALLET_CONNECT_PROJECT_ID || window.__WALLET_CONNECT_PROJECT_ID__ || "YOUR_PROJECT_ID";
18758
18927
  }
18759
18928
  return "YOUR_PROJECT_ID";
18760
18929
  };
18761
- createRainbowConfig = (projectId) => {
18762
- return getDefaultConfig({
18930
+ WALLET_MAP = {
18931
+ walletconnect: walletConnectWallet,
18932
+ metamask: metaMaskWallet,
18933
+ coinbase: coinbaseWallet,
18934
+ rainbow: rainbowWallet
18935
+ };
18936
+ createRainbowConfig = (options) => {
18937
+ const opts = typeof options === "string" ? { projectId: options } : options || {};
18938
+ const config = {
18763
18939
  appName: "Mbark Wallet",
18764
- projectId: getProjectId(projectId),
18940
+ projectId: getProjectId(opts.projectId),
18765
18941
  chains: [lumiaMainnetChain2, lumiaTestnetChain2, mainnet, polygon, bsc, arbitrum, optimism, avalanche, base, zora],
18766
18942
  ssr: false
18767
- // Set to true if using SSR
18768
- });
18943
+ };
18944
+ if (opts.allowedWallets && opts.allowedWallets.length > 0) {
18945
+ const wallets = opts.allowedWallets.map((id) => WALLET_MAP[id.toLowerCase()]).filter(Boolean);
18946
+ if (!opts.allowedWallets.some((id) => id.toLowerCase() === "walletconnect")) {
18947
+ wallets.push(walletConnectWallet);
18948
+ }
18949
+ config.wallets = [{ groupName: "Supported", wallets }];
18950
+ }
18951
+ return getDefaultConfig(config);
18769
18952
  };
18770
18953
  rainbowConfig = createRainbowConfig();
18771
18954
  rainbowTheme = {
@@ -18968,7 +19151,13 @@ import { Fragment as Fragment40, jsx as jsx94 } from "react/jsx-runtime";
18968
19151
  function RainbowKitProvider({ children }) {
18969
19152
  const config = useProviderConfig().config;
18970
19153
  const colorMode = useLayoutStore((st) => st.colorMode);
18971
- const rainbowConfig2 = useMemo9(() => createRainbowConfig(config.current?.wallet?.walletConnectProjectId), []);
19154
+ const rainbowConfig2 = useMemo9(
19155
+ () => createRainbowConfig({
19156
+ projectId: config.current?.wallet?.walletConnectProjectId,
19157
+ allowedWallets: config.current?.wallet?.allowedWallets
19158
+ }),
19159
+ []
19160
+ );
18972
19161
  const customTheme = useMemo9(() => {
18973
19162
  if (!config.current?.wallet?.enabled) return {};
18974
19163
  return colorMode === "dark" ? {
@@ -19064,7 +19253,7 @@ import {
19064
19253
  createContext,
19065
19254
  useCallback as useCallback24,
19066
19255
  useContext,
19067
- useEffect as useEffect37,
19256
+ useEffect as useEffect38,
19068
19257
  useMemo as useMemo10,
19069
19258
  useRef as useRef15
19070
19259
  } from "react";
@@ -19072,11 +19261,11 @@ import { jsx as jsx96 } from "react/jsx-runtime";
19072
19261
  function Provider(props) {
19073
19262
  const { children, projectId, initialConfig = {}, callbacks } = props;
19074
19263
  const callbacksRef = useRef15(callbacks);
19075
- useEffect37(() => {
19264
+ useEffect38(() => {
19076
19265
  callbacksRef.current = callbacks;
19077
19266
  }, [callbacks]);
19078
- useEffect37(() => notifyNoProjetctId(projectId), [projectId]);
19079
- const config = useRef15({ projectId, ...DEFAULT_PROVIDER_CONFIG });
19267
+ useEffect38(() => notifyNoProjetctId(projectId), [projectId]);
19268
+ const config = useRef15(merge3({}, DEFAULT_PROVIDER_CONFIG, { projectId }, initialConfig));
19080
19269
  const updateConfig = useCallback24((updates) => {
19081
19270
  const prev = config.current;
19082
19271
  const next = { ...prev };
@@ -19110,7 +19299,12 @@ function Provider(props) {
19110
19299
  if (updates.translations) next.translations = { ...next.translations, ...updates.translations };
19111
19300
  config.current = next;
19112
19301
  }, []);
19113
- useEffect37(() => {
19302
+ const updateCallbacks = useCallback24((updates) => {
19303
+ const prev = callbacksRef.current;
19304
+ const next = updates ? { ...prev, ...updates } : void 0;
19305
+ callbacksRef.current = next;
19306
+ }, []);
19307
+ useEffect38(() => {
19114
19308
  if (typeof window === "undefined" || !projectId) return;
19115
19309
  const mergedConfig = merge3(DEFAULT_PROVIDER_CONFIG, initialConfig);
19116
19310
  updateConfig(mergedConfig);
@@ -19128,7 +19322,7 @@ function Provider(props) {
19128
19322
  useSession.getState().setActiveChainId(mergedConfig.network.chainId);
19129
19323
  }
19130
19324
  }, [projectId, initialConfig]);
19131
- useEffect37(() => {
19325
+ useEffect38(() => {
19132
19326
  if (typeof window === "undefined" || !projectId) return;
19133
19327
  try {
19134
19328
  initSdkErrorTracking();
@@ -19157,7 +19351,10 @@ function Provider(props) {
19157
19351
  console.error("[PROVIDER] Error setting up iframe manager:", error);
19158
19352
  }
19159
19353
  }, [projectId]);
19160
- const contextValue = useMemo10(() => ({ config, updateConfig, callbacks }), [config, updateConfig, callbacks]);
19354
+ const contextValue = useMemo10(
19355
+ () => ({ config, updateConfig, callbacks, updateCallbacks }),
19356
+ [config, updateConfig, callbacks, updateCallbacks]
19357
+ );
19161
19358
  if (!!initialConfig?.wallet?.enabled)
19162
19359
  return /* @__PURE__ */ jsx96(WagmiProvider2, { children: /* @__PURE__ */ jsx96(UIContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx96(RainbowKitProvider, { children: /* @__PURE__ */ jsx96(SessionProvider, { children }) }) }) });
19163
19360
  return /* @__PURE__ */ jsx96(WagmiProvider2, { children: /* @__PURE__ */ jsx96(UIContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx96(SessionProvider, { children }) }) });
@@ -19183,7 +19380,7 @@ var init_ProviderContext = __esm({
19183
19380
  // src/components/ConnectWalletButton.tsx
19184
19381
  import { useQuery as useQuery22 } from "@tanstack/react-query";
19185
19382
  import { Cloud as Cloud4, Laptop as Laptop2, Loader as Loader33, Shield as Shield3 } from "lucide-react";
19186
- import { useEffect as useEffect38, useMemo as useMemo11 } from "react";
19383
+ import { useEffect as useEffect39, useMemo as useMemo11 } from "react";
19187
19384
  import { Fragment as Fragment41, jsx as jsx97, jsxs as jsxs84 } from "react/jsx-runtime";
19188
19385
  function getFormattedStatus(label, status, showStatus) {
19189
19386
  const isStatus = showStatus && status && status !== "idle" && status !== "ready";
@@ -19203,7 +19400,7 @@ function ConnectWalletButton(props) {
19203
19400
  const colorMode = useLayoutStore((st) => st.colorMode);
19204
19401
  const { session, address, hasServerVault, isLoading, isIframeReady, status, setUsePaymaster } = useSession();
19205
19402
  const connectButtonLabel = getFormattedStatus(label || "Connect", status, isIframeReady);
19206
- useEffect38(() => setUsePaymaster(usePaymaster), [setUsePaymaster, usePaymaster]);
19403
+ useEffect39(() => setUsePaymaster(usePaymaster), [setUsePaymaster, usePaymaster]);
19207
19404
  const { data: profile, isLoading: isProfileLoading } = useQuery22({
19208
19405
  retry: false,
19209
19406
  enabled: !!address,
@@ -19990,7 +20187,7 @@ var init_Hash = __esm({
19990
20187
  });
19991
20188
 
19992
20189
  // src/internal/components/TransactionsMenu/TransactionsList.tsx
19993
- import { useEffect as useEffect40, useState as useState25 } from "react";
20190
+ import { useEffect as useEffect41, useState as useState25 } from "react";
19994
20191
  import { jsx as jsx103, jsxs as jsxs88 } from "react/jsx-runtime";
19995
20192
  var TransactionsList;
19996
20193
  var init_TransactionsList = __esm({
@@ -20000,7 +20197,7 @@ var init_TransactionsList = __esm({
20000
20197
  const [transactions, setTransactions] = useState25([]);
20001
20198
  const [loading, setLoading] = useState25(true);
20002
20199
  const [error, setError] = useState25(null);
20003
- useEffect40(() => {
20200
+ useEffect41(() => {
20004
20201
  const fetchTransactions2 = async () => {
20005
20202
  try {
20006
20203
  setLoading(true);
@@ -20294,13 +20491,229 @@ var init_useUserOpStatus = __esm({
20294
20491
  }
20295
20492
  });
20296
20493
 
20494
+ // src/hooks/useWalletMode.ts
20495
+ import { useCallback as useCallback28 } from "react";
20496
+ function useWalletMode() {
20497
+ const configMode = useExternalWalletStore((st) => st.configMode);
20498
+ const activeMode = useExternalWalletStore((st) => st.activeMode);
20499
+ const setActiveMode = useExternalWalletStore((st) => st.setActiveMode);
20500
+ const switchMode = useCallback28(
20501
+ (mode) => {
20502
+ if (configMode !== "both") return;
20503
+ setActiveMode(mode);
20504
+ },
20505
+ [configMode, setActiveMode]
20506
+ );
20507
+ return {
20508
+ configMode,
20509
+ activeMode,
20510
+ switchMode,
20511
+ isDirect: activeMode === "direct"
20512
+ };
20513
+ }
20514
+ var init_useWalletMode = __esm({
20515
+ "src/hooks/useWalletMode.ts"() {
20516
+ init_useExternalWalletStore();
20517
+ }
20518
+ });
20519
+
20520
+ // src/hooks/useDirectWallet.ts
20521
+ import { useCallback as useCallback29 } from "react";
20522
+ import { useConnectModal as useConnectModal2 } from "@rainbow-me/rainbowkit";
20523
+ import { useDisconnect as useDisconnect2 } from "wagmi";
20524
+ function useDirectWallet() {
20525
+ const address = useExternalWalletStore((st) => st.externalAddress);
20526
+ const chainId = useExternalWalletStore((st) => st.externalChainId);
20527
+ const isConnected = useExternalWalletStore((st) => st.isExternalConnected);
20528
+ const connectorName = useExternalWalletStore((st) => st.connectorName);
20529
+ const clearExternalWallet = useExternalWalletStore((st) => st.clearExternalWallet);
20530
+ const { disconnect: wagmiDisconnect } = useDisconnect2();
20531
+ const { openConnectModal } = useConnectModal2();
20532
+ const setIsWalletLinking = useLayoutDataStore((st) => st.setIsWalletLinking);
20533
+ const connect = useCallback29(() => {
20534
+ setIsWalletLinking(true);
20535
+ }, [setIsWalletLinking]);
20536
+ const reconnect = useCallback29(() => {
20537
+ if (openConnectModal) openConnectModal();
20538
+ }, [openConnectModal]);
20539
+ const disconnect = useCallback29(() => {
20540
+ wagmiDisconnect();
20541
+ clearExternalWallet();
20542
+ }, [wagmiDisconnect, clearExternalWallet]);
20543
+ return {
20544
+ address,
20545
+ chainId,
20546
+ isConnected,
20547
+ connectorName,
20548
+ connect,
20549
+ reconnect,
20550
+ disconnect
20551
+ };
20552
+ }
20553
+ var init_useDirectWallet = __esm({
20554
+ "src/hooks/useDirectWallet.ts"() {
20555
+ init_useExternalWalletStore();
20556
+ init_useLayoutDataStore();
20557
+ }
20558
+ });
20559
+
20560
+ // src/hooks/useSendDirectTransaction.ts
20561
+ import { useCallback as useCallback30, useState as useState27 } from "react";
20562
+ import { isAddress as isAddress3, parseEther as parseEther4 } from "viem";
20563
+ import { useSendTransaction as useWagmiSendTransaction, useSwitchChain } from "wagmi";
20564
+ function useSendDirectTransaction() {
20565
+ const isConnected = useExternalWalletStore((st) => st.isExternalConnected);
20566
+ const externalChainId = useExternalWalletStore((st) => st.externalChainId);
20567
+ const { sendTransactionAsync } = useWagmiSendTransaction();
20568
+ const { switchChainAsync } = useSwitchChain();
20569
+ const [isPending, setIsPending] = useState27(false);
20570
+ const [error, setError] = useState27(null);
20571
+ const [txHash, setTxHash] = useState27(null);
20572
+ const sendTransaction = useCallback30(
20573
+ async (params) => {
20574
+ if (!isConnected) {
20575
+ setError("No external wallet connected");
20576
+ return null;
20577
+ }
20578
+ if (!isAddress3(params.to)) {
20579
+ setError("Invalid recipient address");
20580
+ return null;
20581
+ }
20582
+ setIsPending(true);
20583
+ setError(null);
20584
+ setTxHash(null);
20585
+ try {
20586
+ if (params.chainId && params.chainId !== externalChainId) {
20587
+ await switchChainAsync({ chainId: params.chainId });
20588
+ }
20589
+ const hash = await sendTransactionAsync({
20590
+ to: params.to,
20591
+ value: parseEther4(params.value),
20592
+ data: params.data
20593
+ });
20594
+ setTxHash(hash);
20595
+ return hash;
20596
+ } catch (err) {
20597
+ const message = err instanceof Error ? err.message : "Transaction failed";
20598
+ setError(message);
20599
+ return null;
20600
+ } finally {
20601
+ setIsPending(false);
20602
+ }
20603
+ },
20604
+ [isConnected, externalChainId, sendTransactionAsync, switchChainAsync]
20605
+ );
20606
+ const reset = useCallback30(() => {
20607
+ setError(null);
20608
+ setTxHash(null);
20609
+ setIsPending(false);
20610
+ }, []);
20611
+ return { sendTransaction, isPending, error, txHash, reset };
20612
+ }
20613
+ var init_useSendDirectTransaction = __esm({
20614
+ "src/hooks/useSendDirectTransaction.ts"() {
20615
+ init_useExternalWalletStore();
20616
+ }
20617
+ });
20618
+
20619
+ // src/hooks/useTransferToLinkedWallet.ts
20620
+ import { useCallback as useCallback31, useMemo as useMemo12, useState as useState28 } from "react";
20621
+ import { encodeFunctionData as encodeFunctionData4, isAddress as isAddress4, parseEther as parseEther5, parseUnits as parseUnits3 } from "viem";
20622
+ function useTransferToLinkedWallet() {
20623
+ const session = useSession((st) => st.session);
20624
+ const { profiles } = useLinkedProfiles();
20625
+ const [isPending, setIsPending] = useState28(false);
20626
+ const [error, setError] = useState28(null);
20627
+ const [userOpHash, setUserOpHash] = useState28(null);
20628
+ const linkedWallets = useMemo12(
20629
+ () => (profiles || []).filter((p) => p.provider === "wallet" && p.externalId).map((p) => p.externalId),
20630
+ [profiles]
20631
+ );
20632
+ const transfer = useCallback31(
20633
+ async (params) => {
20634
+ if (!session) {
20635
+ setError("No active session");
20636
+ return null;
20637
+ }
20638
+ const toAddress = params.toAddress || linkedWallets[0];
20639
+ if (!toAddress || !isAddress4(toAddress)) {
20640
+ setError("No linked wallet address available");
20641
+ return null;
20642
+ }
20643
+ setIsPending(true);
20644
+ setError(null);
20645
+ setUserOpHash(null);
20646
+ try {
20647
+ let to;
20648
+ let value;
20649
+ let data;
20650
+ if (params.token === "native") {
20651
+ to = toAddress;
20652
+ value = parseEther5(params.amount).toString();
20653
+ data = "0x";
20654
+ } else {
20655
+ const decimals = params.decimals ?? 18;
20656
+ to = params.token;
20657
+ value = "0";
20658
+ data = encodeFunctionData4({
20659
+ abi: ERC20_TRANSFER_ABI2,
20660
+ functionName: "transfer",
20661
+ args: [toAddress, parseUnits3(params.amount, decimals)]
20662
+ });
20663
+ }
20664
+ const hash = await sendUserOperation2(session, {
20665
+ to,
20666
+ value,
20667
+ data,
20668
+ feeType: "standard",
20669
+ chainId: params.chainId
20670
+ });
20671
+ setUserOpHash(hash);
20672
+ return hash;
20673
+ } catch (err) {
20674
+ const message = err instanceof Error ? err.message : "Transfer failed";
20675
+ setError(message);
20676
+ return null;
20677
+ } finally {
20678
+ setIsPending(false);
20679
+ }
20680
+ },
20681
+ [session, linkedWallets]
20682
+ );
20683
+ const reset = useCallback31(() => {
20684
+ setError(null);
20685
+ setUserOpHash(null);
20686
+ setIsPending(false);
20687
+ }, []);
20688
+ return { transfer, isPending, error, userOpHash, linkedWallets, reset };
20689
+ }
20690
+ var ERC20_TRANSFER_ABI2;
20691
+ var init_useTransferToLinkedWallet = __esm({
20692
+ "src/hooks/useTransferToLinkedWallet.ts"() {
20693
+ init_SessionContext();
20694
+ init_account();
20695
+ init_linkedProfiles();
20696
+ ERC20_TRANSFER_ABI2 = [
20697
+ {
20698
+ type: "function",
20699
+ name: "transfer",
20700
+ inputs: [
20701
+ { name: "to", type: "address" },
20702
+ { name: "amount", type: "uint256" }
20703
+ ],
20704
+ outputs: [{ name: "", type: "bool" }]
20705
+ }
20706
+ ];
20707
+ }
20708
+ });
20709
+
20297
20710
  // src/hooks/useLogout.ts
20298
20711
  import { logout as coreLogout, jwtTokenManager as jwtTokenManager3 } from "@embarkai/core/auth";
20299
- import { useCallback as useCallback28 } from "react";
20712
+ import { useCallback as useCallback32 } from "react";
20300
20713
  function useLogout() {
20301
20714
  const { setSession, setIsLoading, setAddress, setStatus, setError, address } = useSession();
20302
20715
  const { callbacks } = useProviderConfig();
20303
- const logout2 = useCallback28(async () => {
20716
+ const logout2 = useCallback32(async () => {
20304
20717
  const prevAddress = address;
20305
20718
  let userId = null;
20306
20719
  setIsLoading(true);
@@ -20390,21 +20803,21 @@ var init_clients2 = __esm({
20390
20803
 
20391
20804
  // src/modules/transactions.ts
20392
20805
  import { getViemChain as getViemChain4 } from "@embarkai/core/read";
20393
- import { parseEther as parseEther4 } from "viem";
20394
- import { useAccount as useAccount2, usePublicClient, useWalletClient } from "wagmi";
20806
+ import { parseEther as parseEther6 } from "viem";
20807
+ import { useAccount as useAccount3, usePublicClient, useWalletClient } from "wagmi";
20395
20808
  function useTransactions() {
20396
20809
  const chainId = requireActiveChainId();
20397
20810
  const viemChain = getViemChain4(chainId);
20398
20811
  const publicClient = usePublicClient({ chainId });
20399
20812
  const { data: walletClient } = useWalletClient();
20400
- const { address } = useAccount2();
20813
+ const { address } = useAccount3();
20401
20814
  const sendTransaction = async (params) => {
20402
20815
  if (!walletClient) {
20403
20816
  throw new Error("Wallet not connected");
20404
20817
  }
20405
20818
  const txParams = {
20406
20819
  to: params.to,
20407
- value: parseEther4(params.value),
20820
+ value: parseEther6(params.value),
20408
20821
  data: params.data,
20409
20822
  chain: viemChain
20410
20823
  };
@@ -20721,6 +21134,10 @@ var init_index = __esm({
20721
21134
  init_useSendTransaction();
20722
21135
  init_useUserOpStatus();
20723
21136
  init_useErc3643Compliance();
21137
+ init_useWalletMode();
21138
+ init_useDirectWallet();
21139
+ init_useSendDirectTransaction();
21140
+ init_useTransferToLinkedWallet();
20724
21141
  init_useLogout();
20725
21142
  init_useNicknameResolve();
20726
21143
  init_account();
@@ -20786,6 +21203,7 @@ export {
20786
21203
  useAssets,
20787
21204
  useBalance,
20788
21205
  useColorMode,
21206
+ useDirectWallet,
20789
21207
  useErc3643Compliance,
20790
21208
  useError,
20791
21209
  useHasServerVault,
@@ -20799,13 +21217,16 @@ export {
20799
21217
  useOpenPage,
20800
21218
  useProviderConfig,
20801
21219
  useRecoveryUserId,
21220
+ useSendDirectTransaction,
20802
21221
  useSendTransaction,
20803
21222
  useSession,
20804
21223
  useSmartAccountTransactions,
20805
21224
  useTokenBalance,
20806
21225
  useTokenInfo,
20807
21226
  useTransactions,
21227
+ useTransferToLinkedWallet,
20808
21228
  useUserOpStatus,
21229
+ useWalletMode,
20809
21230
  verifyFingerprint,
20810
21231
  verifyFingerprintDetailed,
20811
21232
  wagmiConfig,