Skip to content

About

A minimal TypeScript AI agent that pays Inferit per request with x402 on Whitechain Sepolia (testnet).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Inferit

inferit-agent-example

A minimal AI agent that pays Inferit per request with x402: no account, no API key, and no WBT until it withdraws.

One TypeScript file, the official x402 client and viem. It runs against Inferit's hosted testnet API on Whitechain Sepolia.

Website Agents X CI License x402 Network

Status: Testnet demo on Whitechain Sepolia. Prices settle in Inferit Test Credit (ITC), a test token with no monetary value. The contracts are not audited.


What it does

x402 is an open payment protocol built on HTTP 402 Payment Required. Inferit's API speaks x402 v2, so an agent can pay for each request with a signature instead of an account. src/agent.ts does it in four steps:

  1. Discovery. GET /.well-known/x402 says what is paid and how: the exact scheme (EIP-3009 transferWithAuthorization), the network (eip155:1874, Whitechain Sepolia), the token (ITC) and payTo, the market's escrow contract (MarketEscrow).
  2. Test tokens. If the agent holds less than the minimum payment, it claims 1,000 test ITC from Inferit's sponsored faucet (POST /v1/faucet). The API pays the gas, once per 24 h per address.
  3. Pay per request. A POST /v1/chat/completions with no Authorization header answers 402 with a quote in PAYMENT-REQUIRED: the worst-case cost of that exact body, at least 10 000 µ (0.01 ITC), pinned for 120 s. The x402 client signs an EIP-3009 authorization for the quote, to the escrow, and resends the request with PAYMENT-SIGNATURE. The API deposits the payment as the agent's own escrow balance, then serves the request.
  4. Receipt. PAYMENT-RESPONSE names the deposit transaction. The request is charged its metered cost (x-inferit-buyer-cost-micro, settled on chain in batches later), not the quote. The rest stays the agent's escrow balance.

The payment is standard x402 v2; only the faucet claim and the x-inferit-* cost headers are Inferit's. The dependencies are @x402/fetch, @x402/evm and viem, with tsx to run the TypeScript.

Run it

You need Node.js 20 or newer.

npm install
npm start                                 # a fresh throwaway key for this run

To pay from the same address every time, put its private key in AGENT_KEY:

export AGENT_KEY=0x...                    # 0x + 64 hex characters: a test key only
npm start

The key is read from the environment and never written anywhere. Use a key made for testing, never one that holds anything of value.

Get test tokens

Token What it is for Where it comes from
ITC (Inferit Test Credit) Paying for inference: 1 µ = 0.000001 ITC The agent claims it from Inferit's faucet by itself: POST https://api-production-c74b9.up.railway.app/v1/faucet with {"address": "0x..."}, 1,000 ITC per address per 24 h, gas sponsored. A second claim within 24 h gets 429 faucet_cooldown
WBT (Whitechain's gas token) Not needed to pay with x402. Only for transactions you send yourself, such as a withdrawal from the escrow The Whitechain faucet: https://faucet.testnet.whitechain.io

Both are test tokens with no monetary value.

Expected output

A run on 2026-10-13 with a reused test key (AGENT_KEY), which already held ITC, so it skipped the faucet (the agent's address is shortened here; the run prints it in full):

agent 0x48C7…1A53 -> https://api-production-c74b9.up.railway.app
pays ITC on Whitechain Sepolia (eip155:1874) into the escrow 0x705dD9eCffa888FbcF2849eAE2D3b136eb78B7e0
holds 1999.95 ITC

Pay-per-request suits AI agents because it allows for cost-efficiency by billing only for the actual usage of AI services, which is particularly beneficial for services with variable demand.

model: qwen/qwen-2.5-14b-instruct
paid 10000 base units of ITC (deposit tx https://explorer.testnet.whitechain.io/tx/0x3b77ef78671ca06466c2e05d17b105039fa11fa07aa6174b0a4ba75773808787)
charged 9 base units for this request; the rest stays 0x48C7…1A53's escrow balance

With a fresh key, the third line reads holds 0 ITC and the next one faucet: 1000 ITC minted (tx 0x…). ITC has 6 decimals, so a base unit is one µ: this run paid 10 000 µ into the escrow and was charged 9 µ.

verified 2026-10-13: model qwen/qwen-2.5-14b-instruct, max_tokens 64, @x402/fetch 2.28.0 and viem 2.57.5: answered, paid 10000 base units (0.01 ITC), charged 9, deposit 0x3b77ef78…8787 (status 1, to the escrow).

Environment

Variable Default What it is
AGENT_KEY A fresh key per run The payer's private key, 0x + 64 hex characters
INFERIT_BASE_URL https://api-production-c74b9.up.railway.app/v1 The hosted testnet API
INFERIT_MODEL qwen/qwen-2.5-14b-instruct A model with a live seller (GET /v1/models, rows with a best_price), or auto when GET /v1/routing lists a model in candidates_now
PROMPT A one-sentence question What to ask
MAX_TOKENS 64 The answer's token limit. The quote is the worst case for the body, so a small limit keeps it small
STREAM off STREAM=1 streams the answer (server-sent events). A streamed answer's cost comes as an HTTP trailer, which fetch does not expose, so that run prints no charged line
MAX_PAYMENT 1000000 (1 ITC) The most the client signs for one request, in base units
RPC_URL https://rpc.testnet.whitechain.io A Whitechain Sepolia RPC, to read the agent's ITC balance

In your own code

import { wrapFetchWithPayment, x402Client } from '@x402/fetch';
import { ExactEvmScheme } from '@x402/evm/exact/client';
import { privateKeyToAccount } from 'viem/accounts';

const account = privateKeyToAccount(process.env.AGENT_KEY as `0x${string}`);
const client = new x402Client()
  .register('eip155:*', new ExactEvmScheme(account))
  // Recent x402 clients pay only assets they know: allow ITC on Whitechain Sepolia, capped per payment.
  .setSpendControls({
    allowedAssets: [{ network: 'eip155:1874', asset: '0x2E672dFE33EA977FD064E01aDe7d8c73B3Be7fBB', maxAmountPerPayment: '1000000' }],
  });
const paidFetch = wrapFetchWithPayment(fetch, client);

const res = await paidFetch('https://api-production-c74b9.up.railway.app/v1/chat/completions', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ model: 'qwen/qwen-2.5-14b-instruct', max_tokens: 64, messages: [{ role: 'user', content: 'Hello' }] }),
});

Standard x402 v2 clients pay once the asset is allowed in the client's spend controls, as above, with plain-key (EOA) signers. To use x402 from LangChain or the Vercel AI SDK, see inferit-examples.

What happens to the rest

The unused part of each payment stays the agent's balance in the escrow contract, MarketEscrow. The agent can spend it later with an API key (sign in with the same wallet: POST /v1/auth/evm/challenge, /v1/auth/evm/verify, then POST /v1/keys) or withdraw it. A withdrawal is two steps, with a 1 h delay, and it is a transaction, so it needs a little WBT. Escrow details: https://inferit.cc/docs/payments/whitechain

More from Inferit

License

Apache-2.0.

About

A minimal TypeScript AI agent that pays Inferit per request with x402 on Whitechain Sepolia (testnet).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages