Developers
Build agents on the Prime SDK.
An agent on Prime is a program that produces typed intents — it never builds calldata. The SDK turns those intents into policy-scoped trades that settle inside the user's account, and the on-chain validator re-checks every one. Whatever you build, it's bounded: swap-only, listed tokens, within caps, never a withdrawal.
Two ways to ship an agent
No-code
Use the Publish flow: define a strategy's scope and caps in the UI, preview the exact permission it runs under, and register it on-chain. No SDK required.
The SDK
Write a strategy in TypeScript against @prime/agent-sdk. You emit intents; the SDK handles session-key signing, the venue adapter, and userOp submission.
The typed intent
The only thing a model or strategy is allowed to produce. Fields are registry keys and numbers — there is no address or bytes field, by construction.
type Intent =
| { kind: "spot_buy"; tokenOut: string; quoteToken: string; amountUsd: number }
| { kind: "sell"; token: string; quoteToken: string; fraction: number }
| { kind: "limit_buy"; tokenOut: string; quoteToken: string; amountUsd: number; triggerPriceUsd: number }
| { kind: "guardian"; token: string; trigger: "stop_loss" | "take_profit"; priceUsd: number }
| { kind: "dca"; tokenOut: string; quoteToken: string; amountUsd: number; everyHours: number }
| { kind: "basket"; quoteToken: string; legs: { tokenOut: string; amountUsd: number }[] }
| { kind: "portfolio" }
| { kind: "price"; token: string }
| { kind: "reject"; reason: string };Connect an agent
PrimeAgent binds a session key to a delegation and executes swaps through a whitelisted venue. It signs userOps; it never holds funds.
import { PrimeAgent, UniswapV3VenueAdapter, EntryPointSubmitter } from "@prime/agent-sdk";
const agent = await PrimeAgent.connect({
rpcUrl, validator, entryPoint,
delegationId, // the scoped permission granted from the account
sessionPrivateKey, // the agent's hot key — bounded by the delegation
registry, // the ticker -> address authority
submitter: new EntryPointSubmitter(wallet, bundler, entryPoint),
});
// A swap runs inside the account; the on-chain validator re-checks asset, venue, action, and caps.
await agent.swap(new UniswapV3VenueAdapter(venue), { tokenIn, tokenOut, amountIn });Strategies as building blocks
The shipped strategies are pure functions — give them a snapshot, they return what to do. Compose them, or write your own.
The policy is the boundary
Whatever your agent does, the delegation bounds it. The SDK mirrors the on-chain rules (kept in lockstep by a parity test) so you can check locally, but the chain is the final authority:
- Swap-only. transfer / transferFrom / setApprovalForAll / native sends are forbidden — to any destination.
- Listed tokens only, checked on the decoded trade, not raw calldata.
- Whitelisted venues + actions (function selectors); self-calls forbidden.
- Per-trade + rolling-24h notional caps, oracle-priced at execution.
- Revocable + expiring — one-way, re-checked in the execution phase.
Run it locally
The whole stack runs on a local devnet. Each command is a real, verified proof.
anvil && pnpm deploy:local # a local chain + the protocol pnpm plan "buy $50 of Tesla" # English -> a typed intent (needs an API key) pnpm e2e:agent # the unified agent: stop-loss + dip + DCA in one tick pnpm e2e:rebalance # a drifted basket restored to target weights pnpm e2e:keeper # the always-on loop fires a stop-loss on a market move pnpm keeper # run the always-on agent yourself
Status
Unaudited, devnet software. The SDK and strategies are covered by contract tests + live on-chain end-to-end proofs, but nothing here has been through a security audit — don't point it at real funds. A bring-your-own-agent publish flow is live, and the HTTP API (English → typed intents, with stateless keys) is live with a browser console.