Veyto

Quickstart

From an API key to a governed payment on Base Sepolia.

You need: a Veyto sandbox API key, Node 22+, a throwaway Base Sepolia wallet, and a little test USDC.

1. Install

bash
npm install @veyto/sdk viem

2. Get test money

Generate a throwaway key — one that holds nothing but test funds:

bash
node -e "console.log(require('viem/accounts').generatePrivateKey())"

Fund it with Base Sepolia USDC at faucet.circle.com. You do not need ETH: the facilitator submits the transaction and pays the gas. You only sign.

⚠️ Testnet keys only. Veyto never receives your key, but you should still use one that has never touched mainnet.

3. Point the SDK at Veyto

ts
import { VeytoClient, localSigner } from "@veyto/sdk";

const veyto = new VeytoClient({
  baseUrl: "https://sandbox.veyto.io",
  apiKey: process.env.VEYTO_API_KEY!,     // the one credential Veyto needs
  agentId: "pending",
  rail: "eip155:84532",                   // Base Sepolia
  currency: "USDC-6",
  sign: localSigner(process.env.MY_WALLET_KEY!),   // stays in YOUR process
});

4. Create an agent and give it limits

ts
const agentId = await veyto.createAgent(
  "research-agent",
  "noncustodial",
  "0xYourPublicPayerAddress",             // an address, never a key
);

// $1.00 per payment, $5.00 per day, 20 payments per hour
await veyto.setPolicy(agentId, "1000000", "5000000", 20);

5. Let it pay

ts
const agent = new VeytoClient({ /* …same config, agentId… */ });

const res = await agent.payingFetch("https://some-service/premium/data");
const data = await res.json();

payingFetch does the whole dance: the 402, the authorization request to Veyto, the local signature, the retry with payment attached, and reporting the outcome back.

6. See it get blocked

ts
import { VeytoDeniedError } from "@veyto/sdk";

try {
  await agent.payingFetch("https://some-service/expensive");
} catch (e) {
  if (e instanceof VeytoDeniedError) {
    console.log("Blocked:", e.reason);   // "exceeds per-payment cap"
  }
}

No money moved. That is Veyto working, not failing — see Blocked.

7. Read the receipt

ts
const { items } = await veyto.listReceipts({ limit: 1 });
console.log(items[0].signed.body_canonical);   // exactly what was signed

Then verify it.

A complete, runnable example

The hosted payment example does all of the above in one file you can copy: it creates an agent, sets guardrails, makes a real Base Sepolia payment, gets blocked on purpose, and checks the receipt. It runs no Veyto backend — Veyto is a URL.