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
Package Version Purpose @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
Symbol Kind Description SideenumBuy | Sell — order sideTimeInForceenumGtc | Ioc | FokActionTypeenumDiscriminant for every action variant BranchenumYes | No branch on a conditional marketOutcomeenumResolution 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 / Constant Signature Description 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" ;
Function Description 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
Option Type Default Description rpcUrlstringhttps://api.dev.proof.tradeCometBFT RPC endpoint apiUrlstringhttps://api.dev.proof.tradeGo REST API endpoint wsUrlstringDerived from rpcUrl WebSocket URL for event subscriptions chainIdstring— CometBFT chain ID string (e.g. "proof-testnet-1"). Pin this in production to prevent cross-chain replay. gatewayUrlstringDerived from rpcUrl Public gateway endpoint for POST /exchange useGatewaybooleantrueRoute submissions through the public gateway (auth, rate-limiting); set false for internal tools apiKeystring— X-Api-Key header value for gateway authenticationallowUnboundbooleanfalseFall 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" ;
Symbol Description 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:
Code Name Action 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