├── .eslintignore ├── .eslintrc.json ├── .gitignore ├── .npmrc ├── .vscode ├── launch.json └── settings.json ├── LICENSE ├── README.md ├── components ├── icons.tsx ├── navbar.tsx ├── primitives.ts └── theme-switch.tsx ├── config ├── fonts.ts └── site.ts ├── image.png ├── layouts ├── default.tsx └── head.tsx ├── next.config.js ├── package.json ├── pages ├── _app.tsx ├── _document.tsx └── index.tsx ├── postcss.config.js ├── public └── favicon.ico ├── styles └── globals.css ├── tailwind.config.js ├── tsconfig.json ├── types └── index.ts └── util └── tron.js /.eslintignore: -------------------------------------------------------------------------------- 1 | .now/* 2 | *.css 3 | .changeset 4 | dist 5 | esm/* 6 | public/* 7 | tests/* 8 | scripts/* 9 | *.config.js 10 | .DS_Store 11 | node_modules 12 | coverage 13 | .next 14 | build 15 | !.commitlintrc.cjs 16 | !.lintstagedrc.cjs 17 | !jest.config.js 18 | !plopfile.js 19 | !react-shim.js 20 | !tsup.config.ts -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/eslintrc.json", 3 | "env": { 4 | "browser": false, 5 | "es2021": true, 6 | "node": true 7 | }, 8 | "extends": [ 9 | "plugin:react/recommended", 10 | "plugin:prettier/recommended", 11 | "plugin:react-hooks/recommended", 12 | "plugin:jsx-a11y/recommended" 13 | ], 14 | "plugins": ["react", "unused-imports", "import", "@typescript-eslint", "jsx-a11y", "prettier"], 15 | "parser": "@typescript-eslint/parser", 16 | "parserOptions": { 17 | "ecmaFeatures": { 18 | "jsx": true 19 | }, 20 | "ecmaVersion": 12, 21 | "sourceType": "module" 22 | }, 23 | "settings": { 24 | "react": { 25 | "version": "detect" 26 | } 27 | }, 28 | "rules": { 29 | "no-console": "warn", 30 | "react/prop-types": "off", 31 | "react/jsx-uses-react": "off", 32 | "react/react-in-jsx-scope": "off", 33 | "react-hooks/exhaustive-deps": "off", 34 | "jsx-a11y/click-events-have-key-events": "warn", 35 | "jsx-a11y/interactive-supports-focus": "warn", 36 | "prettier/prettier": "warn", 37 | "no-unused-vars": "off", 38 | "unused-imports/no-unused-vars": "off", 39 | "unused-imports/no-unused-imports": "warn", 40 | "@typescript-eslint/no-unused-vars": [ 41 | "warn", 42 | { 43 | "args": "after-used", 44 | "ignoreRestSiblings": false, 45 | "argsIgnorePattern": "^_.*?$" 46 | } 47 | ], 48 | "import/order": [ 49 | "warn", 50 | { 51 | "groups": [ 52 | "type", 53 | "builtin", 54 | "object", 55 | "external", 56 | "internal", 57 | "parent", 58 | "sibling", 59 | "index" 60 | ], 61 | "pathGroups": [ 62 | { 63 | "pattern": "~/**", 64 | "group": "external", 65 | "position": "after" 66 | } 67 | ], 68 | "newlines-between": "always" 69 | } 70 | ], 71 | "react/self-closing-comp": "warn", 72 | "react/jsx-sort-props": [ 73 | "warn", 74 | { 75 | "callbacksLast": true, 76 | "shorthandFirst": true, 77 | "noSortAlphabetically": false, 78 | "reservedFirst": true 79 | } 80 | ], 81 | "padding-line-between-statements": [ 82 | "warn", 83 | {"blankLine": "always", "prev": "*", "next": "return"}, 84 | {"blankLine": "always", "prev": ["const", "let", "var"], "next": "*"}, 85 | { 86 | "blankLine": "any", 87 | "prev": ["const", "let", "var"], 88 | "next": ["const", "let", "var"] 89 | } 90 | ] 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "启动程序", 11 | "skipFiles": [ 12 | "/**" 13 | ], 14 | "program": "${workspaceFolder}/util/tron.js", 15 | "outFiles": [ 16 | "${workspaceFolder}/**/*.js" 17 | ] 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Next UI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Welcome to Tron Monitor 👋

2 | 3 |

4 | Version 5 |

6 | 7 | > A front-end Tron chain transaction monitoring written in react+NextUI+next.js 8 | > ![1726688473835.png](./image.png) 9 | 10 | ## Live Demo 11 | 12 | link: [https://tronspan.netlify.app/](https://tronspan.netlify.app/) 13 | 14 | ## Install 15 | 16 | ```sh 17 | npm install 18 | ``` 19 | 20 | ## Usage 21 | 22 | ```sh 23 | npm run start 24 | ``` 25 | 26 | ## Author 27 | 28 | 👤 **Tom** 29 | 30 | - Website: http://tomcn.uk/ 31 | 32 | ## Show your support 33 | 34 | Give a ⭐️ if this project helped you! 35 | -------------------------------------------------------------------------------- /components/icons.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { IconSvgProps } from "@/types"; 4 | 5 | export const Logo: React.FC = ({ 6 | size = 36, 7 | height, 8 | ...props 9 | }) => ( 10 | 17 | 23 | 24 | ); 25 | 26 | export const DiscordIcon: React.FC = ({ 27 | size = 24, 28 | width, 29 | height, 30 | ...props 31 | }) => { 32 | return ( 33 | 39 | 43 | 44 | ); 45 | }; 46 | 47 | export const TwitterIcon: React.FC = ({ 48 | size = 24, 49 | width, 50 | height, 51 | ...props 52 | }) => { 53 | return ( 54 | 60 | 64 | 65 | ); 66 | }; 67 | 68 | export const GithubIcon: React.FC = ({ 69 | size = 24, 70 | width, 71 | height, 72 | ...props 73 | }) => { 74 | return ( 75 | 81 | 87 | 88 | ); 89 | }; 90 | 91 | export const MoonFilledIcon = ({ 92 | size = 24, 93 | width, 94 | height, 95 | ...props 96 | }: IconSvgProps) => ( 97 | 111 | ); 112 | 113 | export const SunFilledIcon = ({ 114 | size = 24, 115 | width, 116 | height, 117 | ...props 118 | }: IconSvgProps) => ( 119 | 133 | ); 134 | 135 | export const HeartFilledIcon = ({ 136 | size = 24, 137 | width, 138 | height, 139 | ...props 140 | }: IconSvgProps) => ( 141 | 158 | ); 159 | 160 | export const SearchIcon = (props: IconSvgProps) => ( 161 | 186 | ); 187 | 188 | export const NextUILogo: React.FC = (props) => { 189 | const { width, height = 40 } = props; 190 | 191 | return ( 192 | 200 | 204 | 208 | 212 | 213 | ); 214 | }; 215 | -------------------------------------------------------------------------------- /components/navbar.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Navbar as NextUINavbar, 3 | NavbarContent, 4 | NavbarMenu, 5 | NavbarMenuToggle, 6 | NavbarBrand, 7 | NavbarItem, 8 | NavbarMenuItem, 9 | } from "@nextui-org/navbar"; 10 | import { Button } from "@nextui-org/button"; 11 | import { Kbd } from "@nextui-org/kbd"; 12 | import { Link } from "@nextui-org/link"; 13 | import { Input } from "@nextui-org/input"; 14 | import { link as linkStyles } from "@nextui-org/theme"; 15 | import NextLink from "next/link"; 16 | import clsx from "clsx"; 17 | 18 | import { siteConfig } from "@/config/site"; 19 | import { ThemeSwitch } from "@/components/theme-switch"; 20 | import { 21 | TwitterIcon, 22 | GithubIcon, 23 | DiscordIcon, 24 | HeartFilledIcon, 25 | SearchIcon, 26 | Logo, 27 | } from "@/components/icons"; 28 | 29 | export const Navbar = () => { 30 | const searchInput = ( 31 | 39 | K 40 | 41 | } 42 | labelPlacement="outside" 43 | placeholder="Search..." 44 | startContent={ 45 | 46 | } 47 | type="search" 48 | /> 49 | ); 50 | 51 | return ( 52 | 53 | 54 | 55 | 56 | 57 |

ACME

58 |
59 |
60 |
61 | {siteConfig.navItems.map((item) => ( 62 | 63 | 71 | {item.label} 72 | 73 | 74 | ))} 75 |
76 |
77 |
78 | ); 79 | }; 80 | -------------------------------------------------------------------------------- /components/primitives.ts: -------------------------------------------------------------------------------- 1 | import { tv } from "tailwind-variants"; 2 | 3 | export const title = tv({ 4 | base: "tracking-tight inline font-semibold", 5 | variants: { 6 | color: { 7 | violet: "from-[#FF1CF7] to-[#b249f8]", 8 | yellow: "from-[#FF705B] to-[#FFB457]", 9 | blue: "from-[#5EA2EF] to-[#0072F5]", 10 | cyan: "from-[#00b7fa] to-[#01cfea]", 11 | green: "from-[#6FEE8D] to-[#17c964]", 12 | pink: "from-[#FF72E1] to-[#F54C7A]", 13 | foreground: "dark:from-[#FFFFFF] dark:to-[#4B4B4B]", 14 | }, 15 | size: { 16 | sm: "text-3xl lg:text-4xl", 17 | md: "text-[2.3rem] lg:text-5xl leading-9", 18 | lg: "text-4xl lg:text-6xl", 19 | }, 20 | fullWidth: { 21 | true: "w-full block", 22 | }, 23 | }, 24 | defaultVariants: { 25 | size: "md", 26 | }, 27 | compoundVariants: [ 28 | { 29 | color: [ 30 | "violet", 31 | "yellow", 32 | "blue", 33 | "cyan", 34 | "green", 35 | "pink", 36 | "foreground", 37 | ], 38 | class: "bg-clip-text text-transparent bg-gradient-to-b", 39 | }, 40 | ], 41 | }); 42 | 43 | export const subtitle = tv({ 44 | base: "w-full md:w-1/2 my-2 text-lg lg:text-xl text-default-600 block max-w-full", 45 | variants: { 46 | fullWidth: { 47 | true: "!w-full", 48 | }, 49 | }, 50 | defaultVariants: { 51 | fullWidth: true, 52 | }, 53 | }); 54 | -------------------------------------------------------------------------------- /components/theme-switch.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useState, useEffect } from "react"; 2 | import { VisuallyHidden } from "@react-aria/visually-hidden"; 3 | import { SwitchProps, useSwitch } from "@nextui-org/switch"; 4 | import { useTheme } from "next-themes"; 5 | import clsx from "clsx"; 6 | 7 | import { SunFilledIcon, MoonFilledIcon } from "@/components/icons"; 8 | 9 | export interface ThemeSwitchProps { 10 | className?: string; 11 | classNames?: SwitchProps["classNames"]; 12 | } 13 | 14 | export const ThemeSwitch: FC = ({ 15 | className, 16 | classNames, 17 | }) => { 18 | const [isMounted, setIsMounted] = useState(false); 19 | 20 | const { theme, setTheme } = useTheme(); 21 | 22 | const onChange = () => { 23 | theme === "light" ? setTheme("dark") : setTheme("light"); 24 | }; 25 | 26 | const { 27 | Component, 28 | slots, 29 | isSelected, 30 | getBaseProps, 31 | getInputProps, 32 | getWrapperProps, 33 | } = useSwitch({ 34 | isSelected: theme === "light", 35 | onChange, 36 | }); 37 | 38 | useEffect(() => { 39 | setIsMounted(true); 40 | }, [isMounted]); 41 | 42 | // Prevent Hydration Mismatch 43 | if (!isMounted) return
; 44 | 45 | return ( 46 | 56 | 57 | 58 | 59 |
78 | {isSelected ? ( 79 | 80 | ) : ( 81 | 82 | )} 83 |
84 |
85 | ); 86 | }; 87 | -------------------------------------------------------------------------------- /config/fonts.ts: -------------------------------------------------------------------------------- 1 | import { Fira_Code as FontMono, Inter as FontSans } from "next/font/google"; 2 | 3 | export const fontSans = FontSans({ 4 | subsets: ["latin"], 5 | variable: "--font-sans", 6 | }); 7 | 8 | export const fontMono = FontMono({ 9 | subsets: ["latin"], 10 | variable: "--font-mono", 11 | }); 12 | -------------------------------------------------------------------------------- /config/site.ts: -------------------------------------------------------------------------------- 1 | export type SiteConfig = typeof siteConfig; 2 | 3 | export const siteConfig = { 4 | name: "Tron Monitor", 5 | description: "Monitor transfer information", 6 | navItems: [ 7 | { 8 | label: "Home", 9 | href: "/", 10 | }, 11 | { 12 | label: "Docs", 13 | href: "/docs", 14 | }, 15 | { 16 | label: "Pricing", 17 | href: "/pricing", 18 | }, 19 | { 20 | label: "Blog", 21 | href: "/blog", 22 | }, 23 | { 24 | label: "About", 25 | href: "/about", 26 | }, 27 | ], 28 | navMenuItems: [ 29 | { 30 | label: "Profile", 31 | href: "/profile", 32 | }, 33 | { 34 | label: "Dashboard", 35 | href: "/dashboard", 36 | }, 37 | { 38 | label: "Projects", 39 | href: "/projects", 40 | }, 41 | { 42 | label: "Team", 43 | href: "/team", 44 | }, 45 | { 46 | label: "Calendar", 47 | href: "/calendar", 48 | }, 49 | { 50 | label: "Settings", 51 | href: "/settings", 52 | }, 53 | { 54 | label: "Help & Feedback", 55 | href: "/help-feedback", 56 | }, 57 | { 58 | label: "Logout", 59 | href: "/logout", 60 | }, 61 | ], 62 | links: { 63 | github: "https://github.com/CodeCat-maker/tronMonitor.git", 64 | docs: "https://github.com/CodeCat-maker/tronMonitor.git", 65 | }, 66 | }; 67 | -------------------------------------------------------------------------------- /image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeCat-maker/tronMonitor/32fb0d48a2ffef215e20ca7db5f95872121c4952/image.png -------------------------------------------------------------------------------- /layouts/default.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from "@nextui-org/link"; 2 | 3 | import { Head } from "./head"; 4 | 5 | import { Navbar } from "@/components/navbar"; 6 | 7 | export default function DefaultLayout({ 8 | children, 9 | }: { 10 | children: React.ReactNode; 11 | }) { 12 | return ( 13 |
14 | 15 | {/* */} 16 |
17 | {children} 18 |
19 |
20 | 26 | Design by 27 | Tom 28 | 29 |
30 |
31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /layouts/head.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import NextHead from "next/head"; 3 | 4 | import { siteConfig } from "@/config/site"; 5 | 6 | export const Head = () => { 7 | return ( 8 | 9 | {siteConfig.name} 10 | 11 | 12 | 13 | 18 | 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | ignoreDuringBuilds: true, 5 | } 6 | 7 | module.exports = nextConfig 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-pages-template", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev --turbo", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "eslint . --ext .ts,.tsx -c .eslintrc.json --fix" 10 | }, 11 | "dependencies": { 12 | "@nextui-org/button": "2.0.38", 13 | "@nextui-org/card": "^2.0.34", 14 | "@nextui-org/code": "2.0.33", 15 | "@nextui-org/input": "2.2.5", 16 | "@nextui-org/kbd": "2.0.34", 17 | "@nextui-org/link": "2.0.35", 18 | "@nextui-org/listbox": "2.1.27", 19 | "@nextui-org/navbar": "2.0.37", 20 | "@nextui-org/progress": "^2.0.34", 21 | "@nextui-org/snippet": "2.0.43", 22 | "@nextui-org/switch": "2.0.34", 23 | "@nextui-org/system": "2.2.6", 24 | "@nextui-org/theme": "2.2.11", 25 | "@react-aria/visually-hidden": "3.8.12", 26 | "axios": "^1.7.7", 27 | "clsx": "2.1.1", 28 | "framer-motion": "~11.1.1", 29 | "intl-messageformat": "^10.5.0", 30 | "next": "14.2.4", 31 | "next-themes": "^0.2.1", 32 | "react": "18.3.1", 33 | "react-dom": "18.3.1" 34 | }, 35 | "devDependencies": { 36 | "@types/node": "20.5.7", 37 | "@types/react": "18.3.3", 38 | "@types/react-dom": "18.3.0", 39 | "@typescript-eslint/eslint-plugin": "7.2.0", 40 | "@typescript-eslint/parser": "7.2.0", 41 | "autoprefixer": "10.4.19", 42 | "eslint": "^8.57.0", 43 | "eslint-config-prettier": "^8.2.0", 44 | "eslint-plugin-import": "^2.26.0", 45 | "eslint-plugin-jsx-a11y": "^6.4.1", 46 | "eslint-plugin-node": "^11.1.0", 47 | "eslint-plugin-prettier": "^5.1.3", 48 | "eslint-plugin-react": "^7.23.2", 49 | "eslint-plugin-react-hooks": "^4.6.0", 50 | "eslint-plugin-unused-imports": "^3.2.0", 51 | "postcss": "8.4.38", 52 | "tailwind-variants": "0.1.20", 53 | "tailwindcss": "3.4.3", 54 | "typescript": "5.0.4" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import type { AppProps } from "next/app"; 2 | 3 | import { NextUIProvider } from "@nextui-org/system"; 4 | import { ThemeProvider as NextThemesProvider } from "next-themes"; 5 | import { useRouter } from "next/router"; 6 | 7 | import { fontSans, fontMono } from "@/config/fonts"; 8 | import "@/styles/globals.css"; 9 | 10 | export default function App({ Component, pageProps }: AppProps) { 11 | const router = useRouter(); 12 | 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | } 21 | 22 | export const fonts = { 23 | sans: fontSans.style.fontFamily, 24 | mono: fontMono.style.fontFamily, 25 | }; 26 | -------------------------------------------------------------------------------- /pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from "next/document"; 2 | import clsx from "clsx"; 3 | 4 | import { fontSans } from "@/config/fonts"; 5 | 6 | export default function Document() { 7 | return ( 8 | 9 | 10 | 16 |
17 | 18 | 19 | 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | import { Link } from "@nextui-org/link"; 3 | import { Input } from "@nextui-org/input"; 4 | import { button as buttonStyles } from "@nextui-org/theme"; 5 | import { Progress } from "@nextui-org/progress"; 6 | import { siteConfig } from "@/config/site"; 7 | import { title, subtitle } from "@/components/primitives"; 8 | import { GithubIcon } from "@/components/icons"; 9 | import { fetchTronTransactions } from "@/util/tron"; 10 | import DefaultLayout from "@/layouts/default"; 11 | import { Card, CardBody } from "@nextui-org/card"; 12 | import { Button } from "@nextui-org/button"; 13 | 14 | export default function IndexPage() { 15 | const [address, setAddress] = useState(""); // 存储用户输入的地址 16 | const [transactions, setTransactions] = useState([]); 17 | const [loading, setLoading] = useState(false); 18 | const [progress, setProgress] = useState(0); // 进度条百分比 19 | const [isMonitoring, setIsMonitoring] = useState(false); // 控制是否显示倒计时 20 | 21 | const fetchTransactions = async () => { 22 | if (!address) { 23 | alert("Please enter a valid address"); 24 | return; 25 | } 26 | setLoading(true); 27 | try { 28 | const data = await fetchTronTransactions(address); // 使用输入的地址 29 | setTransactions(data); 30 | } catch (error) { 31 | console.error("Error fetching transactions", error); 32 | } finally { 33 | setLoading(false); 34 | } 35 | }; 36 | 37 | const handleMonitorClick = () => { 38 | setIsMonitoring(true); // 开始监控并显示进度条 39 | setProgress(0); // 重置进度条 40 | }; 41 | 42 | useEffect(() => { 43 | let intervalId:NodeJS.Timeout | undefined; 44 | if (isMonitoring) { 45 | let progressValue = 0; 46 | intervalId = setInterval(() => { 47 | if (progressValue >= 100) { 48 | fetchTransactions(); // 进度条满后获取数据 49 | setProgress(0); // 重置进度条 50 | progressValue = 0; 51 | } else { 52 | progressValue += 20; // 每秒增加 20% 53 | setProgress(progressValue); 54 | } 55 | }, 1000); // 每秒更新一次进度 56 | } 57 | 58 | return () => clearInterval(intervalId); // 清除定时器 59 | }, [isMonitoring]); 60 | 61 | return ( 62 | 63 |
64 |
65 | Tron  66 | 监控  67 |
68 | 69 | Monitor transfer information 70 | 71 |
72 | Fast, Safe, and Powerful 73 |
74 |
75 | 76 |
77 | 86 | Documentation 87 | 88 | 93 | 94 | GitHub 95 | 96 |
97 | 98 |
99 |
100 | setAddress(e.target.value)} // 输入变化时更新状态 107 | /> 108 | 118 |
119 |
120 |
121 | 122 | {isMonitoring && ( 123 |
124 | 125 | {/*

{5 - progress / 20} seconds remaining...

*/} 126 |
127 | )} 128 | 129 |
130 | {transactions.length > 0 && ( 131 |
132 | {transactions.map((transaction) => ( 133 | 134 | 135 |
136 |
137 | 140 | {transaction.from_address} 141 | 144 | {transaction.to_address} 145 |
146 |
147 | Transaction amount:{" "} 148 | {transaction.quant / 1000000}{" "} 149 | {transaction.tokenInfo.tokenAbbr} 150 |
151 |
152 | {new Date(transaction.block_ts).toLocaleString()} 153 |
154 |
155 |
156 |
157 | ))} 158 |
159 | )} 160 |
161 |
162 | ); 163 | } -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeCat-maker/tronMonitor/32fb0d48a2ffef215e20ca7db5f95872121c4952/public/favicon.ico -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | import {nextui} from '@nextui-org/theme' 2 | 3 | /** @type {import('tailwindcss').Config} */ 4 | module.exports = { 5 | content: [ 6 | './layouts/**/*.{js,ts,jsx,tsx,mdx}', 7 | './pages/**/*.{js,ts,jsx,tsx,mdx}', 8 | './components/**/*.{js,ts,jsx,tsx,mdx}', 9 | './node_modules/@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}', 10 | ], 11 | theme: { 12 | extend: { 13 | fontFamily: { 14 | sans: ["var(--font-sans)"], 15 | mono: ["var(--font-mono)"], 16 | }, 17 | }, 18 | }, 19 | darkMode: "class", 20 | plugins: [nextui()], 21 | } 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "paths": { 18 | "@/*": ["./*"] 19 | } 20 | }, 21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /types/index.ts: -------------------------------------------------------------------------------- 1 | import { SVGProps } from "react"; 2 | 3 | export type IconSvgProps = SVGProps & { 4 | size?: number; 5 | }; 6 | -------------------------------------------------------------------------------- /util/tron.js: -------------------------------------------------------------------------------- 1 | const axios = require("axios"); 2 | 3 | async function fetchTronTransactions(address) { 4 | 5 | const apiUrl = `https://apilist.tronscanapi.com/api/filter/trc20/transfers?limit=20&start=0&sort=-timestamp&count=true&filterTokenValue=0&relatedAddress=${address}`; // Tron API URL 6 | 7 | const response = await axios.get(apiUrl); 8 | if (response.status !== 200) { 9 | throw new Error(`请求失败: ${response.status}`); 10 | } 11 | // console.log(response.data); 12 | const data = response.data; 13 | return data.token_transfers; 14 | } 15 | 16 | 17 | export { fetchTronTransactions }; --------------------------------------------------------------------------------