Liquistate

Agents & developers Devnet

Plug your agent or bot into Liquistate. Every trade is non-custodial: you ask for a transaction, you get it unsigned, you sign it with your own key, then submit it (to us or to any devnet RPC). Liquistate never holds funds, keys, the coin or the quote asset.

Flow: prepare (/swap/build) → sign (your wallet) → submit (/swap/submit). Humans on Live pools use the exact same flow with your wallet.

Wallets. The site uses the Solana Wallet Standard: any installed standard wallet (Phantom, Solflare, Backpack, Glow, OKX, Coinbase Wallet and others) is detected automatically. In the browser, call await LQW.get() for the selected wallet; it exposes connect(), signTransaction(tx), signAndSendTransaction(tx), signMessage(bytes) and disconnect(). WalletConnect (mobile QR) turns on when the deployment sets a Reown project ID. Agents and scripts sign with their own keypair against the same unsigned-transaction APIs.

Risk: a coin paired with a tokenized stock gives no claim to shares, dividends or votes; its value moves with both the stock token and the coin. Devnet tokens have no value. Nothing here is an offer to sell securities.

Auth

Agent routes live under /api/agent/* and need an API key from a Liquistate admin, sent as X-API-Key: lq_…. Keys are stored only as hashes and are rate-limited per key (default 60 requests/min). The same read and build routes are also open under /api/amm/* with per-IP limits.

Specs: OpenAPI 3 · MCP-style tool manifest

MCP server: connect your AI bot in 2 minutes

Remote MCP (Streamable HTTP) at https://liquistate-preview.pages.dev/mcp with header X-API-Key: lq_…. Tools: list_board, get_token, quote, build_launch, build_trade, submit, register_launch, launch_status, gate_status. Build tools return unsigned transactions, so your bot signs with its own wallet. Card and real estate launches need an unlocked asset verification (gateId). Crypto and stock-paired coins do not; agent launches show a "Launched by AI agent" badge. Step-by-step guide: Build with agents.

curl -s $H/mcp -H "X-API-Key: $KEY" -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Endpoints

GET  /api/agent/markets                         pools, live on-chain price + reserves
GET  /api/agent/tokens                          coins + allowed quote assets (USDC/SOL/tokenized-stock mints)
GET  /api/agent/quote?pool=<id>&side=buy|sell&amount=1.5
GET  /api/agent/trades?pool=<id>                 recent on-chain swaps
GET  /api/agent/stream?pool=<id>                 live trades (Server-Sent Events: snapshot, trade, ping)
POST /api/agent/swap/build   {pool, wallet, side, amount, slippageBps}  → {tx: base64 UNSIGNED}
POST /api/agent/swap/submit  {tx: base64 SIGNED}                       → {signature, explorer}
POST /api/agent/pool/build   {wallet, coinMint, quote, coinAmount, quoteAmount} → stock-paired pool tx (UNSIGNED)

curl

KEY=lq_your_key; H="https://liquistate-preview.pages.dev"
curl -s -H "X-API-Key: $KEY" $H/api/agent/markets
curl -s -H "X-API-Key: $KEY" "$H/api/agent/quote?pool=DzqDEvkvkEB51qgKQ4Z7uJVGowHYZDbUGU2wbCmYdkJ9&side=buy&amount=1"
curl -s -H "X-API-Key: $KEY" -H 'content-type: application/json' \
  -d '{"pool":"DzqDEvkvkEB51qgKQ4Z7uJVGowHYZDbUGU2wbCmYdkJ9","wallet":"YOUR_PUBKEY","side":"buy","amount":"1"}' \
  $H/api/agent/swap/build

Live trades stream (SSE)

Server-Sent Events, not WebSocket. Events: snapshot (recent trades), trade (each new on-chain swap), ping. The server closes after about a minute and clients reconnect automatically.

curl -N -H "X-API-Key: $KEY" "$H/api/agent/stream?pool=DzqDEvkvkEB51qgKQ4Z7uJVGowHYZDbUGU2wbCmYdkJ9"
// browser / no key: new EventSource("/api/amm/stream?pool=...").addEventListener("trade", e => console.log(JSON.parse(e.data)))

@solana/web3.js

import { Keypair, Transaction } from "@solana/web3.js";
const H = "https://liquistate-preview.pages.dev", KEY = process.env.LQ_KEY;
const me = Keypair.fromSecretKey(/* your own devnet key, never sent to Liquistate */);
const post = (p, b) => fetch(H + p, { method: "POST", headers: { "content-type": "application/json", "x-api-key": KEY }, body: JSON.stringify(b) }).then(r => r.json());
const b = await post("/api/agent/swap/build", { pool: "DzqDEvkvkEB51qgKQ4Z7uJVGowHYZDbUGU2wbCmYdkJ9", wallet: me.publicKey.toBase58(), side: "buy", amount: "1", slippageBps: 100 });
const tx = Transaction.from(Buffer.from(b.tx, "base64"));
tx.partialSign(me);                                     // you sign locally
const r = await post("/api/agent/swap/submit", { tx: tx.serialize().toString("base64") });
console.log(r.signature, r.explorer);

Stock-paired launch

A creator launches a new coin, then pairs it with a quote asset: USDC, SOL or a listed tokenized-stock token issued by a third party. /pool/build returns an unsigned Raydium CPMM pool creation tx; the creator's wallet pays the pool fee and rent and seeds both sides. On devnet, real stock tokens don't exist, so the quote list includes TESTSTOCKx (devnet mock).