Gasless HTTP payments on NEAR - x402 protocol implementation using meta-transactions for pay-per-request APIs
x402-near-demo is an early-stage TypeScript project in the AI payments / x402 ecosystem. It currently has 5 GitHub stars and 0 forks.
Gasless, programmable payments for HTTP APIs using NEAR meta-transactions.
This is a working implementation of the x402 protocol on NEAR Protocol. It turns 402 Payment Required into a real payment system where clients can pay for API access without holding gas tokens—perfect for AI agents, headless services, and programmatic API consumption.
You want to charge for API access. Your clients don't want wallets, popups, or gas management.
With x402 on NEAR:
Perfect for: AI agents, data APIs, rate-limited services, paywalled content.
This implementation uses near-kit - a modern, intuitive TypeScript library for building on NEAR.
Why near-kit?
// Creating a gasless meta-transaction with near-kit
const result = await near
.transaction(TOKEN_ACCOUNT_ID)
.functionCall(TOKEN_ACCOUNT_ID, "ft_transfer", args, { gas: "30 Tgas" })
.delegate()
1. Client → Seller: GET /weather
Seller → Client: 402 Payment Required + payment instructions
2. Client signs NEAR meta-transaction (off-chain, gasless)
3. Client → Seller: GET /weather + X-PAYMENT header
Seller → Relayer: Verify + settle transaction (relayer pays gas)
Seller → Client: 200 OK + weather data + receipt
Key insight: The client just signs. The relayer submits and pays gas. The seller gets paid before returning data.
# 1. Install dependencies
bun install
# 2. Copy and configure .env
cp .env.example .env
# Edit .env with your NEAR testnet accounts and token
# 3. Run services (in separate terminals)
bun run facilitator # Starts relayer on :4022
bun run seller # Starts weather API on :4021
bun run buyer # Runs payment demo
You'll see:
402 response with payment requirementsThree simple services:
src/seller.ts)Your protected API. Returns 402 with payment requirements on first call. On retry with X-PAYMENT header, calls facilitator to verify and settle, then returns your data.
// Price lives with the seller
PRICE_ATOMIC = 10000 // 0.01 USDC (6 decimals)
src/facilitator.ts)The relayer/verifier. Has two endpoints:
POST /verify - Validates the signed meta-transaction matches payment requirementsPOST /settle - Submits transaction on-chain and pays gassrc/buyer.ts)Your client (or an agent). Gets 402, signs a NEAR DelegateAction that transfers tokens to seller, retries with X-PAYMENT header.
You need three accounts:
Use any NEP-141 token on testnet. For testing, wrap.testnet (wNEAR) works great.
Important: Both buyer and seller must be storage-registered:
# For buyer
near contract call-function as-transaction wrap.testnet storage_deposit \
json-args '{"account_id":"buyer.testnet"}' \
prepaid-gas 30Tgas attached-deposit 0.1NEAR \
sign-as buyer.testnet network-config testnet \
sign-with-legacy-keychain send
# For seller
near contract call-function as-transaction wrap.testnet storage_deposit \
json-args '{"account_id":"seller.testnet"}' \
prepaid-gas 30Tgas attached-deposit 0.1NEAR \
sign-as seller.testnet network-config testnet \
sign-with-legacy-keychain send
# Network
NEAR_NETWORK=testnet
NEAR_RPC=https://rpc.testnet.fastnear.com
# Token (NEP-141 contract)
TOKEN_ACCOUNT_ID=wrap.testnet
# Accounts
SELLER_ACCOUNT_ID=seller.testnet
RELAYER_ACCOUNT_ID=relayer.testnet
RELAYER_PRIVATE_KEY=ed25519:xxx...
BUYER_ACCOUNT_ID=buyer.testnet
BUYER_PRIVATE_KEY=ed25519:yyy...
# Price in atomic units (respect token decimals!)
# USDC (6 decimals): 10000 = 0.01 USDC
# wNEAR (24 decimals): 10000000000000000000000 = 0.01 NEAR
PRICE_ATOMIC=10000
# Ports
SELLER_PORT=4021
FACILITATOR_PORT=4022
DelegateAction (NEP-366) is NEAR's meta-transaction primitive:
DelegateAction off-chain (no gas needed)In this demo:
ft_transfer(seller, amount) on token contractsignedDelegate(buyer's signature)src/
├── facilitator.ts # Relayer (/verify + /settle endpoints)
├── seller.ts # Protected API (402 → payment → 200)
└── buyer.ts # Headless client (signs + pays)
.env.example # Configuration template
package.json # Bun scripts (facilitator, seller, buyer)
PAYMENT_INVALID: Delegate missing required transfer
ft_transfer to the seller for the exact amountPAYMENT_NOT_SETTLED
near account view-account-summary relayer.testnet network-config testnet nowWrong decimals / amounts
PRICE_ATOMIC must match token decimals exactly1000000 = 1 USDC)1000000000000000000000000 = 1 NEAR)Buyer "needs gas"?
Before deploying:
/verify and /settle endpointsx402 is an open protocol for HTTP-native payments. This implementation follows the spec:
402 Payment Required response with accepts[] arrayX-PAYMENT request header with signed transactionX-PAYMENT-RESPONSE response header with settlement receiptThe protocol is chain-agnostic—this demo uses NEAR, but x402 also works on EVM (EIP-3009) and Solana (Token-2022).
NEAR's meta-transactions make this particularly elegant:
MIT
Questions? Open an issue. Want to contribute? PRs welcome.