import { useCallback, useState } from "react"; import { createRoot } from "react-dom/client"; import { ThemeProvider } from "@cloudflare/agents-ui/hooks"; import { ConnectionIndicator, ModeToggle, PoweredByAgents, type ConnectionStatus } from "@cloudflare/agents-ui"; import { Button, Badge, Surface, Text, Empty } from "@cloudflare/kumo"; import { CurrencyDollarIcon, ShieldCheckIcon, PaperPlaneRightIcon, TrashIcon, InfoIcon, WarningCircleIcon, CheckCircleIcon } from "@phosphor-icons/react"; import { useAgent } from "agents/react"; import { nanoid } from "nanoid"; import "./styles.css"; let sessionId = localStorage.getItem("x402-session"); if (!sessionId) { sessionId = nanoid(8); localStorage.setItem("x402-session", sessionId); } interface FetchResult { text: string; isError: boolean; timestamp: number; } function App() { const [status, setStatus] = useState("connecting"); const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const agent = useAgent({ agent: "pay-agent", name: sessionId!, onOpen: useCallback(() => setStatus("connected"), []), onClose: useCallback(() => setStatus("disconnected"), []) }); const handleFetch = async () => { setLoading(true); try { const res = (await agent.call("fetchProtectedRoute", [])) as { text: string; isError: boolean; }; setResults((prev) => [ { text: res.text, isError: res.isError, timestamp: Date.now() }, ...prev ]); } catch (err) { setResults((prev) => [ { text: err instanceof Error ? err.message : String(err), isError: true, timestamp: Date.now() }, ...prev ]); } setLoading(false); }; return (

x402 Payments

HTTP Payment Gating (x402) This demo uses the{" "} @x402/* {" "} libraries to gate an HTTP endpoint behind a $0.10 paywall. An Agent with a test wallet pays automatically using{" "} wrapFetchWithPayment . The server uses Hono middleware to verify payments.
{status === "disconnected" && ( } title="Disconnected" description="Could not connect to the agent. Make sure the server is running." /> )} {status === "connected" && ( <>
Protected Route $0.10
The agent will fetch{" "} /protected-route {" "} and automatically sign a $0.10 payment on Base Sepolia using its configured wallet.
{results.length > 0 && (
Results
{results.map((r) => (
{r.isError ? ( ) : ( )}
                            {r.text}
                          
{new Date(r.timestamp).toLocaleTimeString()}
))}
)} )}
); } createRoot(document.getElementById("root")!).render( );