Inspiration

AI agents and trading bots need keys, and keys get stolen. Prompt injection, malware or a leaked API key is enough for an agent to sign whatever an attacker wants. In most "safe AI wallets" the protection lives in the bot or on the server, which are exactly the parts that get hacked. We wanted the rules to live where a hacked server cannot switch them off: in the customer's own on-chain vault.

What it does

EPK gives every customer a separate vault at a permanent address. AI agents, bots and servers pay from it, but only within the rules the vault itself enforces:

  • Limits: outflow limits per asset, measured on real balance changes.
  • Allowed destinations: money only goes to addresses on the vault's list, and token approvals never outlive the batch that created them.
  • Agent sessions: AI agents get short sessions with their own budget and expiry, only for calls the owner approved in advance.
  • Guardians and timelock: tightening is instant, while loosening waits in a timelock that any guardian can veto. Guardians can stop everything but never move funds.
  • Panic: one call pauses the vault and revokes every earlier permission.
  • Emergency evacuation: the owner's recovery key moves every asset at once, but only to a cold wallet registered in advance. Redirecting that wallet waits 3× the timelock and can be cancelled.
  • Watchtower: an automatic guardian that cancels any change the owner did not plan, within seconds.
  • Guard modules for trading: DexGuard checks the swap recipient, a token list, deadlines and Chainlink prices on DEX routers. ThreatFeed V2 is a shared blocklist.
  • Owner-only upgrades: new releases come through a public registry, and each vault opts in through its own timelock. Nobody, including IBITI Labs, can upgrade a customer's vault for them.

Proven on BSC Testnet (November 2026, release 2.3.0)

All of this ran on one vault, and every step is a real transaction:

  • The AI agent paid the treasury on its own.
  • 5 attacks were rejected on-chain: over budget, an unknown address, a forbidden call, a forged signature, and a stranger replaying the agent's signature.
  • A guardian pressed panic. Recovery went through the timelock, and the old session stays dead.
  • A stolen admin key scheduled a new payout address. The Watchtower cancelled it 9 blocks (about 4 seconds) later.
  • The same key tried to redirect the owner's cold wallet. That was cancelled 6 blocks later, and executing it anyway was rejected.
  • A guardian tried to evacuate and was refused.
  • The owner's recovery key evacuated all 9,940 eUSD to the cold wallet in one transaction.

Result: 9 of 9 attacks rejected, 0 eUSD moved by attackers.

A second vault traded on the real PancakeSwap V2 testnet router, and its guards rejected 12 attacks. On the same testnet pool, an unprotected wallet received about 37% less than the Chainlink price for a trade the vault refused (test tokens).

A live vault was also upgraded from 2.2.0 to 2.3.0 through the SDK in about five minutes, on testnet clocks, with the same address and the same funds.

Check every claim yourself, in your browser: https://vovan1980.github.io/ibiti-epk-core/proof/

How we built it

  • Contracts: Solidity 0.8.24 with Foundry and OpenZeppelin.
    • One upgradeable vault per customer, created by a factory with CREATE2.
    • A release registry with a public window.
    • Guard modules: DexGuard, ThreatFeedGuard and CompositeGuard.
  • Watchtower: Python with no dependencies. It watches the vault's timelock and cancels unexpected changes with a guardian key.
  • TypeScript SDK on viem: vaults, signed batches, agent sessions, the timelock, upgrades and guards.
  • Evidence: every claim is written into a machine-readable evidence file. A pure-Python verifier and public proof pages re-check it live against BSC Testnet.

Challenges we ran into

  • Contract size limit (EIP-170). Evacuation pushed the vault 1,011 bytes over the 24,576-byte limit. We moved the emergency code into a module that each implementation deploys itself, which brought the vault to 24,390 bytes.
  • Public nodes forget history. The verifier asks several free nodes in turn, and execution traces of every rejected attack are saved right after sending.
  • One code base, two clocks. Test networks run 5-minute windows and timelocks, while mainnets keep 7 days, 2 days and at least 1 hour, all with the same contract code.

Accomplishments that we're proud of

  • No need to trust us. The proof page re-runs 137 checks in your browser, and the guard demo page runs 113. The deployed bytecode matches the source byte for byte.
  • Tests: 211 contract tests passed and 3 fork tests skipped (214 in total), including fuzz and stateful invariants. There are 16 Watchtower tests and 16 SDK tests, plus five internal security reviews and Slither analysis.

What we learned

Security claims are only worth something when anyone can re-check them. "Prove, don't promise" shaped the whole project: evidence files, saved traces, and proof pages pinned to a fixed commit.

What's next for IBITI EPK

  • A Watchtower 24/7 service with alerts.
  • A fast track for critical security fixes that needs both the owner and the guardians.
  • An independent security audit.
  • Then mainnet, and the final SDK release.

Status: testnet only, test tokens, not audited yet. License: IBITI Labs EPK License. The code is free to read, audit, test on test networks and help develop. Hackathons, grants, real assets and commercial use are only with IBITI Labs.

Built With

Share this project:

Updates