Silent Agents
A hooded robot agent holding a finger to its faceplate
one packet every second, busy or idle

SilentAgents

Your AI agents ask models for things all day, and every request says something about you: when you work, what you want, how much you spend. On October 16, Vitalik Buterin posted a privacy wrapper for his own AI agent and named the piece it still lacked: a mixnet made for AI requests, with cover traffic that never stops. Silent Agents is that network. Your connection sends one packet every second, all day, whether your agents are talking or not. A real request takes the place of a cover packet, crosses three staked relays and reaches the model with nothing to link it back to you.

from X@VitalikButerin, Oct 16, 2026
01

Where this comes from

On October 16, 2026, Vitalik Buterin published an open-source wrapper for his AI agent that keeps the model provider from learning who is asking and what. His test question was a search for the best vegan restaurants in Tallinn. The wrapper combines five protections:

  • A Tor route per chatEvery conversation goes out over its own Tor circuit, so two chats cannot be matched by address.
  • Cover trafficExtra random requests are sent alongside the real ones.
  • zkAPI paymentsOne deposit goes into a vault on Ethereum, and each request is paid with a zero-knowledge proof. The provider is paid and never learns by whom.
  • Local rewritingA small model on your own machine rewrites each prompt, so your phrasing stays at home.
  • A sandboxThe agent runs inside bubblewrap and can only reach the network through Tor.

The gap he pointed out

Tor was designed for web browsing. Random cover traffic defeats someone who only listens. A provider that cooperates with your Tor entry relay can slow your packets down or speed them up, then look for the same rhythm arriving on its side, and most of the protection is gone.

His proposed answer was a mixnet designed for AI requests, with cover traffic that runs all the time. Silent Agents builds that mixnet. Its relays are paid in $SILENT and lose part of their stake if they cut corners.

Silent Agents is an independent project. It is not affiliated with Vitalik Buterin or the Ethereum Foundation.

Run the whole stack with Silent Agents and this is all the model provider receives when your agent sends a request.
your IP address
203.0.113.42The address of the third relay on your route.
hidden by the three-relay route
when you asked
14:32:07.418 burst, 9 packetsNothing. Your traffic had the same shape before, during and after.
hidden by constant-rate cover traffic
who paid
0x71c4...b9a2, card ending 4417A short-lived credit with no link to any deposit.
hidden by zkAPI
how you write
"quick one, cheapest flights to lisbon??"A rewritten prompt with your wording and habits taken out.
hidden by a local model on your machine
02

Your timing is the leak

Encryption hides what a packet contains. It does not hide when it left or how many came after it. Both monitors below watch the same person's agents send the same requests, live. On the left, every burst lines up with a request arriving at the provider. On the right, there is no burst to line up.

Plain Tor packets per second, your side

Each time your agent asks something, traffic jumps, and a request lands at the provider a moment later.

requests linked to you0linkable

Silent Agents packets per second, your side

The rate stays flat. Real packets, shown in green, fill slots that cover packets would have used anyway.

requests linked to you0nothing to link
03

One request, three relays

Keep scrolling to send one. Your agent talks to a small client on your machine the same way it talks to any OpenAI-compatible API. The client handles everything else.

  1. step 1

    Choose the route

    The client reads the relay list from Ethereum and picks three relays in three different regions. Relays with more stake are chosen more often.

  2. step 2

    Seal it

    The request is split into packets of one fixed size. Every packet is encrypted three times, once for each relay.

  3. step 3

    Hide it in the stream

    Your client already sends cover packets at a steady rate. The real packets fill those slots, so the rate does not change.

  4. step 4

    Shuffle it

    Each relay removes its own layer, holds the packet for a short random time, mixes it in with everyone else's traffic and passes it on.

  5. step 5

    Deliver it

    The third relay hands the request to the model provider. The reply travels back along the same route, in packets of the same size.

04

The relays

Anyone who locks $SILENT can run a relay. Relays are paid every day out of the fees users pay. The rules live in the contracts and nobody can change them.

Stake required to join0SILENT
Stake that earns rewardsup to0
Packets each relay sends per day01 per second
Wait before leaving0days
Bond to open a challenge0SILENT
Penalty for a proven false report0%of stake
day N

Relays carry traffic. Fees collect in that day's pool.

day N+1

Each relay reports its packet count.

day N+2

Any report can be challenged and put to a vote.

day N+3

Rewards for day N are ready to claim.

Catching a relay that lies

A relay that stops sending cover traffic when no one is using it saves on bandwidth and exposes the timing of everyone routed through it. That is why every report can be challenged.

  1. i
    Anyone puts up a 1,000 SILENT bond, names a relay and a day, and attaches a hash of the evidence, such as packet captures.
  2. ii
    Active relays vote for one day, each weighted by its stake. Meanwhile the accused relay's reward for that day is frozen.
  3. iii
    If the challenge is upheld, the relay loses that day's reward and 20% of its stake. Half goes to the challenger, half is burned, and the bond is returned.
  4. iv
    If it is rejected, the bond goes to the relay that was wrongly accused. If too few relays vote, the bond is returned and nothing changes.
0
relays online
0
SILENT staked
0
current day
0
in today's reward pool
05

Run a relay

You need a server that stays online, an onion address for it, and at least 50,000 SILENT. Joining takes two confirmations in your wallet: one approves the stake, the second locks it.

Before you join

  • Install the relay software on your server and leave it running for a day. It must hold one packet per second with no gaps.
  • Paste the onion address and public key here. Only their hash is written onchain.
  • Choose the region your server is really in. Clients use it to spread routes across the world.
  • Your stake can still be slashed for 14 days after you begin leaving, so leave cleanly.

Every step is in the relay docs.

GOES LIVE AT LAUNCH
waiting for your details
06

$SILENT

The whole supply is minted once at launch. After that there is no mint, no owner and no pause. Any holder can burn their own tokens.

An ERC-20 on Ethereum
85% to relays
15% burned

how each traffic fee is divided

Users pay with it

Traffic fees on the network are paid in $SILENT. With zkAPI-style credits, a payment cannot be traced to the person who sent the request.

Relays lock it up

Joining as a relay takes 50,000 locked. That deposit is what makes lying costly.

Relays earn it

Each day's pool is shared among the relays that held the full rate, by stake, counted up to 250,000.

Part of every fee is burned

15% of fees and half of every slashed stake are destroyed.

07

What stays visible

Saying plainly where the protection stops is part of the design.

limit 1

What you ask

The provider still has to read a request to answer it. The local rewrite removes how you write, not what you want. A request that contains your name still contains your name.

limit 2

All three relays at once

If one person runs every relay on your route, they can follow you. Routes cross regions and change with every conversation, which keeps that unlikely and short-lived.

limit 3

Speed

Mixing adds delay, mostly at the start of a conversation. Silent Agents trades a second or two for not being watched. It is not made for anything that needs an instant answer.

Silent Agents docs

Token $SILENT, at silentagents.xyz

Silent Agents is a mixnet for the traffic between AI agents and the model providers they call. It has one job: stop anyone watching the network, the provider included, from tying a request to the person behind it through addresses or timing.

Three things do this together:

  • Three relays per route. Each request passes through three relays run by different operators in different regions. A relay only knows the hop before it and the hop after it.
  • A fixed rate. Every client and every relay sends packets of a single size at a fixed rate, around the clock. Real packets replace cover packets, so the stream never changes shape.
  • Relays with stake. Relays lock $SILENT on Ethereum, are paid daily for holding the rate, and are slashed when they are caught skipping cover traffic.

The starting point is the privacy wrapper Vitalik Buterin described for his own AI agent on October 16, 2026. Read his post. Silent Agents is independent and is not affiliated with him or the Ethereum Foundation.

Where it fits

His wrapper has five layers. This network takes over the two that deal with the network itself and leaves the other three as they are.

LayerWhat it hidesHandled by
Local prompt rewriteHow you writeA local model on your machine, unchanged
SandboxAnything the agent might leak by itselfbubblewrap or a microVM, unchanged
zkAPI paymentsWho paid for the requestzkAPI, unchanged
Cover trafficWhen you are activeSilent Agents, as constant-rate traffic in place of random extras
Tor circuit per chatYour IP addressSilent Agents, as a three-relay mixnet built for this traffic

Random cover traffic on top of Tor still leaves bursts an active attacker can spot. Handling both jobs inside one network built for a constant rate closes the timing gap he described.

Architecture

There are four parts.

  1. The client runs on the user's machine next to the agent and looks like an OpenAI-compatible endpoint on localhost. It picks routes, seals packets and keeps the constant-rate stream going.
  2. Relays receive packets, remove one layer, wait a short random time, reorder and forward. Each relay also keeps its own outgoing rate constant by adding cover packets.
  3. The exit is the third relay on a route. It rebuilds the request from its packets, sends it to the provider over TLS, then returns the answer the same way in fixed-size packets.
  4. Ethereum holds the relay list, the stakes, the daily reward pools and the challenge votes. Nothing about any single request is ever written onchain.
agent ── localhost ──▶ client ══▶ relay 1 ══▶ relay 2 ══▶ relay 3 ── TLS ──▶ provider
                         │          (eu)        (asia)      (na)
                         └─ reads the relay list and keys from Ethereum

══ fixed-size packets at a constant rate, three layers of encryption

Packets and timing

Every packet on the network has the same size. A short request might fit in one packet and a long answer might take many, but from the outside they all look identical. Cover packets are encrypted exactly like real ones, so a relay in the middle of a route cannot tell them apart either. Only the client that made a packet knows whether it was real.

Rate

The minimum rate for a relay is one packet per second, every second of the day. That is 86,400 packets per day, and it is the figure the rewards contract checks. Busier relays send more, but never less than the minimum, and their rate never follows demand.

Mixing delay

Each relay holds a packet for a short random time before passing it on, and sends packets out in a different order from the one they arrived in. That breaks the link between a packet going in and a packet coming out, even for someone watching a single relay closely.

What an observer sees

Someone watching your connection sees a flat stream to one relay, all day. Someone watching the provider sees requests arriving from many exit relays. There is no burst on your side to line up with an arrival on theirs.

Choosing a route

The client reads every active relay from RelayRegistry: its endpoint hash, its region and its stake. It then picks three relays by these rules:

  • All three must be in different regions.
  • Within that, a relay's chance of being picked grows with its stake, up to the 250,000 cap.
  • Every new conversation gets a new route, so conversations cannot be tied together through the relays they used.

The endpoint hash onchain lets the client confirm that the onion address and key a relay announces are the ones it registered. If they do not match, the client skips that relay.

Sending traffic

Point your agent at the local client instead of the provider. Anything that talks to an OpenAI-compatible API works with no other changes.

OPENAI_BASE_URL=http://127.0.0.1:8462/v1
OPENAI_API_KEY=<your zkAPI credential>

The client keeps the cover stream running whether or not the agent is busy. Expect a small, steady amount of bandwidth while it is on, and an extra second or two of delay at the start of a conversation while the route is built.

Traffic fees are paid in $SILENT and collected by FeeSplitter. Pair this with zkAPI credentials so the payment itself cannot be traced back to you.

Running a relay

What you need

  • A server that can stay online all day with steady bandwidth.
  • An onion address and an ed25519 public key for the relay.
  • At least 50,000 SILENT in the wallet you will join from.

Joining

  1. Run the relay for a day first and check it never drops below one packet per second.
  2. Hash the onion address and public key together. The join form on the home page does this for you with SHA-256.
  3. Let the registry take your stake: approve(registry, amount) on the token.
  4. Call join(endpointHash, region, amount) on the registry. It returns true once you are in.

Region codes

CodeRegionCodeRegion
1North America5Middle East
2South America6Asia
3Europe7Oceania
4Africa

Leaving

Call beginExit(). Your relay stops being picked at once and your stake stops counting toward rewards. After 14 days, call finishExit() to take the stake back. Your stake can still be slashed during those 14 days, so a relay cannot misbehave and walk away in the same move. You can call cancelExit() at any point before you finish.

If a slash leaves you below 50,000, the registry starts your exit for you.

Days and rewards

Rewards run in days, counted from the moment the rewards contract was wired. currentEpoch() returns today's day number.

DayWhat happens
NRelays carry traffic. Fees arrive and are added to day N's pool.
N+1Each relay calls report(N, packets). A report under 86,400 is refused.
N+1 to N+2Anyone can challenge a day N report. Votes run for one day.
N+3 onwardRelays call claim(N) to collect their share.

A relay's share of day N's pool is its weight divided by the combined weight of every relay that reported. Its weight is its stake at the time of reporting, capped at 250,000. A relay that missed its report window gets nothing for that day.

If nobody earned anything on a day, anyone can call rollover(N) after day N+3 to move that pool into the current day.

Challenges

A relay that quietly drops its cover traffic when nobody is using it saves money and leaks the timing of everyone routed through it. Challenges are how the network catches that.

  1. Open. During day N+1, anyone approves 1,000 SILENT to the court and calls open(relay, N, evidenceHash). The evidence is published offchain and the hash pins it. The relay's day N claim is frozen.
  2. Vote. For one day, active relays call vote(id, support). Each vote counts with the voter's full stake.
  3. Resolve. Once voting closes, anyone calls resolve(id).
OutcomeRuleResult
UpheldVotes cast reach 10% of active stake and yes beats noDay N reward wiped. 20% of stake slashed, half to the challenger, half burned. Bond returned.
RejectedQuorum reached and no is equal to or above yesBond goes to the accused relay. Claim unfrozen.
No quorumVotes cast under 10% of active stakeBond returned. Claim unfrozen.

What counts as evidence

The most useful evidence is a capture from the relay's neighbours: if its peers saw long gaps in what it sent them, it was not holding the rate it reported. Voting relays can check that against their own records, since they were the ones receiving its packets.

Fees and burn

Traffic fees go to FeeSplitter. Anyone can call split(), which sends 85% of the balance to the rewards contract for the current day and burns the other 15%. The split is fixed in the contract and there is no owner who could change it.

Half of every slashed stake is burned as well, by the registry.

$SILENT

NameSilent Agents
SymbolSILENT
Ticker$SILENT
Websitesilentagents.xyz
Decimals18
Supply1,000,000, minted once at deployment
NetworkEthereum mainnet
AddressLAUNCHING SOON
ExtrasEIP-2612 permit, burn, burnFrom, sendMany

$SILENT is the token of Silent Agents. Relays stake it to join and earn it each day for holding the rate, and users pay their traffic fees in it. No owner, no mint after launch, no transfer fee, no pause, no blocklist.

Contracts and wiring

None of the contracts take constructor arguments. Each is deployed bare and then connected once by the deployer with wire. After wiring, the deployer has no further powers. No function in any of the contracts reverts: anything that cannot be done returns false or 0.

1. deploy Token
2. deploy RelayRegistry
          DayRewards
          ChallengeCourt
          FeeSplitter
3. registry.wire(token, court)
   rewards.wire(token, registry, court)
   court.wire(token, registry, rewards)
   splitter.wire(token, rewards)
ContractJobAddress
TokenThe $SILENT tokenLAUNCHING SOON
RelayRegistryRelays, stake, exits, slashingLAUNCHING SOON
DayRewardsDaily pools, reports, claimsLAUNCHING SOON
ChallengeCourtChallenges and votesLAUNCHING SOON
FeeSplitter85/15 fee splitLAUNCHING SOON

Contract reference

RelayRegistry

FunctionWhoDoes
join(bytes32 endpoint, uint16 region, uint256 amount)anyoneLocks at least 50,000 and registers the relay. Needs approval first.
addStake(uint256 amount)relayLocks more stake.
beginExit()relayLeaves the active set and starts the 14 day wait.
cancelExit()relayReturns before the wait ends, if stake is still at least 50,000.
finishExit()relayPays the stake back after the wait.
slash(address relay, uint256 bps, address challenger)court onlyTakes up to 50% of stake, half to the challenger, half burned.
isActive(address), stakeOf(address)viewRelay status and stake.
relays(address), relayAt(uint256)viewThe full relay record, and relays in join order starting at 1.
activeCount(), totalActiveStake()viewSize of the active set.

DayRewards

FunctionWhoDoes
fund(uint256 amount)anyoneAdds tokens to today's pool. Needs approval.
sync()anyoneAdds tokens sent straight to the contract to today's pool.
report(uint256 epoch, uint256 packets)active relayReports the previous day. Only during the next day, at least 86,400 packets.
claim(uint256 epoch)relayPays out its share from day N+3 on. Returns the amount.
rollover(uint256 epoch)anyoneMoves an unclaimed pool with no earners into today.
hold, forfeitcourt onlyFreezes or wipes a relay's share for one day.
currentEpoch(), claimable(epoch, relay), pool(epoch), weightOf(epoch, relay)viewDay number, payout, pool size, weight.

ChallengeCourt

FunctionWhoDoes
open(address relay, uint256 epoch, bytes32 evidence)anyonePosts the 1,000 bond and opens a case. Returns the case id, or 0.
vote(uint256 id, bool support)active relayVotes once per case with its stake.
resolve(uint256 id)anyoneSettles the case after voting closes.
cases(uint256), caseFor(epoch, relay)viewCase details, and the case id for a relay and day.

FeeSplitter

FunctionWhoDoes
split()anyoneSends 85% of its balance to rewards and burns 15%.
totalToRelays(), totalBurned()viewRunning totals.

Reading the registry

const reg = new ethers.Contract(REGISTRY, [
  "function relayCount() view returns (uint256)",
  "function relayAt(uint256) view returns (address)",
  "function relays(address) view returns (uint256 stake, uint64 joinedAt, uint64 exitAt, uint16 region, bytes32 endpoint)",
  "function isActive(address) view returns (bool)"
], provider);

const n = await reg.relayCount();
for (let i = 1n; i <= n; i++) {
  const addr = await reg.relayAt(i);
  if (await reg.isActive(addr)) console.log(addr, await reg.relays(addr));
}

Parameters

Every one of these is a constant. None can change after deployment.

ConstantValueContract
MIN_STAKE50,000 SILENTRegistry
EXIT_DELAY14 daysRegistry
MAX_SLASH_BPS5,000 (50%)Registry
EPOCH1 dayRewards
MIN_PACKETS86,400 per dayRewards
STAKE_CAP250,000 SILENTRewards
BOND1,000 SILENTCourt
VOTE_TIME1 dayCourt
QUORUM_BPS1,000 (10% of active stake)Court
SLASH_BPS2,000 (20%)Court
TO_RELAYS_BPS8,500 (85%)Fee splitter

Threat model

Covered

  • A provider that wants to know which IP address sent a request.
  • A provider working with the first relay on your route to match timing. This is the attack Vitalik Buterin raised against Tor, and a constant rate is the answer to it.
  • Someone watching your home connection who wants to know when your agents are working.
  • Tying two of your conversations together through the network, since each one gets a fresh route.

Outside its scope

  • The content of a request. The provider has to read it to answer it.
  • One person running all three relays on your route. Region rules and stake weighting make this unlikely, not impossible.
  • An agent that leaks things by itself. That is the sandbox layer's job.
  • Payment tracing if you pay fees straight from your main wallet. Use zkAPI-style credits.

FAQ

Is this Vitalik Buterin's project?

No. It builds the missing piece he described in his post. It is not affiliated with him or the Ethereum Foundation.

Why not use Tor on its own?

Tor sends traffic when you send traffic. That makes it quick for browsing and weak here, because the bursts can be lined up. Silent Agents takes longer to start but sends the same amount at all times.

Does the client use a lot of bandwidth?

It uses a small, steady amount the whole time it is on, instead of nothing most of the time and a lot in bursts. That steady amount is what the privacy costs.

Can a relay fake its packet count?

It can write any number into its report, but its neighbours saw what it actually sent. That is what the challenge court is for, and a proven lie costs 20% of its stake.

Who controls the contracts?

Nobody. The deployer wires them once and has no powers after that. Every parameter is a constant.