Pay for APIs from an agent
Your agent signs a USDC payment for each request it makes, within limits you set. Works with any x402 endpoint on Solana Devnet, not only Plinth.
Start paying
Pick one. All three sign the same standard x402 payment, so any x402 server on this network accepts them.
# see what is for sale on a site, free
npx plinth x402-catalog --url https://www.plinthcity.com
# preview only: the price, your balance, any loan it would need
npx plinth pay --url https://www.plinthcity.com/api/x402/pool --max-price 0.05
# pay (a keypair file; the key never leaves your machine)
SOLANA_CLUSTER=devnet SOLANA_KEYPAIR=~/.config/solana/agent.json npx plinth pay --url https://www.plinthcity.com/api/x402/pool --max-price 0.05 --yesWithout --yes nothing is signed. --max-price is a hard limit: a higher price is refused, not paid.
import { LendingClient, X402Payer, loadSolanaDeployment, loadKeypairSigner, parseUsd } from "@plinth/sdk/solana";
const signer = await loadKeypairSigner(process.env.SOLANA_KEYPAIR);
const pool = new LendingClient({ rpcUrl: process.env.SOLANA_RPC_URL, deployment: loadSolanaDeployment("devnet"), signer });
const payer = new X402Payer({ client: pool, maxPrice: parseUsd("0.05") });
const preview = await payer.preview("https://www.plinthcity.com/api/x402/pool"); // nothing is signed
const { response, paid } = await payer.pay("https://www.plinthcity.com/api/x402/pool");
const data = await response.json();import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactSvmScheme } from "@x402/svm/exact/client";
import { createKeyPairSignerFromBytes } from "@solana/kit";
const signer = await createKeyPairSignerFromBytes(agentKeyBytes); // loaded from a keypair file, never hard-coded
const pay = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [{ network: "solana:*", client: new ExactSvmScheme(signer) }],
// the official client pays only assets you allow; cap each payment (atomic units: 50000 = 0.05 USDC)
spendControls: { allowedAssets: [{ network: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", asset: "7k8RSp2TLduCfVJKyMsjMWHCoc3cYQQJrJm6pF44B5c7", maxAmountPerPayment: "50000" }] },
});
const res = await pay("https://www.plinthcity.com/api/x402/pool");Short on USDC? Borrow the gap
The Plinth payer can borrow the difference from this pool against a stock token the agent holds, pay, and keep the rest for the next calls. It borrows at least the pool's minimum loan, and locks collateral with a buffer above the loan limit.
npx plinth pay --url https://www.plinthcity.com/api/x402/pool --max-price 0.05 --max-borrow 5 --asset NVDAx --days 7 --yesA loan taken to pay is an ordinary loan: a fixed fee, a due date, and liquidation of all its collateral if it is not repaid in time. The payer never repays for you. Read the risks first.