This guide walks you through the complete flow from a blank Node.js project to a confirmed limit order on the Proof devnet. The Proof Exchange runs on CometBFT and every action — from key generation to order submission — happens entirely over HTTP, with no node software to install or manage locally.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 package is a pure ESM module. Make sure your
package.json includes "type": "module" and that you are running Node.js 18 or later.Key generation is fully local — no network request is needed. The SDK derives your 20-byte owner address from your Ed25519 public key using
keccak256(pubkey)[12..32]:import { generateKeypair, pubkeyToOwner, ownerToHex } from "@proof/trading-sdk";
const { publicKey, privateKey } = generateKeypair();
const address = pubkeyToOwner(publicKey); // Uint8Array (20 bytes)
const addressHex = ownerToHex(address); // hex string, no 0x prefix
console.log(`0x${addressHex}`); // your new address
Store
privateKey (a Uint8Array) securely. It cannot be recovered from the address alone. Never log or commit private keys to source control.The devnet faucet drips approximately 10,000 USDC (10,000,000,000 µUSDC) to any address, with a 24-hour cooldown per address. You need a faucet token to call the endpoint:
curl -X POST https://faucet.dev.proof.trade/drip \
-H "Authorization: Bearer $PROOF_FAUCET_TOKEN" \
-H "Content-Type: application/json" \
-d '{"address": "0x<your-hex-address>"}'
If you are a paper-trading competition participant, do not use the faucet flow above — it requires a privileged token you will not have. You receive a pre-funded private key by redeeming your access code instead.
After funding, wait a few seconds for the deposit transaction to be included in a block before querying your balance.
Construct an
ExchangeClient with the devnet chainId, then load your private key. The client uses the key for all subsequent submitTx calls:import { ExchangeClient } from "@proof/trading-sdk";
const client = new ExchangeClient({ chainId: "exchange-devnet-1" });
client.setPrivateKey(privateKey);
All three URL options (
rpcUrl, apiUrl, gatewayUrl) default to https://api.dev.proof.trade, so no additional config is required for devnet.const book = await client.queryOrderbook(1);
// {
// bids: [{ price: bigint, totalQty: bigint, orderCount: number }, ...],
// asks: [...]
// }
if (book.bids.length > 0) {
const best = book.bids[0];
console.log(`Best bid: $${best.price} qty=${best.totalQty} orders=${best.orderCount}`);
}
const account = await client.queryAccount(addressHex);
// { balance: bigint, equity: bigint, totalMm: bigint, totalIm: bigint, positions: [...] }
console.log(`Balance: ${account?.balance} µUSDC`);
import { Side } from "@proof/trading-sdk";
const result = await client.submitTx({
type: "PlaceOrder",
data: {
market: 1,
owner: address, // 20-byte Uint8Array from pubkeyToOwner()
side: Side.Buy,
price: 5000000n, // $50,000.00 in integer cents
quantity: 1n, // 1 contract
},
});
console.log(result);
// { code: 0, hash: "ABC123...", log: "" }
const result = await client.submitTxCommit({
type: "PlaceOrder",
data: {
market: 1,
owner: address,
side: Side.Buy,
price: 5000000n,
quantity: 1n,
},
});
// result.height is set once the tx lands in a block
console.log(`Confirmed at block ${result.height}`);
Every
submitTx and submitTxCommit call returns a TxResult. Always check code before assuming success:code: 0 means CheckTx passed — the gateway accepted the transaction and it was broadcast to CometBFT. A non-zero code on submitTx means the transaction was rejected before entering the mempool. With submitTxCommit, a non-zero code at height means the engine rejected the action at DeliverTx (block inclusion), even after CheckTx passed.Full working example
The complete generate → fund → query → trade flow, taken directly from the SDK’s agent quickstart:Common error codes
Whenresult.code is non-zero, consult the table below. The result.log field usually contains a human-readable explanation alongside the code.
| Code | Name | What it means and how to handle it |
|---|---|---|
0 | Success | CheckTx passed. Transaction was accepted. |
12 | InsufficientMargin | Not enough free margin. Check account.equity and reduce order size. |
17 | InvalidSignature | The signature is malformed. Verify chainId matches the target network. |
21 | TimestampNonceRejected | Nonce was outside the sliding window or was a replay. Retry — the SDK auto-advances. |
34 | PostOnlyWouldCross | A postOnly: true order would have matched immediately. Adjust the price. |
401 | MissingApiKey | Gateway requires an apiKey in ExchangeClientOptions. |
429 | RateLimited | Too many requests. Back off and retry. |
Error handling pattern
Next steps
Installation
TypeScript, Python, and Rust setup guides with runtime requirements.
Key Management
Secure key generation, storage patterns, and address derivation details.
Placing Orders
Full guide to limit orders, market orders, cancel-replace, and basket orders.
Account Queries
Query balances, positions, open orders, history, and margin ratios.