diff --git a/.changeset/tame-gifts-hope.md b/.changeset/tame-gifts-hope.md new file mode 100644 index 000000000..7542eec0b --- /dev/null +++ b/.changeset/tame-gifts-hope.md @@ -0,0 +1,5 @@ +--- +"hub": patch +--- + +update wallet connect diff --git a/apps/hub/.env b/apps/hub/.env index 5d2858140..f3ed585dd 100644 --- a/apps/hub/.env +++ b/apps/hub/.env @@ -16,4 +16,5 @@ # – https://vercel.com/docs/cli/env#exporting-development-environment-variables -NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="123" +NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="" +NEXT_PUBLIC_STATUS_NETWORK_API_URL="" \ No newline at end of file diff --git a/apps/hub/.env.development b/apps/hub/.env.development new file mode 100644 index 000000000..f3ed585dd --- /dev/null +++ b/apps/hub/.env.development @@ -0,0 +1,20 @@ +# note: next lint doesn't use .env.development +# note: use .env.local instead for now +# +# – https://github.com/vercel/next.js/discussions/32354 + +# .env, .env.development, and .env.production files should be included in your repository as they define defaults. +# .env*.local should be added to .gitignore, as those files are intended to be ignored. +# .env.local is where secrets can be stored. +# +# – https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#default-environment-variables + +# The vercel env pull sub-command will export development environment variables to a local .env file or a different file of your choice. +# +# `vercel env pull .env[.development].local` +# +# – https://vercel.com/docs/cli/env#exporting-development-environment-variables + + +NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID="" +NEXT_PUBLIC_STATUS_NETWORK_API_URL="" \ No newline at end of file diff --git a/apps/hub/package.json b/apps/hub/package.json index 509c86da3..1154132ff 100644 --- a/apps/hub/package.json +++ b/apps/hub/package.json @@ -38,7 +38,7 @@ "rehype-slug": "^6.0.0", "siwe": "^2.3.2", "ts-pattern": "^5.6.2", - "viem": "^2.21.1", + "viem": "^2.29.1", "wagmi": "2.15.2", "zod": "^3.24.1" }, diff --git a/apps/hub/src/app/_components/connect-button.tsx b/apps/hub/src/app/_components/connect-button.tsx index e8cb92ab6..dfa6a5c04 100644 --- a/apps/hub/src/app/_components/connect-button.tsx +++ b/apps/hub/src/app/_components/connect-button.tsx @@ -2,45 +2,39 @@ import { Button, ShortenAddress } from '@status-im/status-network/components' import { ConnectKitButton } from 'connectkit' -import { useAccount } from 'wagmi' import type { ComponentProps } from 'react' type Props = { size?: ComponentProps['size'] label?: string - shortLabel?: string + className?: string + /** If true, shows the label instead of the shortened address when connected */ + alwaysShowLabel?: boolean } const ConnectButton = (props: Props) => { const { size = '32', label = 'Connect wallet', - shortLabel = 'Connect', + className, + alwaysShowLabel = false, } = props - const { address, isConnected } = useAccount() - return ( - {({ show }) => { + {({ show, isConnected, address }) => { return ( ) diff --git a/apps/hub/src/app/_constants/chain.ts b/apps/hub/src/app/_constants/chain.ts index d2e71f3c6..6c79c921b 100644 --- a/apps/hub/src/app/_constants/chain.ts +++ b/apps/hub/src/app/_constants/chain.ts @@ -1,20 +1,26 @@ -import type { Chain } from 'wagmi/chains' +import { getDefaultConfig } from 'connectkit' +import { defineChain } from 'viem' +import { createConfig, http } from 'wagmi' +import { type Chain, mainnet } from 'wagmi/chains' -export const statusNetworkTestnet: Chain = { - id: Number(1660990954), +import { clientEnv } from './env.client.mjs' + +import type { + CreateConfigParameters, + CreateConnectorFn, + Transport, +} from 'wagmi' + +export const testnet = defineChain({ + id: 1660990954, name: 'Status Network Testnet', - nativeCurrency: { - decimals: 18, - name: 'Ether', - symbol: 'ETH', - }, + testnet: true, + sourceId: 1660990954, + nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 }, rpcUrls: { default: { http: ['https://public.sepolia.rpc.status.network'], }, - public: { - http: ['https://public.sepolia.rpc.status.network'], - }, }, blockExplorers: { default: { @@ -22,4 +28,25 @@ export const statusNetworkTestnet: Chain = { url: 'https://sepoliascan.status.network', }, }, -} +}) + +export const getDefaultWagmiConfig = () => + getDefaultConfig({ + chains: [mainnet, testnet], + transports: { + [mainnet.id]: http(mainnet.rpcUrls.default.http[0]), + [testnet.id]: http(testnet.rpcUrls.default.http[0]), + }, + walletConnectProjectId: + clientEnv.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID as string, + appName: 'Status Hub', + appDescription: 'Status Network DeFi Dashboard', + appUrl: 'https://status.app', + appIcon: 'https://status.app/icon.png', + }) as CreateConfigParameters< + readonly [Chain, ...Chain[]], + Record, + readonly CreateConnectorFn[] + > + +export const wagmiConfig = createConfig(getDefaultWagmiConfig()) diff --git a/apps/hub/src/app/_constants/env.client.mjs b/apps/hub/src/app/_constants/env.client.mjs index eab850ac1..aa2881576 100644 --- a/apps/hub/src/app/_constants/env.client.mjs +++ b/apps/hub/src/app/_constants/env.client.mjs @@ -5,11 +5,14 @@ export const envSchema = z.object({ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID: z .string() .min(1, 'WalletConnect Project ID is required.'), + NEXT_PUBLIC_STATUS_NETWORK_API_URL: z.string().url(), }) export const result = envSchema.strip().safeParse({ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID, + NEXT_PUBLIC_STATUS_NETWORK_API_URL: + process.env.NEXT_PUBLIC_STATUS_NETWORK_API_URL, }) if (!result.success) { diff --git a/apps/hub/src/app/_constants/index.ts b/apps/hub/src/app/_constants/index.ts index 4ee2947e8..59ce36462 100644 --- a/apps/hub/src/app/_constants/index.ts +++ b/apps/hub/src/app/_constants/index.ts @@ -1,3 +1,4 @@ export * from './address' export * from './chain' +export * from './siwe' export * from './staking' diff --git a/apps/hub/src/app/_constants/siwe.ts b/apps/hub/src/app/_constants/siwe.ts new file mode 100644 index 000000000..a31553776 --- /dev/null +++ b/apps/hub/src/app/_constants/siwe.ts @@ -0,0 +1,73 @@ +import { clientEnv } from './env.client.mjs' + +import type { SIWEConfig } from 'connectkit' + +// API configuration +const API_BASE_URL = clientEnv.NEXT_PUBLIC_STATUS_NETWORK_API_URL + +const AUTH_ENDPOINTS = { + verify: `${API_BASE_URL}/auth/ethereum`, + session: `${API_BASE_URL}/auth/me`, + logout: `${API_BASE_URL}/auth/logout`, +} as const + +// Helper for API calls +const fetchAPI = async (url: string, options?: RequestInit) => { + const response = await fetch(url, { + credentials: 'include', // Send cookies with cross-origin requests + headers: { + 'Content-Type': 'application/json', + ...options?.headers, + }, + ...options, + }) + return response +} + +export const siweConfig: SIWEConfig = { + getNonce: async () => { + return Math.random().toString(36).substring(2, 15) + }, + + createMessage: async () => { + const payload = { timestamp: Math.floor(Date.now() / 1000) } + return window.btoa(JSON.stringify(payload)) + }, + + verifyMessage: async ({ message, signature }) => { + try { + const response = await fetchAPI(AUTH_ENDPOINTS.verify, { + method: 'POST', + body: JSON.stringify({ payload: message, signature }), + }) + return response.ok + } catch { + return false + } + }, + + getSession: async () => { + try { + const response = await fetchAPI(AUTH_ENDPOINTS.session) + if (!response.ok) return null + + const data = await response.json() + return data.result ?? null + } catch { + return null + } + }, + + signOut: async () => { + try { + const response = await fetchAPI(AUTH_ENDPOINTS.logout, { + method: 'POST', + }) + return response.ok + } catch { + return false + } + }, + + signOutOnDisconnect: false, +} diff --git a/apps/hub/src/app/_providers/connectkit-provider.tsx b/apps/hub/src/app/_providers/connectkit-provider.tsx deleted file mode 100644 index c39640cc0..000000000 --- a/apps/hub/src/app/_providers/connectkit-provider.tsx +++ /dev/null @@ -1,15 +0,0 @@ -'use client' - -import { ConnectKitProvider as ConnectKit } from 'connectkit' - -type ConnectKitProviderProps = { - children: React.ReactNode -} - -export function ConnectKitProvider({ children }: ConnectKitProviderProps) { - return ( - - {children} - - ) -} diff --git a/apps/hub/src/app/_providers/index.tsx b/apps/hub/src/app/_providers/index.tsx index 1e55ed291..c917f1e22 100644 --- a/apps/hub/src/app/_providers/index.tsx +++ b/apps/hub/src/app/_providers/index.tsx @@ -1,21 +1,61 @@ 'use client' -import { VaultStateProvider } from '../_hooks/useVaultStateContext' -import { ConnectKitProvider } from './connectkit-provider' -import { QueryClientProvider } from './query-client-provider' -import { WagmiProvider } from './wagmi-provider' +import { ToastContainer } from '@status-im/components' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { ConnectKitProvider, SIWEProvider } from 'connectkit' +import { WagmiProvider } from 'wagmi' + +import { testnet, wagmiConfig } from '~constants/chain' +import { siweConfig } from '~constants/siwe' +import { VaultStateProvider } from '~hooks/useVaultStateContext' + +import { VaultProvider } from './vault-provider' interface ProvidersProps { children: React.ReactNode } +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + retryOnMount: false, + refetchOnMount: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }, + }, +}) + +/** + * Application Providers + * + * Provider hierarchy (order matters): + * 1. WagmiProvider - Blockchain connection & wallet state + * 2. QueryClientProvider - React Query for data fetching + * 3. SiweProvider - SIWE authentication + * 4. ConnectKitProvider - Wallet connection UI + * 5. VaultStateProvider - Vault operation state machine + * 6. VaultProvider - Vault-specific features + */ export function Providers({ children }: ProvidersProps) { return ( - - - - {children} - + + + + + + + {children} + + + + + ) diff --git a/apps/hub/src/app/_providers/query-client-provider.tsx b/apps/hub/src/app/_providers/query-client-provider.tsx deleted file mode 100644 index 4cdc10c62..000000000 --- a/apps/hub/src/app/_providers/query-client-provider.tsx +++ /dev/null @@ -1,31 +0,0 @@ -'use client' - -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' - -import type React from 'react' - -const queryClient = new QueryClient({ - defaultOptions: { - queries: { - retry: false, - retryOnMount: false, - refetchOnMount: false, - refetchOnWindowFocus: false, - refetchOnReconnect: false, - }, - }, -}) - -type Props = { - children: React.ReactNode -} - -function _QueryClientProvider(props: Props) { - const { children } = props - - return ( - {children} - ) -} - -export { _QueryClientProvider as QueryClientProvider } diff --git a/apps/hub/src/app/_providers/vault-provider.tsx b/apps/hub/src/app/_providers/vault-provider.tsx new file mode 100644 index 000000000..025c3eded --- /dev/null +++ b/apps/hub/src/app/_providers/vault-provider.tsx @@ -0,0 +1,28 @@ +'use client' + +import { ActionStatusDialog } from '../_components/stake/action-status-dialog' +import { useActionStatusContent } from '../_components/stake/hooks/use-action-status-content' +import { useVaultStateContext } from '../_hooks/useVaultStateContext' + +export const VaultProvider = ({ children }: { children: React.ReactNode }) => { + const { state: vaultState, reset: resetVault } = useVaultStateContext() + const dialogContent = useActionStatusContent(vaultState) + + // Only render dialog in DOM if state is not idle + const shouldRenderDialog = + vaultState.type !== 'idle' && dialogContent !== null + + return ( + <> + {children} + + {shouldRenderDialog ? ( + + ) : null} + + ) +} diff --git a/apps/hub/src/app/_providers/wagmi-provider.tsx b/apps/hub/src/app/_providers/wagmi-provider.tsx deleted file mode 100644 index a8085e27b..000000000 --- a/apps/hub/src/app/_providers/wagmi-provider.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import { createConfig, http, WagmiProvider as WagmiProviderBase } from 'wagmi' -import { mainnet } from 'wagmi/chains' -import { injected, metaMask, walletConnect } from 'wagmi/connectors' - -import { clientEnv } from '~constants/env.client.mjs' - -import type React from 'react' - -export const config = createConfig({ - chains: [mainnet], - ssr: false, - connectors: [ - injected(), - metaMask(), - walletConnect({ - projectId: clientEnv.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID, - showQrModal: false, - }), - ], - transports: { - // todo: replace public clients - [mainnet.id]: http(), - }, -}) - -declare module 'wagmi' { - interface Register { - config: typeof config - } -} - -type Props = { - children: React.ReactNode -} - -function WagmiProvider(props: Props) { - const { children } = props - - return ( - ['config'] - } - > - {children} - - ) -} - -export { config as wagmiConfig, WagmiProvider } diff --git a/apps/hub/src/wagmi.ts b/apps/hub/src/wagmi.ts deleted file mode 100644 index 2ee534d06..000000000 --- a/apps/hub/src/wagmi.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { createConfig, http } from 'wagmi' - -import type { Config, CreateConfigParameters, Transport } from 'wagmi' -import type { Chain } from 'wagmi/chains' - -// Todo: move this to shared packages - -/** - * Configuration options for Status Hub wagmi config - */ -export interface DefineWagmiConfigOptions { - /** - * Array of chains to support - */ - chains: [Chain, ...Chain[]] - - /** - * Enable server-side rendering support - * @default false - */ - ssr?: boolean - - /** - * Custom RPC URLs per chain (optional) - * Maps chain IDs to RPC URLs - */ - rpcUrls?: Record - - /** - * Batch JSON-RPC requests - * @default undefined - */ - batch?: CreateConfigParameters['batch'] - - /** - * Polling interval in milliseconds - * @default undefined - */ - pollingInterval?: number - - /** - * WalletConnect project ID - * @default undefined - */ - walletConnectProjectId?: string -} - -/** - * Creates a wagmi configuration for Status Hub with the specified chains and options - * - * @param options - Configuration options - * @returns Wagmi config instance - * - * @example - * ```ts - * import { mainnet, optimism } from 'wagmi/chains' - * - * const config = defineWagmiConfig({ - * chains: [mainnet, optimism], - * ssr: true, - * walletConnectProjectId: 'your-project-id', - * rpcUrls: { - * [mainnet.id]: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY' - * } - * }) - * ``` - */ -export const defineWagmiConfig = ( - options: DefineWagmiConfigOptions -): Config => { - const { chains, ssr = false, rpcUrls, batch, pollingInterval } = options - - const transports = chains.reduce( - (acc, chain) => { - const rpcUrl = rpcUrls?.[chain.id] - acc[chain.id] = http(rpcUrl, { - batch: batch ? true : undefined, - ...(pollingInterval && { pollingInterval }), - }) - return acc - }, - {} as Record - ) - - return createConfig({ - chains, - ssr, - transports, - batch, - }) -} - -/** - * Type helper to infer the config type from defineWagmiConfig - */ -export type InferWagmiConfig = ReturnType diff --git a/package.json b/package.json index 87196f915..00f5426c4 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,8 @@ "@scure/base": "^1.2.6" }, "devDependencies": { - "@ianvs/prettier-plugin-sort-imports": "^4.1.1", "@changesets/cli": "^2.26.2", + "@ianvs/prettier-plugin-sort-imports": "^4.1.1", "@status-im/eslint-config": "workspace:*", "@tsconfig/strictest": "^2.0.0", "@types/prettier": "^2.7.2", @@ -80,6 +80,7 @@ "dependencies": { "@tanstack/react-query": "^5.90.2", "connectkit": "^1.9.0", + "iron-session": "^8.0.4", "wagmi": "^2.12.8" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 840176b41..4fab1e23b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,6 +43,9 @@ importers: connectkit: specifier: ^1.9.0 version: 1.9.0(@babel/core@7.27.1)(@tanstack/react-query@5.90.2(react@19.1.0))(react-dom@19.1.1(react@19.1.0))(react-is@18.1.0)(react@19.1.0)(viem@2.29.1(bufferutil@4.0.9)(typescript@5.6.2)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.15.2(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.0))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.6.2)(utf-8-validate@5.0.10)(viem@2.29.1(bufferutil@4.0.9)(typescript@5.6.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) + iron-session: + specifier: ^8.0.4 + version: 8.0.4 wagmi: specifier: ^2.12.8 version: 2.15.2(@tanstack/query-core@5.90.2)(@tanstack/react-query@5.90.2(react@19.1.0))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(typescript@5.6.2)(utf-8-validate@5.0.10)(viem@2.29.1(bufferutil@4.0.9)(typescript@5.6.2)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) @@ -329,7 +332,7 @@ importers: specifier: ^5.6.2 version: 5.7.1 viem: - specifier: ^2.21.1 + specifier: ^2.29.1 version: 2.29.1(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: 2.15.2 @@ -5849,8 +5852,8 @@ packages: '@radix-ui/react-alert-dialog@1.1.13': resolution: {integrity: sha512-/uPs78OwxGxslYOG5TKeUsv9fZC0vo376cXSADdKirTmsLJU2au6L3n34c3p6W26rFDDDze/hwy4fYeNd0qdGA==} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1 react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: @@ -6303,8 +6306,8 @@ packages: '@radix-ui/react-roving-focus@1.1.9': resolution: {integrity: sha512-ZzrIFnMYHHCNqSNCsuN6l7wlewBEq0O0BCSBkabJMFXVO51LRUTq71gLP1UxFvmrXElqmPjA5VX7IqC9VpazAQ==} peerDependencies: - '@types/react': '*' - '@types/react-dom': '*' + '@types/react': 19.1.0 + '@types/react-dom': 19.1.1 react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: @@ -10324,6 +10327,10 @@ packages: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + copy-anything@2.0.6: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} @@ -11842,15 +11849,6 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} @@ -12766,6 +12764,9 @@ packages: resolution: {integrity: sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==} engines: {node: '>= 10'} + iron-session@8.0.4: + resolution: {integrity: sha512-9ivNnaKOd08osD0lJ3i6If23GFS2LsxyMU8Gf/uBUEgm8/8CC1hrrCHFDpMo3IFbpBgwoo/eairRsaD3c5itxA==} + iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} @@ -18872,6 +18873,9 @@ packages: zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -19078,7 +19082,7 @@ snapshots: '@babel/traverse': 7.27.1(supports-color@5.5.0) '@babel/types': 7.27.1 convert-source-map: 2.0.0 - debug: 4.4.0 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -20554,7 +20558,7 @@ snapshots: '@eslint/config-array@0.18.0': dependencies: '@eslint/object-schema': 2.1.4 - debug: 4.4.0 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -20564,7 +20568,7 @@ snapshots: '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 - debug: 4.4.0 + debug: 4.4.3 espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 @@ -28395,7 +28399,7 @@ snapshots: babel-dead-code-elimination: 1.0.10 chokidar: 3.6.0 unplugin: 2.3.2 - zod: 3.25.76 + zod: 3.23.8 optionalDependencies: '@tanstack/react-router': 1.120.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) vite: 6.3.5(@types/node@22.7.5)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.27.0)(sass@1.80.4)(tsx@4.19.4)(yaml@2.8.1) @@ -31814,7 +31818,7 @@ snapshots: axios@0.21.4: dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.9 transitivePeerDependencies: - debug @@ -32868,6 +32872,8 @@ snapshots: cookie@0.6.0: {} + cookie@0.7.2: {} + copy-anything@2.0.6: dependencies: is-what: 3.14.1 @@ -33251,7 +33257,7 @@ snapshots: dependencies: call-bind: 1.0.7 es-get-iterator: 1.1.2 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 is-arguments: 1.1.1 is-array-buffer: 3.0.2 is-date-object: 1.0.5 @@ -33750,8 +33756,8 @@ snapshots: es-get-iterator@1.1.2: dependencies: call-bind: 1.0.7 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 is-arguments: 1.1.1 is-map: 2.0.2 is-set: 2.0.2 @@ -34042,7 +34048,7 @@ snapshots: debug: 4.3.7(supports-color@5.5.0) enhanced-resolve: 5.17.1 eslint: 9.14.0(jiti@2.4.2) - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.14.0(jiti@2.4.2)))(eslint@9.14.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.14.0(jiti@2.4.2)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -34061,7 +34067,7 @@ snapshots: debug: 4.3.7(supports-color@5.5.0) enhanced-resolve: 5.17.1 eslint: 9.14.0(jiti@2.4.2) - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.40.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.40.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.14.0(jiti@2.4.2)))(eslint@9.14.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.40.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.14.0(jiti@2.4.2)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -34094,7 +34100,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.14.0(jiti@2.4.2)))(eslint@9.14.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.14.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: @@ -34105,7 +34111,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.40.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.40.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.14.0(jiti@2.4.2)))(eslint@9.14.0(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.40.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.14.0(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: @@ -34133,7 +34139,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.14.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.14.0(jiti@2.4.2)))(eslint@9.14.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.13.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.14.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -34162,7 +34168,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.14.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.40.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.40.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.14.0(jiti@2.4.2)))(eslint@9.14.0(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.40.0(eslint@9.14.0(jiti@2.4.2))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.14.0(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -34305,7 +34311,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.4.0 + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint-scope: 8.2.0 eslint-visitor-keys: 4.2.1 @@ -34882,8 +34888,6 @@ snapshots: flatted@3.3.1: {} - follow-redirects@1.15.2: {} - follow-redirects@1.15.9: {} for-each@0.3.3: @@ -35806,7 +35810,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.2 + follow-redirects: 1.15.9 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -36011,6 +36015,12 @@ snapshots: ipaddr.js@2.1.0: {} + iron-session@8.0.4: + dependencies: + cookie: 0.7.2 + iron-webcrypto: 1.2.1 + uncrypto: 0.1.3 + iron-webcrypto@1.2.1: {} is-absolute-url@4.0.1: {} @@ -36041,7 +36051,7 @@ snapshots: is-arguments@1.1.1: dependencies: call-bind: 1.0.7 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-array-buffer@3.0.2: dependencies: @@ -36101,7 +36111,7 @@ snapshots: is-date-object@1.0.5: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-decimal@1.0.4: {} @@ -36135,7 +36145,7 @@ snapshots: is-generator-function@1.0.10: dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 is-glob@4.0.3: dependencies: @@ -36320,12 +36330,12 @@ snapshots: is-weakset@2.0.2: dependencies: call-bind: 1.0.7 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 is-weakset@2.0.3: dependencies: call-bind: 1.0.7 - get-intrinsic: 1.2.4 + get-intrinsic: 1.3.0 is-what@3.14.1: {} @@ -38975,10 +38985,10 @@ snapshots: ox@0.6.7(typescript@5.6.2)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.10.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 + '@noble/curves': 1.9.0 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 abitype: 1.0.8(typescript@5.6.2)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: @@ -38989,10 +38999,10 @@ snapshots: ox@0.6.7(typescript@5.8.3)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.10.1 - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 + '@noble/curves': 1.9.0 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 abitype: 1.0.8(typescript@5.8.3)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: @@ -44636,6 +44646,8 @@ snapshots: zod@3.22.4: {} + zod@3.23.8: {} + zod@3.25.76: {} zustand@4.3.7(react@18.3.1):