A prepaid rail for agents
An AI agent deposits once into an on-chain balance it still owns, then spends against that balance request by request. No wallet prompt, no transaction to sign, no human in the loop after the first one. Every debit is enforced on Solana at the price the seller published, and whatever is left can be withdrawn at any time.
An agent can decide to pay in milliseconds, then waits on a signature. Chainalysis measured what that did to the market: between early 2025 and early 2026 the share of x402 volume between 10 cents and $1 collapsed from 46% to 4%, while payments of $1 and up climbed to 95% of value. Agents did not stop making small requests. Small settlements stopped making sense. Solinkify splits the two apart: settle once, in the size range a blockchain is good at, then consume in the size range agents actually work in.
A $1 deposit covers 1,000 requests against the demo endpoint below, and costs exactly one signature to open.
The balance lives in a program-owned account derived from the payer wallet and the token mint. Solinkify holds no key that can move it anywhere else: the only debit the program accepts is the seller's published price, for a request that was actually served.
Any standard Solana keypair works. Fund it with a little devnet SOL for fees and devnet USDC from Circle's faucet. Everything on this page is test money, so the whole walkthrough costs nothing.
solana-keygen new --no-bip39-passphrase -o agent.json
solana airdrop 1 "$(solana address -k agent.json)" --url devnet
# devnet USDC: https://faucet.circle.com → Solana Devnet → paste the addressThe MCP server gives any MCP-capable agent (Claude Code, Claude Desktop, and others) 18 tools, with fail-closed spending caps enforced before anything moves: $1 per payment and $10 per UTC day by default, both configurable.
claude mcp add solinkify -e SOLINKIFY_WALLET_PATH=$PWD/agent.json -- npx -y @solinkify/mcpOr in any MCP host config:
{
"mcpServers": {
"solinkify": {
"command": "npx",
"args": ["-y", "@solinkify/mcp"],
"env": { "SOLINKIFY_WALLET_PATH": "/path/to/agent.json" }
}
}
}Ask the agent:
Deposit $1 into my Solinkify prepaid balance.That runs gate_prepaid_deposit, which checks the amount against both caps before signing, then opens the on-chain balance:
{
"deposited_usd": 1,
"token": "USDC",
"signature": "3nKp…paste into Solana Explorer (devnet)",
"balancePda": "9ktQ…" // owned by the agent wallet, not by Solinkify
}The whole deposit counts against the daily cap at once, on purpose: funding a balance is the moment worth guarding, not the thousand debits that follow it.
Ask for the protected resource, repeatedly:
Fetch https://www.solinkify.com/api/demo-feed ten times and tell me what each call cost.Each call sends the agent's wallet address and a short-lived capability token it signed locally. The backend debits the published price on-chain and serves the content. No wallet prompt appears, because there is no transaction for the agent to sign:
{
"status": 200,
"paid": true,
"via": "prepaid", // not "payment": no per-request escrow lock
"amount": "0.001 USDC",
"content": { "feed": [ … ] }
}Ten calls, one signature, and 990 requests still funded. If the balance ever runs dry the client falls back to a per-request escrow payment instead of failing, and if that price is over the cap it refuses rather than paying.
A prepaid balance is a deposit, not a purchase. It is readable at any time and withdrawable in full, minus what was actually spent.
curl "https://api.solinkify.com/api/gate/prepaid/balance?payer=<AGENT_ADDRESS>&mint=4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"From the agent, gate_prepaid_balance reads it and withdrawPrepaid in the SDK returns the remainder to the wallet. Nobody has to approve the withdrawal.
Before spending anything, an agent can ask the resource what it costs. An unfunded request gets an x402 v2 answer: a machine-readable price tag, with no human onboarding anywhere in the loop.
curl -sD - -A "GPTBot/1.0" https://www.solinkify.com/api/demo-feedHTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJDb250…
www-authenticate: Solinkify-Payment realm="H9EvV8...Ry4qxw", price="0.001"
x-payment-required: true
x-solinkify-gate: 1.0The payment-required header is base64. Decoded:
{
"x402Version": 2,
"resource": { "url": "/api/demo-feed", "mimeType": "application/json" },
"accepts": [{
"scheme": "solinkify-escrow",
"network": "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
"amount": "1000", // 0.001 USDC (6 decimals)
"payTo": "H9EvV8T4gwpynxGpeanGzgdos1CBx6tk6bsCK7Ry4qxw", // seller wallet
"asset": "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", // USDC mint (devnet)
"maxTimeoutSeconds": 3600,
"extra": {
"flow": "solana-escrow-lock",
"endpoint_id": "solinkify-demo-feed",
"payment_header": "x-solinkify-payment",
"payer_header": "x-solinkify-payer",
"discovery": "/.well-known/solinkify"
}
}]
}The scheme is named solinkify-escrow, not exact, because money locks in escrow before the content is served rather than transferring straight to the seller. A conformant x402 client should know that before it pays, so the manifest says so. Full access modes, including prepaid, are advertised at /.well-known/solinkify.
@solinkify/gate-sdk does the same thing in two calls: fund once, then fetch. Prepaid is preferred automatically when a balance covers the price, so the fetch loop never signs anything.
import { GateClient, depositPrepaid } from "@solinkify/gate-sdk";
const wallet = Keypair.fromSecretKey(/* agent secret key */);
const rpcUrl = "https://api.devnet.solana.com";
// Once: fund the on-chain balance (1 signature).
await depositPrepaid({ wallet, rpcUrl }, USDC_MINT, 1_000_000n); // $1.00
// Then: as often as you like, with no signing round-trip.
const client = new GateClient({
wallet,
rpcUrl,
maxPricePerRequest: 0.01, // refuse anything pricier (USDC)
preferPrepaid: true, // default
});
for (const url of urls) {
const { response, via } = await client.fetchProtected(url);
console.log(via, await response.text()); // via === "prepaid"
}When no balance covers the price, the same call falls back to a per-request escrow payment and returns a paymentId to release once the content is in hand.
What this walkthrough uses. Deposit once, then every request is debited on-chain with no signing round-trip. Withdraw the remainder at any time.
Pay once for time-boxed access to one endpoint. Renewing extends from the current expiry rather than from today.
One escrow lock per request, released 99% to the seller. The honest option for occasional access, and the fallback when a balance runs out.
Discovery does not stop at one site. Solinkify keeps a public registry of x402-priced endpoints, and every entry earns its place the same way: Solinkify fetches the URL as an AI agent, requires a real 402 with a valid x402 v2 manifest, and checks that the manifest pays the wallet that signed the submission. Open by verification, never by partnership.
curl https://api.solinkify.com/api/x402/resourcesFlat JSON, one object per endpoint: url, price, mint, network, endpoint id, payout wallet and access modes, so an agent can budget before it spends. Run a Gate-protected endpoint? List it here.
A8qS…S22B). Solinkify never holds a key that can move it to itself. The backend can trigger exactly one thing: a debit of the seller's published price_per_request for a request that was served.maxPricePerRequest budget, and the balance itself is a hard ceiling: an agent cannot spend money it never deposited.One deposit, a hard ceiling on chain, and a spend log you can read without asking anyone. Start with the demo endpoint above, then point it at any Gate-protected URL.
Selling instead of buying? Put a price on any URL with one line of middleware and protect an endpoint.