AI agent that executes ETH transactions autonomously at the cheapest gas moment.
WhenCheap is a gas-aware intent execution agent for Ethereum. Users describe transactions in plain English — "swap 0.001 ETH to USDC when gas is under $2" — and the agent monitors gas prices and executes automatically at the optimal moment.
Built on EIP-7702 session authorization, every swap executes atomically in a single transaction: fees collected on-chain, routing via Uniswap's /swap_7702 endpoint, and tokens landing directly in the user's wallet. Intent parsing runs on 0G's TEE-verified inference network, making every routing decision cryptographically verifiable. whencheap.eth serves as the agent's on-chain identity via ENS.
WhenCheap is built with NestJS (TypeScript) backend, Next.js frontend, PostgreSQL for persistence, and Redis for caching — all running in Docker.
The core execution uses EIP-7702 type-4 transactions. Users authorize a session by delegating their wallet to WhenCheapSession.sol (deployed on Sepolia and Ethereum mainnet). When gas drops below the user's limit, the agent calls executeSwap() which atomically collects protocol fees via _collectFees() and forwards net ETH to Uniswap's Universal Router — one transaction, everything done.
Swap calldata is generated via Uniswap Trading API's /swap_7702 endpoint, passing WhenCheapSession as the delegation address for EIP-7702-optimized execution.
Intent parsing uses 0G Compute Router (Qwen-2.5-7b, TEE-verified) with Groq (llama-3.3-70b) and deterministic regex as fallbacks. Gas data comes from Alchemy eth_feeHistory + Etherscan Gas Oracle, stored every 30 seconds in PostgreSQL for historical pattern analysis.
ENS: whencheap.eth is registered on mainnet and resolves as the agent's sender identity. Users can also type ENS names as recipients.
The most notable technical challenge was EIP-7702's storage constraint — agentAddress must be immutable because delegated accounts read storage as zero. We also discovered Uniswap's AlphaRouter returns value:0 for ETH input routes, requiring a workaround, and that Sepolia V3 pools have out-of-range liquidity — switching to the Trading API resolved both issues.

