"use client"; import { makeAssistantToolUI } from "@assistant-ui/react"; import { z } from "zod"; import { cn } from "@/lib/utils"; import { Fish, ArrowUpRight, ArrowDownRight, ExternalLink, Clock } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { ChainIcon } from "@/components/crypto/ChainIcon"; // Schema for whale transaction const WhaleTransactionSchema = z.object({ id: z.string(), type: z.enum(["buy", "sell", "transfer"]), amount: z.number(), amountUsd: z.number(), tokenSymbol: z.string(), walletAddress: z.string(), walletLabel: z.string().optional(), timestamp: z.string(), txHash: z.string().optional(), }); // Schema for whale activity tool arguments export const WhaleActivityArgsSchema = z.object({ tokenSymbol: z.string(), chain: z.string(), transactions: z.array(WhaleTransactionSchema), summary: z.object({ totalBuyVolume: z.number(), totalSellVolume: z.number(), netFlow: z.number(), uniqueWhales: z.number(), }).optional(), }); export type WhaleActivityArgs = z.infer; // Schema for whale activity result export const WhaleActivityResultSchema = z.object({ success: z.boolean(), message: z.string().optional(), }); export type WhaleActivityResult = z.infer; const formatLargeNumber = (num: number): string => { if (num >= 1e6) return `$${(num / 1e6).toFixed(2)}M`; if (num >= 1e3) return `$${(num / 1e3).toFixed(2)}K`; return `$${num.toFixed(2)}`; }; const shortenAddress = (address: string): string => { return `${address.slice(0, 6)}...${address.slice(-4)}`; }; const formatTimeAgo = (timestamp: string): string => { const diff = Date.now() - new Date(timestamp).getTime(); const minutes = Math.floor(diff / 60000); if (minutes < 60) return `${minutes}m ago`; const hours = Math.floor(minutes / 60); if (hours < 24) return `${hours}h ago`; return `${Math.floor(hours / 24)}d ago`; }; /** * WhaleActivityToolUI - Displays whale transactions inline in chat * Used when AI responds to "show whale activity for BULLA" or similar */ export const WhaleActivityToolUI = makeAssistantToolUI({ toolName: "get_whale_activity", render: ({ args, status }) => { const isLoading = status.type === "running"; const transactions = args.transactions || []; const summary = args.summary; return (
Whale Activity - {args.tokenSymbol} {isLoading && Loading...}
{/* Summary Stats */} {summary && (

Buy Volume

{formatLargeNumber(summary.totalBuyVolume)}

Sell Volume

{formatLargeNumber(summary.totalSellVolume)}

= 0 ? "bg-green-500/10" : "bg-red-500/10")}>

Net Flow

= 0 ? "text-green-500" : "text-red-500")}> {summary.netFlow >= 0 ? "+" : ""}{formatLargeNumber(summary.netFlow)}

Unique Whales

{summary.uniqueWhales}

)} {/* Transaction List */} {transactions.length === 0 ? (

No whale transactions detected

) : (
{transactions.map((tx) => (
{tx.type === "buy" ? : tx.type === "sell" ? : }
{tx.type} {formatLargeNumber(tx.amountUsd)}
{tx.walletLabel || shortenAddress(tx.walletAddress)} {formatTimeAgo(tx.timestamp)}
{tx.txHash && ( )}
))}
)}
); }, });