npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@dome-api/sdk

v0.17.0

Published

The Dome SDK - A comprehensive TypeScript SDK for Dome API

Readme

Dome TypeScript SDK

A comprehensive TypeScript SDK for interacting with the Dome API. Features include market data, wallet analytics, order tracking, and cross-platform market matching for prediction markets. For detailed API documentation, visit DomeApi.io.

Installation

# Using npm
npm install @dome-api/sdk

# Using yarn
yarn add @dome-api/sdk

# Using pnpm
pnpm add @dome-api/sdk

Quick Start

import { DomeClient } from '@dome-api/sdk';

// Initialize the client with your API key
const dome = new DomeClient({
  apiKey: 'your-dome-api-key-here',
});

// Get market price
const marketPrice = await dome.polymarket.markets.getMarketPrice({
  token_id:
    '56369772478534954338683665819559528414197495274302917800610633957542171787417',
});

console.log('Market Price:', marketPrice);
// { price: 0.65, at_time: 1766634610 }

Configuration

The SDK accepts the following configuration options:

interface DomeSDKConfig {
  /** Authentication token for API requests (required) */
  apiKey: string;
  /** Base URL for the API (optional, defaults to https://api.domeapi.io/v1) */
  baseURL?: string;
}

Environment Variables

You can also configure the SDK using environment variables:

DOME_API_KEY=your-api-token
const dome = new DomeClient({
  apiKey: process.env.DOME_API_KEY!,
});

API Endpoints

Polymarket

Markets

Get Market Price

Get current or historical market prices by token ID:

// Current price
const price = await dome.polymarket.markets.getMarketPrice({
  token_id:
    '56369772478534954338683665819559528414197495274302917800610633957542171787417',
});

// Historical price at specific timestamp
const historicalPrice = await dome.polymarket.markets.getMarketPrice({
  token_id:
    '56369772478534954338683665819559528414197495274302917800610633957542171787417',
  at_time: 1760470000, // Unix timestamp (optional)
});

Response:

{
  price: 0.65,
  at_time: 1766634610
}
Get Candlesticks

Get historical candlestick data for market analysis:

const candlesticks = await dome.polymarket.markets.getCandlesticks({
  condition_id:
    '0x4567b275e6b667a6217f5cb4f06a797d3a1eaf1d0281fb5bc8c75e2046ae7e57',
  start_time: 1640995200, // Unix timestamp (required)
  end_time: 1672531200, // Unix timestamp (required)
  interval: 60, // Optional: 1 = 1 minute, 60 = 1 hour, 1440 = 1 day (default)
});

Parameters:

  • condition_id (string, required): The condition ID for the market
  • start_time (number, required): Unix timestamp for start time
  • end_time (number, required): Unix timestamp for end time
  • interval (1 | 60 | 1440, optional): Time interval for candles
Get Orderbooks

Fetch historical orderbook snapshots for a specific asset:

const orderbooks = await dome.polymarket.markets.getOrderbooks({
  token_id:
    '56369772478534954338683665819559528414197495274302917800610633957542171787417',
  start_time: 1760470000000, // Unix timestamp in milliseconds (required)
  end_time: 1760480000000, // Unix timestamp in milliseconds (required)
  limit: 100, // Optional: number of snapshots per page (default: 100)
  pagination_key: 'abc123', // Optional: pagination key for next page
});

Parameters:

  • token_id (string, required): The token ID for the market
  • start_time (number, required): Unix timestamp in milliseconds
  • end_time (number, required): Unix timestamp in milliseconds
  • limit (number, optional): Results per page
  • pagination_key (string, optional): Key for pagination
Get Markets

Fetch market data with filtering and search functionality:

// Search by market slug
const markets = await dome.polymarket.markets.getMarkets({
  market_slug: ['bitcoin-up-or-down-july-25-8pm-et'],
  limit: 50,
  offset: 0,
});

// Filter by condition ID
const marketsByCondition = await dome.polymarket.markets.getMarkets({
  condition_id: [
    '0x4567b275e6b667a6217f5cb4f06a797d3a1eaf1d0281fb5bc8c75e2046ae7e57',
  ],
  limit: 10,
});

// Filter by tags and status
const marketsByTags = await dome.polymarket.markets.getMarkets({
  tags: ['politics', 'election'],
  status: 'open',
  min_volume: 10000,
  limit: 20,
});

// Search by event slug
const marketsByEvent = await dome.polymarket.markets.getMarkets({
  event_slug: ['presidential-election-2024'],
});

Parameters:

  • market_slug (string[], optional): Array of market slugs
  • event_slug (string[], optional): Array of event slugs
  • condition_id (string[], optional): Array of condition IDs
  • tags (string[], optional): Array of tags to filter by
  • status ('open' | 'closed', optional): Market status filter
  • min_volume (number, optional): Minimum volume filter
  • limit (number, optional): Results per page
  • offset (number, optional): Pagination offset

Wallet

Get Wallet

Get wallet information by EOA or proxy address:

// Get wallet by EOA address
const wallet = await dome.polymarket.wallet.getWallet({
  eoa: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
  with_metrics: true, // Optional: include trading metrics
});

// Get wallet by proxy address
const walletByProxy = await dome.polymarket.wallet.getWallet({
  proxy: '0x60881d7dce725bfb0399ee0b11cc11f5782f257d',
});

Parameters:

  • eoa (string, optional): EOA wallet address (either eoa or proxy required)
  • proxy (string, optional): Proxy wallet address (either eoa or proxy required)
  • with_metrics (boolean, optional): Include trading metrics in response
  • start_time (number, optional): Start time for metrics calculation
  • end_time (number, optional): End time for metrics calculation

Response:

{
  eoa: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
  proxy: '0x60881d7dce725bfb0399ee0b11cc11f5782f257d',
  wallet_type: 'safe',
  wallet_metrics: {
    total_volume: 150000.50,
    total_trades: 450,
    total_markets: 25,
    highest_volume_day: {
      date: '2025-10-12',
      volume: 25000.75,
      trades: 145
    },
    merges: 262,
    splits: 31,
    conversions: 4,
    redemptions: 2338
  }
}
Get Wallet PnL

Get profit and loss data for a wallet address:

const walletPnL = await dome.polymarket.wallet.getWalletPnL({
  wallet_address: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
  granularity: 'day', // Required: 'day', 'week', 'month', 'year', or 'all'
  start_time: 1726857600, // Optional: Unix timestamp
  end_time: 1758316829, // Optional: Unix timestamp
});

Parameters:

  • wallet_address (string, required): Ethereum wallet address
  • granularity ('day' | 'week' | 'month' | 'year' | 'all', required): Time granularity
  • start_time (number, optional): Unix timestamp for start time
  • end_time (number, optional): Unix timestamp for end time

Response:

{
  granularity: 'day',
  start_time: 1726857600,
  end_time: 1758316829,
  wallet_address: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
  pnl_over_time: [
    {
      timestamp: 1726857600,
      pnl_to_date: 1250.50
    },
    // ... more data points
  ]
}

Orders

Get Orders

Fetch order data with optional filtering:

// Get orders by market
const orders = await dome.polymarket.orders.getOrders({
  market_slug: 'bitcoin-up-or-down-july-25-8pm-et',
  limit: 50,
  offset: 0,
});

// Get orders by condition ID and time range
const ordersByCondition = await dome.polymarket.orders.getOrders({
  condition_id:
    '0x4567b275e6b667a6217f5cb4f06a797d3a1eaf1d0281fb5bc8c75e2046ae7e57',
  start_time: 1640995200,
  end_time: 1672531200,
  limit: 100,
});

// Get orders by token ID
const ordersByToken = await dome.polymarket.orders.getOrders({
  token_id:
    '56369772478534954338683665819559528414197495274302917800610633957542171787417',
  limit: 25,
});

// Get orders for a specific user
const userOrders = await dome.polymarket.orders.getOrders({
  user: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
  start_time: 1640995200,
  end_time: 1672531200,
  limit: 50,
});

Parameters:

  • market_slug (string, optional): Market slug to filter by
  • condition_id (string, optional): Condition ID to filter by
  • token_id (string, optional): Token ID to filter by
  • user (string, optional): User address to filter by
  • start_time (number, optional): Unix timestamp for start time
  • end_time (number, optional): Unix timestamp for end time
  • limit (number, optional): Results per page
  • offset (number, optional): Pagination offset

Response:

{
  orders: [
    {
      token_id: '56369772478534954338683665819559528414197495274302917800610633957542171787417',
      token_label: 'Yes',
      side: 'BUY',
      market_slug: 'bitcoin-up-or-down-july-25-8pm-et',
      condition_id: '0x4567b275e6b667a6217f5cb4f06a797d3a1eaf1d0281fb5bc8c75e2046ae7e57',
      shares: 1000000,
      shares_normalized: 1.0,
      price: 0.65,
      tx_hash: '0x...',
      title: 'Bitcoin Price',
      timestamp: 1640995200,
      order_hash: '0x...',
      user: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
      taker: '0x...'
    },
    // ... more orders
  ],
  pagination: {
    limit: 50,
    offset: 0,
    total: 150,
    has_more: true
  }
}
Get Activity

Fetch trading activity for a specific user (including MERGES, SPLITS, and REDEEMS):

const activity = await dome.polymarket.orders.getActivity({
  user: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
  start_time: 1640995200,
  end_time: 1672531200,
  limit: 50,
  offset: 0,
});

// Filter activity by market
const activityByMarket = await dome.polymarket.orders.getActivity({
  user: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
  market_slug: 'bitcoin-up-or-down-july-25-8pm-et',
  limit: 25,
});

// Filter activity by condition
const activityByCondition = await dome.polymarket.orders.getActivity({
  user: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
  condition_id:
    '0x4567b275e6b667a6217f5cb4f06a797d3a1eaf1d0281fb5bc8c75e2046ae7e57',
  limit: 50,
});

Parameters:

  • user (string, required): User address
  • start_time (number, optional): Unix timestamp for start time
  • end_time (number, optional): Unix timestamp for end time
  • market_slug (string, optional): Market slug to filter by
  • condition_id (string, optional): Condition ID to filter by
  • limit (number, optional): Results per page
  • offset (number, optional): Pagination offset

Response:

{
  activities: [
    {
      token_id: '56369772478534954338683665819559528414197495274302917800610633957542171787417',
      side: 'MERGE', // or 'SPLIT' or 'REDEEM'
      market_slug: 'bitcoin-up-or-down-july-25-8pm-et',
      condition_id: '0x4567b275e6b667a6217f5cb4f06a797d3a1eaf1d0281fb5bc8c75e2046ae7e57',
      shares: 1000000,
      shares_normalized: 1.0,
      price: 1.0,
      tx_hash: '0x...',
      title: 'Bitcoin Price',
      timestamp: 1640995200,
      order_hash: '',
      user: '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b'
    },
    // ... more activities
  ],
  pagination: {
    limit: 50,
    offset: 0,
    count: 75,
    has_more: true
  }
}

WebSocket - Real-time Order Events

Subscribe to real-time Polymarket order data via WebSocket. Perfect for copy-trading applications where speed is critical.

Basic Usage
// Create a WebSocket client
const ws = dome.polymarket.createWebSocket();

// Connect to the WebSocket server
await ws.connect();

// Subscribe to orders for specific wallet addresses
const subscription = await ws.subscribe({
  users: [
    '0x6031b6eed1c97e853c6e0f03ad3ce3529351f96d',
    '0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b',
  ],
});

console.log('Subscribed with ID:', subscription.subscription_id);
Filter Types

The WebSocket supports three types of filters:

Filter by Users:

const subscription = await ws.subscribe({
  users: ['0x6031b6eed1c97e853c6e0f03ad3ce3529351f96d'],
});

Filter by Condition IDs:

const subscription = await ws.subscribe({
  condition_ids: [
    '0x17815081230e3b9c78b098162c33b1ffa68c4ec29c123d3d14989599e0c2e113',
  ],
});

Filter by Market Slugs:

const subscription = await ws.subscribe({
  market_slugs: ['btc-updown-15m-1762755300'],
});

// Subscribe to orders by condition IDs const subscriptionByCondition = await ws.subscribe({ condition_ids: [ '0x17815081230e3b9c78b098162c33b1ffa68c4ec29c123d3d14989599e0c2e113', ], });

// Subscribe to orders by market slugs const subscriptionByMarket = await ws.subscribe({ market_slugs: ['btc-updown-15m-1762755300'], });

// Listen for order events ws.on('order', order => { console.log('New order received:', { token_id: order.token_id, token_label: order.token_label, side: order.side, market_slug: order.market_slug, price: order.price, shares: order.shares_normalized, user: order.user, taker: order.taker, timestamp: order.timestamp, }); });

// Listen for connection events ws.on('open', () => { console.log('WebSocket connected'); });

ws.on('close', () => { console.log('WebSocket disconnected'); });

ws.on('error', error => { console.error('WebSocket error:', error); });


##### Configuration Options

Configure reconnection behavior and event handlers:

```typescript
const ws = dome.polymarket.createWebSocket({
  // Custom WebSocket URL (defaults to wss://ws.domeapi.io)
  wsURL: 'wss://ws.domeapi.io',

  // Reconnection settings
  reconnect: {
    enabled: true, // Enable automatic reconnection (default: true)
    maxAttempts: 10, // Maximum reconnection attempts (default: 10)
    delay: 1000, // Base delay in milliseconds for exponential backoff (default: 1000)
    // Reconnection delays: 1s, 2s, 4s, 8s, 16s, 32s, 64s, 128s, 256s, 512s
  },

  // Event callbacks
  onOpen: () => {
    console.log('Connection opened');
  },
  onClose: () => {
    console.log('Connection closed');
  },
  onError: error => {
    console.error('Connection error:', error);
  },
});
Managing Subscriptions
// Subscribe to multiple users
const sub1 = await ws.subscribe({
  users: ['0x6031b6eed1c97e853c6e0f03ad3ce3529351f96d'],
});

const sub2 = await ws.subscribe({
  condition_ids: [
    '0x17815081230e3b9c78b098162c33b1ffa68c4ec29c123d3d14989599e0c2e113',
  ],
});

// Get all active subscriptions
const activeSubscriptions = ws.getActiveSubscriptions();
console.log('Active subscriptions:', activeSubscriptions);
// [
//   {
//     subscription_id: 'sub_abc123',
//     filters: { users: ['0x6031b6eed1c97e853c6e0f03ad3ce3529351f96d'] }
//   },
//   {
//     subscription_id: 'sub_def456',
//     filters: { condition_ids: ['0x17815081230e3b9c78b098162c33b1ffa68c4ec29c123d3d14989599e0c2e113'] }
//   }
// ]

// Update an existing subscription's filters (more efficient than unsubscribe + subscribe)
await ws.update(sub1.subscription_id, {
  users: ['0x7c3db723f1d4d8cb9c550095203b686cb11e5c6b'],
});

// Switch from user filters to condition ID filters
await ws.update(sub1.subscription_id, {
  condition_ids: [
    '0x17815081230e3b9c78b098162c33b1ffa68c4ec29c123d3d14989599e0c2e113',
  ],
});

// Unsubscribe from a specific subscription
await ws.unsubscribe(sub1.subscription_id);

// Check connection status
if (ws.isConnected()) {
  console.log('WebSocket is connected');
}

// Close the connection (automatically unsubscribes from all subscriptions)
ws.close();
Automatic Reconnection

The SDK automatically handles reconnection with exponential backoff:

  • Automatic reconnection: Enabled by default
  • Exponential backoff: Delays increase exponentially (1s, 2s, 4s, 8s, etc.)
  • Max attempts: Default 10 attempts (configurable)
  • Auto re-subscription: All subscriptions are automatically re-established after reconnection
// Disable auto-reconnection if needed
const ws = dome.polymarket.createWebSocket({
  reconnect: {
    enabled: false,
  },
});

// Or customize reconnection behavior
const ws = dome.polymarket.createWebSocket({
  reconnect: {
    enabled: true,
    maxAttempts: 5, // Only try 5 times
    delay: 2000, // Start with 2 second delays
  },
});
Order Event Data

Order events match the format of the orders API endpoint:

ws.on('order', order => {
  // Order object structure:
  console.log({
    token_id: order.token_id, // Token ID
    token_label: order.token_label, // Token label (e.g., 'Yes', 'No')
    side: order.side, // 'BUY' or 'SELL'
    market_slug: order.market_slug, // Market identifier
    condition_id: order.condition_id, // Condition ID
    shares: order.shares, // Raw shares amount
    shares_normalized: order.shares_normalized, // Normalized shares
    price: order.price, // Price (0-1)
    tx_hash: order.tx_hash, // Transaction hash
    title: order.title, // Market title
    timestamp: order.timestamp, // Unix timestamp
    order_hash: order.order_hash, // Order hash
    user: order.user, // User wallet address (maker)
    taker: order.taker, // Taker wallet address
  });
});
Complete Example
import { DomeClient } from '@dome-api/sdk';

const dome = new DomeClient({
  apiKey: 'your-api-key',
});

async function trackOrders() {
  const ws = dome.polymarket.createWebSocket({
    reconnect: {
      enabled: true,
      maxAttempts: 10,
    },
  });

  // Handle connection events
  ws.on('open', () => {
    console.log('✅ Connected to WebSocket');
  });

  ws.on('close', () => {
    console.log('❌ Disconnected from WebSocket');
  });

  ws.on('error', error => {
    console.error('⚠️ WebSocket error:', error.message);
  });

  // Connect
  await ws.connect();

  // Subscribe to orders
  const subscription = await ws.subscribe({
    users: ['0x6031b6eed1c97e853c6e0f03ad3ce3529351f96d'],
  });

  console.log(`📡 Subscribed: ${subscription.subscription_id}`);

  // Handle incoming orders
  ws.on('order', order => {
    console.log(`📦 New ${order.side} order:`, {
      market: order.market_slug,
      token_label: order.token_label,
      price: order.price,
      shares: order.shares_normalized,
      user: order.user,
      taker: order.taker,
    });
  });

  // Keep the process alive
  // In a real application, you might want to keep this running
  // process.on('SIGINT', () => {
  //   ws.close();
  //   process.exit(0);
  // });
}

trackOrders().catch(console.error);

Filter Types:

You can filter orders by:

  • users: Array of wallet addresses to track
  • condition_ids: Array of condition IDs to track
  • market_slugs: Array of market slugs to track

Important Notes:

  • The WebSocket server only supports receiving order information (no user inputs besides subscribe/unsubscribe/update)
  • If disconnected, the SDK automatically reconnects and re-subscribes to all previous subscriptions
  • Order event data follows the same format as the orders API endpoint
  • Subscriptions are tracked internally and can be managed via getActiveSubscriptions()
  • Use update() to modify subscription filters without creating a new subscription (more efficient than unsubscribe + subscribe)

Kalshi

Markets

Get Markets

Fetch Kalshi market data with optional filtering:

// Get markets by market ticker (tickers can contain special characters like ".", "/", ")", "(")
const markets = await dome.kalshi.markets.getMarkets({
  market_ticker: ['KXMAYORNYCPARTY-25-D', '538APPROVE-22AUG03-B38.4'],
  limit: 50,
  offset: 0,
});

// Get markets by event ticker
const marketsByEvent = await dome.kalshi.markets.getMarkets({
  event_ticker: ['KXNFLGAME-25AUG16ARIDEN'],
  limit: 100,
});

// Filter by status and minimum volume
const openMarkets = await dome.kalshi.markets.getMarkets({
  status: 'open',
  min_volume: 50000,
  limit: 20,
});

// Get closed markets
const closedMarkets = await dome.kalshi.markets.getMarkets({
  status: 'closed',
  limit: 50,
});

Parameters:

  • market_ticker (string[], optional): Array of market tickers (can contain special characters like ".", "/", ")", "(")
  • event_ticker (string[], optional): Array of event tickers (can contain special characters like ".", "/", ")", "(")
  • status ('open' | 'closed', optional): Market status filter
  • min_volume (number, optional): Minimum volume filter
  • limit (number, optional): Results per page
  • offset (number, optional): Pagination offset

Response:

{
  markets: [
    {
      event_ticker: 'KXMAYORNYCPARTY-25',
      market_ticker: 'KXMAYORNYCPARTY-25-D', // Can contain special characters like ".", "/", ")", "("
      title: 'Will a representative of the Democratic party win the NYC Mayor race in 2025?',
      start_time: 1731150000,
      end_time: 1793775600,
      close_time: 1793775600,
      status: 'open',
      last_price: 89,
      volume: 18261146,
      volume_24h: 931138,
      result: null
    },
    // ... more markets
  ],
  pagination: {
    limit: 50,
    offset: 0,
    total: 200,
    has_more: true
  }
}
Get Orderbooks

Fetch historical orderbook snapshots for a specific Kalshi market:

// Ticker can contain special characters like ".", "/", ")", "("
const orderbooks = await dome.kalshi.markets.getOrderbooks({
  ticker: 'KXMAYORNYCPARTY-25-D',
  start_time: 1760470000000, // Unix timestamp in milliseconds (required)
  end_time: 1760480000000, // Unix timestamp in milliseconds (required)
  limit: 100, // Optional: number of snapshots per page
});

Parameters:

  • ticker (string, required): Market ticker (can contain special characters like ".", "/", ")", "(")
  • start_time (number, required): Unix timestamp in milliseconds
  • end_time (number, required): Unix timestamp in milliseconds
  • limit (number, optional): Results per page
Get Trades

Fetch historical trade data for Kalshi markets:

// Get trades by ticker (ticker can contain special characters like ".", "/", ")", "(")
const trades = await dome.kalshi.markets.getTrades({
  ticker: 'KXNFLGAME-25NOV09PITLAC-PIT',
  limit: 50,
  offset: 0,
});

// Get trades with time range
const tradesByTime = await dome.kalshi.markets.getTrades({
  ticker: 'KXNFLGAME-25NOV09PITLAC-PIT',
  start_time: 1762716000, // Unix timestamp in seconds
  end_time: 1762720600,
  limit: 100,
});

Parameters:

  • ticker (string, optional): Market ticker to filter trades (can contain special characters)
  • start_time (number, optional): Start time in Unix timestamp (seconds)
  • end_time (number, optional): End time in Unix timestamp (seconds)
  • limit (number, optional): Results per page
  • offset (number, optional): Pagination offset

Response:

{
  trades: [
    {
      trade_id: '587f9eb0-1ae1-7b53-9536-fcf3fc503630',
      market_ticker: 'KXNFLGAME-25NOV09PITLAC-PIT',
      count: 93,
      yes_price: 1,
      no_price: 99,
      yes_price_dollars: 0.01,
      no_price_dollars: 0.99,
      taker_side: 'yes',
      created_time: 1762718746
    },
    // ... more trades
  ],
  pagination: {
    limit: 50,
    offset: 0,
    total: 43154,
    has_more: true
  }
}

Response:

{
  snapshots: [
    {
      orderbook: {
        yes: [[75, 100], [76, 150]], // [price_in_cents, size]
        no: [[24, 200], [25, 250]],
        yes_dollars: [['0.75', 100], ['0.76', 150]], // [price_in_dollars, size]
        no_dollars: [['0.24', 200], ['0.25', 250]]
      },
      timestamp: 1760471849407,
      ticker: 'KXMAYORNYCPARTY-25-D' // Can contain special characters
    },
    // ... more snapshots
  ],
  pagination: {
    limit: 100,
    count: 150,
    has_more: true
  }
}

Matching Markets

Find equivalent markets across different platforms:

// By Polymarket market slugs
const matchingMarkets = await dome.matchingMarkets.getMatchingMarkets({
  polymarket_market_slug: ['nfl-ari-den-2025-08-16'],
});

// By Kalshi event tickers
const matchingMarketsKalshi = await dome.matchingMarkets.getMatchingMarkets({
  kalshi_event_ticker: ['KXNFLGAME-25AUG16ARIDEN'],
});

// By sport and date
const matchingMarketsBySport =
  await dome.matchingMarkets.getMatchingMarketsBySport({
    sport: 'nfl', // 'nfl', 'mlb', 'cfb', 'nba', 'nhl', or 'cbb'
    date: '2025-08-16', // YYYY-MM-DD format
  });

Parameters for getMatchingMarkets:

  • polymarket_market_slug (string[], optional): Array of Polymarket market slugs
  • kalshi_event_ticker (string[], optional): Array of Kalshi event tickers (can contain special characters like ".", "/", ")", "(")

Parameters for getMatchingMarketsBySport:

  • sport ('nfl' | 'mlb' | 'cfb' | 'nba' | 'nhl' | 'cbb', required): Sport type
  • date (string, required): Date in YYYY-MM-DD format

Response:

{
  markets: {
    'nfl-ari-den-2025-08-16': [
      {
        platform: 'POLYMARKET',
        market_slug: 'nfl-ari-den-2025-08-16',
        token_ids: ['1234567890', '0987654321']
      },
      {
        platform: 'KALSHI',
        event_ticker: 'KXNFLGAME-25AUG16ARIDEN',
        market_tickers: ['KXNFLGAME-25AUG16ARIDEN-ARI', 'KXNFLGAME-25AUG16ARIDEN-DEN'] // Can contain special characters
      }
    ]
  }
}

Crypto Prices

Binance Prices

Fetch historical crypto price data from Binance:

// Get latest price
const latestPrice = await dome.cryptoPrices.getBinancePrices({
  currency: 'btcusdt', // Currency format: lowercase, no separators (e.g., btcusdt, ethusdt)
});

// Get prices with time range
const prices = await dome.cryptoPrices.getBinancePrices({
  currency: 'btcusdt',
  start_time: 1766130000000, // Unix timestamp in milliseconds
  end_time: 1766131000000,
  limit: 100,
  pagination_key: 'abc123', // Optional: for pagination
});

Parameters:

  • currency (string, required): Currency pair (lowercase, no separators, e.g., btcusdt, ethusdt)
  • start_time (number, optional): Start time in Unix milliseconds
  • end_time (number, optional): End time in Unix milliseconds
  • limit (number, optional): Results per page (max: 100)
  • pagination_key (string, optional): Pagination key for next page

Response:

{
  prices: [
    {
      symbol: 'btcusdt',
      value: '67500.50',
      timestamp: 1766130500000
    },
    // ... more prices
  ],
  pagination_key: 'eyJpZCI6IlBSSUNFI2J0Y3VzZHQiLCJ0aW1lc3RhbXAiOjE3NjYxMzEwMDAwMDB9',
  total: 100
}

Chainlink Prices

Fetch historical crypto price data from Chainlink:

// Get latest price
const latestPrice = await dome.cryptoPrices.getChainlinkPrices({
  currency: 'eth/usd', // Currency format: slash-separated (e.g., btc/usd, eth/usd)
});

// Get prices with time range
const prices = await dome.cryptoPrices.getChainlinkPrices({
  currency: 'eth/usd',
  start_time: 1766130000000, // Unix timestamp in milliseconds
  end_time: 1766131000000,
  limit: 100,
  pagination_key: 'abc123', // Optional: for pagination
});

Parameters:

  • currency (string, required): Currency pair (slash-separated, e.g., btc/usd, eth/usd)
  • start_time (number, optional): Start time in Unix milliseconds
  • end_time (number, optional): End time in Unix milliseconds
  • limit (number, optional): Results per page (max: 100)
  • pagination_key (string, optional): Pagination key for next page

Response:

{
  prices: [
    {
      symbol: 'eth/usd',
      value: 3250.75,
      timestamp: 1766130500000
    },
    // ... more prices
  ],
  pagination_key: 'eyJpZCI6IkNIQUlOTElOSyNidGMvdXNkIiwidGltZXN0YW1wIjoxNzY2MTMxMDAwMDAwfQ==',
  total: 100
}

Router Integration (Wallet-Agnostic Trading)

The SDK includes router helpers for integrating prediction market trading into your application with any wallet provider (Privy, MetaMask, WalletConnect, etc.).

Quick Start with Privy (Server-Side)

For backends using Privy to manage user wallets, integration is extremely simple - just pass wallet info from your database:

import { PolymarketRouter, createPrivySigner } from '@dome-api/sdk';
import { PrivyClient } from '@privy-io/server-auth';

// Step 1: Initialize router with Privy config (ONCE in your app)
const privy = new PrivyClient(
  process.env.PRIVY_APP_ID!,
  process.env.PRIVY_APP_SECRET!,
  {
    walletApi: {
      authorizationPrivateKey: process.env.PRIVY_AUTHORIZATION_KEY!,
    },
  }
);

const router = new PolymarketRouter({
  chainId: 137,
  privy: {
    appId: process.env.PRIVY_APP_ID!,
    appSecret: process.env.PRIVY_APP_SECRET!,
    authorizationKey: process.env.PRIVY_AUTHORIZATION_KEY!,
  },
  // Builder server automatically enabled for all orders
});

// Step 2: Link user (one-time per user, store credentials in your DB)
const signer = createPrivySigner(privy, user.privyWalletId, user.walletAddress);
const credentials = await router.linkUser({
  userId: user.id,
  signer,
});
// Store credentials in your database

// Step 3: Place orders - JUST PASS WALLET INFO!
await router.placeOrder(
  {
    userId: user.id,
    marketId:
      '60487116984468020978247225474488676749601001829886755968952521846780452448915',
    side: 'buy',
    size: 5,
    price: 0.99,
    // No signer needed - router uses Privy config automatically!
    privyWalletId: user.privyWalletId,
    walletAddress: user.walletAddress,
  },
  credentials
);

Key Benefits:

  • Multi-user support - Works with any number of wallets
  • No manual signer creation per order - Just pass privyWalletId and walletAddress
  • Server-side only - No user popups or frontend dependencies
  • Direct CLOB - Places orders directly on Polymarket

See examples/privy-polymarket-simple.ts for a complete working example.

Dome Builder Server (Always Enabled)

All orders automatically use Dome's builder server (https://builder-signer.domeapi.io/builder-signer/sign) for:

  • Better order routing and execution - Access to private order flow
  • Reduced MEV exposure - Orders are less visible to front-runners
  • Priority order matching - Builder-signed orders get priority
  • Zero configuration - Works automatically with no setup required

The builder server signs orders alongside your user's signature, providing these benefits transparently. See examples/privy-with-builder.ts for implementation details.

Overview

The router pattern allows users to:

  1. Sign ONE EIP-712 message to create a Polymarket CLOB API key
  2. Trade using API keys thereafter (no wallet signatures per trade)
  3. Works with any wallet provider that implements the RouterSigner interface

This is ideal for applications that want to abstract away the complexity of prediction market trading while providing a smooth user experience.

Basic Example

import { PolymarketRouter, RouterSigner, Eip712Payload } from '@dome-api/sdk';

// Step 1: Create a signer adapter for your wallet provider
const signer: RouterSigner = {
  async getAddress() {
    // Return user's wallet address
    return '0x...';
  },
  async signTypedData(payload: Eip712Payload) {
    // Sign EIP-712 payload with user's wallet
    return '0x...signature...';
  },
};

// Step 2: Initialize router
const router = new PolymarketRouter({
  baseURL: 'https://api.domeapi.io/v1',
  apiKey: process.env.DOME_API_KEY,
});

// Step 3: Link user (one-time setup)
await router.linkUser({
  userId: 'user-123',
  signer,
});

// Step 4: Place orders without signatures!
await router.placeOrder({
  userId: 'user-123',
  marketId: 'bitcoin-above-100k',
  side: 'buy',
  size: 10,
  price: 0.65,
});

Wallet Provider Adapters

The SDK is wallet-agnostic. You just need to implement the RouterSigner interface:

Privy Example:

import { usePrivy } from '@privy-io/react-auth';

const { user, signTypedData } = usePrivy();

const signer: RouterSigner = {
  async getAddress() {
    return user.wallet.address;
  },
  async signTypedData(payload) {
    return await signTypedData(payload);
  },
};

MetaMask Example:

const signer: RouterSigner = {
  async getAddress() {
    const accounts = await window.ethereum.request({
      method: 'eth_requestAccounts',
    });
    return accounts[0];
  },
  async signTypedData(payload) {
    const address = await this.getAddress();
    return await window.ethereum.request({
      method: 'eth_signTypedData_v4',
      params: [address, JSON.stringify(payload)],
    });
  },
};

Complete Example

See the examples/ directory for complete integration examples:

Architecture

User Wallet → RouterSigner → Dome Router → Polymarket CLOB
   (Privy, MetaMask, etc.)     (SDK)       (Backend)     (Exchange)

Benefits:

  • Users sign once, trade forever (with API keys)
  • Works with any wallet provider
  • Your backend handles exchange-specific complexity
  • Easy to add more exchanges in the future

Error Handling

The SDK provides comprehensive error handling:

try {
  const result = await dome.polymarket.markets.getMarketPrice({
    token_id: 'invalid-token',
  });
} catch (error) {
  if (error.message.includes('API Error')) {
    console.error('API Error:', error.message);
  } else {
    console.error('Network Error:', error.message);
  }
}

Integration Testing

The SDK includes a comprehensive integration test that makes live calls to the real API endpoints to verify everything works correctly.

# Run integration tests with your API key
yarn integration-test YOUR_API_KEY

This smoke test covers all endpoints with various parameter combinations and provides detailed results. See src/tests/README.md for more information.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Authors