From 5bfc7654fcf07ece0541cc4d4c2ef26dc23b4b88 Mon Sep 17 00:00:00 2001
From: xszxc <2112067692@qq.com>
Date: Mon, 31 Mar 2025 20:52:29 +0800
Subject: [PATCH] add reward system
---
app/rewards/layout.tsx | 147 +++++++
app/rewards/page.tsx | 321 +++++++++++++++
components/navbar/navbar.tsx | 5 +
components/ui/use-toast.tsx | 10 +
components/web3-provider.tsx | 8 +-
lib/contracts/CFCToke.json | 666 +++++++++++++++++++++++++++++++
lib/contracts/RewardToken.json | 339 ++++++++++++++++
lib/contracts/contract-config.ts | 30 ++
lib/hooks/useERC20Token.ts | 231 +++++++++++
lib/hooks/useRewardToken.ts | 114 ++++++
package-lock.json | 486 ++++++++++++----------
package.json | 3 +-
tailwind.config.ts | 115 ++++--
13 files changed, 2232 insertions(+), 243 deletions(-)
create mode 100644 app/rewards/layout.tsx
create mode 100644 app/rewards/page.tsx
create mode 100644 components/ui/use-toast.tsx
create mode 100644 lib/contracts/CFCToke.json
create mode 100644 lib/contracts/RewardToken.json
create mode 100644 lib/contracts/contract-config.ts
create mode 100644 lib/hooks/useERC20Token.ts
create mode 100644 lib/hooks/useRewardToken.ts
diff --git a/app/rewards/layout.tsx b/app/rewards/layout.tsx
new file mode 100644
index 0000000..78b09e9
--- /dev/null
+++ b/app/rewards/layout.tsx
@@ -0,0 +1,147 @@
+"use client";
+
+import { useEffect, useState } from "react";
+import { useAppKit } from "@reown/appkit/react";
+import { useAppKitAccount } from "@reown/appkit/react";
+import { useChainId } from "wagmi";
+import { sepolia } from "wagmi/chains";
+
+export default function RewardsLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const { open } = useAppKit();
+ const { isConnected } = useAppKitAccount();
+ const chainId = useChainId();
+ const [showNetworkAlert, setShowNetworkAlert] = useState(false);
+
+ // 检查网络是否是Sepolia
+ useEffect(() => {
+ // 只有当用户已连接钱包时才显示网络提示
+ if (isConnected && chainId && chainId !== sepolia.id) {
+ setShowNetworkAlert(true);
+ } else {
+ setShowNetworkAlert(false);
+ }
+ }, [chainId, isConnected]);
+
+ // 手动添加Sepolia网络
+ const addSepoliaNetwork = async () => {
+ // 检查window.ethereum是否可用
+ if (typeof window !== "undefined" && "ethereum" in window) {
+ try {
+ // 请求添加Sepolia测试网络
+ await (window as any).ethereum.request({
+ method: "wallet_addEthereumChain",
+ params: [
+ {
+ chainId: "0xaa36a7", // 十六进制形式的链ID
+ chainName: "Sepolia Testnet",
+ nativeCurrency: {
+ name: "Sepolia ETH",
+ symbol: "ETH",
+ decimals: 18,
+ },
+ rpcUrls: ["https://eth-sepolia.g.alchemy.com/v2/demo"],
+ blockExplorerUrls: ["https://sepolia.etherscan.io"],
+ },
+ ],
+ });
+ console.log("Sepolia网络添加成功");
+ } catch (error) {
+ console.error("添加Sepolia网络失败:", error);
+ }
+ } else {
+ console.error(
+ "未检测到以太坊提供程序,请确保已安装MetaMask或其他兼容钱包"
+ );
+ }
+ };
+
+ return (
+
+ {/* 网络提示 */}
+ {showNetworkAlert && (
+
+
+
+ 请切换到Sepolia测试网以访问奖励功能
+
+
+
+
+
+
+ 如果添加失败,请尝试手动添加网络或刷新页面
+
+
+
+ )}
+
+ {/* 背景装饰 - 动态粒子版本 */}
+
+ {/* 主要背景渐变 */}
+
+
+ {/* 网格图案 - 区块链风格 */}
+
+
+ {/* 动态光晕效果 */}
+
+
+
+ {/* 右上角 - 代表代币/奖励的光效 */}
+
+
+ {/* 左下角 - 小粒子区域 */}
+
+
+ {/* 粒子动画区 - 左侧 */}
+
+
+
+
+
+
+ {/* 粒子动画区 - 右侧 */}
+
+
+
+
+
+
+ {/* 粒子连接线 - 模拟区块链节点连接 (使用绝对定位的伪元素模拟连接) */}
+
+
+
+
+ {/* 区块节点 - 大型节点 */}
+
+
+
+
+
+ {/* 内容区域 */}
+
{children}
+
+ );
+}
diff --git a/app/rewards/page.tsx b/app/rewards/page.tsx
new file mode 100644
index 0000000..92a5952
--- /dev/null
+++ b/app/rewards/page.tsx
@@ -0,0 +1,321 @@
+"use client";
+
+import { useState, useEffect } from "react";
+import { useAppKitAccount } from "@reown/appkit/react";
+import { useAppKit } from "@reown/appkit/react";
+import { useRewardToken } from "@/lib/hooks/useRewardToken";
+import { useERC20Token } from "@/lib/hooks/useERC20Token";
+import { formatDistanceToNow } from "date-fns";
+import { zhCN } from "date-fns/locale";
+import { Coins, History, Wallet, ChevronRight, Gift, Clock, ExternalLink, Plus, Info } from "lucide-react";
+import { sepolia } from "wagmi/chains";
+
+export default function RewardsPage() {
+ const { isConnected, address } = useAppKitAccount();
+ const { open } = useAppKit();
+ const {
+ availableRewards,
+ lastClaimTime,
+ claimRewards,
+ isLoading,
+ isSuccess,
+ errorMessage,
+ isSepoliaNetwork
+ } = useRewardToken();
+ const {
+ balance,
+ } = useERC20Token();
+ const [showSuccessMessage, setShowSuccessMessage] = useState(false);
+ const [showNetworkInfo, setShowNetworkInfo] = useState(false);
+ const [switchError, setSwitchError] = useState(null);
+
+ // 处理成功领取后的提示
+ useEffect(() => {
+ if (isSuccess) {
+ setShowSuccessMessage(true);
+ const timer = setTimeout(() => {
+ setShowSuccessMessage(false);
+ }, 3000);
+
+ return () => clearTimeout(timer);
+ }
+ }, [isSuccess]);
+
+ // 格式化上次领取时间
+ const formattedLastClaimTime = lastClaimTime ?
+ formatDistanceToNow(new Date(lastClaimTime * 1000), { addSuffix: true, locale: zhCN }) :
+ "从未领取";
+
+ // 处理钱包连接
+ const handleConnectWallet = () => {
+ open();
+ };
+
+ // 处理网络切换
+ const handleSwitchNetwork = () => {
+ setSwitchError(null);
+ open({ view: "Networks" });
+ };
+
+ // 手动添加Sepolia网络
+ const addSepoliaNetwork = async () => {
+ try {
+ setSwitchError(null);
+ if (typeof window !== 'undefined' && 'ethereum' in window) {
+ await (window as any).ethereum.request({
+ method: 'wallet_addEthereumChain',
+ params: [
+ {
+ chainId: '0xaa36a7', // 十六进制形式的链ID
+ chainName: 'Sepolia Testnet',
+ nativeCurrency: {
+ name: 'Sepolia ETH',
+ symbol: 'ETH',
+ decimals: 18,
+ },
+ rpcUrls: ['https://endpoints.omniatech.io/v1/eth/sepolia/public'],
+ blockExplorerUrls: ['https://sepolia.etherscan.io'],
+ },
+ ],
+ });
+ console.log('Sepolia网络添加成功');
+ } else {
+ setSwitchError("未检测到以太坊提供程序,请确保已安装MetaMask或其他兼容钱包");
+ }
+ } catch (error) {
+ console.error('添加Sepolia网络失败:', error);
+ setSwitchError("添加网络失败,请尝试手动添加或刷新页面");
+ }
+ };
+
+ // 渲染连接钱包按钮
+ const renderConnectWalletPrompt = () => (
+
+
+
连接您的钱包
+
+ 请先连接您的钱包以查看和领取奖励代币
+
+
+
+ );
+
+ // 渲染网络切换提示
+ const renderNetworkSwitchPrompt = () => (
+
+
+
请切换至 Sepolia 测试网
+
+ CFC 奖励仅在 Sepolia 测试网上可用,请切换您的钱包网络
+
+
+ {/* 错误信息 */}
+ {switchError && (
+
+ {switchError}
+
+ )}
+
+
+
+
+
+
+
+
+
+ {showNetworkInfo && (
+
+
Sepolia测试网配置信息:
+
+ - 网络名称: Sepolia
+ - RPC URL: https://eth-sepolia.g.alchemy.com/v2/demo
+ - 链ID (十进制): 11155111
+ - 链ID (十六进制): 0xaa36a7
+ - 货币符号: ETH
+ - 区块浏览器: https://sepolia.etherscan.io
+
+
复制上述信息到您的钱包App中手动添加网络
+
+ )}
+
+ );
+
+ // 渲染奖励卡片
+ const renderRewardsCard = () => (
+
+ {/* 当前余额卡片 */}
+
+
+
+
+
+
+ 上次领取:
+
+
{formattedLastClaimTime}
+
+
+
+ {/* 可用奖励卡片 */}
+
+
+
+
+ {availableRewards}
+ CFC
+
+
+
+
+
+ );
+
+ // 渲染合适的内容
+ const renderContent = () => {
+ if (!isConnected) {
+ return renderConnectWalletPrompt();
+ } else if (!isSepoliaNetwork) {
+ return renderNetworkSwitchPrompt();
+ } else {
+ return renderRewardsCard();
+ }
+ };
+
+ return (
+
+
+ {/* 标题部分 */}
+
+
+ CFC 奖励中心
+
+
+ 参与社区活动和贡献代码,获取 CFC 代币奖励。这些代币可用于社区治理和解锁特殊功能。
+
+
+
+ {/* 动态内容区域 */}
+ {renderContent()}
+
+ {/* 错误信息 */}
+ {errorMessage && (
+
+ {errorMessage}
+
+ )}
+
+ {/* 成功信息 */}
+ {showSuccessMessage && (
+
+ )}
+
+ {/* 奖励说明 */}
+
+
如何获取更多奖励
+
+ -
+
+ 1
+
+
+
参与 Hackathon 活动
+
根据项目完成情况和评分,获得相应的代币奖励。
+
+
+ -
+
+ 2
+
+
+
贡献代码
+
向我们的开源项目提交PR,审核通过后获得代币奖励。
+
+
+ -
+
+ 3
+
+
+
参与社区讨论
+
在社区中积极参与讨论,提供有价值的建议和反馈。
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/components/navbar/navbar.tsx b/components/navbar/navbar.tsx
index a87b410..50dded0 100644
--- a/components/navbar/navbar.tsx
+++ b/components/navbar/navbar.tsx
@@ -59,6 +59,11 @@ export function Navbar() {
href: "/hackathon",
icon: ,
},
+ {
+ name: "Rewards",
+ href: "/rewards",
+ icon: ,
+ },
// { name: "Contact", href: "/contact", icon: },
];
diff --git a/components/ui/use-toast.tsx b/components/ui/use-toast.tsx
new file mode 100644
index 0000000..ae30f8c
--- /dev/null
+++ b/components/ui/use-toast.tsx
@@ -0,0 +1,10 @@
+import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from "./toast"
+import { useToast as useToastOriginal } from "./use-toast-hook"
+
+export const ToastProvider = ToastProvider
+export const ToastViewport = ToastViewport
+export const Toast = Toast
+export const ToastTitle = ToastTitle
+export const ToastDescription = ToastDescription
+export const ToastClose = ToastClose
+export const useToast = useToastOriginal
\ No newline at end of file
diff --git a/components/web3-provider.tsx b/components/web3-provider.tsx
index e41db4d..fc2617a 100644
--- a/components/web3-provider.tsx
+++ b/components/web3-provider.tsx
@@ -9,6 +9,7 @@ import {
base,
polygon,
solana,
+ sepolia,
} from "@reown/appkit/networks";
import {
SolflareWalletAdapter,
@@ -27,7 +28,7 @@ if (!projectId) {
throw new Error("Project ID is not defined");
}
-export const networks = [mainnet, arbitrum, polygon, base, solana];
+export const networks = [mainnet, arbitrum, polygon, base, solana, sepolia];
//Set up the Wagmi Adapter (Config)
export const wagmiAdapter = new WagmiAdapter({
@@ -50,6 +51,9 @@ export const wagmiAdapter = new WagmiAdapter({
[base.id]: http(
"https://base-mainnet.g.alchemy.com/v2/uGsEZP9zr3DFh1rGiFj4safeFvFfC7B0"
),
+ [sepolia.id]: http(
+ "https://endpoints.omniatech.io/v1/eth/sepolia/public"
+ ),
},
});
@@ -78,7 +82,7 @@ const metadata = {
const modal = createAppKit({
adapters: [wagmiAdapter, solanaWeb3JsAdapter],
projectId,
- networks: [mainnet, arbitrum, base, polygon, solana],
+ networks: [mainnet, arbitrum, base, polygon, solana, sepolia],
defaultNetwork: mainnet,
metadata: metadata,
enableWalletConnect: false,
diff --git a/lib/contracts/CFCToke.json b/lib/contracts/CFCToke.json
new file mode 100644
index 0000000..a876a89
--- /dev/null
+++ b/lib/contracts/CFCToke.json
@@ -0,0 +1,666 @@
+[
+ {
+ "inputs": [],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "inputs": [],
+ "name": "ECDSAInvalidSignature",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "length",
+ "type": "uint256"
+ }
+ ],
+ "name": "ECDSAInvalidSignatureLength",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "ECDSAInvalidSignatureS",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "allowance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientAllowance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "balance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientBalance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "approver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidApprover",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidReceiver",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSender",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSpender",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "deadline",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC2612ExpiredSignature",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "signer",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "ERC2612InvalidSigner",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "currentNonce",
+ "type": "uint256"
+ }
+ ],
+ "name": "InvalidAccountNonce",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidShortString",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableInvalidOwner",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "str",
+ "type": "string"
+ }
+ ],
+ "name": "StringTooLong",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "EIP712DomainChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "DOMAIN_SEPARATOR",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "minter",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "approveMinter",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "burn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "burnFrom",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "eip712Domain",
+ "outputs": [
+ {
+ "internalType": "bytes1",
+ "name": "fields",
+ "type": "bytes1"
+ },
+ {
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "internalType": "uint256",
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "verifyingContract",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "salt",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "extensions",
+ "type": "uint256[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "mint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "nonces",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "deadline",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint8",
+ "name": "v",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "r",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "s",
+ "type": "bytes32"
+ }
+ ],
+ "name": "permit",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
\ No newline at end of file
diff --git a/lib/contracts/RewardToken.json b/lib/contracts/RewardToken.json
new file mode 100644
index 0000000..ed2bb2c
--- /dev/null
+++ b/lib/contracts/RewardToken.json
@@ -0,0 +1,339 @@
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "addReward",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "users",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "amounts",
+ "type": "uint256[]"
+ }
+ ],
+ "name": "batchAddRewards",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "claimRewards",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "depositTokens",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "emergencyWithdraw",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "tokenAddress",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableInvalidOwner",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "SafeERC20FailedOperation",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "RewardAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "RewardClaimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newTokenContract",
+ "type": "address"
+ }
+ ],
+ "name": "TokenContractUpdated",
+ "type": "event"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newTokenAddress",
+ "type": "address"
+ }
+ ],
+ "name": "updateTokenContract",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "availableRewards",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "canClaim",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "cfcToken",
+ "outputs": [
+ {
+ "internalType": "contract IERC20",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "CLAIM_COOLDOWN",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "lastClaimTime",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "timeUntilNextClaim",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
\ No newline at end of file
diff --git a/lib/contracts/contract-config.ts b/lib/contracts/contract-config.ts
new file mode 100644
index 0000000..106c46f
--- /dev/null
+++ b/lib/contracts/contract-config.ts
@@ -0,0 +1,30 @@
+import { mainnet, sepolia } from "wagmi/chains";
+import { Address } from "viem";
+
+interface ContractConfig {
+ address: Record;
+ name: string;
+}
+
+export const REWARD_TOKEN_CONTRACT: ContractConfig = {
+ name: "CrazyForCode Token",
+ address: {
+ [mainnet.id]: "0x1234567890123456789012345678901234567890", // 主网测试地址,实际部署时更换
+ [sepolia.id]: "0x3e61503D6504F5f72Fc46a04229048e96d5F9089", // Sepolia测试网地址,实际部署时更换
+ },
+};
+
+export const CFC_TOKEN_CONTRACT: ContractConfig = {
+ name: "CrazyForCode Token",
+ address: {
+ [mainnet.id]: "0x1234567890123456789012345678901234567890", // 主网测试地址,实际部署时更换
+ [sepolia.id]: "0x7c0de9efd6edf521d71bbd4085728b8771a3f675", // Sepolia测试网地址,实际部署时更换
+ },
+ };
+
+export function getContractAddress(
+ contract: ContractConfig,
+ chainId: number
+): Address | undefined {
+ return contract.address[chainId];
+}
\ No newline at end of file
diff --git a/lib/hooks/useERC20Token.ts b/lib/hooks/useERC20Token.ts
new file mode 100644
index 0000000..9c74002
--- /dev/null
+++ b/lib/hooks/useERC20Token.ts
@@ -0,0 +1,231 @@
+import { useReadContract, useWriteContract, useWaitForTransactionReceipt, useChainId } from "wagmi";
+import { formatUnits, parseUnits } from "viem";
+import { useState, useEffect } from "react";
+import { useAppKitAccount } from "@reown/appkit/react";
+import { sepolia } from "wagmi/chains";
+import ERC20_ABI from "../contracts/CFCToke.json";
+import { CFC_TOKEN_CONTRACT, getContractAddress } from "../contracts/contract-config";
+
+
+/**
+ * 使用ERC20代币的钩子函数
+ * @param contractAddress ERC20代币合约地址
+ * @returns 代币相关函数和状态
+ */
+export function useERC20Token() {
+ const { address, isConnected } = useAppKitAccount();
+ const chainId = useChainId();
+ const [isLoading, setIsLoading] = useState(false);
+ const [errorMessage, setErrorMessage] = useState(null);
+ const [tokenInfo, setTokenInfo] = useState<{
+ name: string | undefined;
+ symbol: string | undefined;
+ decimals: number;
+ }>({
+ name: undefined,
+ symbol: undefined,
+ decimals: 18,
+ });
+
+ // 检查网络是否是Sepolia
+ const isSepoliaNetwork = chainId === sepolia.id;
+
+ // 获取合约地址
+ const contractAddress = isSepoliaNetwork
+ ? getContractAddress(CFC_TOKEN_CONTRACT, sepolia.id)
+ : undefined;
+
+ // 读取代币名称
+ const { data: tokenName } = useReadContract({
+ address: contractAddress,
+ abi: ERC20_ABI,
+ functionName: "name",
+ query: {
+ enabled: Boolean(isConnected && contractAddress && isSepoliaNetwork),
+ },
+ });
+
+ // 读取代币符号
+ const { data: tokenSymbol } = useReadContract({
+ address: contractAddress,
+ abi: ERC20_ABI,
+ functionName: "symbol",
+ query: {
+ enabled: Boolean(isConnected && contractAddress && isSepoliaNetwork),
+ },
+ });
+
+ // 读取代币精度
+ const { data: tokenDecimals } = useReadContract({
+ address: contractAddress,
+ abi: ERC20_ABI,
+ functionName: "decimals",
+ query: {
+ enabled: Boolean(isConnected && contractAddress && isSepoliaNetwork),
+ },
+ });
+
+ // 更新代币信息
+ useEffect(() => {
+ if (tokenName || tokenSymbol || tokenDecimals !== undefined) {
+ setTokenInfo({
+ name: tokenName as string | undefined,
+ symbol: tokenSymbol as string | undefined,
+ decimals: tokenDecimals !== undefined ? Number(tokenDecimals) : 18,
+ });
+ }
+ }, [tokenName, tokenSymbol, tokenDecimals]);
+
+ // 读取用户余额
+ const { data: balance, refetch: refetchBalance } = useReadContract({
+ address: contractAddress,
+ abi: ERC20_ABI,
+ functionName: "balanceOf",
+ args: address ? [address] : undefined,
+ query: {
+ enabled: Boolean(isConnected && address && contractAddress && isSepoliaNetwork),
+ staleTime: 10_000,
+ },
+ });
+
+ // 读取授权额度
+ const { data: allowanceData, refetch: refetchAllowance } = useReadContract({
+ address: contractAddress,
+ abi: ERC20_ABI,
+ functionName: "allowance",
+ args: address && contractAddress ? [address, contractAddress] : undefined,
+ query: {
+ enabled: Boolean(isConnected && address && contractAddress && isSepoliaNetwork),
+ staleTime: 10_000,
+ },
+ });
+
+ // 转账相关
+ const { writeContract, data: transferHash, isPending: isTransferPending } = useWriteContract();
+
+ // 授权相关
+ const { writeContract: writeApprove, data: approveHash, isPending: isApprovePending } = useWriteContract();
+
+ // 等待交易完成
+ const { isLoading: isTransferConfirming, isSuccess: isTransferSuccess } = useWaitForTransactionReceipt({
+ hash: transferHash,
+ });
+
+ const { isLoading: isApproveConfirming, isSuccess: isApproveSuccess } = useWaitForTransactionReceipt({
+ hash: approveHash,
+ });
+
+ // 转账函数
+ const transfer = async (to: `0x${string}`, amount: string) => {
+ if (!isConnected || !address) {
+ setErrorMessage("请先连接您的钱包");
+ return;
+ }
+
+ if (!isSepoliaNetwork) {
+ setErrorMessage("请切换到Sepolia测试网");
+ return;
+ }
+
+ if (!contractAddress) {
+ setErrorMessage("合约地址无效");
+ return;
+ }
+
+ try {
+ setIsLoading(true);
+ setErrorMessage(null);
+
+ // 将金额转换为合约所需的格式,考虑代币精度
+ const amountInWei = parseUnits(amount, tokenInfo.decimals);
+
+ writeContract({
+ address: contractAddress,
+ abi: ERC20_ABI,
+ functionName: "transfer",
+ args: [to, amountInWei],
+ });
+ } catch (error) {
+ console.error("转账失败:", error);
+ setErrorMessage("转账失败,请稍后再试");
+ setIsLoading(false);
+ }
+ };
+
+ // 授权函数
+ const approve = async (spender: `0x${string}`, amount: string) => {
+ if (!isConnected || !address) {
+ setErrorMessage("请先连接您的钱包");
+ return;
+ }
+
+ if (!isSepoliaNetwork) {
+ setErrorMessage("请切换到Sepolia测试网");
+ return;
+ }
+
+ if (!contractAddress) {
+ setErrorMessage("合约地址无效");
+ return;
+ }
+
+ try {
+ setIsLoading(true);
+ setErrorMessage(null);
+
+ // 将金额转换为合约所需的格式,考虑代币精度
+ const amountInWei = parseUnits(amount, tokenInfo.decimals);
+
+ writeApprove({
+ address: contractAddress,
+ abi: ERC20_ABI,
+ functionName: "approve",
+ args: [spender, amountInWei],
+ });
+ } catch (error) {
+ console.error("授权失败:", error);
+ setErrorMessage("授权失败,请稍后再试");
+ setIsLoading(false);
+ }
+ };
+
+ // 监听交易状态
+ useEffect(() => {
+ if (isTransferSuccess || isApproveSuccess) {
+ // 刷新数据
+ refetchBalance();
+ refetchAllowance();
+ setIsLoading(false);
+ }
+ }, [isTransferSuccess, isApproveSuccess, refetchBalance, refetchAllowance]);
+
+ // 格式化代币金额
+ const formatTokenAmount = (amount: bigint | undefined) => {
+ if (!amount) return "0";
+ return formatUnits(amount, tokenInfo.decimals);
+ };
+
+ return {
+ // 代币信息
+ tokenName: tokenInfo.name,
+ tokenSymbol: tokenInfo.symbol,
+ tokenDecimals: tokenInfo.decimals,
+
+ // 余额
+ balance: balance ? formatTokenAmount(balance as bigint) : "0",
+ allowance: allowanceData ? formatTokenAmount(allowanceData as bigint) : "0",
+
+ // 操作函数
+ transfer,
+ approve,
+ refetchBalance,
+ refetchAllowance,
+
+ // 状态
+ isLoading: isLoading || isTransferPending || isTransferConfirming || isApprovePending || isApproveConfirming,
+ isTransferSuccess,
+ isApproveSuccess,
+ errorMessage,
+ isSepoliaNetwork,
+ };
+}
\ No newline at end of file
diff --git a/lib/hooks/useRewardToken.ts b/lib/hooks/useRewardToken.ts
new file mode 100644
index 0000000..2355871
--- /dev/null
+++ b/lib/hooks/useRewardToken.ts
@@ -0,0 +1,114 @@
+import { useReadContract, useWriteContract, useWaitForTransactionReceipt, useChainId } from "wagmi";
+import { formatUnits } from "viem";
+import { useState, useEffect } from "react";
+import { useAppKitAccount } from "@reown/appkit/react";
+import { REWARD_TOKEN_CONTRACT, getContractAddress } from "../contracts/contract-config";
+import RewardTokenABI from "../contracts/RewardToken.json";
+import { sepolia } from "wagmi/chains";
+
+export function useRewardToken() {
+ const { address, isConnected } = useAppKitAccount();
+ const [isLoading, setIsLoading] = useState(false);
+ const [errorMessage, setErrorMessage] = useState(null);
+
+ // 获取当前链ID
+ const currentChainId = useChainId();
+
+ // 检查是否在Sepolia测试网上
+ const isSepoliaNetwork = currentChainId === sepolia.id;
+
+ // 获取合约地址
+ const contractAddress = isSepoliaNetwork
+ ? getContractAddress(REWARD_TOKEN_CONTRACT, sepolia.id)
+ : undefined;
+
+ // 读取可用奖励数量
+ const { data: availableRewards, refetch: refetchAvailableRewards } = useReadContract({
+ address: contractAddress,
+ abi: RewardTokenABI,
+ functionName: "availableRewards",
+ args: address ? [address] : undefined,
+ query: {
+ enabled: Boolean(isConnected && address && contractAddress && isSepoliaNetwork),
+ staleTime: 10_000,
+ }
+ });
+
+ // 读取上次领取时间
+ const { data: lastClaimTime, refetch: refetchLastClaimTime } = useReadContract({
+ address: contractAddress,
+ abi: RewardTokenABI,
+ functionName: "lastClaimTime",
+ args: address ? [address] : undefined,
+ query: {
+ enabled: Boolean(isConnected && address && contractAddress && isSepoliaNetwork),
+ staleTime: 10_000,
+ }
+ });
+
+ // 领取奖励
+ const { writeContract, data: hash, isPending } = useWriteContract();
+
+ // 等待交易完成
+ const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({
+ hash,
+ });
+
+ // 处理领取奖励
+ const claimRewards = async () => {
+ if (!isConnected || !address) {
+ setErrorMessage("请先连接您的钱包");
+ return;
+ }
+
+ if (!isSepoliaNetwork) {
+ setErrorMessage("请切换到Sepolia测试网");
+ return;
+ }
+
+ if (!contractAddress) {
+ setErrorMessage("合约地址未配置");
+ return;
+ }
+
+ try {
+ setIsLoading(true);
+ setErrorMessage(null);
+ writeContract({
+ address: contractAddress,
+ abi: RewardTokenABI,
+ functionName: "claimRewards",
+ });
+ } catch (error) {
+ console.error("领取奖励失败:", error);
+ setErrorMessage("领取奖励时出现错误,请稍后再试");
+ setIsLoading(false);
+ }
+ };
+
+ // 监听交易状态
+ useEffect(() => {
+ if (isSuccess) {
+ // 刷新数据
+ refetchAvailableRewards();
+ refetchLastClaimTime();
+ setIsLoading(false);
+ }
+ }, [isSuccess, refetchAvailableRewards, refetchLastClaimTime]);
+
+ // 格式化代币金额
+ const formatTokenAmount = (amount: bigint | undefined, decimals = 18) => {
+ if (!amount) return "0";
+ return formatUnits(amount, decimals);
+ };
+
+ return {
+ availableRewards: availableRewards ? formatTokenAmount(availableRewards as bigint) : "0",
+ lastClaimTime: lastClaimTime ? Number(lastClaimTime) : 0,
+ claimRewards,
+ isLoading: isLoading || isPending || isConfirming,
+ isSuccess,
+ errorMessage,
+ isSepoliaNetwork,
+ };
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index d33542a..9df066e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -30,10 +30,11 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"convex": "^1.19.2",
+ "date-fns": "^4.1.0",
"lucide-react": "^0.469.0",
"mini-svg-data-uri": "^1.4.4",
"motion": "^11.18.2",
- "next": "15.1.3",
+ "next": "^15.2.4",
"next-mdx-remote": "^5.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
@@ -363,24 +364,26 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz",
- "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz",
+ "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==",
+ "license": "MIT",
"peer": true,
"dependencies": {
- "@babel/template": "^7.26.9",
- "@babel/types": "^7.26.9"
+ "@babel/template": "^7.27.0",
+ "@babel/types": "^7.27.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz",
- "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz",
+ "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==",
+ "license": "MIT",
"dependencies": {
- "@babel/types": "^7.26.9"
+ "@babel/types": "^7.27.0"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -469,9 +472,10 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz",
- "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
+ "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
+ "license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -480,13 +484,14 @@
}
},
"node_modules/@babel/template": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz",
- "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz",
+ "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==",
+ "license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.26.2",
- "@babel/parser": "^7.26.9",
- "@babel/types": "^7.26.9"
+ "@babel/parser": "^7.27.0",
+ "@babel/types": "^7.27.0"
},
"engines": {
"node": ">=6.9.0"
@@ -518,9 +523,10 @@
}
},
"node_modules/@babel/types": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
- "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz",
+ "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==",
+ "license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"
@@ -589,12 +595,13 @@
"integrity": "sha512-IlVABlRgo9XaTR1NunwZpWcxnfEv04ba2l1vkUz4S1W7Jt36F4CtffP+jPeqBZGnAe+fnUwo0XjIJC3ZTNToNQ=="
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz",
- "integrity": "sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz",
+ "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==",
"cpu": [
"ppc64"
],
+ "license": "MIT",
"optional": true,
"os": [
"aix"
@@ -604,12 +611,13 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.0.tgz",
- "integrity": "sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz",
+ "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==",
"cpu": [
"arm"
],
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -619,12 +627,13 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz",
- "integrity": "sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz",
+ "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -634,12 +643,13 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.0.tgz",
- "integrity": "sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz",
+ "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"android"
@@ -649,12 +659,13 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz",
- "integrity": "sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz",
+ "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -664,12 +675,13 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz",
- "integrity": "sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz",
+ "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -679,12 +691,13 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz",
- "integrity": "sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz",
+ "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
@@ -694,12 +707,13 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz",
- "integrity": "sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz",
+ "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"freebsd"
@@ -709,12 +723,13 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz",
- "integrity": "sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz",
+ "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==",
"cpu": [
"arm"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -724,12 +739,13 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz",
- "integrity": "sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz",
+ "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -739,12 +755,13 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz",
- "integrity": "sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz",
+ "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==",
"cpu": [
"ia32"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -754,12 +771,13 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz",
- "integrity": "sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz",
+ "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==",
"cpu": [
"loong64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -769,12 +787,13 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz",
- "integrity": "sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz",
+ "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==",
"cpu": [
"mips64el"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -784,12 +803,13 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz",
- "integrity": "sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz",
+ "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==",
"cpu": [
"ppc64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -799,12 +819,13 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz",
- "integrity": "sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz",
+ "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==",
"cpu": [
"riscv64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -814,12 +835,13 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz",
- "integrity": "sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz",
+ "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==",
"cpu": [
"s390x"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -829,12 +851,13 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz",
- "integrity": "sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz",
+ "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -843,13 +866,30 @@
"node": ">=18"
}
},
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz",
+ "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz",
- "integrity": "sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz",
+ "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"netbsd"
@@ -859,12 +899,13 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz",
- "integrity": "sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz",
+ "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"openbsd"
@@ -874,12 +915,13 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz",
- "integrity": "sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz",
+ "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"openbsd"
@@ -889,12 +931,13 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz",
- "integrity": "sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz",
+ "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"sunos"
@@ -904,12 +947,13 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz",
- "integrity": "sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz",
+ "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -919,12 +963,13 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz",
- "integrity": "sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz",
+ "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==",
"cpu": [
"ia32"
],
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -934,12 +979,13 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz",
- "integrity": "sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz",
+ "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -1169,9 +1215,9 @@
}
},
"node_modules/@ethersproject/bytes": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz",
- "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz",
+ "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==",
"funding": [
{
"type": "individual",
@@ -1182,8 +1228,9 @@
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
+ "license": "MIT",
"dependencies": {
- "@ethersproject/logger": "^5.7.0"
+ "@ethersproject/logger": "^5.8.0"
}
},
"node_modules/@ethersproject/constants": {
@@ -1224,9 +1271,9 @@
}
},
"node_modules/@ethersproject/logger": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz",
- "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz",
+ "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==",
"funding": [
{
"type": "individual",
@@ -1236,12 +1283,13 @@
"type": "individual",
"url": "https://www.buymeacoffee.com/ricmoo"
}
- ]
+ ],
+ "license": "MIT"
},
"node_modules/@ethersproject/properties": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz",
- "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz",
+ "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==",
"funding": [
{
"type": "individual",
@@ -1252,8 +1300,9 @@
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
+ "license": "MIT",
"dependencies": {
- "@ethersproject/logger": "^5.7.0"
+ "@ethersproject/logger": "^5.8.0"
}
},
"node_modules/@ethersproject/rlp": {
@@ -1276,9 +1325,9 @@
}
},
"node_modules/@ethersproject/signing-key": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz",
- "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz",
+ "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==",
"funding": [
{
"type": "individual",
@@ -1289,34 +1338,16 @@
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
+ "license": "MIT",
"dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
+ "@ethersproject/properties": "^5.8.0",
"bn.js": "^5.2.1",
- "elliptic": "6.5.4",
+ "elliptic": "6.6.1",
"hash.js": "1.1.7"
}
},
- "node_modules/@ethersproject/signing-key/node_modules/elliptic": {
- "version": "6.5.4",
- "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
- "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
- "dependencies": {
- "bn.js": "^4.11.9",
- "brorand": "^1.1.0",
- "hash.js": "^1.0.0",
- "hmac-drbg": "^1.0.1",
- "inherits": "^2.0.4",
- "minimalistic-assert": "^1.0.1",
- "minimalistic-crypto-utils": "^1.0.1"
- }
- },
- "node_modules/@ethersproject/signing-key/node_modules/elliptic/node_modules/bn.js": {
- "version": "4.12.1",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
- "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg=="
- },
"node_modules/@ethersproject/transactions": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz",
@@ -2485,6 +2516,22 @@
"socket.io-client": "^4.5.1"
}
},
+ "node_modules/@metamask/sdk-communication-layer/node_modules/date-fns": {
+ "version": "2.30.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+ "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.21.0"
+ },
+ "engines": {
+ "node": ">=0.11"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
+ },
"node_modules/@metamask/sdk-install-modal-web": {
"version": "0.32.0",
"resolved": "https://registry.npmjs.org/@metamask/sdk-install-modal-web/-/sdk-install-modal-web-0.32.0.tgz",
@@ -2618,9 +2665,10 @@
}
},
"node_modules/@next/env": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.3.tgz",
- "integrity": "sha512-Q1tXwQCGWyA3ehMph3VO+E6xFPHDKdHFYosadt0F78EObYxPio0S09H9UGYznDe6Wc8eLKLG89GqcFJJDiK5xw=="
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-15.2.4.tgz",
+ "integrity": "sha512-+SFtMgoiYP3WoSswuNmxJOCwi06TdWE733D+WPjpXIe4LXGULwEaofiiAy6kbS0+XjM5xF5n3lKuBwN2SnqD9g==",
+ "license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
"version": "15.1.3",
@@ -2632,12 +2680,13 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.1.3.tgz",
- "integrity": "sha512-aZtmIh8jU89DZahXQt1La0f2EMPt/i7W+rG1sLtYJERsP7GRnNFghsciFpQcKHcGh4dUiyTB5C1X3Dde/Gw8gg==",
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.2.4.tgz",
+ "integrity": "sha512-1AnMfs655ipJEDC/FHkSr0r3lXBgpqKo4K1kiwfUf3iE68rDFXZ1TtHdMvf7D0hMItgDZ7Vuq3JgNMbt/+3bYw==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -2647,12 +2696,13 @@
}
},
"node_modules/@next/swc-darwin-x64": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.1.3.tgz",
- "integrity": "sha512-aw8901rjkVBK5mbq5oV32IqkJg+CQa6aULNlN8zyCWSsePzEG3kpDkAFkkTOh3eJ0p95KbkLyWBzslQKamXsLA==",
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.2.4.tgz",
+ "integrity": "sha512-3qK2zb5EwCwxnO2HeO+TRqCubeI/NgCe+kL5dTJlPldV/uwCnUgC7VbEzgmxbfrkbjehL4H9BPztWOEtsoMwew==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -2662,12 +2712,13 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.1.3.tgz",
- "integrity": "sha512-YbdaYjyHa4fPK4GR4k2XgXV0p8vbU1SZh7vv6El4bl9N+ZSiMfbmqCuCuNU1Z4ebJMumafaz6UCC2zaJCsdzjw==",
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.2.4.tgz",
+ "integrity": "sha512-HFN6GKUcrTWvem8AZN7tT95zPb0GUGv9v0d0iyuTb303vbXkkbHDp/DxufB04jNVD+IN9yHy7y/6Mqq0h0YVaQ==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2677,12 +2728,13 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.1.3.tgz",
- "integrity": "sha512-qgH/aRj2xcr4BouwKG3XdqNu33SDadqbkqB6KaZZkozar857upxKakbRllpqZgWl/NDeSCBYPmUAZPBHZpbA0w==",
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.2.4.tgz",
+ "integrity": "sha512-Oioa0SORWLwi35/kVB8aCk5Uq+5/ZIumMK1kJV+jSdazFm2NzPDztsefzdmzzpx5oGCJ6FkUC7vkaUseNTStNA==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2692,12 +2744,13 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.1.3.tgz",
- "integrity": "sha512-uzafnTFwZCPN499fNVnS2xFME8WLC9y7PLRs/yqz5lz1X/ySoxfaK2Hbz74zYUdEg+iDZPd8KlsWaw9HKkLEVw==",
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.2.4.tgz",
+ "integrity": "sha512-yb5WTRaHdkgOqFOZiu6rHV1fAEK0flVpaIN2HB6kxHVSy/dIajWbThS7qON3W9/SNOH2JWkVCyulgGYekMePuw==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2707,12 +2760,13 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.1.3.tgz",
- "integrity": "sha512-el6GUFi4SiDYnMTTlJJFMU+GHvw0UIFnffP1qhurrN1qJV3BqaSRUjkDUgVV44T6zpw1Lc6u+yn0puDKHs+Sbw==",
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.2.4.tgz",
+ "integrity": "sha512-Dcdv/ix6srhkM25fgXiyOieFUkz+fOYkHlydWCtB0xMST6X9XYI3yPDKBZt1xuhOytONsIFJFB08xXYsxUwJLw==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"linux"
@@ -2722,12 +2776,13 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.1.3.tgz",
- "integrity": "sha512-6RxKjvnvVMM89giYGI1qye9ODsBQpHSHVo8vqA8xGhmRPZHDQUE4jcDbhBwK0GnFMqBnu+XMg3nYukNkmLOLWw==",
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.2.4.tgz",
+ "integrity": "sha512-dW0i7eukvDxtIhCYkMrZNQfNicPDExt2jPb9AZPpL7cfyUo7QSNl1DjsHjmmKp6qNAqUESyT8YFl/Aw91cNJJg==",
"cpu": [
"arm64"
],
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -2737,12 +2792,13 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.1.3.tgz",
- "integrity": "sha512-VId/f5blObG7IodwC5Grf+aYP0O8Saz1/aeU3YcWqNdIUAmFQY3VEPKPaIzfv32F/clvanOb2K2BR5DtDs6XyQ==",
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.2.4.tgz",
+ "integrity": "sha512-SbnWkJmkS7Xl3kre8SdMF6F/XDh1DTFEhp0jRTj/uB8iPKoU2bb2NDfcu+iifv1+mxQEd1g2vvSxcZbXSKyWiQ==",
"cpu": [
"x64"
],
+ "license": "MIT",
"optional": true,
"os": [
"win32"
@@ -8993,9 +9049,10 @@
}
},
"node_modules/axios": {
- "version": "1.7.9",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
- "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
+ "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
+ "license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
@@ -10036,11 +10093,12 @@
"peer": true
},
"node_modules/convex": {
- "version": "1.19.2",
- "resolved": "https://registry.npmjs.org/convex/-/convex-1.19.2.tgz",
- "integrity": "sha512-rwhg5uVxFKVWf9zM8+QmpQ0MONE6FfeRoy8I/F2lZ7MIjtZyHVaIqpzmQ5ZvZFduseuBMrNy/Y9H4Olq1FlazQ==",
+ "version": "1.21.0",
+ "resolved": "https://registry.npmjs.org/convex/-/convex-1.21.0.tgz",
+ "integrity": "sha512-+peYmXSWsnnyASKI302RIlsf07gv6uHAOduBwDFLBjNZciO+kOVjQcskJwhTeNbAV59glL+tf7kvDh8PEnhmCw==",
+ "license": "Apache-2.0",
"dependencies": {
- "esbuild": "0.23.0",
+ "esbuild": "0.25.1",
"jwt-decode": "^3.1.2",
"prettier": "3.4.2"
},
@@ -10316,18 +10374,13 @@
}
},
"node_modules/date-fns": {
- "version": "2.30.0",
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
- "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
- "dependencies": {
- "@babel/runtime": "^7.21.0"
- },
- "engines": {
- "node": ">=0.11"
- },
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
+ "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
+ "license": "MIT",
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/date-fns"
+ "type": "github",
+ "url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/dayjs": {
@@ -10947,10 +11000,11 @@
}
},
"node_modules/esbuild": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.0.tgz",
- "integrity": "sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
+ "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
"hasInstallScript": true,
+ "license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
@@ -10958,30 +11012,31 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.23.0",
- "@esbuild/android-arm": "0.23.0",
- "@esbuild/android-arm64": "0.23.0",
- "@esbuild/android-x64": "0.23.0",
- "@esbuild/darwin-arm64": "0.23.0",
- "@esbuild/darwin-x64": "0.23.0",
- "@esbuild/freebsd-arm64": "0.23.0",
- "@esbuild/freebsd-x64": "0.23.0",
- "@esbuild/linux-arm": "0.23.0",
- "@esbuild/linux-arm64": "0.23.0",
- "@esbuild/linux-ia32": "0.23.0",
- "@esbuild/linux-loong64": "0.23.0",
- "@esbuild/linux-mips64el": "0.23.0",
- "@esbuild/linux-ppc64": "0.23.0",
- "@esbuild/linux-riscv64": "0.23.0",
- "@esbuild/linux-s390x": "0.23.0",
- "@esbuild/linux-x64": "0.23.0",
- "@esbuild/netbsd-x64": "0.23.0",
- "@esbuild/openbsd-arm64": "0.23.0",
- "@esbuild/openbsd-x64": "0.23.0",
- "@esbuild/sunos-x64": "0.23.0",
- "@esbuild/win32-arm64": "0.23.0",
- "@esbuild/win32-ia32": "0.23.0",
- "@esbuild/win32-x64": "0.23.0"
+ "@esbuild/aix-ppc64": "0.25.1",
+ "@esbuild/android-arm": "0.25.1",
+ "@esbuild/android-arm64": "0.25.1",
+ "@esbuild/android-x64": "0.25.1",
+ "@esbuild/darwin-arm64": "0.25.1",
+ "@esbuild/darwin-x64": "0.25.1",
+ "@esbuild/freebsd-arm64": "0.25.1",
+ "@esbuild/freebsd-x64": "0.25.1",
+ "@esbuild/linux-arm": "0.25.1",
+ "@esbuild/linux-arm64": "0.25.1",
+ "@esbuild/linux-ia32": "0.25.1",
+ "@esbuild/linux-loong64": "0.25.1",
+ "@esbuild/linux-mips64el": "0.25.1",
+ "@esbuild/linux-ppc64": "0.25.1",
+ "@esbuild/linux-riscv64": "0.25.1",
+ "@esbuild/linux-s390x": "0.25.1",
+ "@esbuild/linux-x64": "0.25.1",
+ "@esbuild/netbsd-arm64": "0.25.1",
+ "@esbuild/netbsd-x64": "0.25.1",
+ "@esbuild/openbsd-arm64": "0.25.1",
+ "@esbuild/openbsd-x64": "0.25.1",
+ "@esbuild/sunos-x64": "0.25.1",
+ "@esbuild/win32-arm64": "0.25.1",
+ "@esbuild/win32-ia32": "0.25.1",
+ "@esbuild/win32-x64": "0.25.1"
}
},
"node_modules/escalade": {
@@ -14693,11 +14748,12 @@
"dev": true
},
"node_modules/next": {
- "version": "15.1.3",
- "resolved": "https://registry.npmjs.org/next/-/next-15.1.3.tgz",
- "integrity": "sha512-5igmb8N8AEhWDYzogcJvtcRDU6n4cMGtBklxKD4biYv4LXN8+awc/bbQ2IM2NQHdVPgJ6XumYXfo3hBtErg1DA==",
+ "version": "15.2.4",
+ "resolved": "https://registry.npmjs.org/next/-/next-15.2.4.tgz",
+ "integrity": "sha512-VwL+LAaPSxEkd3lU2xWbgEOtrM8oedmyhBqaVNmgKB+GvZlCy9rgaEc+y2on0wv+l0oSFqLtYD6dcC1eAedUaQ==",
+ "license": "MIT",
"dependencies": {
- "@next/env": "15.1.3",
+ "@next/env": "15.2.4",
"@swc/counter": "0.1.3",
"@swc/helpers": "0.5.15",
"busboy": "1.6.0",
@@ -14712,14 +14768,14 @@
"node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
},
"optionalDependencies": {
- "@next/swc-darwin-arm64": "15.1.3",
- "@next/swc-darwin-x64": "15.1.3",
- "@next/swc-linux-arm64-gnu": "15.1.3",
- "@next/swc-linux-arm64-musl": "15.1.3",
- "@next/swc-linux-x64-gnu": "15.1.3",
- "@next/swc-linux-x64-musl": "15.1.3",
- "@next/swc-win32-arm64-msvc": "15.1.3",
- "@next/swc-win32-x64-msvc": "15.1.3",
+ "@next/swc-darwin-arm64": "15.2.4",
+ "@next/swc-darwin-x64": "15.2.4",
+ "@next/swc-linux-arm64-gnu": "15.2.4",
+ "@next/swc-linux-arm64-musl": "15.2.4",
+ "@next/swc-linux-x64-gnu": "15.2.4",
+ "@next/swc-linux-x64-musl": "15.2.4",
+ "@next/swc-win32-arm64-msvc": "15.2.4",
+ "@next/swc-win32-x64-msvc": "15.2.4",
"sharp": "^0.33.5"
},
"peerDependencies": {
diff --git a/package.json b/package.json
index 73e5e64..167d066 100644
--- a/package.json
+++ b/package.json
@@ -31,10 +31,11 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"convex": "^1.19.2",
+ "date-fns": "^4.1.0",
"lucide-react": "^0.469.0",
"mini-svg-data-uri": "^1.4.4",
"motion": "^11.18.2",
- "next": "15.1.3",
+ "next": "^15.2.4",
"next-mdx-remote": "^5.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
diff --git a/tailwind.config.ts b/tailwind.config.ts
index a820074..4bc576f 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -1,5 +1,6 @@
import type { Config } from "tailwindcss";
import flattenColorPalette from "tailwindcss/lib/util/flattenColorPalette";
+import plugin from "tailwindcss/plugin";
export default {
darkMode: ["class"],
@@ -10,6 +11,85 @@ export default {
],
theme: {
extend: {
+ animation: {
+ // 粒子相关动画
+ 'pulse-slow': 'pulse 8s cubic-bezier(0.4, 0, 0.6, 1) infinite',
+ 'float': 'float 10s ease-in-out infinite',
+ 'particle-1': 'particle1 15s ease-in-out infinite',
+ 'particle-2': 'particle2 20s ease-in-out infinite',
+ 'particle-3': 'particle3 18s ease-in-out infinite',
+ 'particle-4': 'particle4 25s ease-in-out infinite',
+ 'fade-in-out': 'fadeInOut 8s ease-in-out infinite',
+ 'rotate-slow': 'rotateSlow 12s linear infinite',
+
+ // 其他动画
+ "meteor-effect": "meteor 5s linear infinite",
+ "float-slow": "float 8s ease-in-out infinite",
+ "float-slower": "float 10s ease-in-out infinite",
+ "neon-sparkle": "neon-sparkle 0.6s cubic-bezier(0.4, 0, 0.6, 1)",
+
+ },
+ keyframes: {
+ // 粒子相关关键帧
+ float: {
+ '0%, 100%': { transform: 'translateY(0)' },
+ '50%': { transform: 'translateY(-10px)' },
+ },
+ particle1: {
+ '0%, 100%': { transform: 'translate(0, 0)' },
+ '25%': { transform: 'translate(20px, -15px)' },
+ '50%': { transform: 'translate(5px, 20px)' },
+ '75%': { transform: 'translate(-15px, 5px)' },
+ },
+ particle2: {
+ '0%, 100%': { transform: 'translate(0, 0)' },
+ '25%': { transform: 'translate(-15px, 10px)' },
+ '50%': { transform: 'translate(10px, -20px)' },
+ '75%': { transform: 'translate(20px, 10px)' },
+ },
+ particle3: {
+ '0%, 100%': { transform: 'translate(0, 0)' },
+ '25%': { transform: 'translate(15px, 20px)' },
+ '50%': { transform: 'translate(-10px, -15px)' },
+ '75%': { transform: 'translate(-20px, 10px)' },
+ },
+ particle4: {
+ '0%, 100%': { transform: 'translate(0, 0)' },
+ '20%': { transform: 'translate(-20px, -10px)' },
+ '40%': { transform: 'translate(15px, 10px)' },
+ '60%': { transform: 'translate(10px, -15px)' },
+ '80%': { transform: 'translate(-15px, 15px)' },
+ },
+ fadeInOut: {
+ '0%, 100%': { opacity: '0' },
+ '50%': { opacity: '1' },
+ },
+ rotateSlow: {
+ '0%': { transform: 'rotate(0deg)' },
+ '100%': { transform: 'rotate(360deg)' },
+ },
+
+ // 其他关键帧
+ meteor: {
+ "0%": { transform: "rotate(215deg) translateX(0)", opacity: "1" },
+ "70%": { opacity: "1" },
+ "100%": {
+ transform: "rotate(215deg) translateX(-500px)",
+ opacity: "0",
+ },
+ },
+ "neon-sparkle": {
+ "0%, 100%": { transform: "translateY(0) scale(1)" },
+ "50%": { transform: "translateY(200%) scale(1.5)" },
+ },
+ },
+ // 动画延迟类
+ animationDelay: {
+ '1000': '1000ms',
+ '1500': '1500ms',
+ '2000': '2000ms',
+ '3000': '3000ms',
+ },
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
@@ -224,31 +304,6 @@ export default {
xs: "calc(var(--radius) - 8px)",
xxs: "calc(var(--radius) - 10px)",
},
- animation: {
- "meteor-effect": "meteor 5s linear infinite",
- float: "float 6s ease-in-out infinite",
- "float-slow": "float 8s ease-in-out infinite",
- "float-slower": "float 10s ease-in-out infinite",
- "neon-sparkle": "neon-sparkle 0.6s cubic-bezier(0.4, 0, 0.6, 1)",
- },
- keyframes: {
- meteor: {
- "0%": { transform: "rotate(215deg) translateX(0)", opacity: "1" },
- "70%": { opacity: "1" },
- "100%": {
- transform: "rotate(215deg) translateX(-500px)",
- opacity: "0",
- },
- },
- float: {
- "0%, 100%": { transform: "translateY(0)" },
- "50%": { transform: "translateY(-20px)" },
- },
- "neon-sparkle": {
- "0%, 100%": { transform: "translateY(0) scale(1)" },
- "50%": { transform: "translateY(200%) scale(1.5)" },
- },
- },
fontFamily: {
mono: ["'Space Mono'", "monospace"],
retro: ["'VT323'", "monospace"],
@@ -380,6 +435,16 @@ export default {
require("tailwindcss-animate"),
require("@tailwindcss/typography"),
addVariablesForColors,
+ plugin(({ matchUtilities, theme }) => {
+ matchUtilities(
+ {
+ 'animation-delay': (value) => ({
+ animationDelay: value,
+ }),
+ },
+ { values: theme('animationDelay') }
+ );
+ }),
],
} satisfies Config;