Skip to main content

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:
ErrorWhen
ContextApiErrorHTTP errors (4xx/5xx) — includes status and body
ContextSigningErrorEIP-712 signing failures
ContextConfigErrorMissing 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.