Skip to content

Add real-time tokenomics dashboard#3

Open
dcccrypto wants to merge 2 commits intomainfrom
codex/create-tokenomics-transparency-page
Open

Add real-time tokenomics dashboard#3
dcccrypto wants to merge 2 commits intomainfrom
codex/create-tokenomics-transparency-page

Conversation

@dcccrypto
Copy link
Owner

@dcccrypto dcccrypto commented Jul 7, 2025

Summary

  • add Tokenomics page with live Solana data
  • fetch market cap and social metrics for progress tracking
  • include Telegram member count API
  • update Navbar to link to new Tokenomics section

Testing

  • npm run lint (fails: next not found)
  • npm run build (fails: next not found)

https://chatgpt.com/codex/tasks/task_e_686b2b4e5dec832cbf9803e40718c354

Summary by CodeRabbit

  • New Features

    • Introduced a Tokenomics page displaying live GUDTEK token metrics, including supply, burned tokens, team wallet balances, market cap, and social stats.
    • Added a burn countdown feature that tracks market cap milestones and triggers a token burn when thresholds are met.
    • Included a pie chart, tables, and progress bars for visualizing token distribution and social goals.
    • Implemented live updates for social metrics such as Twitter followers, token holders, and Telegram members.
  • Chores

    • Added a "Tokenomics" link to the main navigation menu.

@vercel
Copy link

vercel bot commented Jul 7, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
gudtek ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 7, 2025 2:38am
gudtek-82ta ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 7, 2025 2:38am

@coderabbitai
Copy link

coderabbitai bot commented Jul 7, 2025

Walkthrough

A new API endpoint was added to fetch Telegram channel member counts, and a comprehensive Tokenomics page was implemented as a React component, displaying live Solana token metrics, wallet balances, social stats, and burn countdowns. The Navbar was updated to include a link to the new Tokenomics page.

Changes

File(s) Change Summary
app/api/telegram-members/route.ts Added an API route with an async GET handler to fetch and parse Telegram member count.
app/tokenomics/page.tsx Introduced a React component to display live tokenomics, team wallet balances, social stats, and burns.
components/Navbar.tsx Added a "Tokenomics" navigation link to the Navbar items.

Poem

In the warren of code, a new page appears,
Counting tokens, burns, and bunny cheers.
Telegram members tallied with care,
Team wallets and charts—transparency to share!
The Navbar now points to this burrow so bright,
Where numbers and rabbits hop into the light.
🥕✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
app/tokenomics/page.tsx (1)

114-131: Consider extracting burn countdown logic for better maintainability.

The burn countdown logic is complex and could benefit from extraction into separate functions with clear names.

const BURN_HOLD_DURATION_MS = 24 * 60 * 60 * 1000 // 24 hours
const BURN_THRESHOLD_INCREMENT = 100_000 // $100k
const MAX_BURN_THRESHOLD = 1_000_000 // $1M

function getCurrentThreshold(marketCap: number): number {
  const thresholds = Array.from(
    { length: 10 }, 
    (_, i) => BURN_THRESHOLD_INCREMENT * (i + 1)
  )
  return thresholds.find(t => marketCap < t) || MAX_BURN_THRESHOLD
}

function getBurnCountdownMs(holdStart: number | null): number {
  if (!holdStart) return 0
  return Math.max(0, BURN_HOLD_DURATION_MS - (Date.now() - holdStart))
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ce0f14a and f71460f.

📒 Files selected for processing (3)
  • app/api/telegram-members/route.ts (1 hunks)
  • app/tokenomics/page.tsx (1 hunks)
  • components/Navbar.tsx (1 hunks)
🧰 Additional context used
🪛 Gitleaks (8.26.0)
app/tokenomics/page.tsx

13-13: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (1)
components/Navbar.tsx (1)

26-27: LGTM!

The new "Tokenomics" navigation item is properly integrated into the existing navigation structure.

Comment on lines +1 to +11
export async function GET() {
try {
const res = await fetch('https://t.me/gudteksolana', { next: { revalidate: 3600 } })
const text = await res.text()
const match = text.match(/tgme_page_extra[^>]*>([^<]+) members/)
const count = match ? parseInt(match[1].replace(/[^0-9]/g, '')) : 0
return Response.json({ count })
} catch (err) {
return Response.json({ count: 0 })
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider using a more reliable approach than HTML scraping.

Web scraping is fragile and may break when Telegram updates their HTML structure. Additionally, this approach might violate Telegram's terms of service.

Consider these alternatives:

  1. Use the official Telegram Bot API to get channel member count
  2. Add response status validation before parsing
  3. Log errors for debugging purposes

🌐 Web query:

How to get Telegram channel member count using Telegram Bot API?

💡 Result:

To get the member count of a Telegram channel using the Telegram Bot API, you should use the getChatMemberCount method. This provides the total number of members in a channel or group, but does not return a list of user IDs or personal data—only the total count.

Steps to Get Telegram Channel Member Count

  1. Create and add your bot as an admin to the channel (if it’s a private channel, the bot must have permission to see member info).

  2. Obtain your bot token from BotFather.

  3. Make an HTTP GET request to the following endpoint, replacing <TOKEN> with your bot’s token and <CHANNEL_ID> with the username (for public channels) or the full unique channel ID (for private channels):

    https://api.telegram.org/bot<TOKEN>/getChatMemberCount?chat_id=<CHANNEL_ID>
    
    • For example, for a channel with username @example_channel:
      https://api.telegram.org/bot123456789:ABCdefGhIJKlmnoPQRstuVWXyz/getChatMemberCount?chat_id=@example_channel
      
  4. Parse the response: The API will return a JSON object with a result field containing the member count.

Example Response

{
  "ok": true,
  "result": 1523
}

Here, 1523 is the current member count of the channel.

Sample code using JavaScript (fetch):

fetch('https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getChatMemberCount?chat_id=@your_channel_username')
  .then(response => response.json())
  .then(data => {
    console.log('Member count:', data.result);
  });

[1][4][8][10]

Notes and Limitations

  • This method returns only the member count, not the list of members or any identifying info, due to Telegram’s privacy policy[4][8].
  • The bot must be an admin in the channel to use this method in private channels. For public channels, being a member is often sufficient[1].
  • Historical or detailed user information is not accessible via the Bot API; you can only track new join/leave events as they happen, and must store that data yourself if needed[4].
  • If you require deeper analytics or historical data, consider third-party analytics bots like @TGStat_Bot or platforms like TGStat or Combot, but these also face the same privacy limitations for user lists and only provide aggregate statistics[5][7].

In summary:
To get the Telegram channel member count using the Bot API, use the getChatMemberCount method with your bot’s token and the channel’s identifier[1][4][8][10].

Citations:


Use the Telegram Bot API’s getChatMemberCount instead of HTML scraping

Switching to the official Bot API will be far more reliable—and compliant—than parsing Telegram’s page markup.

Key updates for app/api/telegram-members/route.ts (lines 1–11):

  • Pull your bot token and channel identifier from environment variables
  • Call getChatMemberCount via https://api.telegram.org/bot/getChatMemberCount?chat_id=<CHANNEL_ID>
  • Validate both the HTTP status and the API’s ok field before reading result
  • Log errors instead of silently swallowing them
  • Return proper HTTP status codes on failure

Suggested replacement snippet:

export async function GET() {
  const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
  const CHAT_ID  = process.env.TELEGRAM_CHANNEL_ID;
  if (!BOT_TOKEN || !CHAT_ID) {
    console.error('Missing TELEGRAM_BOT_TOKEN or TELEGRAM_CHANNEL_ID');
    return Response.json({ count: 0 }, { status: 500 });
  }

  try {
    const res = await fetch(
      `https://api.telegram.org/bot${BOT_TOKEN}/getChatMemberCount?chat_id=${CHAT_ID}`
    );
    if (!res.ok) throw new Error(`Telegram API responded ${res.status}`);
    const payload = await res.json();
    if (!payload.ok) throw new Error(`Telegram API error: ${JSON.stringify(payload)}`);
    return Response.json({ count: payload.result });
  } catch (err) {
    console.error('Failed to fetch Telegram member count:', err);
    return Response.json({ count: 0 }, { status: 500 });
  }
}

– Ensure your bot is added as an admin (private channels) or a member (public channels).
– Store TELEGRAM_BOT_TOKEN and TELEGRAM_CHANNEL_ID securely (e.g. in your environment or secrets manager).
– Remove the old HTML‐scraping logic entirely.

🤖 Prompt for AI Agents
In app/api/telegram-members/route.ts lines 1 to 11, replace the current HTML
scraping logic with a call to the Telegram Bot API's getChatMemberCount
endpoint. Retrieve the bot token and channel ID from environment variables,
validate their presence, and use them to construct the API request URL. Check
both the HTTP response status and the API's 'ok' field before extracting the
member count from the 'result' field. Log any errors encountered and return
appropriate HTTP status codes on failure. Remove all existing HTML parsing code
and ensure the bot has the necessary permissions in the channel.

Comment on lines +92 to +105
try {
const tgRes = await fetch('/api/telegram-members')
const tgJson = await tgRes.json()
telegram = tgJson?.count || 0
} catch {}

setGoals([
{ name: 'Twitter Followers', target: 10000, value: followers, burn: 0.5 },
{ name: 'Token Holders', target: 5000, value: holders },
{ name: 'Telegram Members', target: 2000, value: telegram }
])
} catch (err) {
console.error('Failed to fetch social metrics', err)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling and user feedback.

Empty catch blocks and console-only error logging provide poor user experience. Users should know when data fails to load.

Add proper error handling:

+  const [loading, setLoading] = useState(true)
+  const [errors, setErrors] = useState<string[]>([])

   let telegram = 0
   try {
     const tgRes = await fetch('/api/telegram-members')
     const tgJson = await tgRes.json()
     telegram = tgJson?.count || 0
-  } catch {}
+  } catch (err) {
+    console.error('Failed to fetch Telegram members', err)
+    setErrors(prev => [...prev, 'Failed to load Telegram data'])
+  }

Display errors in the UI:

{errors.length > 0 && (
  <div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
    {errors.map((error, i) => <p key={i}>{error}</p>)}
  </div>
)}
🤖 Prompt for AI Agents
In app/tokenomics/page.tsx around lines 92 to 105, the current error handling
uses empty catch blocks and only logs errors to the console, which does not
inform users of failures. Modify the code to capture errors in a state variable
(e.g., an errors array) and update this state when fetches fail. Then, update
the UI to conditionally render an error message block displaying these errors so
users receive clear feedback when data fails to load.

import Link from 'next/link'

const INITIAL_SUPPLY = 1_000_000_000 // 1B tokens
const RPC_URL = 'https://mainnet.helius-rpc.com/?api-key=e568033d-06d6-49d1-ba90-b3564c91851b'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Remove hardcoded API key from frontend code.

The Helius API key is exposed in the client-side code, making it visible to anyone who views the page source. This is a serious security vulnerability.

Move the API key to a server-side environment variable and proxy RPC calls through your backend API.

-const RPC_URL = 'https://mainnet.helius-rpc.com/?api-key=e568033d-06d6-49d1-ba90-b3564c91851b'
+const RPC_URL = '/api/solana-rpc' // Proxy through your backend

Create a new API route to handle Solana RPC calls securely:

// app/api/solana-rpc/route.ts
export async function POST(request: Request) {
  const body = await request.json()
  const response = await fetch(process.env.HELIUS_RPC_URL!, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body)
  })
  return response
}
🧰 Tools
🪛 Gitleaks (8.26.0)

13-13: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
In app/tokenomics/page.tsx at line 13, the Helius API key is hardcoded in the
frontend code, exposing it publicly. Remove the API key from this file and
instead create a new backend API route (e.g., app/api/solana-rpc/route.ts) that
proxies RPC calls to the Helius endpoint using the API key stored securely in an
environment variable. Update the frontend to send RPC requests to this new
backend route, ensuring the API key is never exposed client-side.

Comment on lines +83 to +89
const twRes = await fetch('https://cdn.syndication.twimg.com/widgets/followbutton/info.json?screen_names=gudtek_solana')
const twJson = await twRes.json()
const followers = twJson?.[0]?.followers_count || 0

const holdersRes = await fetch('https://public-api.solscan.io/token/holders?tokenAddress=5QUgMieD3YQr9sEZjMAHKs1cKJiEhnvRNZatvzvcbonk&offset=0&limit=1')
const holdersJson = await holdersRes.json()
const holders = holdersJson?.total || 0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify reliability of external APIs.

Using unofficial Twitter CDN endpoint and public APIs without rate limit handling could cause issues.

Consider:

  1. Implementing retry logic with exponential backoff
  2. Caching responses to reduce API calls
  3. Adding fallback values when APIs are unavailable
  4. Moving these calls to your backend to better handle rate limits

🏁 Script executed:

#!/bin/bash
# Check if these API endpoints are publicly documented
curl -I "https://cdn.syndication.twimg.com/widgets/followbutton/info.json?screen_names=gudtek_solana" | head -n 20
curl -I "https://public-api.solscan.io/token/holders?tokenAddress=5QUgMieD3YQr9sEZjMAHKs1cKJiEhnvRNZatvzvcbonk&offset=0&limit=1" | head -n 20

Length of output: 1726


Improve reliability of external API calls in app/tokenomics/page.tsx

Both endpoints were tested—Twitter’s CDN returns HTTP 200 but is unofficial, and Solscan’s public API currently returns HTTP 404—so without proper handling these calls will break the page.

Please update lines 83–89 to:

  • Wrap each fetch in try/catch and verify response.ok before calling .json()
  • Implement retry logic with exponential backoff for transient errors
  • Cache successful responses (e.g. in-memory or edge cache) to reduce outbound requests
  • Provide sensible fallback values or UI placeholders when the APIs fail
  • (Optional) Move these calls to a backend endpoint to better manage rate limits and hide implementation details

Example diff:

- const twRes = await fetch('https://cdn.syndication.twimg.com/widgets/followbutton/info.json?screen_names=gudtek_solana')
- const twJson = await twRes.json()
- const followers = twJson?.[0]?.followers_count || 0
+ let followers = 0
+ try {
+   const twRes = await fetch(TWITTER_INFO_URL)
+   if (twRes.ok) {
+     const [twJson] = await twRes.json()
+     followers = twJson?.followers_count ?? 0
+   } else {
+     console.warn('Twitter fetch failed:', twRes.status)
+   }
+ } catch (err) {
+   console.error('Error fetching Twitter data', err)
+ }

Apply similar patterns for the Solscan call.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In app/tokenomics/page.tsx around lines 83 to 89, the fetch calls to external
APIs lack error handling and retries, risking page breakage on failure. Wrap
each fetch in try/catch blocks, check response.ok before parsing JSON, and
implement retry logic with exponential backoff for transient errors. Cache
successful responses to minimize repeated requests and provide fallback values
or UI placeholders if calls fail. Optionally, consider moving these API calls to
a backend endpoint for better rate limit management and security.

Comment on lines +51 to +59
const updatedWallets = [] as typeof TEAM_WALLETS
let teamTotal = 0
for (const w of TEAM_WALLETS) {
const bal = await getGudtekBalance(w.address)
teamTotal += bal
updatedWallets.push({ ...w, balance: bal })
}
setTeamPercent((teamTotal / INITIAL_SUPPLY) * 100)
setWallets(updatedWallets as any)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix type safety issues with wallet balances.

Avoid using any type casting. Define proper types for wallets with balances.

Add proper type definitions:

+type WalletWithBalance = {
+  name: string
+  address: string
+  balance?: number
+}

-  const [wallets, setWallets] = useState<typeof TEAM_WALLETS>([])
+  const [wallets, setWallets] = useState<WalletWithBalance[]>([])

   // In fetchData function:
-  const updatedWallets = [] as typeof TEAM_WALLETS
+  const updatedWallets: WalletWithBalance[] = []
   
   // Remove the any cast:
-  setWallets(updatedWallets as any)
+  setWallets(updatedWallets)
🤖 Prompt for AI Agents
In app/tokenomics/page.tsx around lines 51 to 59, avoid using 'any' when setting
updated wallets which causes type safety issues. Define a proper type or
interface that extends the TEAM_WALLETS type to include the balance property,
then use this type for updatedWallets and in the setWallets call to ensure type
safety without casting to 'any'.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
app/tokenomics/page.tsx (1)

1-10: Consider past review feedback about this file.

Based on previous reviews, this file previously had API calls and security issues that have been addressed by moving to hardcoded data.

The current implementation uses hardcoded data instead of live API calls, which resolves the security and error handling concerns mentioned in previous reviews.

🧹 Nitpick comments (2)
app/tokenomics/page.tsx (2)

28-31: Consider moving hardcoded simulation values to constants.

The market cap simulation values are embedded in the component logic, making them hard to modify and test.

+const SIMULATION_CONFIG = {
+  MARKET_CAP: 450_000,
+  NEXT_THRESHOLD: 500_000,
+  HOLD_START_HOURS_AGO: 12
+}

 export default function TokenomicsPage() {
   const [now, setNow] = useState(Date.now())
-  // pretend the market cap recently crossed $400k
-  const marketCap = 450_000
-  const nextThreshold = 500_000
-  const holdStart = Date.now() - 12 * 60 * 60 * 1000 // halfway through 24h hold
+  const marketCap = SIMULATION_CONFIG.MARKET_CAP
+  const nextThreshold = SIMULATION_CONFIG.NEXT_THRESHOLD
+  const holdStart = Date.now() - SIMULATION_CONFIG.HOLD_START_HOURS_AGO * 60 * 60 * 1000

88-97: Add error handling for wallet balance calculations.

The percentage calculations could benefit from additional safety checks.

                  <TableCell className="font-bold">{w.name}</TableCell>
                  <TableCell>{formatTokenBalance(w.balance)}</TableCell>
-                  <TableCell>{((w.balance / INITIAL_SUPPLY) * 100).toFixed(3)}%</TableCell>
+                  <TableCell>
+                    {INITIAL_SUPPLY > 0 
+                      ? ((w.balance / INITIAL_SUPPLY) * 100).toFixed(3) + '%'
+                      : 'N/A'
+                    }
+                  </TableCell>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f71460f and f021a0d.

📒 Files selected for processing (1)
  • app/tokenomics/page.tsx (1 hunks)

<p className="mb-2">Current Market Cap: ${marketCap.toLocaleString()}</p>
<p className="mb-2">Threshold: ${nextThreshold.toLocaleString()}</p>
<div className="space-y-1">
<Progress value={countdownPct * 100} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect progress calculation.

The progress value is being multiplied by 100, but the Progress component typically expects values between 0-100, not 0-10000.

-            <Progress value={countdownPct * 100} />
+            <Progress value={countdownPct} />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Progress value={countdownPct * 100} />
<Progress value={countdownPct} />
🤖 Prompt for AI Agents
In app/tokenomics/page.tsx at line 134, the Progress component's value is
incorrectly multiplied by 100, resulting in values up to 10000 instead of the
expected 0-100 range. Remove the multiplication by 100 and pass countdownPct
directly to the Progress value prop to fix the progress calculation.

const countdown = Math.max(0, 24 * 60 * 60 * 1000 - (now - holdStart))
const countdownPct = ((24 * 60 * 60 * 1000 - countdown) / (24 * 60 * 60 * 1000)) * 100

const burnedTokens = 150_000_000
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider making burned tokens dynamic.

The burned tokens value is hardcoded, but the PR mentions displaying "live data from the Solana blockchain."

Is this hardcoded value intentional for the initial implementation, or should it fetch live burn data from the blockchain?


🏁 Script executed:

#!/bin/bash
# Check if there are other components or API routes that might handle live token data
fd -e tsx -e ts | xargs rg -l "burn.*token|token.*burn" | head -10

Length of output: 193


🏁 Script executed:

#!/bin/bash
# Inspect the API route handling token burns to see if it provides live burn data
cat app/api/game/burn-tokens/route.ts

Length of output: 7728


Implement dynamic burned tokens on the tokenomics page
The magic number 150_000_000 is currently a placeholder. To align with “live data from the Solana blockchain,” you’ll need to replace that hard-coded value with a call to an endpoint that returns the total burned GUDTEK supply—your existing POST /api/game/burn-tokens only verifies individual transactions, it doesn’t aggregate the global burn.

Next steps:

  • Add or extend an API route (e.g. GET /api/game/total-burned) that:
    • Connects to Solana (via @solana/web3.js) to fetch the token mint’s supply and compute burned tokens since initial supply,
    • Or indexes burn instructions program-wide (e.g., via a subgraph or on-chain scan).
  • In app/tokenomics/page.tsx (around line 41), fetch this new endpoint on the server or client, handle loading/error states, and render the returned value instead of 150_000_000.

Location to update:
• app/tokenomics/page.tsx – replace

const burnedTokens = 150_000_000

with a dynamic fetch to your total-burned API.

🤖 Prompt for AI Agents
In app/tokenomics/page.tsx at line 41, replace the hard-coded burnedTokens value
of 150_000_000 with a dynamic fetch from a new or extended API endpoint (e.g.,
GET /api/game/total-burned) that returns the total burned GUDTEK tokens.
Implement this API route to connect to Solana using @solana/web3.js or an
indexing method to calculate the burned tokens from the token mint supply. Then,
in the page component, fetch this data on the server or client side, manage
loading and error states, and render the fetched burned token value instead of
the static number.

<div className="bg-white/30 rounded-xl border-2 border-gray-900 p-4 shadow-xl">
<ResponsiveContainer width="100%" height={260}>
<PieChart>
<Pie data={pieData} dataKey="value" nameKey="name" innerRadius={60} outerRadius={100} label>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve pie chart accessibility.

The pie chart lacks proper accessibility attributes for screen readers.

-              <Pie data={pieData} dataKey="value" nameKey="name" innerRadius={60} outerRadius={100} label>
+              <Pie 
+                data={pieData} 
+                dataKey="value" 
+                nameKey="name" 
+                innerRadius={60} 
+                outerRadius={100} 
+                label
+                aria-label="Token distribution chart"
+              >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<Pie data={pieData} dataKey="value" nameKey="name" innerRadius={60} outerRadius={100} label>
<Pie
data={pieData}
dataKey="value"
nameKey="name"
innerRadius={60}
outerRadius={100}
label
aria-label="Token distribution chart"
>
🤖 Prompt for AI Agents
In app/tokenomics/page.tsx at line 66, the Pie chart component lacks
accessibility attributes for screen readers. Add appropriate ARIA attributes
such as aria-label or aria-labelledby to describe the chart, and ensure the
label prop is properly configured to provide accessible labels for each slice.
This will improve screen reader support and overall accessibility.

Comment on lines +13 to +18
const TEAM_WALLETS = [
{ name: 'Treasury', address: '3xmpZy4SFCp6wzqgk4Mh7jg1yF3ggvG5Xqkt3F9CEbLj', balance: 250_000_000 },
{ name: 'Operations', address: 'CXcG8pN7fT9VqgaJcfH8YzjzD4xfH14RJCdxu2YgSUn9', balance: 50_000_000 },
{ name: 'Marketing', address: '4HwME8YgUCnYJdeL9N2qHcNXTc3swaP42gnikLzeGWih', balance: 30_000_000 },
{ name: 'Liquidity', address: 'HkENe7A1Ji4VwWUvDdDhcW7UZ5EKeosFVJeFt3PcTJSd', balance: 120_000_000 }
]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Validate team wallet data structure.

The team wallets contain addresses that should be verified as valid Solana addresses.


🏁 Script executed:

#!/bin/bash
# Check if these addresses follow Solana address format (base58, 32-44 characters)
echo "Validating Solana addresses:"
echo "3xmpZy4SFCp6wzqgk4Mh7jg1yF3ggvG5Xqkt3F9CEbLj" | wc -c
echo "CXcG8pN7fT9VqgaJcfH8YzjzD4xfH14RJCdxu2YgSUn9" | wc -c  
echo "4HwME8YgUCnYJdeL9N2qHcNXTc3swaP42gnikLzeGWih" | wc -c
echo "HkENe7A1Ji4VwWUvDdDhcW7UZ5EKeosFVJeFt3PcTJSd" | wc -c

Length of output: 318


Validate team wallet addresses using Solana PublicKey

The length check shows each string is 45 bytes (including newline), which implies a 44-character base58 string—the upper limit for Solana keys—but length alone doesn’t guarantee validity. Please enforce proper address validation and typing:

• Import and use PublicKey from @solana/web3.js so invalid strings throw at build/runtime.
• Change the address: string entries to address: PublicKey.
• Optionally add a Jest (or preferred framework) test that iterates TEAM_WALLETS and asserts new PublicKey(addr) doesn’t throw.

Example diff:

--- app/tokenomics/page.tsx
+++ app/tokenomics/page.tsx
@@ lines 13-18
- const TEAM_WALLETS = [
-   { name: 'Treasury',  address: '3xmpZy4SFCp6wzqgk4Mh7jg1yF3ggvG5Xqkt3F9CEbLj', balance: 250_000_000 },
+ import { PublicKey } from '@solana/web3.js'
+
+ const TEAM_WALLETS: { name: string; address: PublicKey; balance: number }[] = [
+   { name: 'Treasury',  address: new PublicKey('3xmpZy4SFCp6wzqgk4Mh7jg1yF3ggvG5Xqkt3F9CEbLj'), balance: 250_000_000 },

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In app/tokenomics/page.tsx around lines 13 to 18, the team wallet addresses are
currently plain strings validated only by length, which is insufficient. Import
PublicKey from @solana/web3.js and replace the address string values with
PublicKey instances by wrapping each address string in new PublicKey(). Update
the type of address to PublicKey accordingly. Additionally, create a test that
iterates over TEAM_WALLETS and asserts that constructing a new PublicKey with
each address does not throw an error to ensure validity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant