Skip to content

Testnet quickstart

Buy one article with test money: read the feed, pay its 402 on Arc Testnet, and open the licence on the verify page.

On this page

Buy one article the way your crawler will, with test money: read the articles feed, request an article, pay its 402 on Arc Testnet, and open the licence you get back on the verify page. It takes a few minutes and a wallet with test USDC. Every step is the one you run on mainnet; only three settings change.

What you need

  • Node 20 or later.
  • A private key for a wallet you use only for testing.
  • Arc Testnet USDC in that wallet, from the Circle faucet. Pick Arc Testnet. USDC is also the gas token on Arc, so you need nothing else.

Run it

mkdir naulon-quickstart && cd naulon-quickstart
npm init -y && npm install @circle-fin/x402-batching viem
curl -O https://naulon.app/quickstart/testnet-crawl.mjs
BUYER_PRIVATE_KEY=0x... node testnet-crawl.mjs

A first run prints this, one line per step. This one ran against production on 2026-10-21:

1  feed: 1 row(s); picked "AI crawlers get a price" at 1100 micro-USDC
2  402: 1000 micro-USDC to 0xc0c1be21dc23d1d4a402ca04d938f0b2c42cbf8e on eip155:5042002
3  Gateway holds 0 USDC; depositing 0.05
3  Gateway balance: 0.05 USDC
4  paid read: 154797 bytes, licence received
5  receipt: https://naulon.app/verify?host=sandbox.naulon.app&jti=83f51d2b-b808-4049-84ee-0f58768e8732

The feed's price includes naulon's fee; the 402 asks for the author's share only, so a stock x402 client pays the author and the fee is forgone. Later runs skip the deposit until the balance runs low.

Read the script before you run it with a key. It's about a hundred lines, and it sends your key nowhere: it signs locally and sends only signatures.

What each step does

1. Read the feed. It asks the articles feed for the sandbox publisher, sandbox.naulon.app, whose articles settle on Arc Testnet, and picks the first live row. A real crawler keeps the page's next cursor and asks again later for what changed.

2. Request the article as a machine. It sends X-Naulon-Agent: quickstart, which tells the gate a machine is asking. A person in a browser reads the same page free. You get 402 Payment Required, and the PAYMENT-REQUIRED header (base64 JSON) names the price, the author's wallet and the network. Before signing anything, the script checks the quote: the network is the one it pays on, the amount is no more than the feed's price for that row and no more than NAULON_MAX_MICRO (one cent unless you set it), and the quote is for the url it asked for. Keep those checks in your own crawler.

3. Fund Circle Gateway once. Payments come out of a balance you deposit into Circle Gateway, so each read costs a signature rather than a transaction. The script deposits 0.05 USDC only when the balance can't cover the article. Leftover balance stays yours, and GatewayClient.withdraw() takes it back.

4. Pay and read. It signs the quote with your key and asks again with the signature in payment-signature. The gate settles the payment from you to the author and serves the article, with your licence in X-Naulon-License.

5. Open the receipt. The licence is a signed JWT. The script fills the feed's links.verify template with the licence's jti and the host in its aud, and prints the link. Anyone you send it to can check it in their own browser against the publisher's published keys, without asking naulon.

Moving to mainnet

Change three settings, and pay with real USDC on Arc:

NAULON_SITE= NAULON_CHAIN=arc NAULON_AGENT_ID=your-crawler BUYER_PRIVATE_KEY=0x... node testnet-crawl.mjs

An empty NAULON_SITE reads the whole feed instead of the sandbox. Name your crawler in NAULON_AGENT_ID: publishers see it, and it's how they tell your traffic apart. Prices are in the feed and in each 402, in micro-USDC: 1100 is $0.0011 a read.

A production crawler should also check each feed page's signature before trusting its rows, as checking a page describes. The quickstart skips it to stay short.

When it stops

The script says why in one line. The usual causes:

Message What to do
expected 402 ... got 200 The gate read you as a person. Keep the X-Naulon-Agent header.
the article settles on eip155:5042 That article is on mainnet. Set NAULON_SITE=sandbox.naulon.app to stay on testnet.
the 402 asks ... the feed said ... The price moved between the feed and the read. Read the feed again.
paid read answered 402 The payment was refused, usually an empty Gateway balance. Check the faucet funds arrived and run again.
HTTP request failed during the deposit The RPC is unreachable. Set NAULON_RPC to another Arc Testnet endpoint.