Configuration
The ContextClient constructor accepts an options object to configure authentication, signing, and network settings.
Read-only client
No configuration needed to read public data:
import { ContextClient } from "@contextwtf/sdk"
const ctx = new ContextClient()
// All ctx.markets methods work without auth
const { markets } = await ctx.markets.list()
Authenticated client
To place orders and access account features, provide an API key and signer:
const ctx = new ContextClient({
apiKey: "your-api-key",
signer: { privateKey: "0x..." as `0x${string}` },
})
Options reference
interface ContextClientOptions {
apiKey?: string // API key for authenticated endpoints
baseUrl?: string // Override API base URL
rpcUrl?: string // Custom RPC URL for on-chain operations
signer?: SignerInput // Wallet signer for order signing and transactions
}
apiKey
Required for authenticated endpoints (orders, portfolio, balance). Get an API key by visiting context.markets or reaching out on Discord.
baseUrl
Override the API base URL. Defaults to https://api-testnet.context.markets/v2.
rpcUrl
Custom RPC endpoint for on-chain operations (deposits, withdrawals, wallet setup). Defaults to the public Base Sepolia RPC. Useful if you need higher rate limits or a dedicated node.
signer
The SDK supports three signer formats:
Private key
The simplest option — pass a hex-encoded private key:
const ctx = new ContextClient({
apiKey: "...",
signer: { privateKey: "0xabc123..." as `0x${string}` },
})
Viem account
Pass a viem Account object directly:
import { privateKeyToAccount } from "viem/accounts"
const account = privateKeyToAccount("0xabc123...")
const ctx = new ContextClient({
apiKey: "...",
signer: { account },
})
Viem wallet client
Pass an existing WalletClient for full control over the transport and chain:
import { createWalletClient, http } from "viem"
import { privateKeyToAccount } from "viem/accounts"
import { baseSepolia } from "viem/chains"
const walletClient = createWalletClient({
account: privateKeyToAccount("0xabc123..."),
chain: baseSepolia,
transport: http("https://your-rpc.com"),
})
const ctx = new ContextClient({
apiKey: "...",
signer: { walletClient },
})
Accessing the wallet address
The client exposes the signer’s address:
const ctx = new ContextClient({
signer: { privateKey: "0x..." as `0x${string}` },
})
console.log(ctx.address) // "0xYourAddress..."
Returns null if no signer is configured.
Error handling
The SDK throws typed errors:
| Error | When |
|---|
ContextApiError | HTTP errors (4xx/5xx) — includes status and body |
ContextSigningError | EIP-712 signing failures |
ContextConfigError | Missing signer when calling write operations |
import { ContextApiError, ContextConfigError } from "@contextwtf/sdk"
try {
await ctx.orders.create({ ... })
} catch (err) {
if (err instanceof ContextApiError) {
console.error(`API error ${err.status}:`, err.body)
}
if (err instanceof ContextConfigError) {
console.error("Missing signer:", err.message)
}
}
Environment variables
A common pattern is to load credentials from environment variables:
const ctx = new ContextClient({
apiKey: process.env.CONTEXT_API_KEY!,
signer: { privateKey: process.env.PRIVATE_KEY! as `0x${string}` },
rpcUrl: process.env.RPC_URL, // optional
})
Never commit private keys or API keys to version control. Use .env files or a secrets manager.