Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Proof-labs/trading-sdk/llms.txt

Use this file to discover all available pages before exploring further.

The @proof/trading-sdk package is the primary TypeScript interface for the Proof Exchange. It bundles Ed25519 signing, MessagePack encoding, a full-featured HTTP/WebSocket client, and typed action builders into a single ESM-only package — everything you need to sign, encode, and submit transactions from Node or a browser environment.

Installation

npm install @proof/trading-sdk

Requirements

Node 18+

The SDK uses the native fetch API and WebSocket globals available from Node 18 onwards.

TypeScript 6+

Compiled with "module": "ESNext" and strict mode. TypeScript 6 or later is required for development.

ESM only

The package sets "type": "module". All local imports must use .js extensions even when the source file is .ts.

Runtime dependencies

PackageVersionPurpose
@msgpack/msgpack^3.0.0-beta.3Wire encoding / decoding
@noble/ed25519^3.1.0Ed25519 key generation and signing
@noble/hashes^2.2.0keccak256 (owner derivation), SHA-256 (tx hash)

Exports reference

All public symbols are re-exported from the package root. Import from @proof/trading-sdk — never from sub-paths like @proof/trading-sdk/codec.

Types

Core primitive and domain types used throughout every other module.
import {
  type Address,
  Side,
  TimeInForce,
  ActionType,
  type ActionTypeValue,
  type Action,
} from "@proof/trading-sdk";
Enums
SymbolKindDescription
SideenumBuy | Sell — order side
TimeInForceenumGtc | Ioc | Fok
ActionTypeenumDiscriminant for every action variant
BranchenumYes | No branch on a conditional market
OutcomeenumResolution outcome for an impact market
Action interfaces — one per wire action type: PlaceOrder, CancelOrder, CancelClientOrder, CancelAllOrders, CancelReplaceOrder, AmendOrder, AtomicBasketLeg, AtomicBasketOrder, ClosePosition, OracleUpdate, MarketOrder, Deposit, Withdraw, WithdrawRequest, ConfirmDeposit, ConfirmWithdrawal, FailWithdrawal, ApproveAgent, RevokeAgent, CreateMarket, CreateImpactMarket, EventOracleSource, PriceComparison, ResolveEvent, UpdateMarketFees, SetUserMarketLeverage, ImpactMarketInfo, ImpactMarketStatus Transaction result and event types: TxResult, TxEvent, ExchangeEvent, OrderPlacedEvent, OrderCancelledEvent, TradeExecutedEvent, PositionUpdatedEvent, PositionClosedEvent, PriceUpdatedEvent, FundingAppliedEvent, FundingSettledEvent, AccountLiquidatedEvent, MarketCreatedEvent, AgentApprovedEvent, AgentRevokedEvent, FeesCollectedEvent Query response types: Orderbook, OrderbookLevel, OpenOrder, AccountInfo, PositionInfo, MarketConfig, MarkSourceMode, AdlQueueEntry, Ticker, BindingScenarioEntry, HistoryCashFlow, HistoryResolution, HistoryPositionSnapshot, WithdrawalStatus, WithdrawalRecord, MarketKind, FeeTier

Crypto

Low-level Ed25519 and address utilities. Use these directly when you need to manage keys or sign wire bytes outside of ExchangeClient.
import {
  generateKeypair,
  getPublicKey,
  pubkeyToOwner,
  ownerToHex,
  hexToBytes,
  bytesToHex,
  signingMessage,
  sign,
  verify,
  chainIdFromString,
  UNBOUND_CHAIN_ID,
} from "@proof/trading-sdk";
Function / ConstantSignatureDescription
generateKeypair() → { privateKey, publicKey }Generate a new random Ed25519 keypair
getPublicKey(privateKey: Uint8Array) → Uint8ArrayDerive the 32-byte public key from a private key
pubkeyToOwner(pubkey: Uint8Array) → Uint8ArrayDerive the 20-byte owner address via keccak256
ownerToHex(owner: Uint8Array) → stringEncode 20-byte address to a 40-char hex string (no 0x)
hexToBytes(hex: string) → Uint8ArrayDecode a hex string to bytes
bytesToHex(bytes: Uint8Array) → stringEncode bytes to lowercase hex
signingMessage(chainId, actionType, seq, payload) → Uint8ArrayBuild the canonical ProofExchange-v3 domain-prefixed signing message
sign(privateKey: Uint8Array, message: Uint8Array) → Uint8ArraySign and return a 64-byte Ed25519 signature
verify(pubkey: Uint8Array, signature: Uint8Array, message: Uint8Array) → booleanVerify an Ed25519 signature
chainIdFromString(network: string) → Uint8ArrayHash a CometBFT network string to a 32-byte chain ID
UNBOUND_CHAIN_IDUint8Array32 zero bytes — for offline fixtures only; replayable on real chains

Codec

Functions that encode typed actions into signed MessagePack wire envelopes and decode them back.
import {
  encodeSignedTx,
  signAndEncode,
  signEnvelopeFromPayload,
  encodePayloadBytes,
  decodeTx,
  peekActionType,
} from "@proof/trading-sdk";
FunctionDescription
signAndEncodeSign an Action with a private key and chain ID, returning the complete wire envelope bytes
encodeSignedTxAssemble a wire envelope from an action + pre-computed pubkey and signature (gateway relay path)
signEnvelopeFromPayloadSign raw pre-encoded payload bytes + action type into an envelope (for bindings that hold raw bytes)
encodePayloadBytesEncode an action to its raw MessagePack payload bytes without signing
decodeTxFully decode a wire envelope: returns the typed Action, seq, pubkey, and signature
peekActionTypeExtract the action type byte from a wire tx without deserialising the full payload
The wire format is a 6-element MessagePack fixarray: [version=2, action_type, seq, payload_bytes, pubkey, signature]. Integers are encoded with minimal width (no padding), matching the Rust codec’s rmp-serde output exactly. Do not construct envelopes manually.

Client

The high-level client that manages chain-ID resolution, nonce allocation, gateway or CometBFT submission, and all query endpoints.
import { ExchangeClient, type ExchangeClientOptions, fetchChainId } from "@proof/trading-sdk";

ExchangeClientOptions

OptionTypeDefaultDescription
rpcUrlstringhttps://api.dev.proof.tradeCometBFT RPC endpoint
apiUrlstringhttps://api.dev.proof.tradeGo REST API endpoint
wsUrlstringDerived from rpcUrlWebSocket URL for event subscriptions
chainIdstringCometBFT chain ID string (e.g. "proof-testnet-1"). Pin this in production to prevent cross-chain replay.
gatewayUrlstringDerived from rpcUrlPublic gateway endpoint for POST /exchange
useGatewaybooleantrueRoute submissions through the public gateway (auth, rate-limiting); set false for internal tools
apiKeystringX-Api-Key header value for gateway authentication
allowUnboundbooleanfalseFall back to UNBOUND_CHAIN_ID if /status is unreachable. Never use in production.

Key ExchangeClient methods

const client = new ExchangeClient({ chainId: "proof-testnet-1" });
client.setPrivateKey(privateKey);
await client.ready(); // pre-warm chain-ID resolution

// Submit fire-and-forget (spawns background DeliverTx verifier)
const result = await client.submitTx(action);

// Submit and wait for block inclusion
const committed = await client.submitTxCommit(action);

// Drain background verifier results
const deliveries = await client.awaitPendingVerifies();

// Query endpoints
const account = await client.queryAccount(ownerHex);
const orderbook = await client.queryOrderbook(marketId);
const orders = await client.queryOpenOrders(ownerHex);
const markets = await client.queryMarkets();
const ticker = await client.queryTicker(marketId);

// WebSocket subscription
const unsub = client.subscribeBlocks((event) => console.log(event));
client.disconnect(); // close WebSocket

fetchChainId

const chainId: Uint8Array = await fetchChainId("https://api.dev.proof.trade");
Fetches GET /status from a CometBFT RPC, reads result.node_info.network, and returns its 32-byte SHA-256 hash. ExchangeClient uses this lazily on first submit; call it directly for offline signing tools.

Errors

import {
  type ExecErrorInfo,
  decodeExecError,
  execErrorName,
} from "@proof/trading-sdk";
SymbolDescription
ExecErrorInfoInterface holding code, name, and message for an engine rejection
decodeExecErrorParse the log string from a TxResult into an ExecErrorInfo
execErrorNameLook up a canonical error name from a numeric engine error code (e.g. 21 → "InvalidNonce")
Common engine codes to handle:
CodeNameAction
0Success
1DecodeErrorMalformed envelope — inspect payload construction
12InsufficientMarginReduce order size or deposit more collateral
21InvalidNoncePick a fresh millisecond timestamp and retry
401Auth failure (gateway)Check your apiKey
429Rate limited (gateway)Back off and retry

Building from source

npm install
npm run build   # tsc → dist/
npm test        # vitest run
The build output in dist/ is what gets published. All imports within dist/ use .js extensions — TypeScript’s "moduleResolution": "bundler" does not rewrite extensions, so source files must reference ./foo.js even when the actual source is foo.ts. Run a live example (requires a running devnet gateway):
npx tsx examples/connect-and-trade.ts

Build docs developers (and LLMs) love