> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arc.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Sample app | Arc nanopayments

> Autonomous AI agent buyer pays for paywalled API endpoints using Circle Nanopayments and the x402 protocol on Arc.

export const PreviewImage = ({src, alt, portrait = false}) => <div className={`not-prose my-4 rounded-xl border border-gray-200 dark:border-white/10 overflow-hidden bg-white dark:bg-[#1F2F44] ${portrait ? "max-w-xs mx-auto" : ""}`}>
    <div className="flex items-center gap-1.5 px-3 py-2 border-b border-gray-200 dark:border-white/10 bg-gray-50 dark:bg-white/[0.04]">
      <span className="w-2.5 h-2.5 rounded-full bg-red-400/70 dark:bg-red-400/60" />
      <span className="w-2.5 h-2.5 rounded-full bg-yellow-400/70 dark:bg-yellow-400/60" />
      <span className="w-2.5 h-2.5 rounded-full bg-green-400/70 dark:bg-green-400/60" />
    </div>
    <img src={src} alt={alt} className="block w-full h-auto" loading="lazy" />
  </div>;

export const SampleAppActions = ({back, repoUrl, arcStudioPrompt}) => {
  const prompt = arcStudioPrompt || `Clone the GitHub repo ${repoUrl} and help me run it locally, then walk me through how it works.`;
  const [copied, setCopied] = useState(false);
  const arcStudioUrl = `https://studio.arc.io/app?prompt=${encodeURIComponent(prompt)}`;
  const handleArcStudioClick = () => {
    try {
      if (typeof navigator !== "undefined" && navigator.clipboard && prompt) {
        navigator.clipboard.writeText(prompt).then(() => {
          setCopied(true);
          setTimeout(() => setCopied(false), 4000);
        }, () => {});
      }
    } catch (e) {}
  };
  return <div className="not-prose mb-6">
      <div className="flex items-center gap-3">
        {back && <a href={back} className="inline-flex items-center gap-1 text-sm text-gray-500 dark:text-[#888] hover:text-[#3E74BB] dark:hover:text-[#ACC6E9] no-underline mr-2">
            <span aria-hidden="true">←</span> Back
          </a>}
        <span className="relative inline-flex">
          <a href={arcStudioUrl} target="_blank" rel="noreferrer" onClick={handleArcStudioClick} aria-label="Try it on Arc Studio (opens in new tab)" className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-[#3E74BB] border border-[#3E74BB] text-sm font-medium text-white no-underline hover:bg-[#345f9c] hover:border-[#345f9c] transition-all">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z" />
            </svg>
            Try it on Arc Studio
          </a>
          {copied && <span role="status" aria-live="polite" className="absolute left-0 top-full mt-2 w-72 text-sm text-gray-500 dark:text-[#888]">
              Opening Arc Studio — prompt copied to your clipboard in case you need to
              sign in first.
            </span>}
        </span>
        {repoUrl && <a href={repoUrl} target="_blank" rel="noreferrer" className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-white dark:bg-[#1F2F44] border border-gray-200 dark:border-white/10 text-sm font-medium text-gray-900 dark:text-white no-underline hover:border-gray-300 dark:hover:border-white/25 hover:bg-gray-50 dark:hover:bg-white/[0.06] transition-all">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
              <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
            </svg>
            Clone and edit
          </a>}
      </div>
    </div>;
};

<SampleAppActions back="/arc/references/sample-applications" repoUrl="https://github.com/circlefin/arc-nanopayments" />

Arc nanopayments shows how to monetize API endpoints with per-request USDC
payments and have an AI agent pay for them autonomously. The repo contains two
components: a Next.js seller app that exposes x402-protected premium routes, and
a LangChain buyer agent that pays each request without human involvement. Run
both locally to see the full flow end to end. See the repository README for
setup prerequisites.

## Preview

<PreviewImage src="/images/sample-apps/arc-nanopayments.png" alt="Arc nanopayments seller dashboard showing real-time payment events" />

## Flow

<Steps>
  <Step title="Seller registers paywalled endpoints">
    The Next.js app exposes x402-protected premium routes priced from $0.0003 to
            $0.03 USDC per request, using Circle Nanopayments middleware to enforce
    payment before serving content.
  </Step>

  <Step title="Buyer agent deposits USDC through Gateway">
    The LangChain buyer agent checks its wallet balance and deposits USDC into
    Circle Gateway. Gateway aggregates the USDC into a nanopayments balance the
    agent draws from for each request, so the agent settles against its Gateway
    balance rather than submitting a separate onchain transaction per call.
  </Step>

  <Step title="Agent requests a paywalled endpoint">
    The agent sends an HTTP request to a premium route. The server responds with
    a `402 Payment Required` status and a payment challenge header (an
    [x402](https://x402.org/) standard header that specifies the payment amount,
    token, and receiving address on Arc).
  </Step>

  <Step title="Agent pays the x402 challenge">
    The agent constructs and signs a USDC payment transaction on Arc to satisfy
    the payment challenge. The signed transaction hash is attached to the retry
    request as the payment proof in the `X-Payment` header.
  </Step>

  <Step title="Seller verifies and serves content">
    The Nanopayments middleware verifies the payment onchain, then serves the
    premium response. The payment event is recorded in Supabase.
  </Step>

  <Step title="Seller dashboard updates in real time">
    Supabase Realtime pushes new payment events to the seller dashboard.
    Accumulated earnings are available to withdraw via the Gateway UI.
  </Step>
</Steps>

## Tech stack

* [Next.js App Router](https://nextjs.org/docs/app) for the seller app and
  seller dashboard
* [Circle Nanopayments](https://developers.circle.com/nanopayments) with
  [x402](https://x402.org/) for per-request API monetization
* [Circle Gateway](https://developers.circle.com/gateway) for buyer USDC
  deposits and seller withdrawals
* [LangChain](https://www.langchain.com/) and
  [DeepAgents](https://deepagents.ai/) for the autonomous buyer agent
* [Viem](https://viem.sh/) for wallet interactions and onchain payment signing
* [Supabase](https://supabase.com/) for payment event persistence and real-time
  dashboard updates
* [Tailwind CSS](https://tailwindcss.com/) and
  [shadcn/ui](https://ui.shadcn.com/) for the seller interface
