Cetus Yield Agent on Sui
Build a Node.js agent that deposits funds into trading pools on Cetus Protocol (Sui’s largest DEX) and earns a share of every trade. With no private key in your .env.
The recipe is split into five phases. Each phase builds on the previous one. You can stop at any phase and have a working agent.
| Phase | What it does | Time | Risk level |
|---|---|---|---|
| 1. Monitor a Pool | Watch pool prices, detect when positions would need repositioning | 10 min | None (read-only) |
| 2. Earn Fees | Open a position, earn fees, auto-reposition when price moves | 15 min | Real funds at risk |
| 3. Adaptive Strategy | Auto-adjust earning zone width based on market volatility | 5 min | Same as Phase 2 |
| 4. Compare Pools | Scan all Cetus pools and rank by return | 5 min | None (monitoring) |
| 5. Watch the Sui yield landscape | See where your Cetus position sits in the broader Sui DeFi landscape | 5 min | None (monitoring) |
What you need
- Node.js 20+
- WaaP CLI (
npm install -g @human.tech/waap-cli@latest) - A WaaP account with SUI for gas. Phase 1 is read-only, so run it on whichever network you
intend to trade on — the
.envbelow shipsNETWORK=mainnet, and Cetus pool IDs and coin types differ per network, so a Phase 1 run on testnet does not tell you a mainnet pool resolves. If you do start on testnet, setNETWORK=testnetand swapCETUS_POOL_IDfor a testnet pool; the ID below is mainnet SUI/USDC.
Project setup
This is shared across all phases:
mkdir cetus-yield-agent && cd cetus-yield-agent
npm init -y
npm pkg set type=module
npm install @cetusprotocol/cetus-sui-clmm-sdk @mysten/sui@^1 bn.js dotenv tslib
npm install -g @human.tech/waap-cli@latestBoth pins are load-bearing — do not drop them.
@mysten/sui@^1 — the Cetus CLMM SDK targets the 1.x client API, but declares its peer as
>=1.1.2, so an unpinned install pulls 2.x, which removed SuiClient and getFullnodeUrl
from @mysten/sui/client. The agent then fails at its first import.
tslib — required by @syntsugar/cc-graph (a transitive dependency of the Cetus SDK) but not
declared by it, so npm does not install it for you.
Create a WaaP wallet
waap-cli signup --email youremail+cetus-agent@example.com --password 'YourSecurePassword!'
waap-cli whoami # note your Sui address — fund it with SUI
# Signing calls below pass --chain sui:mainnet (or sui:testnet) explicitly.Funding tip: Send native SUI from an exchange (Coinbase, Binance, etc.) directly to your Sui address. Do not bridge ETH. The Sui Bridge creates wrapped ETH, not native SUI, and you need SUI for gas. Reserve at least 0.2 SUI for transaction fees.
Testnet tip: The Sui testnet faucet rate-limits aggressively from VPS and cloud IPs. Use a browser-based faucet if the API faucet fails.
Configuration
Create a .env file. You’ll add to this as you progress through phases:
# Pool (SUI/USDC on Cetus — get pool IDs from app.cetus.zone)
CETUS_POOL_ID=0xb8d7d9e66a60c239e7a60110efcf8de6c705580ed924d0dde141f4a0e2c90105
# Agent mode: "monitor" (Phase 1) or "active" (Phase 2+).
# Documentation only — the code in these phases does not read it. Which phase you are on is
# decided by what runAgent() calls, not by this value. Kept so your .env records your intent.
AGENT_MODE=monitor
# Strategy
REBALANCE_THRESHOLD_TICKS=100
POSITION_RANGE_TICKS=200
CHECK_INTERVAL_MS=300000
# Network
NETWORK=mainnet
# Sui RPC. REQUIRED — set it. JSON-RPC is deprecated on Mysten's public fullnodes, which is
# what @mysten/sui reaches for by default, so balance and object reads fail without this.
# The code falls back to the Mysten fullnode if you leave it unset; that fallback is the
# broken path, not a working default. Treat an unset SUI_RPC as a misconfiguration.
SUI_RPC=https://sui-rpc.publicnode.comSecurity model
Every transaction goes through WaaP CLI. The signing key stays inside WaaP’s enclave, so the agent never holds a key at all, and each transaction is separately authorized by the Policy Engine.
| Layer | What it does |
|---|---|
| Signing | The signature is produced in secure hardware on WaaP’s infrastructure, gated by security policies |
| Daily limit | The point where you get asked. It reads the day’s running total, not a single transaction: below it — and exactly on it — the agent acts alone; only once a payment would take the total past it are you asked. It never halts the account. Approving one transaction does not clear the condition: while the day’s total stays above the limit, later priced requests keep asking |
| Your approval | You answer once, via Telegram or email, and the transaction goes through |
| No .env secrets | No private key in environment variables or code |
Now pick a phase and start building.
Related
- WaaP for Agents: CLI reference and setup
- CLI Commands: Full command reference