> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blockdb.io/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript / TypeScript SDK

> Official BlockDB SDK for Node.js and browsers — install from npm, full TypeScript types, async generators for pagination, and API key authentication.

The BlockDB JavaScript/TypeScript SDK supports **Node ≥ 18** (native `fetch`) and browsers. It ships as ESM and CJS with complete TypeScript types and zero required runtime dependencies.

## Where it's available

* **npm:** [@blockdb/sdk](https://www.npmjs.com/package/@blockdb/sdk)
* **Source (open source):** [github.com/blockdb-io/blockdb-js-api-sdk](https://github.com/blockdb-io/blockdb-js-api-sdk)

## Installation

```bash theme={null}
npm install @blockdb/sdk
```

## Quick example

```typescript theme={null}
import { BlockDbClient } from "@blockdb/sdk";

const client = new BlockDbClient({
  apiKey: process.env.BLOCKDB_API_KEY!,
});

// Fetch a single page of blocks
const result = await client.primitives.getBlocks({
  chain_id: 1,
  from_block: 21_000_000,
  to_block: 21_001_000,
  limit: 50,
});

console.log(`Got ${result.count} blocks. Next cursor: ${result.cursor}`);
result.data.forEach((b) => console.log(b.block_number, b.block_hash));
```

## Prices example

```typescript theme={null}
// WETH/USDC VWAP over a block range
const vwap = await client.prices.crypto.getVwap({
  chain_id: 1,
  base_token_address: "c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",  // WETH
  quote_token_address: "a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // USDC
  from_block: 21_000_000,
  to_block: 21_010_000,
});

console.log(`WETH/USDC VWAP: ${vwap.data[0]?.vwap}`);
```

## Pagination

Every endpoint returns a `cursor` field. Pass it back to fetch the next page, or use the built-in `paginate*` async generators to iterate all pages automatically.

<CodeGroup>
  ```typescript Manual paging theme={null}
  let cursor: string | null | undefined;

  do {
    const page = await client.primitives.getBlocks({
      chain_id: 1,
      from_block: 21_000_000,
      to_block: 21_001_000,
      limit: 100,
      cursor,
    });

    page.data.forEach((b) => process(b));
    cursor = page.cursor;
  } while (cursor);
  ```

  ```typescript Async generator (all pages) theme={null}
  for await (const block of client.primitives.paginateBlocks({
    chain_id: 1,
    from_block: 21_000_000,
    to_block: 21_001_000,
  })) {
    console.log(block.block_number, block.block_hash);
  }
  ```

  ```typescript Paginate transactions theme={null}
  for await (const tx of client.primitives.paginateTransactions({
    chain_id: 1,
    from_block: 21_000_000,
    to_block: 21_000_100,
  })) {
    console.log(tx.tx_hash, tx.gas_used);
  }
  ```
</CodeGroup>

## Cancellation

Every request accepts an `AbortSignal` via the optional second `options` argument:

```typescript theme={null}
const controller = new AbortController();
setTimeout(() => controller.abort(), 3_000);

const tokens = await client.entities.getErc20Tokens(
  { chain_id: 1, contract_address: "c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" },
  { signal: controller.signal }
);
```

## Configuration reference

```typescript theme={null}
new BlockDbClient({
  // Required — from https://dashboard.blockdb.io
  apiKey: process.env.BLOCKDB_API_KEY!,

  // Optional overrides
  baseUrl:   "https://api.blockdb.io/v1",  // default
  timeoutMs: 30_000,                      // 30 s

  retry: {
    maxAttempts:      3,
    initialDelayMs:   500,
    maxDelayMs:       30_000,
    backoffMultiplier: 2,
  },

  // Inject a custom fetch (Node <18, test mocks, proxies, …)
  fetch: myCustomFetch,

  // Structured log hook
  onLog: (entry) => logger.debug(entry),
});
```
