From d39dd9e40882591aee9665d7e1751ef1ef4e4a9e Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 23 Mar 2026 09:58:23 +0000 Subject: [PATCH 1/3] [#448] Add PLOT Token Page (/token) - Hero section with wallet balance - Token utility: reserve token, TVL growth, creator royalties - How to get PLOT: Mint Club, sell story tokens, Zap - Token information: total supply, network, contract address - Links to Mint Club, Hunt Town, BaseScan - Copy contract address button - Mobile responsive, matches Moleskine design Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/token/page.tsx | 214 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 src/app/token/page.tsx diff --git a/src/app/token/page.tsx b/src/app/token/page.tsx new file mode 100644 index 00000000..8b8d3a95 --- /dev/null +++ b/src/app/token/page.tsx @@ -0,0 +1,214 @@ +"use client"; + +import { useAccount, useReadContract } from "wagmi"; +import { formatUnits, erc20Abi } from "viem"; +import { useState } from "react"; +import { + PLOT_TOKEN, MCV2_BOND, EXPLORER_URL, +} from "../../../lib/contracts/constants"; + +const BASESCAN_URL = `${EXPLORER_URL}/token/${PLOT_TOKEN}`; +const MINT_CLUB_URL = "https://mint.club/token/base/PLOT"; +const HUNT_TOWN_URL = "https://hunt.town/project/PLOT"; + +export default function TokenPage() { + const { address, isConnected } = useAccount(); + const [copied, setCopied] = useState(false); + + const { data: balance, isLoading: balanceLoading } = useReadContract({ + address: PLOT_TOKEN, + abi: erc20Abi, + functionName: "balanceOf", + args: address ? [address] : undefined, + query: { enabled: !!address }, + }); + + const { data: totalSupply, isLoading: supplyLoading } = useReadContract({ + address: PLOT_TOKEN, + abi: erc20Abi, + functionName: "totalSupply", + }); + + const formattedBalance = balance ? formatUnits(balance, 18) : "0"; + const formattedSupply = totalSupply ? formatUnits(totalSupply, 18) : "0"; + + const handleCopyAddress = async () => { + try { + await navigator.clipboard.writeText(PLOT_TOKEN); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch {} + }; + + return ( +
+ {/* Page Title */} +
+

$PLOT Token

+

The reserve token behind every story on PlotLink

+
+ + {/* Your Balance */} +
+
+

Your Balance

+ {isConnected && ( +
+
+ Connected +
+ )} +
+ + {!isConnected ? ( +
+

Connect your wallet to view balance

+
+ ) : balanceLoading ? ( +
+

Loading...

+
+ ) : ( +
+
+ {parseFloat(formattedBalance).toLocaleString(undefined, { + minimumFractionDigits: 0, + maximumFractionDigits: 2, + })}{" "} + PLOT +
+
+ )} +
+ + {/* Token Utility */} +
+

Why PLOT?

+
+
+ 1 +

+ Reserve token for story tokens — every storyline token on PlotLink is backed by PLOT via MCV2 bonding curves. +

+
+
+ 2 +

+ TVL growth — as more story tokens are minted, more PLOT gets locked in bonding curve reserves, increasing total value locked across all storylines. +

+
+
+ 3 +

+ Creator royalties — 5% mint/burn royalty on every trade flows directly to the story writer. +

+
+
+
+ + {/* How to Get PLOT */} +
+

How to Get PLOT

+
+
+ +

+ Buy via Mint Club — purchase PLOT on the bonding curve using HUNT tokens. +

+
+
+ +

+ Sell story tokens — selling any storyline token returns PLOT to your wallet. +

+
+
+ +

+ Use the Zap — buy story tokens with ETH, USDC, or HUNT and the zap contract handles PLOT conversion automatically. +

+
+
+
+ + {/* Token Information */} +
+

Token Information

+ + {/* Stats */} +
+
+
Total Supply
+ {supplyLoading ? ( +
+ ) : ( +
+ {parseFloat(formattedSupply).toLocaleString(undefined, { + minimumFractionDigits: 0, + maximumFractionDigits: 0, + })} PLOT +
+ )} +
+
+
Network
+
+ + Base Mainnet +
+
+
+ + {/* Links */} + +
+
+ ); +} From 3a72559944eab82c8f1634929079fed4a215cff1 Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 23 Mar 2026 10:00:04 +0000 Subject: [PATCH 2/3] [#448] Fix royalty percentage (1% not 5%) Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/token/page.tsx | 2 +- src/components/TradingWidget.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/token/page.tsx b/src/app/token/page.tsx index 8b8d3a95..2657a525 100644 --- a/src/app/token/page.tsx +++ b/src/app/token/page.tsx @@ -100,7 +100,7 @@ export default function TokenPage() {
3

- Creator royalties — 5% mint/burn royalty on every trade flows directly to the story writer. + Creator royalties — 1% mint and 1% burn royalty on every trade flows directly to the story writer.

diff --git a/src/components/TradingWidget.tsx b/src/components/TradingWidget.tsx index 7ab6008d..251ef219 100644 --- a/src/components/TradingWidget.tsx +++ b/src/components/TradingWidget.tsx @@ -345,7 +345,7 @@ export function TradingWidget({ tokenAddress }: { tokenAddress: Address }) {

Trade to Support - Every trade generates a 5% creator royalty — buying and selling these story tokens directly supports the writer to keep continuing this story. + Every trade generates a creator royalty — buying and selling these story tokens directly supports the writer to keep continuing this story.

From f7026df63b1932665e27a9b2a36271e0efddad6f Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 23 Mar 2026 10:09:09 +0000 Subject: [PATCH 3/3] [#448] Remove unused MCV2_BOND import Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/token/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/token/page.tsx b/src/app/token/page.tsx index 2657a525..be076ede 100644 --- a/src/app/token/page.tsx +++ b/src/app/token/page.tsx @@ -4,7 +4,7 @@ import { useAccount, useReadContract } from "wagmi"; import { formatUnits, erc20Abi } from "viem"; import { useState } from "react"; import { - PLOT_TOKEN, MCV2_BOND, EXPLORER_URL, + PLOT_TOKEN, EXPLORER_URL, } from "../../../lib/contracts/constants"; const BASESCAN_URL = `${EXPLORER_URL}/token/${PLOT_TOKEN}`;