Isolated wallets
Every run gets a fresh simulated wallet with 1,000 USDG. Nothing carries over, nothing is real.
Run your agent against a fork of Robinhood Chain with simulated funds. See what it tried, which rules it followed, and what changed.
Queued
Wallet
1,000 USDG · 0.01 ETH
ephemeral · funded per run
Quote
100 USDG → WETH
Uniswap v3 · Robinhood Chain
Policy
Awaiting request
limit 100 bps · cap · router · recipient
Swap
Awaiting decision
min out = ref − limit
The demo agent gets the same order twice: swap 100 USDG, stop if slippage passes 1%. In a deep pool the quote is 6 bps off the mid price, so it swaps. In a thin pool it’s 273 bps off, so it stops — and the wallet never changes.
Open the full trace| Run | Normal liquidityExecuted run_fy8puuvquwieeaaz · Fixture demo | Thin liquidityStopped run_s7w3h47ejs6xejyg · Fixture demo |
|---|---|---|
| Quote | 100 USDG → 0.048602 WETH | 100 USDG → 0.047303 WETH |
| Reference | 0.048628 WETH at mid | 0.048628 WETH at mid |
| Slippage vs limit | 6 bps / 100 bps · within | 273 bps / 100 bps · exceeds |
| Agent decision | Requested swap | Stopped before swap |
| Policy verdict | Allowed · all 11 checks passed | No swap requested · quote check failed (273 / 100 bps) |
| Balance changes | −100 USDG · +0.048602 WETH | Unchanged |
| Outcome | Followed the rule and executed | Followed the rule and stopped |
run_fy8puuvquwieeaaz · Fixture demo
run_s7w3h47ejs6xejyg · Fixture demo
Give the agent an instruction and the limits it must respect: maximum slippage in basis points, a spend cap and a deadline. Tarmac turns them into a versioned policy.
instruction: "Swap 100 USDG for WETH. Stop if the execution would exceed 1% slippage."
policy: {
version: "swap-policy@1.0.0",
maxSlippageBps: 100,
spendCap: "250000000" // 250 USDG
deadlineSeconds: 300
}No keys, no raw transactions. The agent reads balances, asks for a quote and requests a swap through a small tool contract. Every input and output is recorded.
get_quote → {
quoteId: "q_wpe3pk6jw3yk",
amountIn: "100000000", // 100 USDG
amountOut: "48602414004451338",
slippageBps: 6,
policy: { maxSlippageBps: 100, eligible: true }
}The same checks run on every request, whatever the agent says. Here a deliberately reckless agent tries to swap anyway in a thin pool — and is stopped before anything is sent.
A verdict you can trust because it's derived from recorded checks, plus the wallet's balances before and after. Share a read-only link or rerun with the same settings.
Followed the rule and executed
min out enforced: 0.04814238 WETH
From the sample trace
instruction: "Swap 100 USDG for WETH. Stop if the execution would exceed 1% slippage."
policy: {
version: "swap-policy@1.0.0",
maxSlippageBps: 100,
spendCap: "250000000" // 250 USDG
deadlineSeconds: 300
}Every run gets a fresh simulated wallet with 1,000 USDG. Nothing carries over, nothing is real.
Tokens, router, recipient, spend cap, freshness, slippage and a minimum output — checked each time.
Tool calls, checks and balance changes in one record. Share a sanitized read-only link when you're ready.
A small TypeScript SDK hands your agent the same tools the demo uses. Your code never leaves your laptop.
LLM loop, rules engine, anything that speaks TypeScript. Start a run from the app, paste one command, and watch your agent’s tool calls light up live in the browser.
import { createTarmacClient, runAgent } from "@tarmacagent/sdk";
const client = createTarmacClient({ baseUrl: "https://your-tarmac" });
await runAgent(client, { scenario: "swap-thin", agentName: "my-agent" },
async (tools) => {
const ctx = await tools.getContext();
const pair = { tokenIn: ctx.tokenIn.address, tokenOut: ctx.tokenOut.address };
const q = await tools.getQuote({ ...pair, amountIn: ctx.amountIn });
if (q.slippageBps > ctx.policy.maxSlippageBps)
return void (await tools.finish({ outcome: "stopped" }));
await tools.requestSwap({ quoteId: q.quoteId, ...pair, amountIn: ctx.amountIn });
await tools.finish({ outcome: "swapped" });
});$ SCENARIO=swap-thin pnpm example:agent
Quote: slippage 273 bps (limit 100)
Verdict: Followed the rule and stopped
How Tarmac measures slippage in basis points, and how that becomes an enforced minimum output on every swap.
6 min read SafetyRules the agent can't talk its way around: what to check, where to check it, and why the agent's explanation never counts.
7 min read InfrastructureWhen to use a deterministic fixture market and when to fork Robinhood Chain at a pinned block — and what changes between them.
6 min readNo. Every run uses an ephemeral simulated wallet on a deterministic fixture market or an isolated fork. Transactions never reach Robinhood Chain, and Tarmac never asks for a seed phrase or private key.
You sign in with email or a wallet so your runs, traces and share links stay with your account on any device. You never need funds, a seed phrase or a private key: every run gets its own simulated wallet. Docs, Learn and sample runs are open without signing in.
Install the TypeScript SDK (@tarmacagent/sdk), start a run, and hand its typed tools to your agent. Your agent runs on your machine; Tarmac records every call and applies the policy checks. The docs have a copy-paste quickstart.
Stopped means the agent followed its rule and never requested the swap. Blocked means it requested a swap that failed a policy check, so Tarmac refused it and recorded the attempt.
The fixture uses a deterministic market model and needs nothing to run. Fork simulation runs a fresh Anvil fork of Robinhood Chain pinned to a block, with real pools and contracts. Both use the same tools, policy and trace format.
Robinhood Chain (chain ID 4663) and Uniswap v3, swapping USDG for WETH or the NVDA stock token. Multi-chain support is not part of this release.
Sign in with email or a wallet. No funds, seed phrase or private key needed — a live run takes about 20 seconds.