Skip to main content
The owner of a TradeAgent has four on-chain actions, all gated by AgentOwnerCap (Move-level) or by the server’s ownerAddress check (hosted-fleet endpoints). Surfaced as the OwnerControls block on /agents and /agents/:agentId.

Reclaim (hosted fleet)

The hosted fleet agent owns a PredictManager whose owner is the agent’s ephemeral key. The user can’t sign predict_manager::withdraw from their wallet directly. Instead:
Server decrypts the agent key, signs predict_manager::withdraw_all<DUSDC>, and transfers the resulting coin to the fixed ownerAddress from the agent_runtime row. The recipient is never user-supplied. the agent can only reclaim to its registered owner. Frontend wiring:
Demo line: “your funds, your keys. The agent never had the right to keep them.”

Reclaim (CLI / single-agent path)

For a TradeAgent registered via pnpm agent:register, the owner withdraws from the BalanceManager directly. balance_manager::withdraw_all<DUSDC> is owner-gated by Move:
Renders only when account.address === agent.owner. Reads the BalanceManager id via sui.getObject(TradeAgent) (field balance_manager_id).

Fund (hosted fleet)

Owner signs a predict_manager::deposit<DUSDC> PTB from their wallet (sponsored), then the frontend POSTs /v1/agents/:id/sweep so the deposited coin lands inside the agent’s PredictManager via a server-signed sweep call. Two-step is required because Predict’s deposit asserts sender == manager.owner and the manager is owned by the agent’s ephemeral key.
POST /v1/agents/:id/sweep updates last_funded_ms so the auto-disable rule (3-day idle + < $1 PM balance) doesn’t fire.

Pause / Resume

Both abort with ENotOwner if cap.agent_id != object::id(agent).
Neither emits an event. The server paused column in the agents table is stale. The frontend OwnerControls and the fleet runtime’s tick guard both read is_active live via sui.getObject(TradeAgent). Do not rely on the API field.
Frontend wiring:
Header on /agents/:agentId always surfaces an ACTIVE (green) or PAUSED on-chain (warn) pill so the state is never ambiguous.

Runtime gate

Both the legacy single-agent runtime and the hosted fleet read is_active at the start of every tick:
Defensive default = active so transient RPC hiccups don’t silently halt the agent.

Three kinds of “off”

  1. Pause on-chain. Owner signs agent::pause. Runtime keeps polling but never trades. Reversible.
  2. Reclaim DUSDC. Owner POSTs /v1/agents/:id/reclaim (hosted) or signs balance_manager::withdraw_all (CLI). Funds back in wallet.
  3. Auto-disable. Server flips enabled=false if PM balance < $1 for > 3 days. Fleet stops ticking. Owner can reclaim, then either fund + reactivate or leave it dead.