First unpaid 402 for EVM agent builders
This page exists for one decision only: trigger one live unpaid 402 Payment Required response and stop there unless the route looks correct.
If the journey started on https://nishvault.com, the canonical bridge for this exact step is https://nishvault.com/go/first-check.
Readable path
- Trust starts on
https://nishvault.com. - The bridge URL is
https://nishvault.com/go/first-check. - The live metadata stays on
https://api.nishvault.com/.well-known/x402. - This page runs the first unpaid check on
https://api.nishvault.com/simulate/transaction-preflight. - Only after a correct unpaid result do you open
https://api.nishvault.com/required-before-send.
Start here: run the live unpaid check now
Do not browse more docs first. Run the inline request, inspect the real payment_required response, and only then decide whether anything paid is worth your time.
The only job on this page
- Click Run the live unpaid 402 now once.
- Confirm the inline result says
status = 402anderror = "payment_required". - If both are true, take exactly one paid next step. If not, stop and do not branch into other docs.
Qualified first-check signal
A real first-check success is not “the page loaded.” It is one live unpaid response from /simulate/transaction-preflight with the same route and price metadata you would use for the paid retry.
{
"status": 402,
"ok": false,
"body": {
"error": "payment_required",
"product": "evm-transaction-preflight",
"price": "$0.01",
"network": "eip155:8453",
"firstCheckUrl": "https://api.nishvault.com/first-unpaid-402",
"quickstartUrl": "https://api.nishvault.com/quickstart",
"browserDemoUrl": "https://api.nishvault.com/#landing-browser-402"
}
}
Live unpaid 402 result
This is the main action on this page. Run one live unpaid request inline, inspect the real payment_required response, and stop here unless the route looks correct.
{
"chainId": "0x2105",
"from": "0x1111111111111111111111111111111111111111",
"to": "0x2222222222222222222222222222222222222222",
"data": "0x",
"value": "0x0"
}
The live result will appear here. Expected first success: status 402 with error = "payment_required" from /simulate/transaction-preflight.
If you arrived from the root bridge with autorun=1, the page will run this unpaid check automatically and print the live result inline.
The 402 worked. Now copy one guard shape and keep one paid next step.
Copy this next: it is the shortest public transaction guard and it belongs exactly where your agent would otherwise call sendTransaction.
npx --package nishvault-preflight-buy nishvault-guard-tx -- --seller-url https://api.nishvault.com --to 0x2222222222222222222222222222222222222222 --data 0x --value 0x0
Keep the route, price, and network the same. If you already know your send slot, use the exact runtime pick below and copy the matching wrapper without leaving this page.
Choose your send slot now
AgentKit / walletProvider.sendTransaction
Best first fit for AgentKit issue #1167, awesome-x402, and generic wallet-provider send paths.
Agent step / MCP tool
Use this when a job, tool, or queued step chooses the send.
viem
Put the wrapper directly around walletClient.sendTransaction.
import { createViemPreflightGuard } from "nishvault-preflight-buy";
const guardedSendTransaction = createViemPreflightGuard({
walletClient,
buyerKey: process.env.X402_BUYER_PRIVATE_KEY,
sellerUrl: "https://api.nishvault.com",
});
const { preflight, txHash } = await guardedSendTransaction({
account: walletClient.account,
to: "0x2222222222222222222222222222222222222222",
data: "0x",
value: "0x0",
});
ethers
Use this when your signer owns the broadcast call.
import { createEthersPreflightGuard } from "nishvault-preflight-buy";
const guardedSendTransaction = createEthersPreflightGuard({
signer,
buyerKey: process.env.X402_BUYER_PRIVATE_KEY,
sellerUrl: "https://api.nishvault.com",
});
const { preflight, txHash } = await guardedSendTransaction({
to: "0x2222222222222222222222222222222222222222",
data: "0x",
value: "0x0",
});
AgentKit / generic sendTransaction
Use the EIP-1193 wrapper when the send path is provider-driven or when walletProvider.sendTransaction is the live send slot.
import { createEip1193PreflightGuard } from "nishvault-preflight-buy";
const guardedSendTransaction = createEip1193PreflightGuard({
provider: window.ethereum,
account: "0x1111111111111111111111111111111111111111",
buyerKey: process.env.X402_BUYER_PRIVATE_KEY,
sellerUrl: "https://api.nishvault.com",
});
const { preflight, txHash } = await guardedSendTransaction({
from: "0x1111111111111111111111111111111111111111",
to: "0x2222222222222222222222222222222222222222",
data: "0x",
value: "0x0",
});
Agent step
Use this when the transaction is created inside a job or tool step.
import { createAgentGuardStep } from "nishvault-preflight-buy";
const guardedStep = createAgentGuardStep({
buyerKey: process.env.X402_BUYER_PRIVATE_KEY,
sellerUrl: "https://api.nishvault.com",
mapInputToTransaction: (job) => ({
from: job.sender,
to: job.target,
data: job.calldata,
value: job.value ?? "0x0",
}),
runStep: async (job, { preflight }) => executeJob(job, preflight),
});
The only paid next step after this unpaid proof is one live receipt-producing guard run. Open the launch gate when you are ready to spend $0.01 real Base USDC. Need deeper context later? The full wrapper index still lives on /integrations.
Stop here if this does not look like a real unpaid 402
If the response is not payment_required, do not fund a wallet, do not test a paid retry, and do not jump to integrations yet.
Advanced / after-first-check paths
Fastest fallback: one paste
SELLER_BASE_URL=https://api.nishvault.com bash -lc '
curl -sS "$SELLER_BASE_URL/.well-known/x402" | jq "{title, primaryPersona, route, price, network, payTo, quickstartUrl, browserDemoUrl}" &&
curl -sS -H "content-type: application/json" -X POST "$SELLER_BASE_URL/simulate/transaction-preflight" --data '"'"'{"chainId":"0x2105","from":"0x1111111111111111111111111111111111111111","to":"0x2222222222222222222222222222222222222222","data":"0x","value":"0x0"}'"'"' | jq "{error, product, price, network, quickstartUrl, browserDemoUrl}"
'
This runs discovery and then one unpaid POST. If the second response is not payment_required, stop and do not pay.
Only after the unpaid 402
- /quickstart for the paid buyer CLI.
- /integrations for
preflightTransactionRequest,createViemPreflightGuard, orcreateAgentGuardStep. - /examples and /recipes only if you still need workflow fit.
Mark this browser as owner traffic if you are testing the funnel yourself.