@agg-build/sdk

中文文档
4.37.0发布于 2026/11/06MITTypeScriptESM + CJS近 30 天下载 5933

Vanilla TypeScript client for the AGG prediction market aggregator (auth, markets, orderbooks, charts, trading, managed execution, WebSockets). Works in browsers, Node.js, and React Native.

原始使用文档
文档目录21 节
  1. What it is
  2. When to use this package
  3. Install
  4. Quick start
  5. Authenticate a user (SIWE)
  6. HttpOnly cookie-refresh mode
  7. Streaming data (WebSocket)
  8. Server-side helpers
  9. Client options
  10. Main exports
  11. AggClient methods
  12. Standalone utilities
  13. Error handling
  14. @agg-build/sdk/server
  15. WebSocket callbacks
  16. Headers attached automatically
  17. Entrypoints
  18. Peer dependencies
  19. Links
  20. License
  21. Venue event read admission

@agg-build/sdk

Vanilla TypeScript client for the AGG prediction market aggregator — one client, every surface (auth, markets, orderbooks, charts, trading, managed execution, WebSockets).

What it is

@agg-build/sdk is the lowest-level package partners install. It speaks to the AGG API over HTTPS and WebSockets, manages auth/session state, and exposes typed wrappers for every product endpoint (markets, orderbooks, charts, trade execution, deposits/withdrawals, managed wallets, admin and more). It has no framework dependency and works in browsers, Node.js, and React Native.

For React apps, layer @agg-build/hooks, @agg-build/ui, and @agg-build/auth on top — they all use this client under the hood.

When to use this package

  • You are building a vanilla TS/JS app, React Native app, or server-side integration.
  • You want a typed, batteries-included client for the AGG REST API and WebSocket gateway.
  • You are authoring your own React layer and need the underlying auth/session/trade primitives.
  • You need a server-only helper: SSR config fetching, webhook verification, external-ID signing, or the admin API client (see @agg-build/sdk/server).

If you are shipping a React app and want ready-made hooks or UI, install @agg-build/hooks, @agg-build/ui, and @agg-build/auth instead — those packages are built on top of @agg-build/sdk.

Install

npm install @agg-build/sdk

Quick start

import { createAggClient } from "@agg-build/sdk";

const client = createAggClient({
  baseUrl: "https://api.agg.market",
  appId: "your-app-id",
});

// Health check
const hello = await client.getHello();

// Current auth state (persisted across reloads via localStorage)
console.log(client.isAuthenticated, client.user);

Authenticate a user (SIWE)

// 1. Start the auth flow
const { nonce } = await client.authStart({ provider: "siwe" });

// 2. Build the EIP-4361 message
const message = client.buildSiweMessage({
  address: "0x…",
  chainId: 1,
  nonce,
  domain: window.location.host,
  uri: window.location.origin,
});

// 3. Sign with the user's wallet (wagmi, viem, ethers, …)
const signature = await wallet.signMessage(message);

// 4. Verify → stores accessToken + user in the client
const { accessToken, user } = await client.verify({ message, signature });

SIWS (Solana) uses the same flow with buildSiwsMessage and a base58-encoded Ed25519 signature.

Redirect flows (Google, Apple, Twitter, email magic-link) return a URL to navigate to:

const response = await client.authStart({
  provider: "google",
  redirectUrl: "https://yourapp.com/auth/callback",
});

if (response.type === "redirect") {
  window.location.assign(response.url);
}

// …back on the callback page:
const code = new URLSearchParams(window.location.search).get("code");
if (code) {
  await client.exchangeAuthCode(code);
  window.history.replaceState(null, "", window.location.pathname);
}

For browser apps that prefer an HttpOnly refresh cookie over storing the refresh token in JS, construct the client with authDelivery: "cookie-refresh":

const client = createAggClient({
  baseUrl: "https://api.agg.market",
  appId: "your-app-id",
  authDelivery: "cookie-refresh",
});

In this mode, verify() and exchangeAuthCode() may omit refreshToken from the returned object. The refresh cookie stays scoped to the AGG API host under /auth and is never exposed to partner frontend domains.

Streaming data (WebSocket)

const ws = client.createWebSocket({
  onSnapshot: (outcomeId, book) => console.log("snapshot", outcomeId, book),
  onDelta: (outcomeId, book) => console.log("delta", outcomeId, book),
  onTrade: (trade) => console.log("trade", trade.venue, trade.price, trade.size),
});

// Orderbooks are keyed by venueMarketOutcomeId (the `outcomes[].id` on REST).
const unsubscribe = ws.subscribe("venue-market-outcome-id");

// Optional: authenticate for user-scoped events (orders, balances)
ws.authenticate(accessToken);

// Cleanup
unsubscribe();
ws.destroy();

createWebSocket requires wsUrl to be passed to createAggClient. The underlying AggWebSocket can also be instantiated directly if you want finer control.

Server-side helpers

Import from the /server entrypoint for Node-only utilities:

import { AggAdminClient, signExternalId, verifyWebhook } from "@agg-build/sdk/server";

// Sign a partner external-ID assertion before sending to the browser
const assertion = signExternalId(process.env.AGG_APP_SECRET!, partnerUser.id);

// Verify an inbound webhook
verifyWebhook(rawBody, req.headers, process.env.AGG_WEBHOOK_SECRET!);

// Admin API client (uses x-app-api-key)
const admin = new AggAdminClient({
  baseUrl: "https://api.agg.market",
  apiKey: process.env.AGG_APP_API_KEY!,
});
const users = await admin.listUsers("your-app-id", { limit: 50 });

Client options

OptionTypeRequiredDescription
baseUrlstringYesAPI base URL (e.g. https://api.agg.market)
appIdstringOne of appId/adminKeyPartner app ID
adminKeystringOne of appId/adminKeyAdmin API key for admin-tier routes
wsUrlstringFor WebSocketWebSocket gateway URL (required by createWebSocket)
orderbookUrlstringNoSecond socket for the orderbook channel. Unset keeps orderbooks on wsUrl. When set, an orderbook-only subscription leaves wsUrl idle
orderbookLatency"conflated" | "realtime"NoOrderbook tier. Default conflated omits latency; realtime sends it
authDelivery"body" | "cookie-refresh"NoToken delivery mode (default: "body")
persistSessionbooleanNoPersist auth hint to localStorage (default: true)
kalshiDemobooleanNoDeprecated compatibility option; ignored

Call client.destroy() when you no longer need the client to release internal resources (BroadcastChannel used for cross-tab auth sync).

Main exports

AggClient methods

Auth & session

MethodDescription
authStart(body)Start any auth flow (SIWE nonce, OAuth redirect, etc)
buildSiweMessage(params)Build an EIP-4361 message string
buildSiwsMessage(params)Build a Solana sign-in message
verify({ message, signature })Verify SIWE/SIWS signature, store tokens
exchangeAuthCode(code)Exchange redirect auth code for tokens
refreshAccessToken()Refresh the JWT using the stored refresh token
setSession({ accessToken, refreshToken?, user? })Seed tokens from a redirect callback
setAccessToken(token) / clearAccessToken()Manage the JWT directly
signOut()Revoke tokens server-side and clear local session
onAuthStateChange(listener)Subscribe to auth state changes
isAuthenticated / user / authStatusGetters for current session state

User profile & accounts

MethodDescription
getCurrentUser()Fetch current user profile from /users/me
updateUser(data)Update username, avatar, etc.
createAvatarUploadUrl(contentType)Get a presigned avatar upload URL
linkExternalId({ externalId, timestamp, hmac })Link a backend-signed partner user ID
disconnectAccount(provider)Remove a linked auth provider

Market data

MethodDescription
getVenueEvents(options?)List prediction market events (cursor pagination)
getVenueEventById(id)Get a single event by ID
getVenueMarkets(options?)List venue markets with filters (cursor pagination)
getCategories(options?)List market categories

Correlated Markets

MethodDescription
resolveCorrelatedMarkets(params)Resolve a market and return expand/hedge ideas
getCorrelatedMarketCascade(params)Get expand/hedge ideas for a known venueMarketId
getMarketCorrelatedSignals(id)Inspect generated signals for a market
queryCorrelatedMarkets(params)Search markets by signal similarity

Orderbooks & routing

MethodDescription
getOrderbooks(params)Get live per-venue orderbooks for given venueMarketIds
getSmartRoute(params)MILP solver for optimal order routing across venues

Chart data

MethodDescription
getChartBars(params)TradingView-style OHLCV candles for an outcome
getPricesHistory(params)Price history for venue market outcomes
getOrderbookHistory(params)Orderbook depth history for an outcome

Trading

MethodDescription
validateTrade(body)Pre-flight trade validation
executeTrade(body)Execute supported prediction-market orders via backend
computeSplits(body)Compute best order splits across venues via API

Venue keys

MethodDescription
listVenueKeys(venues?)List stored venue API keys (no secrets returned)
upsertVenueKey(body)Create or update a venue API key
deleteVenueKey(venue)Delete a venue API key

Managed execution & balances

MethodDescription
validateManaged(params)Check balances and bridge requirements
executeManaged(params)Fill a quote from getSmartRoute() — see note below
withdrawManaged(params)Withdraw from managed wallets to an external address
withdrawPreview(params)Preview withdrawal receive amount and route fees
getWithdrawalQuote(params)Quote the maximum deliverable withdrawal amount
syncManagedBalances()Trigger on-chain balance sync
cancelManagedOrder(orderId)Cancel a pending managed execution order
getVenueBalances(venues)Get balances across venues
getManagedBalances()Get managed wallet balances per-chain + per-venue
getDepositAddresses()Get managed wallet deposit addresses (EVM + Solana)

To quote and fill a managed trade, target a venue market outcome. Buys are budgeted with maxSpend; sells specify the number of contracts with sellShares. Pass the returned quoteId to executeManaged():

const buyRoute = await client.getSmartRoute({
  venueMarketOutcomeId,
  tradeSide: "buy",
  maxSpend: 50,
});
await client.executeManaged({ quoteId: buyRoute.quoteId });

const sellRoute = await client.getSmartRoute({
  venueMarketOutcomeId,
  tradeSide: "sell",
  sellShares: 10,
});
await client.executeManaged({ quoteId: sellRoute.quoteId });

venueMarketId, outcomeId, and side: "yes" | "no" remain deprecated compatibility aliases; new integrations should use venueMarketOutcomeId and tradeSide.

Removed in v4. quoteManaged() was deleted — its endpoint, POST /execution/quote, does not exist on the API, so the call only ever returned 404. Use the two-step flow above.

Orders & positions

MethodDescription
getOrders(params?)List trade-executor orders
getExecutionOrders(params?)List execution orders (cursor pagination)
getExecutionPositions(params?)List execution positions (cursor pagination)
getPositions(params?)Get open positions grouped by matched market
getUserHoldings(params)Get user positions per venue

Leaderboard

MethodDescription
getLeaderboard(params?)Trader leaderboard by realized P&L or volume (cursor pagination)

Utilities

MethodDescription
getHello()Health check
request(path, init?)Generic HTTP with auto-retry on 401
createWebSocket(callbacks?)Create a WebSocket instance (requires wsUrl)
destroy()Release resources (BroadcastChannel, etc.)

Standalone utilities

ExportDescription
AggWebSocketLow-level WebSocket client (used by client.createWebSocket())
CandleBuilderChart-library-agnostic candle builder (trades → OHLC)
computeBestSplitsByAmountPure function: optimal split across venue orderbooks
applyOrderbookDeltaApply WS delta to an in-memory orderbook
computeChecksumCRC32 orderbook checksum (used to detect desync)
snapshotToOrderbookConvert a WS snapshot to the in-memory shape
aggregateMidpointAggregate outcome midpoints across venues
mergeCandlesMerge live + historical candles, live-wins on collision
mergeClosedCandlesVariant that merges only fully closed candles
TurnstileChallengeErrorThrown when an auth endpoint requires a Turnstile challenge
AggApiErrorThrown for every non-2xx API response — see below
isAggApiErrorType guard for AggApiError

Error handling

Every non-2xx response is thrown as an AggApiError carrying status, and — when the API supplies them — code, retryable and per-field errors. Branch on status/code rather than matching message text; messages are human-facing and may be reworded.

import { isAggApiError } from "@agg-build/sdk";

try {
  await client.getPositions();
} catch (err) {
  if (isAggApiError(err)) {
    if (err.status === 401) return promptReconnect(); // session lapsed
    if (err.code === "unregistered_domain") {
      // The signed SIWE `domain` is not in the app's allowedOrigins.
      // Note this is NOT the Origin header — sign-in works with no Origin
      // at all, which is what makes Node and React Native work.
    }
  }
  throw err;
}

@agg-build/sdk/server

ExportDescription
AggAdminClientAdmin REST client using x-app-api-key (server-only)
signExternalId(secret, userId)HMAC-sign a partner user ID before calling linkExternalId()
verifyWebhook(payload, headers, secret)Verify an inbound webhook signature
parseWebhookEvent(payload, headers, secret)Verify + parse a webhook into a typed event
WebhookVerificationErrorThrown on signature/timestamp failures

WebSocket callbacks

CallbackWhen it fires
onSnapshot(outcomeId, book)Full orderbook snapshot received
onDelta(outcomeId, book)Incremental orderbook update applied
onTrade(trade)Trade execution
onHeartbeat(hb)Server heartbeat (every 30s)
onSubscribed / onUnsubscribedSubscription lifecycle
onConnected / onAuthenticatedConnection / auth lifecycle
onOrderSubmittedOrder placed via WebSocket
onBalanceUpdateBalance change event
onMarketResolvedMarket resolution
onDiagnostics(event)Diagnostic events (seq gaps, stale connection)
onConnectionStateChange(connected)Primary connection state changed
onOrderbookConnectionStateChange(connected)Orderbook socket state. Fires only when orderbookUrl is set
onError(msg)Error message from server

Orderbook books are keyed by outcome. OrderbookState.outcomeId is the identity of a book; the deprecated OrderbookState.marketId holds the same outcome id, not a venue market id, because orderbook frames carry no market id. Use the REST venueMarketId (e.g. from getOutcomeOrderbooks) or your own outcome → market mapping when you need the market.

Key behaviors:

  • Single persistent connection with refcounted per-market subscriptions. orderbookUrl moves the orderbook channel onto a second socket and reports it through onOrderbookConnectionStateChange. An orderbook-only subscription does not keep wsUrl connected. Trades, arb, catalog, and user events stay on wsUrl.
  • In-memory orderbook state per market (snapshot + delta with CRC32 verification).
  • Sequence gap or checksum mismatch triggers automatic resnapshot.
  • snapshot_unavailable retries only affected active outcomes, with up to three jittered retries and at most 20 outcomes retried per second per socket. Errors still reach onError; successful snapshots, unsubscribe, and socket closure cancel pending retries. Missing replies remain covered by the optional book watchdog.
  • Auto-reconnect with exponential backoff (base 1s, max 30s).
  • Liveness: no message for 45s triggers reconnect; server heartbeats every 30s.
  • Bids always sorted descending, asks always sorted ascending.

Headers attached automatically

  • x-app-id — from the appId option
  • Authorization: Bearer <jwt> — after sign-in
  • x-admin-key — if adminKey is provided
  • x-auth-delivery: cookie-refresh + credentials: "include" on auth-only requests when authDelivery: "cookie-refresh" is enabled

Entrypoints

EntryPurpose
@agg-build/sdkAggClient, createAggClient, AggWebSocket, utilities
@agg-build/sdk/serverNode-only helpers: admin client, external-ID / webhook signing

Peer dependencies

None — and as of v4, no runtime dependencies either. The only module the bundle imports is node:crypto (used by @agg-build/sdk/server), so a fresh install is under 1 MB with nothing transitive.

Bring your own wallet library. The SDK builds SIWE/SIWS message strings and never signs anything itself, so viem, ethers, or any other signer works — you pass in a signMessage function.

Changed in v4. Earlier versions declared viem, ethers@5, @polymarket/clob-client and @polymarket/builder-signing-sdk as runtime dependencies. No code path ever imported them, but installers still paid for them — roughly 100 MB of node_modules across their transitive trees. They were removed in v4; nothing in the SDK's behaviour changed.

License

MIT

Venue event read admission

getVenueEventById shares concurrent identical reads within each client and auth session (including normalized cluster and minVolume query values). It retains no completed result cache. At most four distinct event reads run concurrently; up to 128 wait in FIFO order. A full queue rejects with AggApiError status 429, code client_read_queue_full, and a retry delay hint.

A server 429 still rejects the original call without an automatic retry. New and queued event reads honor its Retry-After delay plus up to 250ms positive jitter; missing hints use one second. Callers may cancel independently; the shared fetch is cancelled only after all callers leave. Queued reads reject with AbortError if authentication changed before admission. destroy() cancels pending reads. Other read methods and write methods keep their existing retry behavior.

版本与发布记录

@agg-build/sdk 共发布 82 个版本,首次发布于 2026/04/28;过去 12 个月发布了 82 个版本。

版本发布日期距今
4.37.0latest2026/11/06今天
4.36.02026/11/042 天前
4.34.12026/11/033 天前
4.34.02026/10/306 天前
4.33.02026/10/307 天前
4.32.02026/10/289 天前

关于 @agg-build/sdk 的常见问题

@agg-build/sdk 是什么?

Vanilla TypeScript client for the AGG prediction market aggregator (auth, markets, orderbooks, charts, trading, managed execution, WebSockets). Works in browsers, Node.js, and React Native.

如何安装 @agg-build/sdk?

在项目目录运行 npm install @agg-build/sdk,或使用 pnpm add / yarn add / bun add。

@agg-build/sdk 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@agg-build/sdk 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@agg-build/sdk 可以商用吗?

@agg-build/sdk 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@agg-build/sdk 的下载量有多少?

根据 npm 官方下载统计,@agg-build/sdk 在 2026/10/05 – 2026/11/03 这 30 天内被下载 5,933 次,日均约 198 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@agg-build/sdk 还在维护吗?

最新版本 4.37.0 发布于 2026/11/06(今天);至今共发布 82 个版本,其中过去 12 个月发布了 82 个;首次发布于 2026/04/28。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。