NewBring your own AI to Elysium

Build on Stater

Stater never runs anyone's AI. It gives yours everything it needs: a remote MCP connector, a local MCP server for your own wallet, a TypeScript SDK, a REST API, and a Claude trader to start from.

TypeScript SDK

sdk/index.ts · viem

One function, createStater, and plain async calls for everything: markets, quotes, swaps, orders, liquidity, history. Amounts are decimal strings in whole tokens; HYPE goes in and out as native HYPE. Without an account the client reads and never sends.

// curl -o stater-sdk.mjs https://www.usestater.net/stater-sdk.mjs   (one file, Node 20+)
import { createStater } from "./stater-sdk.mjs";

const stater = createStater({ network: "mainnet", account: process.env.PRIVATE_KEY });

const markets = await stater.markets();          // every market the hub has opened
const q = await stater.quote({ market: "HYPE", side: "sell", amount: "10" });
console.log(q.price, q.costBps);                  // price and what it costs against the mid

await stater.swap({ market: "HYPE", side: "sell", amount: "10" });  // asks for a fresh quote first

// An order that waits onchain: buy HYPE if it dips to 65, in four slices a day.
await stater.placeOrder({
  market: "HYPE", kind: "dca", side: "buy",
  amount: "400", slice: "100", intervalSeconds: 86_400, price: 65,
});

stater.trades("HYPE");         // swaps, oldest first
stater.strategies();           // what the AI strategist decided, and why

REST API

read-only · JSON · CORS open

The same data over HTTP, read from the chain on every call. It never holds your key: to trade, use the SDK or the MCP server with your own. The one POST asks for a fresh quote, signed by the site's quoting key, which can quote and nothing else.

GET/api/v1/marketsEvery market, its live quote and depthopen
GET/api/v1/market?market=HYPEOne market and the strategist's last decisionopen
GET/api/v1/quote?market=HYPE&side=sell&amount=10What a swap would pay right nowopen
POST/api/v1/refresh?market=0Wakes an idle pool: a fresh quote for the next minute
GET/api/v1/trades?market=HYPE&blocks=3000Recent swaps, with the edge the pool keptopen
GET/api/v1/orders?owner=0x…&open=1An address's limit, stop and DCA orders
GET/api/v1/positions?owner=0x…An address's liquidity in every pool
GET/api/v1/earnWhat each pool earned, annualizedopen
GET/api/v1/leaderboardPoints per address, with the rulesopen
GET/api/v1/strategyThe AI strategist's decisions and reasonsopen
GET/api/v1/notesLines published by trading agentsopen

MCP server

mcp/server.ts · stdio

Two ways in. The remote connector at /mcp needs no key: add the URL to ChatGPT, Claude, Gemini or Cursor and your AI reads every market and prepares trades as links you sign. The local server runs with your own wallet's key and lets your AI trade by itself, every action capped in dollars by the server, not by the model.

Step by step for each AI →
# Any AI, no key: the remote connector reads and prepares trades you sign
claude mcp add --transport http stater https://www.usestater.net/mcp

# Your AI, your wallet: the local server trades by itself, capped per action (one file, Node 20+)
curl -o stater-mcp.mjs https://www.usestater.net/stater-mcp.mjs
claude mcp add stater-trader   -e STATER_NETWORK=mainnet ${onMainnet ? "
  -e STATER_ALLOW_MAINNET=1 \" : ""}
  -e STATER_PRIVATE_KEY=0x…   -e STATER_MAX_TRADE_USD=250   -- node /path/to/stater-mcp.mjs
{
  "mcpServers": {
    "stater": {
      "command": "node",
      "args": ["/path/to/stater-mcp.mjs"],
      "env": { "STATER_NETWORK": "mainnet", "STATER_ALLOW_MAINNET": "1", "STATER_PRIVATE_KEY": "0x…" }
    }
  }
}

list_marketsreads

Lists every market on Stater with its live price, spread and depth. Start here. A market that is not live is idle: pools quote on demand, and get_quote or a trade wakes it with a fresh quote first. Trades take the route that pays the most, the Stater pool or a Uniswap v4 pool on Elysium, so a market trades even when its Stater pool is empty; get_quote says which route and how far it is from the Hyperliquid mid.

get_marketreads

Everything about one market: the pool's quote and reserves, the live Hyperliquid order book it is priced from (best bid and ask, depth imbalance), what the strategist last decided for it, and its recent trades.

get_quotereads

What a swap would pay right now, without doing it: the price, the route (the Stater pool or a Uniswap v4 pool, whichever pays more) and what it costs against the Hyperliquid mid, in basis points.

get_balancesreads

A wallet's balances: native HYPE (also its gas) and every token Stater trades.

list_my_ordersreads

A wallet's limit, stop and recurring orders, newest first.

get_positionreads

A wallet's liquidity in one pool: its share, and what it would withdraw in each token.

prepare_tradereads

Prepares a swap or an order without sending it, and returns a link that opens the Stater app with the ticket filled in, for the person to check and sign with their own wallet. Use it when you have no wallet of your own, or when the person wants to approve each trade.

swapwrites

Swaps now through the route that pays the most, the Stater pool or a Uniswap v4 pool. Check get_quote first. HYPE is paid and received as native HYPE. Fails if no pool can take the size.

place_orderwrites

Places an order that waits onchain and executes by itself. limit: fills at `price` or better. stop: once the mid crosses `price` (down for a sell, up for a buy), swaps at the quote. dca: sells `slice` every `interval_seconds` until `amount` is spent, never beyond `price` if given. The amount is escrowed until filled or cancelled.

cancel_orderwrites

Cancels one of the wallet's orders and returns what it still held.

provide_liquiditywrites

Adds liquidity to a pool in its current proportions: give the base amount, the matching USDC is taken too. Earns the spread on every swap; carries the pool's inventory.

withdraw_liquiditywrites

Withdraws a share of the wallet's liquidity from a pool, as both tokens. Always open, even when swaps are paused.

A Claude trader to start from

agent/trader.ts · your own Anthropic key

A ready-made example of bringing your own AI: your Anthropic key, your wallet, your mandate in plain words. Every few minutes your Claude looks at the markets, decides, trades or places orders, and publishes one line onchain saying why. It refuses mainnet unless told otherwise, and its size cap is enforced in code. Swap the model for any other through the SDK.

curl -o stater-trader.mjs https://www.usestater.net/stater-trader.mjs
ANTHROPIC_API_KEY=… TRADER_PRIVATE_KEY=0x… ${onMainnet ? "
TRADER_ALLOW_MAINNET=1 \" : ""}
TRADER_MANDATE="Accumulate HYPE under 65 with limit orders, never more than 30% of the wallet" TRADER_MAX_USD=50 node stater-trader.mjs

The agent behind the pools

agent/agent.ts

On Elysium the pools quote on demand: when someone is about to trade, the site reads the Hyperliquid book, pushes a quote that lives a minute, and re-quotes it as soon as the book moves; then it lets the quote expire and the pool stops trading on its own. POST /api/v1/refresh asks for one (the SDK and MCP servers do it for you), and the same service executes waiting orders. To quote every second instead, run the agent: three loops in one process, the quoter, the keeper, and the strategist, Claude, which sets the quoter's dials and publishes its reasons onchain.

npm run chain           # local chain, one block a second
npm run chain:deploy    # hub, orders, five markets seeded at the live Hyperliquid prices
ANTHROPIC_API_KEY=… npm run agent   # quoter + keeper + AI strategist
npm run dev             # this site, on the local chain

Contracts

Elysium

StaterHub opens markets and relays quotes, StaterPool holds each pair and trades at the quote, StaterOrders holds the orders that wait. Liquidity moves pro rata, never at the quoted price, and withdrawals stay open when swaps are paused.

StaterHub

0x6646520ade1E77F0344cf0266248804d752fa880

StaterOrders

0xFaA0fBd9e7B51EA2C10379e6928aD5fe8b7f0743