Getting started
Getting started
Plan a purchase, buy it under a policy, and check the receipt. About ten minutes on Robinhood Chain testnet.
Tollex runs on Robinhood Chain testnet (eip155:46630) and pays in testnet USDG. Writes to mainnet are disabled until an independent audit is complete. See Security.
What you need
- The base URL of a Tollex service. Everything else is discovered from
/.well-known/tollex.json. - An agent wallet with testnet USDG. The private key stays in your signer; Tollex never receives it.
- A few limits you are comfortable with: the most a single call may cost, and a daily budget.
1. Plan without spending
Ask for what you need with a cost ceiling. Resolve looks at every capability, rules out the ones that cannot meet your constraints, ranks the rest and tells you which one it would buy and why. Nothing is signed and nothing is charged. This works from any language:
const response = await fetch(`${TOLLEX_URL}/v1/resolve`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
need: "spot price for a trading pair",
input: { pair: "ETH-USD" },
constraints: { maxCost: "5000", receiptRequired: true }, // atomic units: 0.005 USDG
quote: true,
}),
});
const { resolutionId, plan, quote, execute } = await response.json();
// plan.selected, plan.evaluations[].rejections, plan.ranking.formula
// execute: { url, method, headers } to call with an x402 clientmaxCost is in atomic units. USDG has six decimals, so "5000" is 0.005 USDG.
2. Set up the client
The TypeScript client wraps your wallet in a policy. The policy is checked before the wallet is asked to sign anything.
import { TollexClient, TollexTools, usdg, type AgentPolicyProfile } from "@tollex/client";
import { PolicyEngine } from "@tollex/policy";
import { verifyReceipt } from "@tollex/receipts";
const client = new TollexClient({
wallet, // a viem account or a remote signer; the key never leaves it
policy: new PolicyEngine({
id: "research-policy",
agentId: "research-03",
networks: [NETWORK],
assets: [{ network: NETWORK, address: USDG_ADDRESS, decimals: 6 }],
schemes: ["exact"],
maxPerRequest: usdg("0.01"),
budgets: { daily: usdg("5") },
}),
requireReceipt: true,
});
const tollex = new TollexTools(client, TOLLEX_URL);3. Buy the outcome
do() resolves the intent, re-reads the live payment terms, pays within your policy, runs the capability and returns the result together with the payment and the signed receipt.
const result = await tollex.do<{ address: string; balance: string }>({
need: "token balance of a wallet",
input: { address: wallet.address },
constraints: { maxCost: usdg("0.001"), receiptRequired: true },
});
result.result.balance; // the capability's output
result.payment.actualAmount; // what was charged, in atomic USDG
result.receiptVerification?.valid; // the signed receipt checked out
result.settlement?.status.settlement; // "included", "finalized", ...4. Check settlement
A result can arrive before its settlement is final. When you need to know, ask for the operation’s state rather than inferring it from a timeout.
const { status, reached } = await tollex.awaitSettlement(result.tool.id, result.operationId!, {
until: "included",
timeoutMs: 30_000,
});
if (!reached && status.status.moneyInFlight) {
// Not known yet. Do not pay again: ask for the status later.
}5. Verify the receipt yourself
const res = await fetch(`${TOLLEX_URL}/.well-known/tollex-receipt-keys`);
const { keys } = (await res.json()) as { keys: { address: `0x${string}`; status: string }[] };
const check = await verifyReceipt(result.receipt!, {
trustedSigners: keys.filter((k) => k.status === "active").map((k) => k.address),
});
check.valid; // signature, content hash and bindings all hold
result.receipt!.body.quote?.quoteHash; // the quote this payment was bound toThat check trusts whatever keys the merchant publishes at that moment. In production, pin the receipt keys you trust instead; Receipts explains how.
Where to go next
- Intents: every constraint you can set and how they combine.
- Economic policy: budgets, allow lists and signature lifetimes.
- SDKs: what the TypeScript and Python clients and the MCP server cover.
GET /.well-known/tollex.json
→ endpoints.resolve, endpoints.catalog, endpoints.openapi, endpoints.operation, ...