TradeAgent is the on-chain identity for an AI trader. Holds name, Walrus strategy blob ref, agent address, human owner, BalanceManager id, TradeCap id, PredictManager id. Tracks reputation via signed PnL and a PLP score.
Custody surface
TradeAgent
public struct TradeAgent has key, store {
id: UID,
name: String,
strategy_blob: vector<u8>, // Walrus blob id
agent_address: address, // operator address
owner: address, // human owner
balance_manager_id: ID, // DeepBook V3 BalanceManager
trade_cap_id: ID, // DeepBook V3 TradeCap
predict_manager_id: ID, // optional; 0 sentinel if absent
is_active: bool, // pause / resume gate
realized_pnl_abs: u128, // signed via two fields
realized_pnl_sign: bool,
plp_score: u128, // cumulative utilization share
}
Signed-PnL trick. Sui Move has no native i128. We split the signed quantity into realized_pnl_abs: u128 + realized_pnl_sign: bool. On record_outcome, the runtime computes new = old + delta in i128 mentally and writes back the abs+sign.
AgentOwnerCap
public struct AgentOwnerCap has key, store {
id: UID,
agent_id: ID,
}
Gates the three owner-only actions:
public fun pause(agent: &mut TradeAgent, cap: &AgentOwnerCap)
public fun resume(agent: &mut TradeAgent, cap: &AgentOwnerCap)
public fun record_outcome(
agent: &mut TradeAgent,
cap: &AgentOwnerCap,
pnl_delta_abs: u128,
pnl_delta_sign: bool,
plp_score_delta: u128,
)
All three abort with ENotOwner if cap.agent_id != object::id(agent).
Registration
public fun register_agent(
registry: &mut AgentRegistry,
name: String,
strategy_blob: vector<u8>,
agent_address: address,
balance_manager_id: ID,
trade_cap_id: ID,
predict_manager_id: ID,
ctx: &mut TxContext,
): (TradeAgent, AgentOwnerCap)
Wraps AgentRegistered { agent_id, name, owner, agent_address } event. Wired via scripts/register-trade-agent.ts and the /agents Create wizard.
Pause/resume + indexer
pause and resume emit no events (verified at agent.move:215). The server paused column in the agents table is stuck at the registration default. Authoritative source for an agent’s active state is sui.getObject(TradeAgent).is_active. Frontend OwnerControls and the agent-service tick guard both read it live. Do not trust the API field.
Tests
No dedicated test file in tests/; covered indirectly by predict_facade_tests and the per-agent flows.