diff --git a/.gitignore b/.gitignore
index 023a0bd12..27c2b6a62 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,4 +35,3 @@ release-artifacts
*.tgz
.claude
-apps/appkit-minter/src/pages/example.tsx
diff --git a/apps/appkit-minter/src/core/configs/app-kit.ts b/apps/appkit-minter/src/core/configs/app-kit.ts
index 2d39192d1..e16449cf1 100644
--- a/apps/appkit-minter/src/core/configs/app-kit.ts
+++ b/apps/appkit-minter/src/core/configs/app-kit.ts
@@ -6,9 +6,8 @@
*
*/
-import { AppKit, Network } from '@ton/appkit';
+import { AppKit, Network, createTonConnectConnector, ApiClientTonApi } from '@ton/appkit';
import { OmnistonSwapProvider } from '@ton/appkit/swap/omniston';
-import { TonConnectConnector, ApiClientTonApi } from '@ton/appkit';
import { ENV_TON_API_KEY_TESTNET, ENV_TON_API_KEY_MAINNET } from '@/core/configs/env';
@@ -34,7 +33,7 @@ export const appKit = new AppKit({
},
},
connectors: [
- new TonConnectConnector({
+ createTonConnectConnector({
tonConnectOptions: {
manifestUrl: 'https://tonconnect-sdk-demo-dapp.vercel.app/tonconnect-manifest.json',
},
diff --git a/apps/appkit-next/.gitignore b/apps/appkit-next/.gitignore
new file mode 100644
index 000000000..5ef6a5207
--- /dev/null
+++ b/apps/appkit-next/.gitignore
@@ -0,0 +1,41 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.*
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/versions
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.pnpm-debug.log*
+
+# env files (can opt-in for committing if needed)
+.env*
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/apps/appkit-next/README.md b/apps/appkit-next/README.md
new file mode 100644
index 000000000..66bb426ff
--- /dev/null
+++ b/apps/appkit-next/README.md
@@ -0,0 +1,36 @@
+This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+
+## Getting Started
+
+First, run the development server:
+
+```bash
+npm run dev
+# or
+yarn dev
+# or
+pnpm dev
+# or
+bun dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
+
+This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
diff --git a/apps/appkit-next/next.config.js b/apps/appkit-next/next.config.js
new file mode 100644
index 000000000..134ac014d
--- /dev/null
+++ b/apps/appkit-next/next.config.js
@@ -0,0 +1,6 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ distDir: 'dist',
+};
+
+export default nextConfig;
diff --git a/apps/appkit-next/package.json b/apps/appkit-next/package.json
new file mode 100644
index 000000000..8e5a8756d
--- /dev/null
+++ b/apps/appkit-next/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "appkit-next",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "clean": "rm -rf .next dist .turbo node_modules"
+ },
+ "dependencies": {
+ "@tanstack/react-query": "catalog:",
+ "@ton/appkit": "workspace:*",
+ "@ton/appkit-react": "workspace:*",
+ "@ton/core": "catalog:",
+ "@ton/crypto": "catalog:",
+ "@ton/walletkit": "workspace:*",
+ "@tonconnect/sdk": "catalog:",
+ "@tonconnect/ui": "catalog:",
+ "next": "16.1.6",
+ "react": "catalog:",
+ "react-dom": "catalog:"
+ },
+ "devDependencies": {
+ "@tailwindcss/postcss": "^4",
+ "@types/node": "^25.2.3",
+ "@types/react": "catalog:",
+ "@types/react-dom": "catalog:",
+ "tailwindcss": "^4",
+ "typescript": "^5.9.3"
+ }
+}
diff --git a/apps/appkit-next/postcss.config.mjs b/apps/appkit-next/postcss.config.mjs
new file mode 100644
index 000000000..f3926c273
--- /dev/null
+++ b/apps/appkit-next/postcss.config.mjs
@@ -0,0 +1,7 @@
+const config = {
+ plugins: {
+ '@tailwindcss/postcss': {},
+ },
+};
+
+export default config;
diff --git a/apps/appkit-next/public/ton.png b/apps/appkit-next/public/ton.png
new file mode 100644
index 000000000..7bdf41f11
Binary files /dev/null and b/apps/appkit-next/public/ton.png differ
diff --git a/apps/appkit-next/src/app/icon.png b/apps/appkit-next/src/app/icon.png
new file mode 100644
index 000000000..f1f0faac2
Binary files /dev/null and b/apps/appkit-next/src/app/icon.png differ
diff --git a/apps/appkit-next/src/app/layout.tsx b/apps/appkit-next/src/app/layout.tsx
new file mode 100644
index 000000000..a6460489a
--- /dev/null
+++ b/apps/appkit-next/src/app/layout.tsx
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import type { Metadata } from 'next';
+import type { ReactNode } from 'react';
+
+import AppKitContext from '@/core/contexts/context';
+
+import '@/core/styles/app.css';
+import '@/core/styles/index.css';
+import '@ton/appkit-react/styles.css';
+
+export const metadata: Metadata = {
+ title: 'NFT Minter - AppKit Demo App',
+ description: 'NFT Minter - AppKit Demo App',
+};
+
+export default function RootLayout({ children }: { children: ReactNode }) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/apps/appkit-next/src/app/page.tsx b/apps/appkit-next/src/app/page.tsx
new file mode 100644
index 000000000..038aa65ab
--- /dev/null
+++ b/apps/appkit-next/src/app/page.tsx
@@ -0,0 +1,13 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { MinterPage } from '@/core/pages/minter-page';
+
+export default function Home() {
+ return ;
+}
diff --git a/apps/appkit-next/src/core/components/common/button.tsx b/apps/appkit-next/src/core/components/common/button.tsx
new file mode 100644
index 000000000..b30647602
--- /dev/null
+++ b/apps/appkit-next/src/core/components/common/button.tsx
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import type React from 'react';
+import { Loader2 } from 'lucide-react';
+
+import { cn } from '@/core/lib/utils';
+
+interface ButtonProps extends React.ButtonHTMLAttributes {
+ variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
+ size?: 'sm' | 'md' | 'lg';
+ isLoading?: boolean;
+ children: React.ReactNode;
+}
+
+export const Button: React.FC = ({
+ variant = 'primary',
+ size = 'md',
+ isLoading = false,
+ children,
+ disabled,
+ className = '',
+ ...props
+}) => {
+ const baseClasses =
+ 'font-medium rounded-lg transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center';
+
+ const variantClasses = {
+ primary: 'bg-primary text-primary-foreground hover:bg-primary/90 focus:ring-ring shadow-md hover:shadow-lg',
+ secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 focus:ring-ring',
+ danger: 'bg-destructive text-destructive-foreground hover:bg-destructive/90 focus:ring-destructive',
+ ghost: 'hover:bg-accent hover:text-accent-foreground focus:ring-ring',
+ };
+
+ const sizeClasses = {
+ sm: 'px-3 py-2 text-sm',
+ md: 'px-4 py-2.5 text-base',
+ lg: 'px-6 py-3 text-lg',
+ };
+
+ return (
+
+ {isLoading ? (
+ <>
+
+ Loading...
+ >
+ ) : (
+ children
+ )}
+
+ );
+};
diff --git a/apps/appkit-next/src/core/components/common/card.tsx b/apps/appkit-next/src/core/components/common/card.tsx
new file mode 100644
index 000000000..43880042e
--- /dev/null
+++ b/apps/appkit-next/src/core/components/common/card.tsx
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import type { FC, ComponentProps } from 'react';
+
+import { cn } from '@/core/lib/utils';
+
+interface CardProps extends ComponentProps<'div'> {
+ title?: string;
+}
+
+export const Card: FC = ({ children, className, title, ...props }) => {
+ return (
+
+ {title && (
+
+
{title}
+
+ )}
+
+
{children}
+
+ );
+};
diff --git a/apps/appkit-next/src/core/components/common/index.ts b/apps/appkit-next/src/core/components/common/index.ts
new file mode 100644
index 000000000..a19bc8d08
--- /dev/null
+++ b/apps/appkit-next/src/core/components/common/index.ts
@@ -0,0 +1,10 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export { Button } from './button';
+export { Card } from './card';
diff --git a/apps/appkit-next/src/core/components/index.ts b/apps/appkit-next/src/core/components/index.ts
new file mode 100644
index 000000000..8e4ac9860
--- /dev/null
+++ b/apps/appkit-next/src/core/components/index.ts
@@ -0,0 +1,13 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+// Common components
+export { Button, Card } from './common';
+
+// Layout components
+export { Layout, ThemeProvider } from './layout';
diff --git a/apps/appkit-next/src/core/components/layout/index.ts b/apps/appkit-next/src/core/components/layout/index.ts
new file mode 100644
index 000000000..9192bf1ff
--- /dev/null
+++ b/apps/appkit-next/src/core/components/layout/index.ts
@@ -0,0 +1,10 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export { Layout } from './layout';
+export { ThemeProvider } from './theme-provider';
diff --git a/apps/appkit-next/src/core/components/layout/layout.tsx b/apps/appkit-next/src/core/components/layout/layout.tsx
new file mode 100644
index 000000000..2ed94bba9
--- /dev/null
+++ b/apps/appkit-next/src/core/components/layout/layout.tsx
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import type React from 'react';
+import { TonConnectButton } from '@ton/appkit-react';
+import { Layers } from 'lucide-react';
+
+import { ThemeSwitcher } from './theme-switcher';
+
+import { NetworkPicker } from '@/features/network';
+
+interface LayoutProps {
+ children: React.ReactNode;
+ title?: string;
+}
+
+export const Layout: React.FC = ({ children, title = 'NFT Minter' }) => {
+ return (
+
+ );
+};
diff --git a/apps/appkit-next/src/core/components/layout/theme-provider.tsx b/apps/appkit-next/src/core/components/layout/theme-provider.tsx
new file mode 100644
index 000000000..854fa5a45
--- /dev/null
+++ b/apps/appkit-next/src/core/components/layout/theme-provider.tsx
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import React, { createContext, useEffect, useMemo, useState } from 'react';
+
+type Theme = 'dark' | 'light';
+type ThemeOption = 'dark' | 'light' | 'system';
+
+type ThemeProviderProps = {
+ children: React.ReactNode;
+ defaultTheme?: ThemeOption;
+ storageKey?: string;
+};
+
+type ThemeProviderState = {
+ theme: ThemeOption;
+ calculatedTheme: Theme;
+ setTheme: (theme: ThemeOption) => void;
+};
+
+const initialState: ThemeProviderState = {
+ theme: 'system',
+ calculatedTheme: 'light',
+ setTheme: () => null,
+};
+
+export const ThemeProviderContext = createContext(initialState);
+
+export function ThemeProvider({
+ children,
+ defaultTheme = 'system',
+ storageKey = 'vite-ui-theme',
+ ...props
+}: ThemeProviderProps) {
+ const [theme, setTheme] = useState(() => {
+ if (typeof window !== 'undefined') {
+ return (window.localStorage.getItem(storageKey) as ThemeOption) || defaultTheme;
+ }
+ return defaultTheme;
+ });
+ const calculatedTheme: Theme = useMemo(() => {
+ if (theme === 'system') {
+ if (typeof window !== 'undefined') {
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
+ }
+ return 'light';
+ }
+ return theme === 'dark' ? 'dark' : 'light';
+ }, [theme]);
+
+ useEffect(() => {
+ const root = window.document.documentElement;
+
+ root.classList.remove('light', 'dark');
+
+ if (theme === 'system') {
+ const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
+
+ root.classList.add(systemTheme);
+ root.setAttribute('data-theme', systemTheme);
+ return;
+ }
+
+ root.classList.add(theme);
+ if (theme === 'light') {
+ root.classList.remove('dark');
+ }
+ root.setAttribute('data-theme', theme);
+ }, [theme]);
+
+ const value = {
+ theme,
+ calculatedTheme,
+ setTheme: (theme: ThemeOption) => {
+ if (typeof window !== 'undefined') {
+ window.localStorage.setItem(storageKey, theme);
+ }
+ setTheme(theme);
+ },
+ };
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/apps/appkit-next/src/core/components/layout/theme-switcher.tsx b/apps/appkit-next/src/core/components/layout/theme-switcher.tsx
new file mode 100644
index 000000000..af95559f0
--- /dev/null
+++ b/apps/appkit-next/src/core/components/layout/theme-switcher.tsx
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { Moon, Sun } from 'lucide-react';
+
+import { useTheme } from '@/core/hooks';
+
+export function ThemeSwitcher() {
+ const { theme, setTheme } = useTheme();
+
+ return (
+ setTheme(theme === 'light' ? 'dark' : 'light')}
+ >
+ {theme === 'light' ? : }
+ Toggle theme
+
+ );
+}
diff --git a/apps/appkit-next/src/core/configs/app-kit.ts b/apps/appkit-next/src/core/configs/app-kit.ts
new file mode 100644
index 000000000..86beda41b
--- /dev/null
+++ b/apps/appkit-next/src/core/configs/app-kit.ts
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { AppKit, Network, createTonConnectConnector, ApiClientTonApi } from '@ton/appkit';
+import { OmnistonSwapProvider } from '@ton/appkit/swap/omniston';
+
+import { ENV_TON_API_KEY_TESTNET, ENV_TON_API_KEY_MAINNET } from '@/core/configs/env';
+
+export const appKit = new AppKit({
+ networks: {
+ [Network.mainnet().chainId]: {
+ apiClient: {
+ url: 'https://toncenter.com',
+ key: ENV_TON_API_KEY_MAINNET,
+ },
+ },
+ [Network.testnet().chainId]: {
+ apiClient: {
+ url: 'https://testnet.toncenter.com',
+ key: ENV_TON_API_KEY_TESTNET,
+ },
+ },
+ [Network.tetra().chainId]: {
+ apiClient: new ApiClientTonApi({
+ network: Network.tetra(),
+ endpoint: 'https://tetra.tonapi.io',
+ }),
+ },
+ },
+ connectors: [
+ createTonConnectConnector({
+ tonConnectOptions: {
+ manifestUrl: 'https://tonconnect-sdk-demo-dapp.vercel.app/tonconnect-manifest.json',
+ },
+ }),
+ ],
+ providers: [new OmnistonSwapProvider()],
+ ssr: true,
+});
diff --git a/apps/appkit-next/src/core/configs/env.ts b/apps/appkit-next/src/core/configs/env.ts
new file mode 100644
index 000000000..7e58e3ad2
--- /dev/null
+++ b/apps/appkit-next/src/core/configs/env.ts
@@ -0,0 +1,12 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export const ENV_TON_API_KEY_MAINNET =
+ process.env.NEXT_PUBLIC_TON_API_KEY ?? '25a9b2326a34b39a5fa4b264fb78fb4709e1bd576fc5e6b176639f5b71e94b0d';
+export const ENV_TON_API_KEY_TESTNET =
+ process.env.NEXT_PUBLIC_TON_API_TESTNET_KEY ?? 'd852b54d062f631565761042cccea87fa6337c41eb19b075e6c7fb88898a3992';
diff --git a/apps/appkit-next/src/core/configs/query.ts b/apps/appkit-next/src/core/configs/query.ts
new file mode 100644
index 000000000..464b48ca0
--- /dev/null
+++ b/apps/appkit-next/src/core/configs/query.ts
@@ -0,0 +1,11 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { QueryClient } from '@tanstack/react-query';
+
+export const queryClient = new QueryClient();
diff --git a/apps/appkit-next/src/core/contexts/context.tsx b/apps/appkit-next/src/core/contexts/context.tsx
new file mode 100644
index 000000000..c2cd30aa5
--- /dev/null
+++ b/apps/appkit-next/src/core/contexts/context.tsx
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { AppKitProvider } from '@ton/appkit-react';
+import { QueryClientProvider } from '@tanstack/react-query';
+import type { ReactNode } from 'react';
+import { Toaster } from 'sonner';
+
+import { appKit } from '../configs/app-kit';
+import { queryClient } from '../configs/query';
+import { ThemeProvider } from '../components';
+
+export default function AppKitContext({ children }: { children: ReactNode }) {
+ return (
+
+
+
+ {children}
+
+
+
+
+ );
+}
diff --git a/apps/appkit-next/src/core/hooks/index.ts b/apps/appkit-next/src/core/hooks/index.ts
new file mode 100644
index 000000000..29a891e12
--- /dev/null
+++ b/apps/appkit-next/src/core/hooks/index.ts
@@ -0,0 +1,9 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export { useTheme } from './use-theme';
diff --git a/apps/appkit-next/src/core/hooks/use-theme.ts b/apps/appkit-next/src/core/hooks/use-theme.ts
new file mode 100644
index 000000000..47763a3ad
--- /dev/null
+++ b/apps/appkit-next/src/core/hooks/use-theme.ts
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { useContext, useEffect } from 'react';
+import { useAppKitTheme } from '@ton/appkit-react';
+
+import { ThemeProviderContext } from '@/core/components/layout/theme-provider';
+
+export const useTheme = () => {
+ const context = useContext(ThemeProviderContext);
+ const [, setTheme] = useAppKitTheme();
+
+ if (context === undefined) throw new Error('useTheme must be used within a ThemeProvider');
+
+ useEffect(() => {
+ setTheme(context.theme);
+ }, [context.theme]);
+
+ return context;
+};
diff --git a/apps/appkit-next/src/core/lib/utils.ts b/apps/appkit-next/src/core/lib/utils.ts
new file mode 100644
index 000000000..32eabbb95
--- /dev/null
+++ b/apps/appkit-next/src/core/lib/utils.ts
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { clsx } from 'clsx';
+import type { ClassValue } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
+
+export function formatAddress(address: string): string {
+ if (address.length <= 10) return address;
+ return `${address.slice(0, 6)}...${address.slice(-4)}`;
+}
+
+export function generateId(): string {
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
+}
diff --git a/apps/appkit-next/src/core/pages/minter-page.tsx b/apps/appkit-next/src/core/pages/minter-page.tsx
new file mode 100644
index 000000000..0ab7fe561
--- /dev/null
+++ b/apps/appkit-next/src/core/pages/minter-page.tsx
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import type React from 'react';
+import { useSelectedWallet } from '@ton/appkit-react';
+
+import { TokensCard } from '@/features/balances';
+import { CardGenerator } from '@/features/mint';
+import { NftsCard } from '@/features/nft';
+import { WalletInfo } from '@/features/wallet';
+import { Layout } from '@/core/components';
+import { SwapButton } from '@/features/swap';
+import { SignMessageCard } from '@/features/signing';
+
+export const MinterPage: React.FC = () => {
+ const [wallet] = useSelectedWallet();
+ const isConnected = !!wallet;
+
+ return (
+
+
+
+
+ {/* Card Generator with integrated mint button */}
+
+
+ {/* Connected wallet assets */}
+ {isConnected && (
+
+
+
+
+
+
Swap Demo
+
+
+
+ )}
+
+
+ );
+};
diff --git a/apps/appkit-next/src/core/styles/app.css b/apps/appkit-next/src/core/styles/app.css
new file mode 100644
index 000000000..d631e3f75
--- /dev/null
+++ b/apps/appkit-next/src/core/styles/app.css
@@ -0,0 +1,189 @@
+@import "tailwindcss";
+
+@import "tw-animate-css";
+
+@custom-variant dark (&:is(.dark *));
+
+#root {
+ width: 100%;
+}
+
+/* Rarity glow effects */
+.rarity-common {
+ --rarity-color: #9ca3af;
+ --rarity-glow: rgba(156, 163, 175, 0.3);
+}
+
+.rarity-rare {
+ --rarity-color: #3b82f6;
+ --rarity-glow: rgba(59, 130, 246, 0.4);
+}
+
+.rarity-epic {
+ --rarity-color: #8b5cf6;
+ --rarity-glow: rgba(139, 92, 246, 0.5);
+}
+
+.rarity-legendary {
+ --rarity-color: #f59e0b;
+ --rarity-glow: rgba(245, 158, 11, 0.6);
+}
+
+/* Card glow animation */
+.card-glow {
+ box-shadow: 0 0 20px var(--rarity-glow), 0 0 40px var(--rarity-glow);
+}
+
+.card-glow-legendary {
+ animation: legendary-glow 2s ease-in-out infinite;
+}
+
+@keyframes legendary-glow {
+ 0%, 100% {
+ box-shadow: 0 0 20px rgba(245, 158, 11, 0.6), 0 0 40px rgba(245, 158, 11, 0.4), 0 0 60px rgba(245, 158, 11, 0.2);
+ }
+ 50% {
+ box-shadow: 0 0 30px rgba(245, 158, 11, 0.8), 0 0 60px rgba(245, 158, 11, 0.6), 0 0 90px rgba(245, 158, 11, 0.4);
+ }
+}
+
+/* Shimmer effect for legendary cards */
+.shimmer-overlay {
+ background: linear-gradient(
+ 90deg,
+ transparent 0%,
+ rgba(255, 255, 255, 0.2) 50%,
+ transparent 100%
+ );
+ background-size: 200% 100%;
+ animation: shimmer 2s linear infinite;
+}
+
+@keyframes shimmer {
+ 0% {
+ background-position: -200% 0;
+ }
+ 100% {
+ background-position: 200% 0;
+ }
+}
+
+@theme inline {
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+ --radius-xl: calc(var(--radius) + 4px);
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --font-sans: 'Inter Variable', sans-serif;
+ --color-sidebar-ring: var(--sidebar-ring);
+ --color-sidebar-border: var(--sidebar-border);
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
+ --color-sidebar-accent: var(--sidebar-accent);
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
+ --color-sidebar-primary: var(--sidebar-primary);
+ --color-sidebar-foreground: var(--sidebar-foreground);
+ --color-sidebar: var(--sidebar);
+ --color-chart-5: var(--chart-5);
+ --color-chart-4: var(--chart-4);
+ --color-chart-3: var(--chart-3);
+ --color-chart-2: var(--chart-2);
+ --color-chart-1: var(--chart-1);
+ --radius-2xl: calc(var(--radius) + 8px);
+ --radius-3xl: calc(var(--radius) + 12px);
+ --radius-4xl: calc(var(--radius) + 16px);
+}
+
+:root {
+ --radius: 0.625rem;
+ --card: oklch(1 0 0);
+ --card-foreground: oklch(0.147 0.004 49.25);
+ --popover: oklch(1 0 0);
+ --popover-foreground: oklch(0.147 0.004 49.25);
+ --primary: oklch(0.6543 0.1605 243.75);
+ --primary-foreground: oklch(0.98 0.02 201);
+ --secondary: oklch(0.967 0.001 286.375);
+ --secondary-foreground: oklch(0.21 0.006 285.885);
+ --muted: oklch(0.97 0.001 106.424);
+ --muted-foreground: oklch(0.553 0.013 58.071);
+ --accent: oklch(0.6543 0.1605 243.75);
+ --accent-foreground: oklch(0.98 0.02 201);
+ --destructive: oklch(0.577 0.245 27.325);
+ --border: oklch(0.923 0.003 48.717);
+ --input: oklch(0.923 0.003 48.717);
+ --ring: oklch(0.709 0.01 56.259);
+ --background: oklch(1 0 0);
+ --foreground: oklch(0.147 0.004 49.25);
+ --chart-1: oklch(0.87 0.12 207);
+ --chart-2: oklch(0.80 0.13 212);
+ --chart-3: oklch(0.71 0.13 215);
+ --chart-4: oklch(0.6543 0.1605 243.75);
+ --chart-5: oklch(0.52 0.09 223);
+ --sidebar: oklch(0.985 0.001 106.423);
+ --sidebar-foreground: oklch(0.147 0.004 49.25);
+ --sidebar-primary: oklch(0.6543 0.1605 243.75);
+ --sidebar-primary-foreground: oklch(0.98 0.02 201);
+ --sidebar-accent: oklch(0.6543 0.1605 243.75);
+ --sidebar-accent-foreground: oklch(0.98 0.02 201);
+ --sidebar-border: oklch(0.923 0.003 48.717);
+ --sidebar-ring: oklch(0.709 0.01 56.259);
+}
+
+.dark {
+ --background: oklch(0.147 0.004 49.25);
+ --foreground: oklch(0.985 0.001 106.423);
+ --card: oklch(0.216 0.006 56.043);
+ --card-foreground: oklch(0.985 0.001 106.423);
+ --popover: oklch(0.216 0.006 56.043);
+ --popover-foreground: oklch(0.985 0.001 106.423);
+ --primary: oklch(0.71 0.13 215);
+ --primary-foreground: oklch(0.30 0.05 230);
+ --secondary: oklch(0.274 0.006 286.033);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.268 0.007 34.298);
+ --muted-foreground: oklch(0.709 0.01 56.259);
+ --accent: oklch(0.71 0.13 215);
+ --accent-foreground: oklch(0.30 0.05 230);
+ --destructive: oklch(0.704 0.191 22.216);
+ --border: oklch(1 0 0 / 10%);
+ --input: oklch(1 0 0 / 15%);
+ --ring: oklch(0.553 0.013 58.071);
+ --chart-1: oklch(0.87 0.12 207);
+ --chart-2: oklch(0.80 0.13 212);
+ --chart-3: oklch(0.71 0.13 215);
+ --chart-4: oklch(0.6543 0.1605 243.75);
+ --chart-5: oklch(0.52 0.09 223);
+ --sidebar: oklch(0.216 0.006 56.043);
+ --sidebar-foreground: oklch(0.985 0.001 106.423);
+ --sidebar-primary: oklch(0.80 0.13 212);
+ --sidebar-primary-foreground: oklch(0.30 0.05 230);
+ --sidebar-accent: oklch(0.71 0.13 215);
+ --sidebar-accent-foreground: oklch(0.30 0.05 230);
+ --sidebar-border: oklch(1 0 0 / 10%);
+ --sidebar-ring: oklch(0.553 0.013 58.071);
+}
+
+@layer base {
+ * {
+ @apply border-border outline-ring/50;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/apps/appkit-next/src/core/styles/index.css b/apps/appkit-next/src/core/styles/index.css
new file mode 100644
index 000000000..509ca420e
--- /dev/null
+++ b/apps/appkit-next/src/core/styles/index.css
@@ -0,0 +1,21 @@
+:root {
+ font-family: 'Inter', system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ width: 100%;
+ min-height: 100vh;
+}
diff --git a/apps/appkit-next/src/features/balances/components/token-transfer-modal.tsx b/apps/appkit-next/src/features/balances/components/token-transfer-modal.tsx
new file mode 100644
index 000000000..a713168b6
--- /dev/null
+++ b/apps/appkit-next/src/features/balances/components/token-transfer-modal.tsx
@@ -0,0 +1,229 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import React, { useMemo, useState } from 'react';
+import type { Jetton } from '@ton/appkit';
+import { getFormattedJettonInfo, getErrorMessage } from '@ton/appkit';
+import { SendTonButton, SendJettonButton } from '@ton/appkit-react';
+import { Gem, X } from 'lucide-react';
+
+import { Button } from '@/core/components';
+import { TransactionStatus } from '@/features/transaction';
+
+interface TokenTransferModalProps {
+ tokenType: 'TON' | 'JETTON';
+ jetton?: Jetton;
+ tonBalance: string;
+ isOpen: boolean;
+ onClose: () => void;
+}
+
+export const TokenTransferModal: React.FC = ({
+ tokenType,
+ jetton,
+ tonBalance,
+ isOpen,
+ onClose,
+}) => {
+ const [recipientAddress, setRecipientAddress] = useState('');
+ const [amount, setAmount] = useState('');
+ const [comment, setComment] = useState('');
+ const [transferError, setTransferError] = useState(null);
+ const [txBoc, setTxBoc] = useState(null);
+
+ const tokenInfo = useMemo(() => {
+ if (tokenType === 'TON') {
+ return {
+ name: 'Toncoin',
+ symbol: 'TON',
+ decimals: 9,
+ balance: tonBalance,
+ image: './ton.png',
+ address: null,
+ };
+ }
+
+ if (!jetton) {
+ throw new Error('Jetton not found');
+ }
+
+ const jettonInfo = getFormattedJettonInfo(jetton);
+
+ return {
+ name: jettonInfo.name,
+ symbol: jettonInfo.symbol,
+ decimals: jettonInfo.decimals,
+ balance: jettonInfo.balance,
+ image: jettonInfo.image,
+ address: jettonInfo.address,
+ };
+ }, [tokenType, tonBalance, jetton]);
+
+ const handleClose = () => {
+ setRecipientAddress('');
+ setAmount('');
+ setComment('');
+ setTransferError(null);
+ setTxBoc(null);
+ onClose();
+ };
+
+ if (!isOpen || !tokenInfo.decimals) return null;
+
+ return (
+
+
+
+
+
+
+ {tokenInfo.image ? (
+
+ ) : tokenType === 'TON' ? (
+
+ ) : (
+
+ {tokenInfo.symbol?.slice(0, 2)}
+
+ )}
+
+
+
Transfer {tokenInfo.name}
+
+ Balance: {tokenInfo.balance} {tokenInfo.symbol}
+
+
+
+
+
+
+
+
+ {txBoc ? (
+
+
+
+ Close
+
+
+ ) : (
+ <>
+
+
+
+ {tokenType === 'TON' && (
+ setTransferError(getErrorMessage(error))}
+ onSuccess={(data) => setTxBoc(data.boc)}
+ >
+ {({ isLoading, onSubmit, disabled, text }) => (
+
+ {text}
+
+ )}
+
+ )}
+
+ {tokenType === 'JETTON' && jetton?.address && (
+ setTransferError(getErrorMessage(error))}
+ onSuccess={(data) => setTxBoc(data.boc)}
+ >
+ {({ isLoading, onSubmit, disabled, text }) => (
+
+ {text}
+
+ )}
+
+ )}
+
+
+ Cancel
+
+
+ >
+ )}
+
+
+
+ );
+};
diff --git a/apps/appkit-next/src/features/balances/components/tokens-card.tsx b/apps/appkit-next/src/features/balances/components/tokens-card.tsx
new file mode 100644
index 000000000..8a62bf899
--- /dev/null
+++ b/apps/appkit-next/src/features/balances/components/tokens-card.tsx
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { useMemo, useState } from 'react';
+import type { FC, ComponentProps } from 'react';
+import type { Jetton } from '@ton/appkit';
+import { getFormattedJettonInfo } from '@ton/appkit';
+import { CurrencyItem, useJettons, useBalance } from '@ton/appkit-react';
+import { AlertCircle } from 'lucide-react';
+
+import { TokenTransferModal } from './token-transfer-modal';
+
+import { Card, Button } from '@/core/components';
+
+interface SelectedToken {
+ type: 'TON' | 'JETTON';
+ jetton?: Jetton;
+}
+
+export const TokensCard: FC> = (props) => {
+ const [selectedToken, setSelectedToken] = useState(null);
+
+ const {
+ data: balance,
+ isLoading: isBalanceLoading,
+ isError: isBalanceError,
+ } = useBalance({ query: { refetchInterval: 10000 } });
+
+ const {
+ data: jettonsResponse,
+ isLoading: isJettonsLoading,
+ isError: isJettonsError,
+ refetch: onRefresh,
+ } = useJettons({ query: { refetchInterval: 10000 } });
+
+ const jettons = useMemo(() => jettonsResponse?.jettons ?? [], [jettonsResponse?.jettons]);
+
+ const isLoading = isBalanceLoading || isJettonsLoading;
+ const isError = isBalanceError || isJettonsError;
+
+ const totalTokens = jettons.length + 1; // +1 for TON
+
+ if (isError) {
+ return (
+
+
+
+
+
Failed to load balances
+
+
onRefresh()}>
+ Try Again
+
+
+
+ );
+ }
+
+ return (
+ <>
+
+ {isLoading ? (
+
+
+
Loading balances...
+
+ ) : (
+
+ {/* Summary */}
+
+
+ {totalTokens} {totalTokens === 1 ? 'Asset' : 'Assets'}
+
+
onRefresh()}>
+ Refresh
+
+
+
+ {/* Token List */}
+
+ setSelectedToken({ type: 'TON' })}
+ icon="./ton.png"
+ isVerified
+ />
+
+ {/* Jettons */}
+ {jettons.map((jetton) => {
+ const info = getFormattedJettonInfo(jetton);
+
+ if (!info || !info.symbol) {
+ return null;
+ }
+
+ return (
+ setSelectedToken({ type: 'JETTON', jetton })}
+ />
+ );
+ })}
+
+
+ )}
+
+
+ {/* Token Transfer Modal */}
+ {selectedToken && (
+ setSelectedToken(null)}
+ />
+ )}
+ >
+ );
+};
diff --git a/apps/appkit-next/src/features/balances/index.ts b/apps/appkit-next/src/features/balances/index.ts
new file mode 100644
index 000000000..49fef305b
--- /dev/null
+++ b/apps/appkit-next/src/features/balances/index.ts
@@ -0,0 +1,11 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+// Components
+export { TokensCard } from './components/tokens-card';
+export { TokenTransferModal } from './components/token-transfer-modal';
diff --git a/apps/appkit-next/src/features/mint/components/card-generator.tsx b/apps/appkit-next/src/features/mint/components/card-generator.tsx
new file mode 100644
index 000000000..7b67d18a4
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/components/card-generator.tsx
@@ -0,0 +1,130 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { useState } from 'react';
+import type React from 'react';
+import { Sparkles, Coins, AlertCircle } from 'lucide-react';
+import { useSelectedWallet, Transaction } from '@ton/appkit-react';
+import { getErrorMessage } from '@ton/appkit';
+import { toast } from 'sonner';
+
+import { CardPreview } from './card-preview';
+import { useCardGenerator } from '../hooks/use-card-generator';
+import { useNftMintTransaction } from '../hooks/use-nft-mint-transaction';
+import { mintCard } from '../store/actions/mint-card';
+import { setMintError } from '../store/actions/set-mint-error';
+
+import { Button, Card } from '@/core/components';
+
+interface CardGeneratorProps {
+ className?: string;
+}
+
+export const CardGenerator: React.FC = ({ className }) => {
+ const { currentCard, isGenerating, generate } = useCardGenerator();
+ const { createMintTransaction, canMint } = useNftMintTransaction();
+ const [wallet] = useSelectedWallet();
+ const [mintErrorLocal, setMintErrorLocal] = useState(null);
+ const isConnected = !!wallet;
+
+ return (
+
+
+ {/* Card preview area */}
+
+ {currentCard ? (
+
+
+
+ ) : (
+
+
+
+
+
Your card will appear here
+
+
+
+
+ )}
+
+
+ {/* Rarity odds info */}
+
+
+ {/* Mint error */}
+ {mintErrorLocal && (
+
+ )}
+
+ {/* Action buttons */}
+
+
+
+ {currentCard ? 'New' : 'Generate'}
+
+
+ {isConnected && canMint && (
+ {
+ mintCard();
+ setMintErrorLocal(null);
+ setMintError(null);
+ toast.success('NFT minted successfully!');
+ }}
+ onError={(error) => {
+ const msg = getErrorMessage(error);
+ setMintErrorLocal(msg);
+ setMintError(msg);
+ }}
+ disabled={!canMint}
+ >
+ {({ isLoading, onSubmit, disabled }) => (
+
+
+ Mint
+
+ )}
+
+ )}
+
+
+
+ );
+};
diff --git a/apps/appkit-next/src/features/mint/components/card-preview.tsx b/apps/appkit-next/src/features/mint/components/card-preview.tsx
new file mode 100644
index 000000000..d6f668f49
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/components/card-preview.tsx
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import type React from 'react';
+import { Image as ImageIcon } from 'lucide-react';
+
+import { RarityBadge } from './rarity-badge';
+import { RarityValues, RARITY_CONFIGS } from '../types/card';
+import type { CardData, Rarity } from '../types/card';
+
+import { cn } from '@/core/lib/utils';
+
+const borderStyles: Record = {
+ [RarityValues.Common]: 'border-gray-300',
+ [RarityValues.Rare]: 'border-blue-400',
+ [RarityValues.Epic]: 'border-purple-500',
+ [RarityValues.Legendary]: 'border-amber-400',
+};
+
+const bgStyles: Record = {
+ [RarityValues.Common]: 'bg-gradient-to-br from-gray-50 to-gray-100',
+ [RarityValues.Rare]: 'bg-gradient-to-br from-blue-50 to-blue-100',
+ [RarityValues.Epic]: 'bg-gradient-to-br from-purple-50 to-purple-100',
+ [RarityValues.Legendary]: 'bg-gradient-to-br from-amber-50 via-yellow-50 to-orange-50',
+};
+
+interface CardPreviewProps {
+ card: CardData;
+ className?: string;
+}
+
+export const CardPreview: React.FC = ({ card, className }) => {
+ const config = RARITY_CONFIGS[card.rarity];
+ const isLegendary = card.rarity === RarityValues.Legendary;
+
+ return (
+
+ {/* Shimmer overlay for legendary cards */}
+ {isLegendary &&
}
+
+ {/* Card content */}
+
+ {/* Card image */}
+
+ {card.imageUrl ? (
+
+ ) : (
+
+
+
+ )}
+
+ {/* Rarity badge overlay */}
+
+
+
+
+
+ {/* Card info */}
+
+
+ {card.name}
+
+
+ {card.description && (
+
+ {card.description}
+
+ )}
+
+
+
+ {/* Decorative corner elements for epic/legendary */}
+ {/* {(card.rarity === RarityValues.Epic || card.rarity === RarityValues.Legendary) && (
+ <>
+
+
+
+
+ >
+ )} */}
+
+ );
+};
diff --git a/apps/appkit-next/src/features/mint/components/rarity-badge.tsx b/apps/appkit-next/src/features/mint/components/rarity-badge.tsx
new file mode 100644
index 000000000..c7471aa9b
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/components/rarity-badge.tsx
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import type React from 'react';
+
+import { RarityValues, RARITY_CONFIGS } from '../types/card';
+import type { Rarity } from '../types/card';
+
+import { cn } from '@/core/lib/utils';
+
+interface RarityBadgeProps {
+ rarity: Rarity;
+ className?: string;
+}
+
+export const RarityBadge: React.FC = ({ rarity, className }) => {
+ const config = RARITY_CONFIGS[rarity];
+
+ const badgeStyles: Record = {
+ [RarityValues.Common]: 'bg-muted text-muted-foreground border-border',
+ [RarityValues.Rare]:
+ 'bg-blue-100 text-blue-700 border-blue-300 dark:bg-blue-900/30 dark:text-blue-300 dark:border-blue-700',
+ [RarityValues.Epic]:
+ 'bg-purple-100 text-purple-700 border-purple-300 dark:bg-purple-900/30 dark:text-purple-300 dark:border-purple-700',
+ [RarityValues.Legendary]:
+ 'bg-amber-100 text-amber-700 border-amber-300 dark:bg-amber-900/30 dark:text-amber-300 dark:border-amber-700',
+ };
+
+ return (
+
+ {rarity === RarityValues.Legendary && ✨ }
+ {rarity}
+
+ );
+};
diff --git a/apps/appkit-next/src/features/mint/contracts/index.ts b/apps/appkit-next/src/features/mint/contracts/index.ts
new file mode 100644
index 000000000..722f2dbc1
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/contracts/index.ts
@@ -0,0 +1,13 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export { makeSnakeCell } from './snake-cell';
+export { encodeOffChainContent, encodeOnChainContent } from './nft-content';
+export type { NftMetadata } from './nft-content';
+export { NftSingleCodeCell, buildSingleNftDataCell, buildSingleNftStateInit } from './nft-single';
+export type { RoyaltyParams, NftSingleData } from './nft-single';
diff --git a/apps/appkit-next/src/features/mint/contracts/nft-content.ts b/apps/appkit-next/src/features/mint/contracts/nft-content.ts
new file mode 100644
index 000000000..243397bd2
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/contracts/nft-content.ts
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { beginCell, Dictionary } from '@ton/core';
+import type { Cell } from '@ton/core';
+import { sha256_sync } from '@ton/crypto';
+
+import { makeSnakeCell } from './snake-cell';
+
+const OFF_CHAIN_CONTENT_PREFIX = 0x01;
+const ON_CHAIN_CONTENT_PREFIX = 0x00;
+const SNAKE_PREFIX = 0x00;
+
+/**
+ * Encode off-chain content for NFT metadata
+ * Format: 0x01 prefix + URL as snake cell
+ */
+export function encodeOffChainContent(content: string): Cell {
+ let data = Buffer.from(content);
+ const offChainPrefix = Buffer.from([OFF_CHAIN_CONTENT_PREFIX]);
+ data = Buffer.concat([offChainPrefix, data]);
+ return makeSnakeCell(data);
+}
+
+/**
+ * NFT metadata for on-chain content
+ */
+export interface NftMetadata {
+ name: string;
+ description?: string;
+ image?: string;
+ imageData?: string; // base64 encoded image data
+}
+
+/**
+ * Encode on-chain content for NFT metadata
+ * Format: 0x00 prefix + Dictionary
+ */
+export function encodeOnChainContent(metadata: NftMetadata): Cell {
+ // Create dictionary with Buffer(32) keys (SHA256 hashes)
+ const dict = Dictionary.empty(Dictionary.Keys.Buffer(32), {
+ serialize: (src: Cell, builder) => {
+ builder.storeRef(src);
+ },
+ parse: (src) => src.loadRef(),
+ });
+
+ // Helper to add a field to dictionary
+ const addField = (key: string, value: string) => {
+ const keyHash = sha256_sync(key);
+ // Value is stored as snake cell with 0x00 prefix
+ const valueData = Buffer.concat([Buffer.from([SNAKE_PREFIX]), Buffer.from(value, 'utf-8')]);
+ const valueCell = makeSnakeCell(valueData);
+ dict.set(keyHash, valueCell);
+ };
+
+ // Add metadata fields
+ addField('name', metadata.name);
+
+ if (metadata.description) {
+ addField('description', metadata.description);
+ }
+
+ if (metadata.image) {
+ addField('image', metadata.image);
+ }
+
+ if (metadata.imageData) {
+ addField('image_data', metadata.imageData);
+ }
+
+ // Build content cell: 0x00 prefix + dictionary
+ return beginCell().storeUint(ON_CHAIN_CONTENT_PREFIX, 8).storeDict(dict).endCell();
+}
diff --git a/apps/appkit-next/src/features/mint/contracts/nft-single.ts b/apps/appkit-next/src/features/mint/contracts/nft-single.ts
new file mode 100644
index 000000000..fa457f9b3
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/contracts/nft-single.ts
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { Cell, beginCell, contractAddress, storeStateInit } from '@ton/core';
+import type { StateInit, Address } from '@ton/core';
+
+// NFT Single contract bytecode (compiled TEP-62 standard contract)
+const NftSingleCodeBoc =
+ 'te6cckECFQEAAwoAART/APSkE/S88sgLAQIBYgcCAgEgBAMAI7x+f4ARgYuGRlgOS/uAFoICHAIBWAYFABG0Dp4AQgRr4HAAHbXa/gBNhjoaYfph/0gGEAICzgsIAgEgCgkAGzIUATPFljPFszMye1UgABU7UTQ+kD6QNTUMIAIBIA0MABE+kQwcLry4U2AEuQyIccAkl8D4NDTAwFxsJJfA+D6QPpAMfoAMXHXIfoAMfoAMPACBtMf0z+CEF/MPRRSMLqOhzIQRxA2QBXgghAvyyaiUjC64wKCEGk9OVBSMLrjAoIQHARBKlIwuoBMSEQ4BXI6HMhBHEDZAFeAxMjQ1NYIQGgudURK6n1ETxwXy4ZoB1NQwECPwA+BfBIQP8vAPAfZRNscF8uGR+kAh8AH6QNIAMfoAggr68IAboSGUUxWgod4i1wsBwwAgkgahkTbiIML/8uGSIY4+ghBRGkRjyFAKzxZQC88WcSRKFFRGsHCAEMjLBVAHzxZQBfoCFctqEssfyz8ibrOUWM8XAZEy4gHJAfsAEFeUECo4W+IQAIICjjUm8AGCENUydtsQN0UAbXFwgBDIywVQB88WUAX6AhXLahLLH8s/Im6zlFjPFwGRMuIByQH7AJMwMzTiVQLwAwBUFl8GMwHQEoIQqMsArXCAEMjLBVAFzxYk+gIUy2oTyx/LPwHPFsmAQPsAAIYWXwZsInDIywHJcIIQi3cXNSHIy/8D0BPPFhOAQHCAEMjLBVAHzxZQBfoCFctqEssfyz8ibrOUWM8XAZEy4gHJAfsAAfZRN8cF8uGR+kAh8AH6QNIAMfoAggr68IAboSGUUxWgod4i1wsBwwAgkgahkTbiIMIA8uGSIY4+ghAFE42RyFALzxZQC88WcSRLFFRGwHCAEMjLBVAHzxZQBfoCFctqEssfyz8ibrOUWM8XAZEy4gHJAfsAEGeUECo5W+IUAIICjjUm8AGCENUydtsQN0YAbXFwgBDIywVQB88WUAX6AhXLahLLH8s/Im6zlFjPFwGRMuIByQH7AJMwNDTiVQLwA+GNLv4=';
+
+export const NftSingleCodeCell = Cell.fromBase64(NftSingleCodeBoc);
+
+export interface RoyaltyParams {
+ royaltyFactor: number; // numerator
+ royaltyBase: number; // denominator (usually 1000)
+ royaltyAddress: Address;
+}
+
+export interface NftSingleData {
+ ownerAddress: Address;
+ editorAddress: Address;
+ contentCell: Cell; // Pre-encoded content cell (on-chain or off-chain)
+ royaltyParams: RoyaltyParams;
+}
+
+/**
+ * Build data cell for NFT Single contract
+ */
+export function buildSingleNftDataCell(data: NftSingleData): Cell {
+ const royaltyCell = beginCell()
+ .storeUint(data.royaltyParams.royaltyFactor, 16)
+ .storeUint(data.royaltyParams.royaltyBase, 16)
+ .storeAddress(data.royaltyParams.royaltyAddress)
+ .endCell();
+
+ return beginCell()
+ .storeAddress(data.ownerAddress)
+ .storeAddress(data.editorAddress)
+ .storeRef(data.contentCell)
+ .storeRef(royaltyCell)
+ .endCell();
+}
+
+/**
+ * Build StateInit for NFT Single contract
+ * Returns stateInit cell and calculated contract address
+ */
+export function buildSingleNftStateInit(data: NftSingleData) {
+ const dataCell = buildSingleNftDataCell(data);
+
+ const stateInit: StateInit = {
+ code: NftSingleCodeCell,
+ data: dataCell,
+ };
+
+ const stateInitCell = beginCell().store(storeStateInit(stateInit)).endCell();
+
+ const address = contractAddress(0, stateInit);
+
+ return {
+ stateInit,
+ stateInitCell,
+ address,
+ };
+}
diff --git a/apps/appkit-next/src/features/mint/contracts/snake-cell.ts b/apps/appkit-next/src/features/mint/contracts/snake-cell.ts
new file mode 100644
index 000000000..f17cbfcbc
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/contracts/snake-cell.ts
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { beginCell } from '@ton/core';
+import type { Cell } from '@ton/core';
+
+/**
+ * Split buffer into chunks of specified size
+ */
+function bufferToChunks(buff: Buffer, chunkSize: number): Buffer[] {
+ const chunks: Buffer[] = [];
+ while (buff.byteLength > 0) {
+ chunks.push(buff.subarray(0, chunkSize));
+ buff = buff.subarray(chunkSize);
+ }
+ return chunks;
+}
+
+/**
+ * Create a snake cell from buffer data
+ * Snake cells store data across multiple cells linked by refs
+ */
+export function makeSnakeCell(data: Buffer): Cell {
+ const chunks = bufferToChunks(data, 127);
+
+ if (chunks.length === 0) {
+ return beginCell().endCell();
+ }
+
+ if (chunks.length === 1) {
+ return beginCell().storeBuffer(chunks[0]).endCell();
+ }
+
+ let curCell = beginCell();
+
+ for (let i = chunks.length - 1; i >= 0; i--) {
+ const chunk = chunks[i];
+
+ curCell.storeBuffer(chunk);
+
+ if (i - 1 >= 0) {
+ const nextCell = beginCell();
+ nextCell.storeRef(curCell.endCell());
+ curCell = nextCell;
+ }
+ }
+
+ return curCell.endCell();
+}
diff --git a/apps/appkit-next/src/features/mint/hooks/use-card-generator.ts b/apps/appkit-next/src/features/mint/hooks/use-card-generator.ts
new file mode 100644
index 000000000..f86877d36
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/hooks/use-card-generator.ts
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { useCallback } from 'react';
+
+import { generateCard } from '../store/actions/generate-card';
+import { clearCard } from '../store/actions/clear-card';
+import { useMinterStore } from '../store/minter-store';
+
+export function useCardGenerator() {
+ const currentCard = useMinterStore((state) => state.currentCard);
+ const isGenerating = useMinterStore((state) => state.isGenerating);
+
+ const generate = useCallback(() => {
+ generateCard();
+ }, []);
+
+ const clear = useCallback(() => {
+ clearCard();
+ }, []);
+
+ return {
+ currentCard,
+ isGenerating,
+ generate,
+ clear,
+ };
+}
diff --git a/apps/appkit-next/src/features/mint/hooks/use-nft-mint-transaction.ts b/apps/appkit-next/src/features/mint/hooks/use-nft-mint-transaction.ts
new file mode 100644
index 000000000..a279d83b8
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/hooks/use-nft-mint-transaction.ts
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { useCallback } from 'react';
+import { toNano, Address, beginCell, storeStateInit } from '@ton/core';
+import { useSelectedWallet } from '@ton/appkit-react';
+import type { Base64String, TransactionRequest } from '@ton/appkit';
+
+import { useMinterStore } from '../store/minter-store';
+import { buildSingleNftStateInit, encodeOnChainContent } from '../contracts';
+
+type UseNftTransactionType =
+ | {
+ canMint: true;
+ createMintTransaction: () => Promise;
+ }
+ | {
+ canMint: false;
+ createMintTransaction: () => Promise;
+ };
+
+/**
+ * Hook to create NFT mint transaction request
+ */
+export function useNftMintTransaction(): UseNftTransactionType {
+ const currentCard = useMinterStore((state) => state.currentCard);
+ const [wallet] = useSelectedWallet();
+
+ const createMintTransaction = useCallback(async (): Promise => {
+ if (!currentCard || !wallet) {
+ throw new Error('Cannot mint NFT: No current card or wallet');
+ }
+
+ const walletAddress = Address.parse(wallet.getAddress());
+
+ // Build on-chain NFT metadata content cell
+ const contentCell = encodeOnChainContent({
+ name: currentCard.name,
+ description: currentCard.description,
+ image: currentCard.imageUrl,
+ });
+
+ // Build NFT StateInit
+ const { stateInit, address: nftAddress } = buildSingleNftStateInit({
+ ownerAddress: walletAddress,
+ editorAddress: walletAddress,
+ contentCell,
+ royaltyParams: {
+ royaltyFactor: 0,
+ royaltyBase: 1000,
+ royaltyAddress: walletAddress,
+ },
+ });
+
+ // Create deployment message
+ const stateInitCell = beginCell().store(storeStateInit(stateInit)).endCell();
+
+ return {
+ validUntil: Math.floor(Date.now() / 1000) + 600, // 10 minutes
+ messages: [
+ {
+ address: nftAddress.toString(),
+ amount: toNano('0.05').toString(), // 0.05 TON for deployment
+ stateInit: stateInitCell.toBoc().toString('base64') as Base64String,
+ },
+ ],
+ };
+ }, [currentCard, wallet]);
+
+ const canMint = !!currentCard && !!wallet;
+
+ if (canMint) {
+ return {
+ createMintTransaction,
+ canMint: true,
+ };
+ } else {
+ return {
+ createMintTransaction: () => Promise.reject(new Error('Cannot mint NFT: No current card or wallet')),
+ canMint: false,
+ };
+ }
+}
diff --git a/apps/appkit-next/src/features/mint/index.ts b/apps/appkit-next/src/features/mint/index.ts
new file mode 100644
index 000000000..734b90a1e
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/index.ts
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+// Components
+export { CardGenerator } from './components/card-generator';
+export { CardPreview } from './components/card-preview';
+export { RarityBadge } from './components/rarity-badge';
+
+// Hooks
+export { useCardGenerator } from './hooks/use-card-generator';
+export { useNftMintTransaction } from './hooks/use-nft-mint-transaction';
+
+// Store
+export { useMinterStore } from './store/minter-store';
+
+// Types
+export type { CardData, Rarity, RarityConfig } from './types/card';
+export { RarityValues, RARITY_CONFIGS } from './types/card';
diff --git a/apps/appkit-next/src/features/mint/lib/card-data.ts b/apps/appkit-next/src/features/mint/lib/card-data.ts
new file mode 100644
index 000000000..b733ec014
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/lib/card-data.ts
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { RarityValues, RARITY_CONFIGS } from '../types/card';
+import type { Rarity } from '../types/card';
+import { textToSvgPath, getTextWidth } from './svg-glyphs';
+
+// Card names organized by rarity
+export const CARD_NAMES: Record = {
+ [RarityValues.Common]: [
+ 'Forest Sprite',
+ 'Stone Golem',
+ 'River Nymph',
+ 'Wind Wisp',
+ 'Earth Guardian',
+ 'Flame Imp',
+ 'Shadow Cat',
+ 'Crystal Beetle',
+ 'Moss Troll',
+ 'Dust Elemental',
+ ],
+ [RarityValues.Rare]: [
+ 'Storm Drake',
+ 'Frost Mage',
+ 'Thunder Wolf',
+ 'Void Walker',
+ 'Ember Phoenix',
+ 'Ocean Serpent',
+ 'Mountain Giant',
+ 'Star Gazer',
+ ],
+ [RarityValues.Epic]: [
+ 'Ancient Dragon',
+ 'Celestial Knight',
+ 'Shadow Reaper',
+ 'Arcane Wizard',
+ 'Divine Guardian',
+ 'Chaos Lord',
+ ],
+ [RarityValues.Legendary]: ['Eternal Phoenix', 'World Serpent', 'Cosmic Titan', 'Primordial Dragon'],
+};
+
+// Card descriptions by rarity
+export const CARD_DESCRIPTIONS: Record = {
+ [RarityValues.Common]: [
+ 'A humble creature of the wild.',
+ 'Born from the elements themselves.',
+ 'A faithful companion on any journey.',
+ ],
+ [RarityValues.Rare]: [
+ 'A powerful being with hidden potential.',
+ 'Sought after by collectors across the realm.',
+ 'Wielding magic beyond ordinary means.',
+ ],
+ [RarityValues.Epic]: [
+ 'A legendary creature of immense power.',
+ 'Few have witnessed such magnificence.',
+ 'Ancient magic flows through its veins.',
+ ],
+ [RarityValues.Legendary]: [
+ 'A mythical being of unparalleled power.',
+ 'Said to exist only in legends.',
+ 'The rarest of all creatures in existence.',
+ ],
+};
+
+/**
+ * Get a random rarity based on configured weights
+ */
+export function getRandomRarity(): Rarity {
+ const totalWeight = Object.values(RARITY_CONFIGS).reduce((sum, config) => sum + config.weight, 0);
+ let random = Math.random() * totalWeight;
+
+ for (const rarity of Object.values(RarityValues)) {
+ const config = RARITY_CONFIGS[rarity];
+ if (random < config.weight) {
+ return rarity;
+ }
+ random -= config.weight;
+ }
+
+ return RarityValues.Common;
+}
+
+/**
+ * Get a random name for a given rarity
+ */
+export function getRandomName(rarity: Rarity): string {
+ const names = CARD_NAMES[rarity];
+ return names[Math.floor(Math.random() * names.length)];
+}
+
+/**
+ * Get a random description for a given rarity
+ */
+export function getRandomDescription(rarity: Rarity): string {
+ const descriptions = CARD_DESCRIPTIONS[rarity];
+ return descriptions[Math.floor(Math.random() * descriptions.length)];
+}
+
+/**
+ * Generate a placeholder image URL based on rarity (inline SVG with path-based text)
+ */
+export async function getCardImageUrl(rarity: Rarity, name: string): Promise {
+ const config = RARITY_CONFIGS[rarity];
+ const fontSize = 18;
+ const textWidth = await getTextWidth(name, fontSize);
+ const textX = (300 - textWidth) / 2;
+ const textY = 200 + fontSize / 3; // Approximate vertical centering
+ const textPath = await textToSvgPath(name, fontSize, textX, textY);
+
+ const svg = `
+
+
+ `;
+ return `data:image/svg+xml,${encodeURIComponent(svg)}`;
+}
diff --git a/apps/appkit-next/src/features/mint/lib/svg-glyphs.ts b/apps/appkit-next/src/features/mint/lib/svg-glyphs.ts
new file mode 100644
index 000000000..56373e116
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/lib/svg-glyphs.ts
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+// @ts-expect-error - opentype.js doesn't have types
+import opentype from 'opentype.js';
+
+const FONT_URL = 'https://cdn.jsdelivr.net/gh/rsms/inter@v3.19/docs/font-files/Inter-Regular.otf';
+
+let fontPromise: Promise | null = null;
+
+/**
+ * Load the Inter font (cached)
+ */
+function loadFont(): Promise {
+ if (!fontPromise) {
+ fontPromise = opentype.load(FONT_URL);
+ }
+ return fontPromise!;
+}
+
+/**
+ * Convert text to SVG path data
+ */
+export async function textToSvgPath(text: string, fontSize: number, x: number, y: number): Promise {
+ const font = await loadFont();
+ const path = font.getPath(text, x, y, fontSize);
+ return path.toPathData(2);
+}
+
+/**
+ * Get the width of text when rendered
+ */
+export async function getTextWidth(text: string, fontSize: number): Promise {
+ const font = await loadFont();
+ return font.getAdvanceWidth(text, fontSize);
+}
diff --git a/apps/appkit-next/src/features/mint/store/actions/clear-card.ts b/apps/appkit-next/src/features/mint/store/actions/clear-card.ts
new file mode 100644
index 000000000..030a1fef3
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/store/actions/clear-card.ts
@@ -0,0 +1,13 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { useMinterStore } from '../minter-store';
+
+export const clearCard = (): void => {
+ useMinterStore.setState({ currentCard: null, mintError: null });
+};
diff --git a/apps/appkit-next/src/features/mint/store/actions/generate-card.ts b/apps/appkit-next/src/features/mint/store/actions/generate-card.ts
new file mode 100644
index 000000000..1be58bafb
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/store/actions/generate-card.ts
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { getRandomRarity, getRandomName, getRandomDescription, getCardImageUrl } from '../../lib/card-data';
+import type { CardData } from '../../types/card';
+import { useMinterStore } from '../minter-store';
+
+import { generateId } from '@/core/lib/utils';
+
+export const generateCard = async (): Promise => {
+ useMinterStore.setState({ isGenerating: true, mintError: null });
+
+ const rarity = getRandomRarity();
+ const name = getRandomName(rarity);
+ const description = getRandomDescription(rarity);
+ const imageUrl = await getCardImageUrl(rarity, name);
+
+ const newCard: CardData = {
+ id: generateId(),
+ name,
+ rarity,
+ description,
+ imageUrl,
+ createdAt: Date.now(),
+ };
+
+ useMinterStore.setState({ currentCard: newCard, isGenerating: false });
+};
diff --git a/apps/appkit-next/src/features/mint/store/actions/mint-card.ts b/apps/appkit-next/src/features/mint/store/actions/mint-card.ts
new file mode 100644
index 000000000..10dfe9b74
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/store/actions/mint-card.ts
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { useMinterStore } from '../minter-store';
+
+export const mintCard = async (): Promise => {
+ const { currentCard } = useMinterStore.getState();
+ if (!currentCard) return;
+
+ useMinterStore.setState({ isMinting: true, mintError: null });
+
+ try {
+ // The actual minting will be handled by the wallet hook
+ // This just updates the local state after successful mint
+ useMinterStore.setState((state) => ({
+ mintedCards: [...state.mintedCards, currentCard],
+ currentCard: null,
+ isMinting: false,
+ }));
+ } catch (error) {
+ useMinterStore.setState({
+ mintError: error instanceof Error ? error.message : 'Failed to mint card',
+ isMinting: false,
+ });
+ }
+};
diff --git a/apps/appkit-next/src/features/mint/store/actions/set-mint-error.ts b/apps/appkit-next/src/features/mint/store/actions/set-mint-error.ts
new file mode 100644
index 000000000..80d0343d3
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/store/actions/set-mint-error.ts
@@ -0,0 +1,13 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { useMinterStore } from '../minter-store';
+
+export const setMintError = (error: string | null): void => {
+ useMinterStore.setState({ mintError: error });
+};
diff --git a/apps/appkit-next/src/features/mint/store/actions/set-minting.ts b/apps/appkit-next/src/features/mint/store/actions/set-minting.ts
new file mode 100644
index 000000000..38098c90b
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/store/actions/set-minting.ts
@@ -0,0 +1,13 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { useMinterStore } from '../minter-store';
+
+export const setMinting = (isMinting: boolean): void => {
+ useMinterStore.setState({ isMinting });
+};
diff --git a/apps/appkit-next/src/features/mint/store/index.ts b/apps/appkit-next/src/features/mint/store/index.ts
new file mode 100644
index 000000000..50559a19e
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/store/index.ts
@@ -0,0 +1,16 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export { useMinterStore } from './minter-store';
+
+// Actions
+export { generateCard } from './actions/generate-card';
+export { mintCard } from './actions/mint-card';
+export { clearCard } from './actions/clear-card';
+export { setMinting } from './actions/set-minting';
+export { setMintError } from './actions/set-mint-error';
diff --git a/apps/appkit-next/src/features/mint/store/minter-store.ts b/apps/appkit-next/src/features/mint/store/minter-store.ts
new file mode 100644
index 000000000..bfb749b01
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/store/minter-store.ts
@@ -0,0 +1,27 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+import { create } from 'zustand';
+
+import type { CardData } from '../types/card';
+
+interface MinterState {
+ currentCard: CardData | null;
+ mintedCards: CardData[];
+ isGenerating: boolean;
+ isMinting: boolean;
+ mintError: string | null;
+}
+
+export const useMinterStore = create(() => ({
+ currentCard: null,
+ mintedCards: [],
+ isGenerating: false,
+ isMinting: false,
+ mintError: null,
+}));
diff --git a/apps/appkit-next/src/features/mint/types/card.ts b/apps/appkit-next/src/features/mint/types/card.ts
new file mode 100644
index 000000000..a5d6bf4b7
--- /dev/null
+++ b/apps/appkit-next/src/features/mint/types/card.ts
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export const RarityValues = {
+ Common: 'common',
+ Rare: 'rare',
+ Epic: 'epic',
+ Legendary: 'legendary',
+} as const;
+
+export type Rarity = (typeof RarityValues)[keyof typeof RarityValues];
+
+export interface CardData {
+ id: string;
+ name: string;
+ rarity: Rarity;
+ imageUrl?: string;
+ description?: string;
+ createdAt: number;
+}
+
+export interface RarityConfig {
+ rarity: Rarity;
+ weight: number;
+ color: string;
+ bgGradient: string;
+ borderColor: string;
+ glowClass: string;
+}
+
+export const RARITY_CONFIGS: Record = {
+ [RarityValues.Common]: {
+ rarity: RarityValues.Common,
+ weight: 60,
+ color: '#9ca3af',
+ bgGradient: 'from-gray-100 to-gray-200',
+ borderColor: 'border-gray-400',
+ glowClass: 'rarity-common',
+ },
+ [RarityValues.Rare]: {
+ rarity: RarityValues.Rare,
+ weight: 25,
+ color: '#3b82f6',
+ bgGradient: 'from-blue-100 to-blue-200',
+ borderColor: 'border-blue-500',
+ glowClass: 'rarity-rare',
+ },
+ [RarityValues.Epic]: {
+ rarity: RarityValues.Epic,
+ weight: 12,
+ color: '#8b5cf6',
+ bgGradient: 'from-purple-100 to-purple-200',
+ borderColor: 'border-purple-500',
+ glowClass: 'rarity-epic',
+ },
+ [RarityValues.Legendary]: {
+ rarity: RarityValues.Legendary,
+ weight: 3,
+ color: '#f59e0b',
+ bgGradient: 'from-amber-100 to-yellow-200',
+ borderColor: 'border-amber-500',
+ glowClass: 'rarity-legendary',
+ },
+};
diff --git a/apps/appkit-next/src/features/network/components/network-picker.tsx b/apps/appkit-next/src/features/network/components/network-picker.tsx
new file mode 100644
index 000000000..325f28b36
--- /dev/null
+++ b/apps/appkit-next/src/features/network/components/network-picker.tsx
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import type { FC, ComponentProps, ChangeEvent } from 'react';
+import { useDefaultNetwork, useNetworks, useSelectedWallet, Network } from '@ton/appkit-react';
+import { ChevronDown } from 'lucide-react';
+
+import { cn } from '@/core/lib/utils';
+
+const NETWORK_LABELS: Record = {
+ [Network.mainnet().chainId]: 'Mainnet',
+ [Network.testnet().chainId]: 'Testnet',
+ [Network.tetra().chainId]: 'Tetra',
+};
+
+const getNetworkLabel = (chainId: string): string => {
+ return NETWORK_LABELS[chainId] ?? `Chain ${chainId}`;
+};
+
+export const NetworkPicker: FC> = ({ className, ...props }) => {
+ const [defaultNetwork, setDefaultNetwork] = useDefaultNetwork();
+ const networks = useNetworks();
+ const [wallet] = useSelectedWallet();
+
+ const handleChange = (e: ChangeEvent) => {
+ const value = e.target.value;
+
+ if (value === '') {
+ setDefaultNetwork(undefined);
+ } else {
+ setDefaultNetwork(Network.custom(value));
+ }
+ };
+
+ if (wallet) {
+ return null;
+ }
+
+ return (
+
+
+ Any Network
+ {networks.map((network) => (
+
+ {getNetworkLabel(network.chainId)}
+
+ ))}
+
+
+
+
+
+ );
+};
diff --git a/apps/appkit-next/src/features/network/index.ts b/apps/appkit-next/src/features/network/index.ts
new file mode 100644
index 000000000..d3727ee53
--- /dev/null
+++ b/apps/appkit-next/src/features/network/index.ts
@@ -0,0 +1,9 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export { NetworkPicker } from './components/network-picker';
diff --git a/apps/appkit-next/src/features/nft/components/nft-transfer-modal.tsx b/apps/appkit-next/src/features/nft/components/nft-transfer-modal.tsx
new file mode 100644
index 000000000..95091acfa
--- /dev/null
+++ b/apps/appkit-next/src/features/nft/components/nft-transfer-modal.tsx
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import React, { useCallback, useMemo, useState } from 'react';
+import type { NFT } from '@ton/appkit';
+import { getFormattedNftInfo, createTransferNftTransaction, getErrorMessage } from '@ton/appkit';
+import { Transaction, useAppKit } from '@ton/appkit-react';
+import { toast } from 'sonner';
+import { X, Image as ImageIcon } from 'lucide-react';
+
+import { Button } from '@/core/components';
+
+interface NftTransferModalProps {
+ nft: NFT;
+ isOpen: boolean;
+ onClose: () => void;
+}
+
+export const NftTransferModal: React.FC = ({ nft, isOpen, onClose }) => {
+ const [recipientAddress, setRecipientAddress] = useState('');
+ const [comment, setComment] = useState('');
+ const [transferError, setTransferError] = useState(null);
+
+ const appKit = useAppKit();
+
+ const nftInfo = useMemo(() => getFormattedNftInfo(nft), [nft]);
+
+ const createTransferTransaction = useCallback(async () => {
+ return createTransferNftTransaction(appKit, {
+ nftAddress: nft.address,
+ recipientAddress,
+ comment,
+ });
+ }, [appKit, nft.address, recipientAddress, comment]);
+
+ const handleClose = () => {
+ setRecipientAddress('');
+ setComment('');
+ setTransferError(null);
+ onClose();
+ };
+
+ if (!isOpen) return null;
+
+ return (
+
+
+
+
+
Transfer NFT
+
+
+
+
+
+ {/* NFT Preview */}
+
+
+ {nftInfo.image ? (
+
+ ) : (
+
+ )}
+
+
{nftInfo.name}
+
{nftInfo.collectionName}
+ {nftInfo.description && (
+
{nftInfo.description}
+ )}
+
+
+
+
+
+ Recipient Address
+
+ setRecipientAddress(e.target.value)}
+ placeholder="Enter TON address"
+ className="w-full px-3 py-2 bg-input border border-border rounded-lg focus:ring-2 focus:ring-ring focus:border-ring text-sm text-foreground placeholder:text-muted-foreground"
+ />
+
+
+
+
+ Comment (optional)
+
+ setComment(e.target.value)}
+ placeholder="Add a comment"
+ className="w-full px-3 py-2 bg-input border border-border rounded-lg focus:ring-2 focus:ring-ring focus:border-ring text-sm text-foreground placeholder:text-muted-foreground"
+ />
+
+
+ {transferError && (
+
+ )}
+
+
+
+ {
+ handleClose();
+ toast.success('NFT transferred successfully');
+ }}
+ onError={(error) => {
+ setTransferError(getErrorMessage(error));
+ }}
+ disabled={!recipientAddress}
+ >
+ {({ isLoading, onSubmit, disabled, text }) => (
+
+ {text}
+
+ )}
+
+
+
+ Cancel
+
+
+
+
+
+ );
+};
diff --git a/apps/appkit-next/src/features/nft/components/nfts-card.tsx b/apps/appkit-next/src/features/nft/components/nfts-card.tsx
new file mode 100644
index 000000000..646662573
--- /dev/null
+++ b/apps/appkit-next/src/features/nft/components/nfts-card.tsx
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { useMemo, useState } from 'react';
+import type { FC, ComponentProps } from 'react';
+import type { NFT } from '@ton/appkit';
+import { NftItem, useNfts } from '@ton/appkit-react';
+import { AlertCircle, Image as ImageIcon } from 'lucide-react';
+
+import { NftTransferModal } from './nft-transfer-modal';
+
+import { Card, Button } from '@/core/components';
+
+export const NftsCard: FC> = (props) => {
+ const [selectedNft, setSelectedNft] = useState(null);
+
+ const {
+ data: nftsResponse,
+ isLoading: isLoading,
+ isError: isError,
+ refetch: onRefresh,
+ } = useNfts({ query: { refetchInterval: 10000 } });
+
+ const nfts = useMemo(() => nftsResponse?.nfts ?? [], [nftsResponse?.nfts]);
+
+ if (isError) {
+ return (
+
+
+
+
+
Failed to load NFTs
+
+
onRefresh()}>
+ Try Again
+
+
+
+ );
+ }
+
+ return (
+ <>
+
+ {isLoading ? (
+
+ ) : nfts.length === 0 ? (
+
+
+
+
+
No NFTs yet
+
Your NFT collection will appear here
+
+ ) : (
+
+ {/* Summary */}
+
+
+ {nfts.length} {nfts.length === 1 ? 'NFT' : 'NFTs'}
+
+
onRefresh()}>
+ Refresh
+
+
+
+ {/* NFT Grid */}
+
+ {nfts.slice(0, 8).map((nft) => (
+ setSelectedNft(nft)}
+ />
+ ))}
+
+
+ {nfts.length > 8 && (
+
+
Showing 8 of {nfts.length} NFTs
+
+ )}
+
+ )}
+
+
+ {/* NFT Transfer Modal */}
+ {selectedNft && (
+ setSelectedNft(null)} />
+ )}
+ >
+ );
+};
diff --git a/apps/appkit-next/src/features/nft/index.ts b/apps/appkit-next/src/features/nft/index.ts
new file mode 100644
index 000000000..005245b13
--- /dev/null
+++ b/apps/appkit-next/src/features/nft/index.ts
@@ -0,0 +1,11 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+// Components
+export { NftsCard } from './components/nfts-card';
+export { NftTransferModal } from './components/nft-transfer-modal';
diff --git a/apps/appkit-next/src/features/signing/components/sign-message-card.tsx b/apps/appkit-next/src/features/signing/components/sign-message-card.tsx
new file mode 100644
index 000000000..567caa610
--- /dev/null
+++ b/apps/appkit-next/src/features/signing/components/sign-message-card.tsx
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { useState } from 'react';
+import type { FC, ComponentProps } from 'react';
+import { useSignText, useSelectedWallet } from '@ton/appkit-react';
+import { toast } from 'sonner';
+
+import { Card, Button } from '@/core/components';
+
+export const SignMessageCard: FC> = (props) => {
+ const [message, setMessage] = useState('');
+ const [signature, setSignature] = useState(null);
+
+ const [wallet] = useSelectedWallet();
+ const { mutate: signText, isPending } = useSignText({
+ mutation: {
+ onSuccess: (result) => {
+ setSignature(result.signature);
+ toast.success('Message signed successfully!');
+ },
+ onError: (error) => {
+ toast.error(`Signing failed: ${error.message}`);
+ },
+ },
+ });
+
+ const handleSign = () => {
+ if (!wallet || !message.trim()) {
+ toast.error('Please enter a message to sign');
+ return;
+ }
+
+ signText({ text: message });
+ };
+
+ const handleCopySignature = () => {
+ if (signature) {
+ navigator.clipboard.writeText(signature);
+ toast.success('Signature copied to clipboard!');
+ }
+ };
+
+ return (
+
+
+ {/* Message Input */}
+
+ Message to sign
+
+
+ {/* Sign Button */}
+
+ {isPending ? 'Signing...' : 'Sign Message'}
+
+
+ {/* Signature Result */}
+ {signature && (
+
+
Signature
+
+ {signature}
+
+
+ Copy Signature
+
+
+ )}
+
+ {/* Info */}
+ {!wallet && (
+
Connect wallet to sign messages
+ )}
+
+
+ );
+};
diff --git a/apps/appkit-next/src/features/signing/index.ts b/apps/appkit-next/src/features/signing/index.ts
new file mode 100644
index 000000000..44a70daa7
--- /dev/null
+++ b/apps/appkit-next/src/features/signing/index.ts
@@ -0,0 +1,9 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export * from './components/sign-message-card';
diff --git a/apps/appkit-next/src/features/swap/components/swap-button.tsx b/apps/appkit-next/src/features/swap/components/swap-button.tsx
new file mode 100644
index 000000000..727ad90f1
--- /dev/null
+++ b/apps/appkit-next/src/features/swap/components/swap-button.tsx
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { useMemo } from 'react';
+import type { FC } from 'react';
+import { Transaction, useSwapQuote, useNetwork, useAddress, useBuildSwapTransaction } from '@ton/appkit-react';
+
+const USDT_ADDRESS = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs';
+const TON = { address: 'ton', decimals: 9, symbol: 'TON' };
+const USDT = { address: USDT_ADDRESS, decimals: 6, symbol: 'USDT' };
+
+export const SwapButton: FC = () => {
+ const network = useNetwork();
+ const address = useAddress();
+
+ const from = TON;
+ const to = USDT;
+ const {
+ data: quote,
+ isError,
+ isLoading,
+ } = useSwapQuote({
+ amount: '1',
+ from,
+ to,
+ network,
+ slippageBps: 100,
+ });
+
+ const { mutateAsync: buildSwapTransaction } = useBuildSwapTransaction();
+
+ const handleBuildSwapTransaction = () => {
+ if (!quote || !address) {
+ return Promise.reject(new Error('Missing quote or address'));
+ }
+
+ return buildSwapTransaction({
+ quote,
+ userAddress: address,
+ });
+ };
+
+ const buttonText = useMemo(() => {
+ if (isLoading) {
+ return 'Fetching quote...';
+ }
+
+ if (isError || !quote) {
+ return 'Swap Unavailable';
+ }
+
+ return `Swap ${quote.fromAmount} ${from.symbol} -> ${quote.toAmount} ${to.symbol}`;
+ }, [isLoading, isError, quote]);
+
+ return (
+
+ );
+};
diff --git a/apps/appkit-next/src/features/swap/index.ts b/apps/appkit-next/src/features/swap/index.ts
new file mode 100644
index 000000000..7857dca09
--- /dev/null
+++ b/apps/appkit-next/src/features/swap/index.ts
@@ -0,0 +1,9 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export * from './components/swap-button';
diff --git a/apps/appkit-next/src/features/transaction/components/transaction-status.tsx b/apps/appkit-next/src/features/transaction/components/transaction-status.tsx
new file mode 100644
index 000000000..4d5ebb254
--- /dev/null
+++ b/apps/appkit-next/src/features/transaction/components/transaction-status.tsx
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { clsx } from 'clsx';
+import { Loader2, CheckCircle2, XCircle, Clock } from 'lucide-react';
+import { TransactionProgress } from '@ton/appkit-react';
+
+export interface TransactionStatusProps {
+ boc: string;
+ className?: string;
+}
+
+export const TransactionStatus = ({ boc, className }: TransactionStatusProps) => {
+ const getStatusColor = (s?: string) => {
+ switch (s) {
+ case 'completed':
+ return 'text-green-500';
+ case 'failed':
+ return 'text-red-500';
+ case 'pending':
+ return 'text-yellow-500';
+ default:
+ return 'text-gray-500';
+ }
+ };
+
+ const getStatusIcon = (s?: string) => {
+ switch (s) {
+ case 'completed':
+ return ;
+ case 'failed':
+ return ;
+ case 'pending':
+ return ;
+ default:
+ return ;
+ }
+ };
+
+ return (
+
+ {({ status, totalMessages, onchainMessages, pendingMessages, error, isFetching }) => {
+ if (error) {
+ return (
+
+ Error checking transaction: {error instanceof Error ? error.message : 'Unknown error'}
+
+ );
+ }
+
+ if (isFetching && status === 'pending' && totalMessages === 0) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+
Status
+
+ {getStatusIcon(status)}
+ {status}
+
+
+
+
+
+
{totalMessages}
+
Total
+
+
+
{onchainMessages}
+
Onchain
+
+
+
{pendingMessages}
+
Pending
+
+
+
+ );
+ }}
+
+ );
+};
diff --git a/apps/appkit-next/src/features/transaction/index.ts b/apps/appkit-next/src/features/transaction/index.ts
new file mode 100644
index 000000000..482cb8002
--- /dev/null
+++ b/apps/appkit-next/src/features/transaction/index.ts
@@ -0,0 +1,9 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export * from './components/transaction-status';
diff --git a/apps/appkit-next/src/features/wallet/components/wallet-info.tsx b/apps/appkit-next/src/features/wallet/components/wallet-info.tsx
new file mode 100644
index 000000000..3ea9129d5
--- /dev/null
+++ b/apps/appkit-next/src/features/wallet/components/wallet-info.tsx
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+'use client';
+
+import { useState, useCallback } from 'react';
+import type { ComponentProps, FC } from 'react';
+import { useSelectedWallet, Network } from '@ton/appkit-react';
+import { Wallet, Check, Copy } from 'lucide-react';
+
+import { Card } from '@/core/components';
+
+const NETWORK_LABELS: Record = {
+ [Network.mainnet().chainId]: 'Mainnet',
+ [Network.testnet().chainId]: 'Testnet',
+ [Network.tetra().chainId]: 'Tetra',
+};
+
+const getNetworkLabel = (chainId: string): string => {
+ return NETWORK_LABELS[chainId] ?? `Chain ${chainId}`;
+};
+
+const truncateAddress = (address: string): string => {
+ if (address.length <= 12) {
+ return address;
+ }
+
+ return `${address.slice(0, 6)}…${address.slice(-6)}`;
+};
+
+export const WalletInfo: FC> = (props) => {
+ const [wallet] = useSelectedWallet();
+ const [copied, setCopied] = useState(false);
+
+ const address = wallet?.getAddress() ?? '';
+ const networkLabel = wallet ? getNetworkLabel(wallet.getNetwork().chainId) : '';
+
+ const handleCopy = useCallback(async () => {
+ if (!address) return;
+ await navigator.clipboard.writeText(address);
+ setCopied(true);
+ setTimeout(() => setCopied(false), 2000);
+ }, [address]);
+
+ return (
+
+
+
+
+
+
+
+ {!wallet &&
Connect wallet to mint
}
+
+ {wallet && (
+
+
+ {truncateAddress(address)}
+
+
+
Network: {networkLabel}
+
+ )}
+
+
+ {wallet && (
+
+ {copied ? (
+ <>
+
+ Copied
+ >
+ ) : (
+ <>
+
+ Copy Address
+ >
+ )}
+
+ )}
+
+
+ );
+};
diff --git a/apps/appkit-next/src/features/wallet/index.ts b/apps/appkit-next/src/features/wallet/index.ts
new file mode 100644
index 000000000..1063decdb
--- /dev/null
+++ b/apps/appkit-next/src/features/wallet/index.ts
@@ -0,0 +1,9 @@
+/**
+ * Copyright (c) TonTech.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ */
+
+export { WalletInfo } from './components/wallet-info';
diff --git a/apps/appkit-next/tsconfig.json b/apps/appkit-next/tsconfig.json
new file mode 100644
index 000000000..125cc590c
--- /dev/null
+++ b/apps/appkit-next/tsconfig.json
@@ -0,0 +1,45 @@
+{
+ "compilerOptions": {
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": [
+ "./src/*"
+ ]
+ },
+ "target": "ES2017"
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts",
+ "build/types/**/*.ts",
+ "build/dev/types/**/*.ts",
+ "dist/types/**/*.ts",
+ "dist/dev/types/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/demo/examples/src/appkit/actions/connectors/add-connector.ts b/demo/examples/src/appkit/actions/connectors/add-connector.ts
index c6e031ce1..5318c3e51 100644
--- a/demo/examples/src/appkit/actions/connectors/add-connector.ts
+++ b/demo/examples/src/appkit/actions/connectors/add-connector.ts
@@ -8,13 +8,13 @@
import type { AppKit } from '@ton/appkit';
import { addConnector } from '@ton/appkit';
-import { TonConnectConnector } from '@ton/appkit';
+import { createTonConnectConnector } from '@ton/appkit';
export const addConnectorExample = (appKit: AppKit) => {
// SAMPLE_START: ADD_CONNECTOR
const stopWatching = addConnector(
appKit,
- new TonConnectConnector({
+ createTonConnectConnector({
tonConnectOptions: {
manifestUrl: 'https://tonconnect-sdk-demo-dapp.vercel.app/tonconnect-manifest.json',
},
diff --git a/demo/examples/src/appkit/actions/connectors/connectors.test.ts b/demo/examples/src/appkit/actions/connectors/connectors.test.ts
index a0c415c53..223439185 100644
--- a/demo/examples/src/appkit/actions/connectors/connectors.test.ts
+++ b/demo/examples/src/appkit/actions/connectors/connectors.test.ts
@@ -50,7 +50,7 @@ describe('Connector Actions Examples (Integration)', () => {
} as unknown as Connector;
// Add connector to AppKit
- appKit.addConnector(mockConnector);
+ appKit.addConnector(() => mockConnector);
});
afterEach(() => {
diff --git a/demo/examples/src/appkit/components/providers/app-kit-provider.tsx b/demo/examples/src/appkit/components/providers/app-kit-provider.tsx
index 0190d7db8..3d8459f74 100644
--- a/demo/examples/src/appkit/components/providers/app-kit-provider.tsx
+++ b/demo/examples/src/appkit/components/providers/app-kit-provider.tsx
@@ -8,7 +8,7 @@
import { AppKit, Network } from '@ton/appkit';
import { AppKitProvider } from '@ton/appkit-react';
-import { TonConnectConnector } from '@ton/appkit';
+import { createTonConnectConnector } from '@ton/appkit';
import type { FC } from 'react';
// Initialize AppKit (outside component)
@@ -19,7 +19,7 @@ const appKit = new AppKit({
},
},
connectors: [
- new TonConnectConnector({
+ createTonConnectConnector({
tonConnectOptions: { manifestUrl: 'https://your-app.com/tonconnect-manifest.json' },
}),
],
diff --git a/demo/examples/src/appkit/connectors/tonconnect/connector.ts b/demo/examples/src/appkit/connectors/tonconnect/connector.ts
index b3d4aedd2..309dcc10d 100644
--- a/demo/examples/src/appkit/connectors/tonconnect/connector.ts
+++ b/demo/examples/src/appkit/connectors/tonconnect/connector.ts
@@ -7,7 +7,7 @@
*/
import { AppKit, Network } from '@ton/appkit';
-import { TonConnectConnector } from '@ton/appkit';
+import { createTonConnectConnector } from '@ton/appkit';
import { TonConnectUI } from '@tonconnect/ui';
export const tonConnectConnectorExample = async () => {
@@ -27,7 +27,7 @@ export const tonConnectConnectorExample = async () => {
},
},
},
- connectors: [new TonConnectConnector({ tonConnectUI })],
+ connectors: [createTonConnectConnector({ tonConnectUI })],
});
// SAMPLE_END: TON_CONNECT_CONNECTOR
@@ -46,7 +46,7 @@ export const tonConnectOptionsExample = async () => {
},
},
connectors: [
- new TonConnectConnector({
+ createTonConnectConnector({
tonConnectOptions: {
manifestUrl: 'https://my-app.com/tonconnect-manifest.json',
},
@@ -72,8 +72,8 @@ export const addConnectorExample = async () => {
},
});
- // 2. Initialize TonConnect connector
- const connector = new TonConnectConnector({
+ // 2. Initialize TonConnect connector function
+ const connector = createTonConnectConnector({
tonConnectOptions: {
manifestUrl: 'https://my-app.com/tonconnect-manifest.json',
},
diff --git a/demo/examples/src/appkit/setup-react.tsx b/demo/examples/src/appkit/setup-react.tsx
index bb33d4b98..40cc2e797 100644
--- a/demo/examples/src/appkit/setup-react.tsx
+++ b/demo/examples/src/appkit/setup-react.tsx
@@ -10,7 +10,7 @@
// SAMPLE_START: APPKIT_REACT_INIT
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
-import { AppKit, Network, TonConnectConnector } from '@ton/appkit';
+import { AppKit, Network, createTonConnectConnector } from '@ton/appkit';
import { AppKitProvider } from '@ton/appkit-react';
import type { FC } from 'react';
@@ -44,7 +44,7 @@ const appKit = new AppKit({
// },
},
connectors: [
- new TonConnectConnector({
+ createTonConnectConnector({
tonConnectOptions: {
manifestUrl: 'https://tonconnect-sdk-demo-dapp.vercel.app/tonconnect-manifest.json',
},
diff --git a/demo/examples/src/appkit/setup.ts b/demo/examples/src/appkit/setup.ts
index 83a09f1d8..652678efa 100644
--- a/demo/examples/src/appkit/setup.ts
+++ b/demo/examples/src/appkit/setup.ts
@@ -6,8 +6,7 @@
*
*/
-import { AppKit, Network } from '@ton/appkit';
-import { TonConnectConnector } from '@ton/appkit';
+import { AppKit, Network, createTonConnectConnector } from '@ton/appkit';
export const setupAppKitExample = () => {
// SAMPLE_START: APPKIT_INIT
@@ -29,7 +28,7 @@ export const setupAppKitExample = () => {
// },
},
connectors: [
- new TonConnectConnector({
+ createTonConnectConnector({
tonConnectOptions: {
manifestUrl: 'https://tonconnect-sdk-demo-dapp.vercel.app/tonconnect-manifest.json',
},
diff --git a/eslint.config.js b/eslint.config.js
index f7c969dda..82d28e4e9 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -27,12 +27,17 @@ module.exports = [
'**/dist/*',
'**/*stryker*/*',
'**/*coverage*/*',
+ '**/.turbo/*',
+ '**/.next/*',
+ '**/.cursor/*',
+ '**/.changeset/*',
'**/dist-extension/*',
'**/dist-extension-chrome/*',
'**/dist-extension-firefox/*',
'**/Packages/TONWalletKit/*',
'**/TONWalletApp/TONWalletApp/*',
'**/androidkit/**',
+ '**/next-env.d.ts',
],
},
{
diff --git a/packages/appkit-react/.gitignore b/packages/appkit-react/.gitignore
index 37fffde8f..ae13eccde 100644
--- a/packages/appkit-react/.gitignore
+++ b/packages/appkit-react/.gitignore
@@ -28,4 +28,5 @@ dist-ssr
styled-system
styled-system-studio
+# Typescript
tsconfig.tsbuildinfo
diff --git a/packages/appkit-react/src/features/wallets/hooks/use-connected-wallets.ts b/packages/appkit-react/src/features/wallets/hooks/use-connected-wallets.ts
index 6f9db71b7..d0edf039e 100644
--- a/packages/appkit-react/src/features/wallets/hooks/use-connected-wallets.ts
+++ b/packages/appkit-react/src/features/wallets/hooks/use-connected-wallets.ts
@@ -28,5 +28,5 @@ export const useConnectedWallets = (): UseConnectedWalletsReturnType => {
return getConnectedWallets(appKit);
}, [appKit]);
- return useSyncExternalStore(subscribe, getSnapshot, () => []);
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
};
diff --git a/packages/appkit-react/src/features/wallets/hooks/use-connector-by-id.ts b/packages/appkit-react/src/features/wallets/hooks/use-connector-by-id.ts
index 52fafef06..143208573 100644
--- a/packages/appkit-react/src/features/wallets/hooks/use-connector-by-id.ts
+++ b/packages/appkit-react/src/features/wallets/hooks/use-connector-by-id.ts
@@ -26,5 +26,5 @@ export const useConnectorById = (id: string): Connector | undefined => {
return getConnectorById(appKit, { id });
}, [appKit, id]);
- return useSyncExternalStore(subscribe, getSnapshot, () => undefined);
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
};
diff --git a/packages/appkit-react/src/features/wallets/hooks/use-connectors.ts b/packages/appkit-react/src/features/wallets/hooks/use-connectors.ts
index 1d6af5eb7..f6553b56c 100644
--- a/packages/appkit-react/src/features/wallets/hooks/use-connectors.ts
+++ b/packages/appkit-react/src/features/wallets/hooks/use-connectors.ts
@@ -28,5 +28,5 @@ export const useConnectors = (): UseConnectorsReturnType => {
return getConnectors(appKit);
}, [appKit]);
- return useSyncExternalStore(subscribe, getSnapshot, () => []);
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
};
diff --git a/packages/appkit-react/src/features/wallets/hooks/use-selected-wallet.ts b/packages/appkit-react/src/features/wallets/hooks/use-selected-wallet.ts
index f87f89d2d..5963eb4bd 100644
--- a/packages/appkit-react/src/features/wallets/hooks/use-selected-wallet.ts
+++ b/packages/appkit-react/src/features/wallets/hooks/use-selected-wallet.ts
@@ -31,7 +31,7 @@ export const useSelectedWallet = (): UseSelectedWalletReturnType => {
return getSelectedWallet(appKit);
}, [appKit]);
- const wallet = useSyncExternalStore(subscribe, getSnapshot, () => null);
+ const wallet = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
const setWalletId = useCallback(
(walletId: string | null) => {
diff --git a/packages/appkit-react/src/tonconnect/tonconnect-bridge.tsx b/packages/appkit-react/src/tonconnect/tonconnect-bridge.tsx
index b38f11b9d..a9f6e6e51 100644
--- a/packages/appkit-react/src/tonconnect/tonconnect-bridge.tsx
+++ b/packages/appkit-react/src/tonconnect/tonconnect-bridge.tsx
@@ -28,11 +28,14 @@ export const TonConnectBridge: FC = ({
children,
connectorId = TONCONNECT_DEFAULT_CONNECTOR_ID,
}) => {
- const connector = useConnectorById(connectorId) as TonConnectConnector | undefined;
- const tonConnectUI = useMemo(() => connector?.tonConnectUI, [connector]);
+ const connector = useConnectorById(connectorId);
+ const tonConnectUI = useMemo(
+ () => (connector && connector.type === 'tonconnect' ? (connector as TonConnectConnector).tonConnectUI : null),
+ [connector],
+ );
if (!tonConnectUI) {
- return <>{children}>;
+ return children;
}
return {children} ;
diff --git a/packages/appkit/src/actions/connectors/add-connector.ts b/packages/appkit/src/actions/connectors/add-connector.ts
index 1558282ad..280a250f1 100644
--- a/packages/appkit/src/actions/connectors/add-connector.ts
+++ b/packages/appkit/src/actions/connectors/add-connector.ts
@@ -7,15 +7,15 @@
*/
import type { AppKit } from '../../core/app-kit';
-import type { Connector } from '../../types/connector';
+import type { CreateConnectorFn } from '../../types/connector';
-export type AddConnectorParameters = Connector;
+export type AddConnectorParameters = CreateConnectorFn;
export type AddConnectorReturnType = () => void;
/**
* Add a wallet connector
*/
-export const addConnector = (appKit: AppKit, connector: AddConnectorParameters): AddConnectorReturnType => {
- return appKit.addConnector(connector);
+export const addConnector = (appKit: AppKit, connectorFn: AddConnectorParameters): AddConnectorReturnType => {
+ return appKit.addConnector(connectorFn);
};
diff --git a/packages/appkit/src/connectors/tonconnect/connectors/ton-connect-connector.ts b/packages/appkit/src/connectors/tonconnect/connectors/ton-connect-connector.ts
index 67b9dac06..ccb49699d 100644
--- a/packages/appkit/src/connectors/tonconnect/connectors/ton-connect-connector.ts
+++ b/packages/appkit/src/connectors/tonconnect/connectors/ton-connect-connector.ts
@@ -9,14 +9,12 @@
import { TonConnectUI } from '@tonconnect/ui';
import type { TonConnectUiCreateOptions } from '@tonconnect/ui';
-import type { Network } from '../../../types/network';
import { TonConnectWalletAdapter } from '../adapters/ton-connect-wallet-adapter';
import { CONNECTOR_EVENTS, NETWORKS_EVENTS } from '../../../core/app-kit';
import type { Connector, ConnectorMetadata } from '../../../types/connector';
import type { WalletInterface } from '../../../types/wallet';
-import type { AppKitEmitter } from '../../../core/app-kit';
import { TONCONNECT_DEFAULT_CONNECTOR_ID } from '../constants/id';
-import type { AppKitNetworkManager } from '../../../core/network';
+import { createConnector } from '../../../types/connector';
export interface TonConnectConnectorConfig {
id?: string;
@@ -25,84 +23,121 @@ export interface TonConnectConnectorConfig {
tonConnectUI?: TonConnectUI;
}
-export class TonConnectConnector implements Connector {
- readonly id: string;
- readonly type = 'tonconnect';
- readonly metadata: ConnectorMetadata;
- readonly tonConnectUI: TonConnectUI;
-
- private emitter: AppKitEmitter | null = null;
- private unsubscribeTonConnect: (() => void) | null = null;
-
- constructor(config: TonConnectConnectorConfig) {
- if (config.tonConnectOptions && config.tonConnectUI) {
- // eslint-disable-next-line no-console
- console.warn(
- 'TonConnectConnector: both tonConnectOptions and tonConnectUI are provided, using tonConnectUI',
- );
- }
+export type TonConnectConnector = Connector & {
+ type: 'tonconnect';
+ tonConnectUI: TonConnectUI | null;
+};
- this.id = config.id ?? TONCONNECT_DEFAULT_CONNECTOR_ID;
- this.tonConnectUI = config?.tonConnectUI ?? new TonConnectUI(config.tonConnectOptions);
- this.metadata = {
- name: 'TonConnect',
- iconUrl: 'https://avatars.githubusercontent.com/u/113980577',
- ...config.metadata,
- };
- }
+export const createTonConnectConnector = (config: TonConnectConnectorConfig) => {
+ return createConnector(({ emitter, networkManager, ssr }): TonConnectConnector => {
+ let originalTonConnectUI: TonConnectUI | null = null;
+ let unsubscribeTonConnect: (() => void) | null = null;
+
+ const id = config.id ?? TONCONNECT_DEFAULT_CONNECTOR_ID;
- async initialize(emitter: AppKitEmitter, networkManager: AppKitNetworkManager): Promise {
- this.emitter = emitter;
+ function getTonConnectUI() {
+ if (originalTonConnectUI) {
+ return originalTonConnectUI;
+ }
- // Subscribe to TonConnect status changes
- this.unsubscribeTonConnect = this.tonConnectUI.onStatusChange((wallet) => {
- const wallets = this.getConnectedWallets();
+ if (ssr && typeof window === 'undefined') {
+ return null;
+ }
- if (wallet) {
- this.emitter?.emit(CONNECTOR_EVENTS.CONNECTED, { wallets, connectorId: this.id }, this.id);
+ // check if we have pre-defined UI
+ if (config.tonConnectUI) {
+ originalTonConnectUI = config.tonConnectUI;
} else {
- this.emitter?.emit(CONNECTOR_EVENTS.DISCONNECTED, { connectorId: this.id }, this.id);
+ originalTonConnectUI = new TonConnectUI(config.tonConnectOptions);
+ }
+
+ setupListeners();
+
+ // restore connection
+ if (originalTonConnectUI) {
+ originalTonConnectUI.connector.restoreConnection();
}
- });
-
- // Set default network and subscribe to changes
- this.tonConnectUI.setConnectionNetwork(networkManager.getDefaultNetwork()?.chainId);
- this.emitter?.on(NETWORKS_EVENTS.DEFAULT_CHANGED, ({ payload }) => {
- this.tonConnectUI.setConnectionNetwork(payload.network?.chainId);
- });
-
- // Restore existing connection
- await this.tonConnectUI.connector.restoreConnection();
- }
-
- destroy(): void {
- this.unsubscribeTonConnect?.();
- this.unsubscribeTonConnect = null;
- this.emitter = null;
- }
-
- async connectWallet(network?: Network): Promise {
- this.tonConnectUI.setConnectionNetwork(network?.chainId);
- await this.tonConnectUI.openModal();
- }
-
- async disconnectWallet(): Promise {
- await this.tonConnectUI.disconnect();
- }
-
- getConnectedWallets(): WalletInterface[] {
- if (this.tonConnectUI.connected && this.tonConnectUI.wallet) {
- const wallet = this.tonConnectUI.wallet;
-
- const walletAdapter = new TonConnectWalletAdapter({
- connectorId: this.id,
- tonConnectWallet: wallet,
- tonConnectUI: this.tonConnectUI,
+
+ return originalTonConnectUI;
+ }
+
+ function getConnectedWallets(): WalletInterface[] {
+ const ui = getTonConnectUI();
+
+ if (ui && ui.connected && ui.wallet) {
+ const wallet = ui.wallet;
+
+ return [
+ new TonConnectWalletAdapter({
+ connectorId: id,
+ tonConnectWallet: wallet,
+ tonConnectUI: ui,
+ }),
+ ];
+ }
+
+ return [];
+ }
+
+ function setupListeners() {
+ if (!originalTonConnectUI || unsubscribeTonConnect) {
+ return;
+ }
+
+ unsubscribeTonConnect = originalTonConnectUI.onStatusChange((wallet) => {
+ const wallets = getConnectedWallets();
+
+ if (wallet) {
+ emitter.emit(CONNECTOR_EVENTS.CONNECTED, { wallets, connectorId: id }, id);
+ } else {
+ emitter.emit(CONNECTOR_EVENTS.DISCONNECTED, { connectorId: id }, id);
+ }
});
- return [walletAdapter];
+ // Set default network and subscribe to changes
+ originalTonConnectUI.setConnectionNetwork(networkManager.getDefaultNetwork()?.chainId);
+ emitter.on(NETWORKS_EVENTS.DEFAULT_CHANGED, ({ payload }) => {
+ if (originalTonConnectUI) {
+ originalTonConnectUI.setConnectionNetwork(payload.network?.chainId);
+ }
+ });
}
- return [];
- }
-}
+ return {
+ id,
+ type: 'tonconnect',
+ metadata: {
+ name: 'TonConnect',
+ iconUrl: 'https://avatars.githubusercontent.com/u/113980577',
+ ...config.metadata,
+ },
+
+ get tonConnectUI() {
+ return getTonConnectUI();
+ },
+
+ getConnectedWallets,
+
+ async connectWallet(): Promise {
+ const ui = getTonConnectUI();
+
+ if (ui) {
+ await ui.openModal();
+ }
+ },
+
+ async disconnectWallet(): Promise {
+ const ui = getTonConnectUI();
+
+ if (ui) {
+ await ui.disconnect();
+ }
+ },
+
+ destroy() {
+ unsubscribeTonConnect?.();
+ originalTonConnectUI = null;
+ },
+ };
+ });
+};
diff --git a/packages/appkit/src/connectors/tonconnect/index.ts b/packages/appkit/src/connectors/tonconnect/index.ts
index 37e0d0991..993c740b8 100644
--- a/packages/appkit/src/connectors/tonconnect/index.ts
+++ b/packages/appkit/src/connectors/tonconnect/index.ts
@@ -26,6 +26,9 @@ export { TonConnectWalletAdapter } from './adapters/ton-connect-wallet-adapter';
export type { TonConnectWalletAdapterConfig } from './adapters/ton-connect-wallet-adapter';
// Connector exports
-export { TonConnectConnector } from './connectors/ton-connect-connector';
+export {
+ createTonConnectConnector,
+ type TonConnectConnectorConfig,
+ type TonConnectConnector,
+} from './connectors/ton-connect-connector';
export { TONCONNECT_DEFAULT_CONNECTOR_ID } from './constants/id';
-export type { TonConnectConnectorConfig } from './connectors/ton-connect-connector';
diff --git a/packages/appkit/src/core/app-kit/services/app-kit.ts b/packages/appkit/src/core/app-kit/services/app-kit.ts
index 094d7bf32..f0f69f540 100644
--- a/packages/appkit/src/core/app-kit/services/app-kit.ts
+++ b/packages/appkit/src/core/app-kit/services/app-kit.ts
@@ -10,7 +10,7 @@ import { SwapManager } from '@ton/walletkit';
import type { Provider } from 'src/types/provider';
import type { AppKitConfig } from '../types/config';
-import type { Connector } from '../../../types/connector';
+import type { Connector, CreateConnectorFn } from '../../../types/connector';
import { Emitter } from '../../emitter';
import { CONNECTOR_EVENTS, WALLETS_EVENTS } from '../constants/events';
import type { AppKitEmitter, AppKitEvents } from '../types/events';
@@ -64,7 +64,12 @@ export class AppKit {
/**
* Add a wallet connector
*/
- addConnector(connector: Connector): () => void {
+ addConnector(createConnectorFn: CreateConnectorFn): () => void {
+ const connector = createConnectorFn({
+ emitter: this.emitter,
+ networkManager: this.networkManager,
+ ssr: this.config.ssr,
+ });
const id = connector.id;
const oldConnector = this.connectors.find((c) => c.id === id);
@@ -73,7 +78,6 @@ export class AppKit {
}
this.connectors.push(connector);
- connector.initialize(this.emitter, this.networkManager);
return () => {
this.removeConnector(connector);
diff --git a/packages/appkit/src/core/app-kit/types/config.ts b/packages/appkit/src/core/app-kit/types/config.ts
index 5021e52b4..f052969b1 100644
--- a/packages/appkit/src/core/app-kit/types/config.ts
+++ b/packages/appkit/src/core/app-kit/types/config.ts
@@ -8,7 +8,7 @@
import type { NetworkAdapters } from '@ton/walletkit';
-import type { Connector } from '../../../types/connector';
+import type { CreateConnectorFn } from '../../../types/connector';
import type { Provider } from '../../../types/provider';
import type { Network } from '../../../types/network';
@@ -25,6 +25,11 @@ export interface AppKitConfig {
*/
networks?: NetworkAdapters;
+ /**
+ * Wallet connectors
+ */
+ connectors?: CreateConnectorFn[];
+
/**
* Default network for wallet connections.
* If set, connectors (e.g. TonConnect) will enforce this network when connecting.
@@ -32,6 +37,10 @@ export interface AppKitConfig {
*/
defaultNetwork?: Network;
- connectors?: Connector[];
providers?: Provider[];
+
+ /**
+ * Enable server-side rendering support
+ */
+ ssr?: boolean;
}
diff --git a/packages/appkit/src/types/connector.ts b/packages/appkit/src/types/connector.ts
index 1a2d92939..09dccf72a 100644
--- a/packages/appkit/src/types/connector.ts
+++ b/packages/appkit/src/types/connector.ts
@@ -18,14 +18,11 @@ export interface Connector {
/** Provider unique identifier */
readonly id: string;
- /** Protocol type (e.g. 'tonconnect', 'ledger', 'mnemonic') */
+ /** Protocol type (e.g. 'tonconnect') */
readonly type: string;
readonly metadata: ConnectorMetadata;
- /** Initialize connector (restore connections, setup event listeners) */
- initialize(emitter: AppKitEmitter, networkManager: AppKitNetworkManager): Promise;
-
/** Cleanup connector resources */
destroy(): void;
@@ -43,3 +40,13 @@ export interface ConnectorMetadata {
name: string;
iconUrl?: string;
}
+
+export type CreateConnectorFn = (config: {
+ emitter: AppKitEmitter;
+ networkManager: AppKitNetworkManager;
+ ssr?: boolean;
+}) => Connector;
+
+export function createConnector(createConnectorFn: CreateConnectorFn): CreateConnectorFn {
+ return createConnectorFn;
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c03e44df7..60ad59979 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -59,10 +59,10 @@ importers:
devDependencies:
'@changesets/cli':
specifier: ^2.29.8
- version: 2.29.8(@types/node@24.10.13)
+ version: 2.29.8(@types/node@25.2.3)
'@ton/toolchain':
specifier: github:the-ton-tech/toolchain#v1.5.0
- version: https://codeload.github.com/the-ton-tech/toolchain/tar.gz/31376da778155bd0984d68abf2a46dce417bacb8(jest@30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1))(jiti@2.6.1)(typescript@5.9.3)
+ version: https://codeload.github.com/the-ton-tech/toolchain/tar.gz/31376da778155bd0984d68abf2a46dce417bacb8(jest@30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1))(jiti@2.6.1)(typescript@5.9.3)
eslint:
specifier: ^9.39.2
version: 9.39.2(jiti@2.6.1)
@@ -89,7 +89,7 @@ importers:
version: 0.7.8
'@tailwindcss/vite':
specifier: ^4.1.18
- version: 4.1.18(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ version: 4.1.18(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@ton/appkit':
specifier: workspace:*
version: link:../../packages/appkit
@@ -159,7 +159,7 @@ importers:
version: 19.2.3(@types/react@19.2.8)
'@vitejs/plugin-react':
specifier: ^5.1.2
- version: 5.1.4(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ version: 5.1.4(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
eslint:
specifier: ^9.39.2
version: 9.39.2(jiti@2.6.1)
@@ -180,11 +180,66 @@ importers:
version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
vite:
specifier: ^7.3.1
- version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ version: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
vite-bundle-analyzer:
specifier: ^1.3.2
version: 1.3.2
+ apps/appkit-next:
+ dependencies:
+ '@tanstack/react-query':
+ specifier: 'catalog:'
+ version: 5.90.20(react@19.2.3)
+ '@ton/appkit':
+ specifier: workspace:*
+ version: link:../../packages/appkit
+ '@ton/appkit-react':
+ specifier: workspace:*
+ version: link:../../packages/appkit-react
+ '@ton/core':
+ specifier: 'catalog:'
+ version: 0.63.0(@ton/crypto@3.3.0)
+ '@ton/crypto':
+ specifier: 'catalog:'
+ version: 3.3.0
+ '@ton/walletkit':
+ specifier: workspace:*
+ version: link:../../packages/walletkit
+ '@tonconnect/sdk':
+ specifier: 'catalog:'
+ version: 3.4.1
+ '@tonconnect/ui':
+ specifier: 'catalog:'
+ version: 2.4.1
+ next:
+ specifier: 16.1.6
+ version: 16.1.6(@babel/core@7.29.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react:
+ specifier: 'catalog:'
+ version: 19.2.3
+ react-dom:
+ specifier: 'catalog:'
+ version: 19.2.3(react@19.2.3)
+ devDependencies:
+ '@tailwindcss/postcss':
+ specifier: ^4
+ version: 4.1.18
+ '@types/node':
+ specifier: ^25.2.3
+ version: 25.2.3
+ '@types/react':
+ specifier: 'catalog:'
+ version: 19.2.8
+ '@types/react-dom':
+ specifier: 'catalog:'
+ version: 19.2.3(@types/react@19.2.8)
+ tailwindcss:
+ specifier: ^4
+ version: 4.1.18
+ typescript:
+ specifier: ^5.9.3
+ version: 5.9.3
+
apps/demo-wallet:
dependencies:
'@demo/v4ledger-adapter':
@@ -201,7 +256,7 @@ importers:
version: 6.30.0
'@tailwindcss/vite':
specifier: ^4.1.18
- version: 4.1.18(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ version: 4.1.18(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@ton/core':
specifier: 'catalog:'
version: 0.63.0(@ton/crypto@3.3.0)
@@ -213,7 +268,7 @@ importers:
version: link:../../packages/walletkit
'@truecarry/vite-plugin-web-extension':
specifier: ^4.5.1
- version: 4.5.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)
+ version: 4.5.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)
'@truecarry/webext-bridge':
specifier: ^6.0.2
version: 6.0.2
@@ -286,7 +341,7 @@ importers:
version: 0.12.4
'@vitejs/plugin-react':
specifier: ^5.1.2
- version: 5.1.4(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ version: 5.1.4(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
allure-js-commons:
specifier: ^3.4.5
version: 3.4.5(allure-playwright@3.4.5(@playwright/test@1.58.2))
@@ -319,7 +374,7 @@ importers:
version: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
vite:
specifier: ^7.3.1
- version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ version: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
vite-bundle-analyzer:
specifier: ^1.3.2
version: 1.3.2
@@ -586,7 +641,7 @@ importers:
version: 20.6.1
vitest:
specifier: ^4.0.17
- version: 4.0.18(@types/node@24.10.13)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ version: 4.0.18(@types/node@25.2.3)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
demo/v4ledger-adapter:
dependencies:
@@ -676,7 +731,7 @@ importers:
version: 5.8.3
vitest:
specifier: ^4.0.17
- version: 4.0.18(@types/node@24.10.13)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ version: 4.0.18(@types/node@25.2.3)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
packages/appkit-react:
dependencies:
@@ -698,13 +753,13 @@ importers:
devDependencies:
'@storybook/addon-docs':
specifier: 10.2.8
- version: 10.2.8(@types/react@19.2.8)(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ version: 10.2.8(@types/react@19.2.8)(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@storybook/react':
specifier: 10.2.8
version: 10.2.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)
'@storybook/react-vite':
specifier: 10.2.8
- version: 10.2.8(esbuild@0.27.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ version: 10.2.8(esbuild@0.27.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@storybook/test':
specifier: ^8.6.15
version: 8.6.15(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))
@@ -737,10 +792,10 @@ importers:
version: 5.9.3
vite:
specifier: ^7.3.1
- version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ version: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
vite-plugin-node-polyfills:
specifier: ^0.25.0
- version: 0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ version: 0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
packages/mcp:
dependencies:
@@ -802,7 +857,7 @@ importers:
version: 30.2.0
'@stryker-mutator/core':
specifier: ^9.4.0
- version: 9.5.1(@types/node@24.10.13)
+ version: 9.5.1(@types/node@25.2.3)
'@ton/core':
specifier: 'catalog:'
version: 0.63.0(@ton/crypto@3.3.0)
@@ -835,7 +890,7 @@ importers:
version: 9.39.2(jiti@2.6.1)
jest:
specifier: ^30.2.0
- version: 30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3))
+ version: 30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))
node-hid:
specifier: ^3.2.0
version: 3.2.0
@@ -847,13 +902,13 @@ importers:
version: 13.2.16(magicast@0.5.1)
ts-jest:
specifier: ^29.4.6
- version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(esbuild@0.27.3)(jest-util@30.2.0)(jest@30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3)))(typescript@5.9.3)
+ version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(esbuild@0.27.3)(jest-util@30.2.0)(jest@30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)))(typescript@5.9.3)
ts-json-schema-generator:
specifier: ^2.4.0
version: 2.4.0
ts-node:
specifier: ^10.9.2
- version: 10.9.2(@types/node@24.10.13)(typescript@5.9.3)
+ version: 10.9.2(@types/node@25.2.3)(typescript@5.9.3)
tsx:
specifier: ^4.21.0
version: 4.21.0
@@ -862,13 +917,13 @@ importers:
version: 5.9.3
vite:
specifier: ^7.3.1
- version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ version: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
vite-bundle-analyzer:
specifier: ^1.3.2
version: 1.3.2
vitest:
specifier: ^4.0.17
- version: 4.0.18(@types/node@24.10.13)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ version: 4.0.18(@types/node@25.2.3)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
optionalDependencies:
'@ston-fi/omniston-sdk':
specifier: ^0.7.8
@@ -897,7 +952,7 @@ importers:
version: 5.9.3
vite:
specifier: ^7.3.1
- version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ version: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
packages/walletkit-ios-bridge:
dependencies:
@@ -928,7 +983,7 @@ importers:
version: 5.9.3
vite:
specifier: ^7.3.1
- version: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ version: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
packages:
@@ -946,6 +1001,10 @@ packages:
'@adobe/css-tools@4.4.4':
resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==}
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
'@anthropic-ai/sdk@0.52.0':
resolution: {integrity: sha512-d4c+fg+xy9e46c8+YnrrgIQR45CZlAi7PwdzIfDXDM6ACxEZli1/fxhURsq30ZpMZy6LvSkr41jGq5aF5TD7rQ==}
hasBin: true
@@ -2023,6 +2082,143 @@ packages:
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
engines: {node: '>=18.18'}
+ '@img/colour@1.0.0':
+ resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.34.5':
+ resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linux-arm64@0.34.5':
+ resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linux-arm@0.34.5':
+ resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@img/sharp-linux-s390x@0.34.5':
+ resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-linux-x64@0.34.5':
+ resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-wasm32@0.34.5':
+ resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.34.5':
+ resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.34.5':
+ resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.34.5':
+ resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
'@inquirer/ansi@2.0.3':
resolution: {integrity: sha512-g44zhR3NIKVs0zUesa4iMzExmZpLUdTLRMCStqX3GE5NT6VkPcxQGJ+uC8tDgBUC/vB1rUhUd55cOf++4NZcmw==}
engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'}
@@ -2398,6 +2594,57 @@ packages:
'@napi-rs/wasm-runtime@1.1.1':
resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==}
+ '@next/env@16.1.6':
+ resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==}
+
+ '@next/swc-darwin-arm64@16.1.6':
+ resolution: {integrity: sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@next/swc-darwin-x64@16.1.6':
+ resolution: {integrity: sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@next/swc-linux-arm64-gnu@16.1.6':
+ resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@next/swc-linux-arm64-musl@16.1.6':
+ resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@next/swc-linux-x64-gnu@16.1.6':
+ resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@next/swc-linux-x64-musl@16.1.6':
+ resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@next/swc-win32-arm64-msvc@16.1.6':
+ resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@next/swc-win32-x64-msvc@16.1.6':
+ resolution: {integrity: sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
'@noble/curves@1.9.7':
resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==}
engines: {node: ^14.21.3 || >=16}
@@ -3616,6 +3863,9 @@ packages:
'@stryker-mutator/util@9.5.1':
resolution: {integrity: sha512-KXmbEeXF3Z20P+9W8i/f1j+U5nWSm9oeb1VNV6j5/RfzhnMKWZCrvojJqRfnxdkCiMIFWMAHSlM9K0mfFZLNXQ==}
+ '@swc/helpers@0.5.15':
+ resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
+
'@tailwindcss/node@4.1.18':
resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==}
@@ -3701,6 +3951,9 @@ packages:
resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==}
engines: {node: '>= 10'}
+ '@tailwindcss/postcss@4.1.18':
+ resolution: {integrity: sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==}
+
'@tailwindcss/vite@4.1.18':
resolution: {integrity: sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==}
peerDependencies:
@@ -3914,8 +4167,8 @@ packages:
'@types/node@22.19.11':
resolution: {integrity: sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==}
- '@types/node@24.10.13':
- resolution: {integrity: sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==}
+ '@types/node@25.2.3':
+ resolution: {integrity: sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==}
'@types/react-dom@19.2.3':
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
@@ -7452,6 +7705,27 @@ packages:
react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
+ next@16.1.6:
+ resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==}
+ engines: {node: '>=20.9.0'}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.51.1
+ babel-plugin-react-compiler: '*'
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+
node-abi@3.77.0:
resolution: {integrity: sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ==}
engines: {node: '>=10'}
@@ -7871,6 +8145,10 @@ packages:
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
engines: {node: '>= 0.4'}
+ postcss@8.4.31:
+ resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
postcss@8.4.49:
resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==}
engines: {node: ^10 || ^12 || >=14}
@@ -8606,6 +8884,10 @@ packages:
shallowequal@1.1.0:
resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==}
+ sharp@0.34.5:
+ resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -8895,6 +9177,19 @@ packages:
stubborn-utils@1.0.2:
resolution: {integrity: sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg==}
+ styled-jsx@5.1.6:
+ resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+
sucrase@3.35.1:
resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -9954,6 +10249,8 @@ snapshots:
'@adobe/css-tools@4.4.4': {}
+ '@alloc/quick-lru@5.2.0': {}
+
'@anthropic-ai/sdk@0.52.0': {}
'@asamuzakjp/css-color@4.1.2':
@@ -10761,7 +11058,7 @@ snapshots:
dependencies:
'@changesets/types': 6.1.0
- '@changesets/cli@2.29.8(@types/node@24.10.13)':
+ '@changesets/cli@2.29.8(@types/node@25.2.3)':
dependencies:
'@changesets/apply-release-plan': 7.0.14
'@changesets/assemble-release-plan': 6.0.9
@@ -10777,7 +11074,7 @@ snapshots:
'@changesets/should-skip-package': 0.1.2
'@changesets/types': 6.1.0
'@changesets/write': 0.4.0
- '@inquirer/external-editor': 1.0.3(@types/node@24.10.13)
+ '@inquirer/external-editor': 1.0.3(@types/node@25.2.3)
'@manypkg/get-packages': 1.1.3
ansi-colors: 4.1.3
ci-info: 3.9.0
@@ -11437,131 +11734,228 @@ snapshots:
'@humanwhocodes/retry@0.4.3': {}
+ '@img/colour@1.0.0':
+ optional: true
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-wasm32@0.34.5':
+ dependencies:
+ '@emnapi/runtime': 1.8.1
+ optional: true
+
+ '@img/sharp-win32-arm64@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.34.5':
+ optional: true
+
'@inquirer/ansi@2.0.3': {}
- '@inquirer/checkbox@5.0.4(@types/node@24.10.13)':
+ '@inquirer/checkbox@5.0.4(@types/node@25.2.3)':
dependencies:
'@inquirer/ansi': 2.0.3
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
'@inquirer/figures': 2.0.3
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/confirm@6.0.4(@types/node@24.10.13)':
+ '@inquirer/confirm@6.0.4(@types/node@25.2.3)':
dependencies:
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/core@11.1.1(@types/node@24.10.13)':
+ '@inquirer/core@11.1.1(@types/node@25.2.3)':
dependencies:
'@inquirer/ansi': 2.0.3
'@inquirer/figures': 2.0.3
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
cli-width: 4.1.0
mute-stream: 3.0.0
signal-exit: 4.1.0
wrap-ansi: 9.0.2
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/editor@5.0.4(@types/node@24.10.13)':
+ '@inquirer/editor@5.0.4(@types/node@25.2.3)':
dependencies:
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
- '@inquirer/external-editor': 2.0.3(@types/node@24.10.13)
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
+ '@inquirer/external-editor': 2.0.3(@types/node@25.2.3)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/expand@5.0.4(@types/node@24.10.13)':
+ '@inquirer/expand@5.0.4(@types/node@25.2.3)':
dependencies:
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/external-editor@1.0.3(@types/node@24.10.13)':
+ '@inquirer/external-editor@1.0.3(@types/node@25.2.3)':
dependencies:
chardet: 2.1.1
iconv-lite: 0.7.2
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/external-editor@2.0.3(@types/node@24.10.13)':
+ '@inquirer/external-editor@2.0.3(@types/node@25.2.3)':
dependencies:
chardet: 2.1.1
iconv-lite: 0.7.2
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
'@inquirer/figures@2.0.3': {}
- '@inquirer/input@5.0.4(@types/node@24.10.13)':
+ '@inquirer/input@5.0.4(@types/node@25.2.3)':
dependencies:
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/number@4.0.4(@types/node@24.10.13)':
+ '@inquirer/number@4.0.4(@types/node@25.2.3)':
dependencies:
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/password@5.0.4(@types/node@24.10.13)':
+ '@inquirer/password@5.0.4(@types/node@25.2.3)':
dependencies:
'@inquirer/ansi': 2.0.3
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
-
- '@inquirer/prompts@8.2.0(@types/node@24.10.13)':
- dependencies:
- '@inquirer/checkbox': 5.0.4(@types/node@24.10.13)
- '@inquirer/confirm': 6.0.4(@types/node@24.10.13)
- '@inquirer/editor': 5.0.4(@types/node@24.10.13)
- '@inquirer/expand': 5.0.4(@types/node@24.10.13)
- '@inquirer/input': 5.0.4(@types/node@24.10.13)
- '@inquirer/number': 4.0.4(@types/node@24.10.13)
- '@inquirer/password': 5.0.4(@types/node@24.10.13)
- '@inquirer/rawlist': 5.2.0(@types/node@24.10.13)
- '@inquirer/search': 4.1.0(@types/node@24.10.13)
- '@inquirer/select': 5.0.4(@types/node@24.10.13)
+ '@types/node': 25.2.3
+
+ '@inquirer/prompts@8.2.0(@types/node@25.2.3)':
+ dependencies:
+ '@inquirer/checkbox': 5.0.4(@types/node@25.2.3)
+ '@inquirer/confirm': 6.0.4(@types/node@25.2.3)
+ '@inquirer/editor': 5.0.4(@types/node@25.2.3)
+ '@inquirer/expand': 5.0.4(@types/node@25.2.3)
+ '@inquirer/input': 5.0.4(@types/node@25.2.3)
+ '@inquirer/number': 4.0.4(@types/node@25.2.3)
+ '@inquirer/password': 5.0.4(@types/node@25.2.3)
+ '@inquirer/rawlist': 5.2.0(@types/node@25.2.3)
+ '@inquirer/search': 4.1.0(@types/node@25.2.3)
+ '@inquirer/select': 5.0.4(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/rawlist@5.2.0(@types/node@24.10.13)':
+ '@inquirer/rawlist@5.2.0(@types/node@25.2.3)':
dependencies:
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/search@4.1.0(@types/node@24.10.13)':
+ '@inquirer/search@4.1.0(@types/node@25.2.3)':
dependencies:
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
'@inquirer/figures': 2.0.3
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/select@5.0.4(@types/node@24.10.13)':
+ '@inquirer/select@5.0.4(@types/node@25.2.3)':
dependencies:
'@inquirer/ansi': 2.0.3
- '@inquirer/core': 11.1.1(@types/node@24.10.13)
+ '@inquirer/core': 11.1.1(@types/node@25.2.3)
'@inquirer/figures': 2.0.3
- '@inquirer/type': 4.0.3(@types/node@24.10.13)
+ '@inquirer/type': 4.0.3(@types/node@25.2.3)
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
- '@inquirer/type@4.0.3(@types/node@24.10.13)':
+ '@inquirer/type@4.0.3(@types/node@25.2.3)':
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
'@isaacs/balanced-match@4.0.1': {}
@@ -11597,13 +11991,13 @@ snapshots:
'@jest/console@30.2.0':
dependencies:
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
chalk: 4.1.2
jest-message-util: 30.2.0
jest-util: 30.2.0
slash: 3.0.0
- '@jest/core@30.2.0(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3))':
+ '@jest/core@30.2.0(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))':
dependencies:
'@jest/console': 30.2.0
'@jest/pattern': 30.0.1
@@ -11611,14 +12005,14 @@ snapshots:
'@jest/test-result': 30.2.0
'@jest/transform': 30.2.0
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
ansi-escapes: 4.3.2
chalk: 4.1.2
ci-info: 4.3.1
exit-x: 0.2.2
graceful-fs: 4.2.11
jest-changed-files: 30.2.0
- jest-config: 30.2.0(@types/node@22.19.11)(esbuild-register@3.6.0(esbuild@0.27.3))(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3))
+ jest-config: 30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))
jest-haste-map: 30.2.0
jest-message-util: 30.2.0
jest-regex-util: 30.0.1
@@ -11651,14 +12045,14 @@ snapshots:
dependencies:
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-mock: 29.7.0
'@jest/environment@30.2.0':
dependencies:
'@jest/fake-timers': 30.2.0
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-mock: 30.2.0
'@jest/expect-utils@30.2.0':
@@ -11676,7 +12070,7 @@ snapshots:
dependencies:
'@jest/types': 29.6.3
'@sinonjs/fake-timers': 10.3.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-message-util: 29.7.0
jest-mock: 29.7.0
jest-util: 29.7.0
@@ -11685,7 +12079,7 @@ snapshots:
dependencies:
'@jest/types': 30.2.0
'@sinonjs/fake-timers': 13.0.5
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-message-util: 30.2.0
jest-mock: 30.2.0
jest-util: 30.2.0
@@ -11703,7 +12097,7 @@ snapshots:
'@jest/pattern@30.0.1':
dependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-regex-util: 30.0.1
'@jest/reporters@30.2.0(node-notifier@10.0.1)':
@@ -11714,7 +12108,7 @@ snapshots:
'@jest/transform': 30.2.0
'@jest/types': 30.2.0
'@jridgewell/trace-mapping': 0.3.31
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
chalk: 4.1.2
collect-v8-coverage: 1.0.3
exit-x: 0.2.2
@@ -11816,7 +12210,7 @@ snapshots:
'@jest/schemas': 29.6.3
'@types/istanbul-lib-coverage': 2.0.6
'@types/istanbul-reports': 3.0.4
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
'@types/yargs': 17.0.34
chalk: 4.1.2
@@ -11826,15 +12220,15 @@ snapshots:
'@jest/schemas': 30.0.5
'@types/istanbul-lib-coverage': 2.0.6
'@types/istanbul-reports': 3.0.4
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
'@types/yargs': 17.0.34
chalk: 4.1.2
- '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
+ '@joshwooding/vite-plugin-react-docgen-typescript@0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
glob: 13.0.2
react-docgen-typescript: 2.4.0(typescript@5.9.3)
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
optionalDependencies:
typescript: 5.9.3
@@ -12009,6 +12403,32 @@ snapshots:
'@tybys/wasm-util': 0.10.1
optional: true
+ '@next/env@16.1.6': {}
+
+ '@next/swc-darwin-arm64@16.1.6':
+ optional: true
+
+ '@next/swc-darwin-x64@16.1.6':
+ optional: true
+
+ '@next/swc-linux-arm64-gnu@16.1.6':
+ optional: true
+
+ '@next/swc-linux-arm64-musl@16.1.6':
+ optional: true
+
+ '@next/swc-linux-x64-gnu@16.1.6':
+ optional: true
+
+ '@next/swc-linux-x64-musl@16.1.6':
+ optional: true
+
+ '@next/swc-win32-arm64-msvc@16.1.6':
+ optional: true
+
+ '@next/swc-win32-x64-msvc@16.1.6':
+ optional: true
+
'@noble/curves@1.9.7':
dependencies:
'@noble/hashes': 1.8.0
@@ -13365,10 +13785,10 @@ snapshots:
- bufferutil
- utf-8-validate
- '@storybook/addon-docs@10.2.8(@types/react@19.2.8)(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
+ '@storybook/addon-docs@10.2.8(@types/react@19.2.8)(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@mdx-js/react': 3.1.1(@types/react@19.2.8)(react@19.2.3)
- '@storybook/csf-plugin': 10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ '@storybook/csf-plugin': 10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@storybook/icons': 2.0.1(react-dom@19.2.4(react@19.2.3))(react@19.2.3)
'@storybook/react-dom-shim': 10.2.8(react-dom@19.2.4(react@19.2.3))(react@19.2.3)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))
react: 19.2.3
@@ -13382,25 +13802,25 @@ snapshots:
- vite
- webpack
- '@storybook/builder-vite@10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
+ '@storybook/builder-vite@10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
- '@storybook/csf-plugin': 10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ '@storybook/csf-plugin': 10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
storybook: 10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
ts-dedent: 2.2.0
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- esbuild
- rollup
- webpack
- '@storybook/csf-plugin@10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
+ '@storybook/csf-plugin@10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
storybook: 10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
unplugin: 2.3.11
optionalDependencies:
esbuild: 0.27.3
rollup: 4.57.1
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
'@storybook/global@5.0.0': {}
@@ -13432,11 +13852,11 @@ snapshots:
react-dom: 19.2.4(react@19.2.3)
storybook: 10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
- '@storybook/react-vite@10.2.8(esbuild@0.27.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
+ '@storybook/react-vite@10.2.8(esbuild@0.27.3)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
- '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.4(typescript@5.9.3)(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@rollup/pluginutils': 5.3.0(rollup@4.57.1)
- '@storybook/builder-vite': 10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ '@storybook/builder-vite': 10.2.8(esbuild@0.27.3)(rollup@4.57.1)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@storybook/react': 10.2.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(storybook@10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(typescript@5.9.3)
empathic: 2.0.0
magic-string: 0.30.21
@@ -13446,7 +13866,7 @@ snapshots:
resolve: 1.22.11
storybook: 10.2.8(@testing-library/dom@10.4.1)(prettier@3.6.2)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
tsconfig-paths: 4.2.0
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- esbuild
- rollup
@@ -13485,9 +13905,9 @@ snapshots:
tslib: 2.8.1
typed-inject: 5.0.0
- '@stryker-mutator/core@9.5.1(@types/node@24.10.13)':
+ '@stryker-mutator/core@9.5.1(@types/node@25.2.3)':
dependencies:
- '@inquirer/prompts': 8.2.0(@types/node@24.10.13)
+ '@inquirer/prompts': 8.2.0(@types/node@25.2.3)
'@stryker-mutator/api': 9.5.1
'@stryker-mutator/instrumenter': 9.5.1
'@stryker-mutator/util': 9.5.1
@@ -13536,6 +13956,10 @@ snapshots:
'@stryker-mutator/util@9.5.1': {}
+ '@swc/helpers@0.5.15':
+ dependencies:
+ tslib: 2.8.1
+
'@tailwindcss/node@4.1.18':
dependencies:
'@jridgewell/remapping': 2.3.5
@@ -13597,12 +14021,20 @@ snapshots:
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.18
'@tailwindcss/oxide-win32-x64-msvc': 4.1.18
- '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
+ '@tailwindcss/postcss@4.1.18':
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ '@tailwindcss/node': 4.1.18
+ '@tailwindcss/oxide': 4.1.18
+ postcss: 8.5.6
+ tailwindcss: 4.1.18
+
+ '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@tailwindcss/node': 4.1.18
'@tailwindcss/oxide': 4.1.18
tailwindcss: 4.1.18
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
'@tanstack/query-core@5.90.20': {}
@@ -13703,14 +14135,14 @@ snapshots:
transitivePeerDependencies:
- debug
- '@ton/toolchain@https://codeload.github.com/the-ton-tech/toolchain/tar.gz/31376da778155bd0984d68abf2a46dce417bacb8(jest@30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1))(jiti@2.6.1)(typescript@5.9.3)':
+ '@ton/toolchain@https://codeload.github.com/the-ton-tech/toolchain/tar.gz/31376da778155bd0984d68abf2a46dce417bacb8(jest@30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1))(jiti@2.6.1)(typescript@5.9.3)':
dependencies:
'@eslint/js': 9.39.2
'@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
'@typescript-eslint/parser': 8.40.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.39.2(jiti@2.6.1)
eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.40.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))
- eslint-plugin-jest: 28.14.0(@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(jest@30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1))(typescript@5.9.3)
+ eslint-plugin-jest: 28.14.0(@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(jest@30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1))(typescript@5.9.3)
eslint-plugin-prettier: 5.5.4(eslint@9.39.2(jiti@2.6.1))(prettier@3.6.2)
globals: 16.5.0
prettier: 3.6.2
@@ -13783,7 +14215,7 @@ snapshots:
transitivePeerDependencies:
- encoding
- '@truecarry/vite-plugin-web-extension@4.5.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)':
+ '@truecarry/vite-plugin-web-extension@4.5.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)':
dependencies:
ajv: 8.17.1
async-lock: 1.4.1
@@ -13793,7 +14225,7 @@ snapshots:
lodash.uniq: 4.5.0
lodash.uniqby: 4.7.0
md5: 2.3.0
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
web-ext-option-types: 8.3.1
web-ext-run: 0.2.4
webextension-polyfill: 0.10.0
@@ -13883,7 +14315,7 @@ snapshots:
'@types/graceful-fs@4.1.9':
dependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
'@types/hammerjs@2.0.46': {}
@@ -13920,7 +14352,7 @@ snapshots:
dependencies:
undici-types: 6.21.0
- '@types/node@24.10.13':
+ '@types/node@25.2.3':
dependencies:
undici-types: 7.16.0
@@ -13963,7 +14395,7 @@ snapshots:
'@types/ws@8.18.1':
dependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
'@types/yargs-parser@21.0.3': {}
@@ -14228,7 +14660,7 @@ snapshots:
'@urql/core': 5.2.0
wonka: 6.3.5
- '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
+ '@vitejs/plugin-react@5.1.4(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@babel/core': 7.29.0
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
@@ -14236,7 +14668,7 @@ snapshots:
'@rolldown/pluginutils': 1.0.0-rc.3
'@types/babel__core': 7.20.5
react-refresh: 0.18.0
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- supports-color
@@ -14252,7 +14684,7 @@ snapshots:
obug: 2.1.1
std-env: 3.10.0
tinyrainbow: 3.0.3
- vitest: 4.0.18(@types/node@24.10.13)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vitest: 4.0.18(@types/node@25.2.3)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
'@vitest/expect@2.0.5':
dependencies:
@@ -14286,13 +14718,13 @@ snapshots:
optionalDependencies:
vite: 7.3.1(@types/node@22.19.11)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
- '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
+ '@vitest/mocker@4.0.18(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))':
dependencies:
'@vitest/spy': 4.0.18
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
'@vitest/pretty-format@2.0.5':
dependencies:
@@ -14344,7 +14776,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
- vitest: 4.0.18(@types/node@24.10.13)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vitest: 4.0.18(@types/node@25.2.3)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
'@vitest/utils@2.0.5':
dependencies:
@@ -15048,7 +15480,7 @@ snapshots:
chrome-launcher@0.15.2:
dependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
escape-string-regexp: 4.0.0
is-wsl: 2.2.0
lighthouse-logger: 1.4.2
@@ -15057,7 +15489,7 @@ snapshots:
chrome-launcher@1.2.0:
dependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
escape-string-regexp: 4.0.0
is-wsl: 2.2.0
lighthouse-logger: 2.0.2
@@ -15066,7 +15498,7 @@ snapshots:
chromium-edge-launcher@0.2.0:
dependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
escape-string-regexp: 4.0.0
is-wsl: 2.2.0
lighthouse-logger: 1.4.2
@@ -15794,13 +16226,13 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
- eslint-plugin-jest@28.14.0(@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(jest@30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1))(typescript@5.9.3):
+ eslint-plugin-jest@28.14.0(@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(jest@30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1))(typescript@5.9.3):
dependencies:
'@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
eslint: 9.39.2(jiti@2.6.1)
optionalDependencies:
'@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
- jest: 30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3))
+ jest: 30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))
transitivePeerDependencies:
- supports-color
- typescript
@@ -16580,7 +17012,7 @@ snapshots:
happy-dom@20.6.1:
dependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
'@types/whatwg-mimetype': 3.0.2
'@types/ws': 8.18.1
entities: 6.0.1
@@ -17043,7 +17475,7 @@ snapshots:
'@jest/expect': 30.2.0
'@jest/test-result': 30.2.0
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
chalk: 4.1.2
co: 4.6.0
dedent: 1.7.0
@@ -17063,15 +17495,15 @@ snapshots:
- babel-plugin-macros
- supports-color
- jest-cli@30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3)):
+ jest-cli@30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)):
dependencies:
- '@jest/core': 30.2.0(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3))
+ '@jest/core': 30.2.0(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))
'@jest/test-result': 30.2.0
'@jest/types': 30.2.0
chalk: 4.1.2
exit-x: 0.2.2
import-local: 3.2.0
- jest-config: 30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3))
+ jest-config: 30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))
jest-util: 30.2.0
jest-validate: 30.2.0
yargs: 17.7.2
@@ -17084,7 +17516,7 @@ snapshots:
- supports-color
- ts-node
- jest-config@30.2.0(@types/node@22.19.11)(esbuild-register@3.6.0(esbuild@0.27.3))(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3)):
+ jest-config@30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)):
dependencies:
'@babel/core': 7.29.0
'@jest/get-type': 30.1.0
@@ -17111,43 +17543,9 @@ snapshots:
slash: 3.0.0
strip-json-comments: 3.1.1
optionalDependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
esbuild-register: 3.6.0(esbuild@0.27.3)
- ts-node: 10.9.2(@types/node@24.10.13)(typescript@5.9.3)
- transitivePeerDependencies:
- - babel-plugin-macros
- - supports-color
-
- jest-config@30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3)):
- dependencies:
- '@babel/core': 7.29.0
- '@jest/get-type': 30.1.0
- '@jest/pattern': 30.0.1
- '@jest/test-sequencer': 30.2.0
- '@jest/types': 30.2.0
- babel-jest: 30.2.0(@babel/core@7.29.0)
- chalk: 4.1.2
- ci-info: 4.3.1
- deepmerge: 4.3.1
- glob: 10.5.0
- graceful-fs: 4.2.11
- jest-circus: 30.2.0
- jest-docblock: 30.2.0
- jest-environment-node: 30.2.0
- jest-regex-util: 30.0.1
- jest-resolve: 30.2.0
- jest-runner: 30.2.0
- jest-util: 30.2.0
- jest-validate: 30.2.0
- micromatch: 4.0.8
- parse-json: 5.2.0
- pretty-format: 30.2.0
- slash: 3.0.0
- strip-json-comments: 3.1.1
- optionalDependencies:
- '@types/node': 24.10.13
- esbuild-register: 3.6.0(esbuild@0.27.3)
- ts-node: 10.9.2(@types/node@24.10.13)(typescript@5.9.3)
+ ts-node: 10.9.2(@types/node@25.2.3)(typescript@5.9.3)
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
@@ -17176,7 +17574,7 @@ snapshots:
'@jest/environment': 29.7.0
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-mock: 29.7.0
jest-util: 29.7.0
@@ -17185,7 +17583,7 @@ snapshots:
'@jest/environment': 30.2.0
'@jest/fake-timers': 30.2.0
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-mock: 30.2.0
jest-util: 30.2.0
jest-validate: 30.2.0
@@ -17196,7 +17594,7 @@ snapshots:
dependencies:
'@jest/types': 29.6.3
'@types/graceful-fs': 4.1.9
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.11
@@ -17211,7 +17609,7 @@ snapshots:
jest-haste-map@30.2.0:
dependencies:
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.11
@@ -17262,13 +17660,13 @@ snapshots:
jest-mock@29.7.0:
dependencies:
'@jest/types': 29.6.3
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-util: 29.7.0
jest-mock@30.2.0:
dependencies:
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-util: 30.2.0
jest-pnp-resolver@1.2.3(jest-resolve@30.2.0):
@@ -17304,7 +17702,7 @@ snapshots:
'@jest/test-result': 30.2.0
'@jest/transform': 30.2.0
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
chalk: 4.1.2
emittery: 0.13.1
exit-x: 0.2.2
@@ -17333,7 +17731,7 @@ snapshots:
'@jest/test-result': 30.2.0
'@jest/transform': 30.2.0
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
chalk: 4.1.2
cjs-module-lexer: 2.1.1
collect-v8-coverage: 1.0.3
@@ -17380,7 +17778,7 @@ snapshots:
jest-util@29.7.0:
dependencies:
'@jest/types': 29.6.3
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
chalk: 4.1.2
ci-info: 3.9.0
graceful-fs: 4.2.11
@@ -17389,7 +17787,7 @@ snapshots:
jest-util@30.2.0:
dependencies:
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
chalk: 4.1.2
ci-info: 4.3.1
graceful-fs: 4.2.11
@@ -17417,7 +17815,7 @@ snapshots:
dependencies:
'@jest/test-result': 30.2.0
'@jest/types': 30.2.0
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
@@ -17426,25 +17824,25 @@ snapshots:
jest-worker@29.7.0:
dependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
jest-util: 29.7.0
merge-stream: 2.0.0
supports-color: 8.1.1
jest-worker@30.2.0:
dependencies:
- '@types/node': 22.19.11
+ '@types/node': 25.2.3
'@ungap/structured-clone': 1.3.0
jest-util: 30.2.0
merge-stream: 2.0.0
supports-color: 8.1.1
- jest@30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3)):
+ jest@30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)):
dependencies:
- '@jest/core': 30.2.0(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3))
+ '@jest/core': 30.2.0(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))
'@jest/types': 30.2.0
import-local: 3.2.0
- jest-cli: 30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3))
+ jest-cli: 30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))
optionalDependencies:
node-notifier: 10.0.1
transitivePeerDependencies:
@@ -18104,6 +18502,32 @@ snapshots:
react: 19.2.3
react-dom: 19.2.3(react@19.2.3)
+ next@16.1.6(@babel/core@7.29.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ dependencies:
+ '@next/env': 16.1.6
+ '@swc/helpers': 0.5.15
+ baseline-browser-mapping: 2.9.19
+ caniuse-lite: 1.0.30001767
+ postcss: 8.4.31
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.3)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 16.1.6
+ '@next/swc-darwin-x64': 16.1.6
+ '@next/swc-linux-arm64-gnu': 16.1.6
+ '@next/swc-linux-arm64-musl': 16.1.6
+ '@next/swc-linux-x64-gnu': 16.1.6
+ '@next/swc-linux-x64-musl': 16.1.6
+ '@next/swc-win32-arm64-msvc': 16.1.6
+ '@next/swc-win32-x64-msvc': 16.1.6
+ '@playwright/test': 1.58.2
+ babel-plugin-react-compiler: 1.0.0
+ sharp: 0.34.5
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+
node-abi@3.77.0:
dependencies:
semver: 7.7.3
@@ -18569,6 +18993,12 @@ snapshots:
possible-typed-array-names@1.1.0: {}
+ postcss@8.4.31:
+ dependencies:
+ nanoid: 3.3.11
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
postcss@8.4.49:
dependencies:
nanoid: 3.3.11
@@ -19544,6 +19974,38 @@ snapshots:
shallowequal@1.1.0: {}
+ sharp@0.34.5:
+ dependencies:
+ '@img/colour': 1.0.0
+ detect-libc: 2.1.2
+ semver: 7.7.3
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.34.5
+ '@img/sharp-darwin-x64': 0.34.5
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ '@img/sharp-linux-arm': 0.34.5
+ '@img/sharp-linux-arm64': 0.34.5
+ '@img/sharp-linux-ppc64': 0.34.5
+ '@img/sharp-linux-riscv64': 0.34.5
+ '@img/sharp-linux-s390x': 0.34.5
+ '@img/sharp-linux-x64': 0.34.5
+ '@img/sharp-linuxmusl-arm64': 0.34.5
+ '@img/sharp-linuxmusl-x64': 0.34.5
+ '@img/sharp-wasm32': 0.34.5
+ '@img/sharp-win32-arm64': 0.34.5
+ '@img/sharp-win32-ia32': 0.34.5
+ '@img/sharp-win32-x64': 0.34.5
+ optional: true
+
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
@@ -19853,6 +20315,13 @@ snapshots:
stubborn-utils@1.0.2: {}
+ styled-jsx@5.1.6(@babel/core@7.29.0)(react@19.2.3):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.2.3
+ optionalDependencies:
+ '@babel/core': 7.29.0
+
sucrase@3.35.1:
dependencies:
'@jridgewell/gen-mapping': 0.3.13
@@ -20101,12 +20570,12 @@ snapshots:
ts-interface-checker@0.1.13: {}
- ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(esbuild@0.27.3)(jest-util@30.2.0)(jest@30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3)))(typescript@5.9.3):
+ ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(esbuild@0.27.3)(jest-util@30.2.0)(jest@30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)))(typescript@5.9.3):
dependencies:
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
handlebars: 4.7.8
- jest: 30.2.0(@types/node@24.10.13)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3))
+ jest: 30.2.0(@types/node@25.2.3)(esbuild-register@3.6.0(esbuild@0.27.3))(node-notifier@10.0.1)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))
json5: 2.2.3
lodash.memoize: 4.1.2
make-error: 1.3.6
@@ -20133,14 +20602,14 @@ snapshots:
tslib: 2.8.1
typescript: 5.9.3
- ts-node@10.9.2(@types/node@24.10.13)(typescript@5.9.3):
+ ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
acorn: 8.15.0
acorn-walk: 8.3.4
arg: 4.1.3
@@ -20502,11 +20971,11 @@ snapshots:
vite-bundle-analyzer@1.3.2: {}
- vite-plugin-node-polyfills@0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)):
+ vite-plugin-node-polyfills@0.25.0(rollup@4.57.1)(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)):
dependencies:
'@rollup/plugin-inject': 5.0.5(rollup@4.57.1)
node-stdlib-browser: 1.3.1
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
transitivePeerDependencies:
- rollup
@@ -20527,7 +20996,7 @@ snapshots:
tsx: 4.21.0
yaml: 2.8.1
- vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
+ vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
esbuild: 0.27.3
fdir: 6.5.0(picomatch@4.0.3)
@@ -20536,7 +21005,7 @@ snapshots:
rollup: 4.57.1
tinyglobby: 0.2.15
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
fsevents: 2.3.3
jiti: 2.6.1
lightningcss: 1.31.1
@@ -20584,10 +21053,10 @@ snapshots:
- tsx
- yaml
- vitest@4.0.18(@types/node@24.10.13)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
+ vitest@4.0.18(@types/node@25.2.3)(@vitest/ui@4.0.18)(happy-dom@20.6.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@2.0.1))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1):
dependencies:
'@vitest/expect': 4.0.18
- '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
+ '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1))
'@vitest/pretty-format': 4.0.18
'@vitest/runner': 4.0.18
'@vitest/snapshot': 4.0.18
@@ -20604,10 +21073,10 @@ snapshots:
tinyexec: 1.0.2
tinyglobby: 0.2.15
tinyrainbow: 3.0.3
- vite: 7.3.1(@types/node@24.10.13)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
+ vite: 7.3.1(@types/node@25.2.3)(jiti@2.6.1)(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.1)
why-is-node-running: 2.3.0
optionalDependencies:
- '@types/node': 24.10.13
+ '@types/node': 25.2.3
'@vitest/ui': 4.0.18(vitest@4.0.18)
happy-dom: 20.6.1
jsdom: 28.0.0(@noble/hashes@2.0.1)