Your deploy key is going to leak.
Not because you are careless — because it has to be hot. It lives in a file, an agent reads it, a script signs with it. Nchedo is the vault that already assumes the file is public: slow money next to a tripwire, on Monad.
one transaction deploys the vault, the bait, and the canary
MONAD_RPC_URL=https://testnet-rpc.monad.xyz
VAULT_OWNER_KEY=0x5bd8…c2b9
CANARY_KEY=0x967e…7e92▍
tripwireThe key has to stay hot. That is the whole problem.
Cold storage works by making signing hard. But a deploy key that signs ten times a day cannot live in a drawer. It sits in .env, readable by every agent and script you run, and one day it is in a public repo, a paste, a screenshot.
The usual answer is to rotate fast and hope you noticed in time. Nchedo's answer is to decide, in advance, exactly what the leak is allowed to cost.
Leaked keys get swept within seconds — bots watch public pushes for them.
The thief keeps 0.100 MON. That was always the price of the alarm.
The canary never fires here. The delay is what buys the time — someone has to use it.
Three moves. Two of them are yours.
Build it.
One transaction deploys the vault and the bait, wires them together, and dusts the canary with gas so a thief can afford to spend it. You choose the reserve, the bait, the delay, and a recovery address that never touches the repo.
Leak it on purpose.
The canary key goes into the same .env as your deploy key. Not a safer file — the same file. A canary you are careful with is a canary that survives the leak that mattered. It only works if the two keys travel together: same commit, same paste, same screenshot.
VAULT_OWNER_KEY=0x5bd8…c2b9
CANARY_KEY=0x967e…7e92
Let it spring.
Nothing legitimate ever signs with the canary, so one signature is not a score or an anomaly — it is proof. The bait pays the thief instantly, and the same transaction locks the vault and kills any withdrawal in flight. You sweep the reserve with the recovery key.
Three keys. Only one is allowed to be careless.
Hot and scriptable. Signs deploys all day and refills from the vault on a delay. The one that leaks — and the one a leak can no longer drain.
.envSpends exactly once, ever. Whoever signs with it gets 0.100 MON instantly and locks the vault in the same transaction. That is the entire detector.
.env · same file, on purposeCold, on another machine, ideally in a drawer. The only key that can unlock a locked vault or sweep it to safety.
never in the repoSlow money
Every withdrawal is announced on-chain and waits out the delay in public.
If a request was not you, this is your fifteen-minute window.
The tape forgets nothing
Every event prints with a transaction hash. If it is on the tape, it happened — there is no other memory.
0xbd93f8…a1 · 0x77c04e…9c · 0x02d1af…4e
armed, still usable
Kill switch included
The lock cancels any withdrawal still in flight — even one requested seconds before.
withdrawal killed mid-flight ✕
· MONAD ·
· FOUNDRY ·
· VIEM ·
Live on Monad Testnet
What it guarantees, and what it does not.
Both columns are provable, and both are in the test suite. A security tool that only lists its wins is one you can't trust with the losses.
- A leaked owner key cannot drain the vault instantly — every withdrawal matures in public.
- A claimed bait locks the vault and cancels any pending withdrawal, in the thief's own transaction.
- Only the recovery key can move a locked vault. The owner key can never unlock it.
- Stop an attacker who reads the code, ignores the bait, and waits out the delay. It gives you a public window; using it is your job.
- Contain a sweeper that only takes the canary's gas and never claims. That is an alert, not containment.
- Protect an EOA. No contract can freeze a wallet — Nchedo protects money you put in the vault.
The delay applies to everyone. Including you.
A vault that pays its owner instantly is a vault that pays a thief instantly. Fifteen minutes is the price of a key you are allowed to lose.
Treat the leak as a when, not an if.
Build the vault before it happens: reserve, bait, and canary in one transaction on Monad testnet.