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

# Local Cache

> Persist selected wallet, trade, position, and settlement data in local SQLite from TypeScript or Rust.

The optional local cache is available in TypeScript and Rust. It is useful when an application repeatedly reads the same tracked wallets or markets and wants a durable local SQLite view between restarts.

<Info>
  The cache is a focused helper, not a local mirror of the complete V3 API. It does not replace V3 for every combo, credit, identity, webhook, or perps resource. Python does not currently expose this helper.
</Info>

## Install

<CodeGroup>
  ```bash TypeScript theme={null}
  npm install polynode-sdk@^0.14.2 better-sqlite3
  ```

  ```toml Rust theme={null}
  [dependencies]
  polynode = { version = "0.17.1", features = ["cache"] }
  tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
  ```
</CodeGroup>

## Watchlist

Create a `polynode.watch.json` file:

```json theme={null}
{
  "version": 1,
  "wallets": [
    { "address": "0xabc...", "label": "strategy-a", "backfill": true }
  ],
  "settings": { "ttl_days": 30 }
}
```

Do not put API keys or private keys in the watchlist.

## Start and query

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { PolyNode, PolyNodeCache } from 'polynode-sdk';

  const apiKey = process.env.POLYNODE_API_KEY;
  if (!apiKey) throw new Error('Set POLYNODE_API_KEY');

  const pn = new PolyNode({ apiKey });
  const cache = new PolyNodeCache(pn, {
    dbPath: './polynode-cache.db',
    watchlistPath: './polynode.watch.json',
  });

  await cache.start();
  const trades = cache.walletTrades('0xabc...', { limit: 50 });
  const positions = cache.walletPositions('0xabc...');
  console.log({ trades, positions, stats: cache.stats() });

  await cache.stop();
  ```

  ```rust Rust theme={null}
  use polynode::{cache::{PolyNodeCache, QueryOptions}, PolyNodeClient};
  use std::sync::Arc;

  #[tokio::main]
  async fn main() -> polynode::Result<()> {
      let client = Arc::new(PolyNodeClient::new(
          std::env::var("POLYNODE_API_KEY").expect("Set POLYNODE_API_KEY")
      )?);
      let mut cache = PolyNodeCache::builder(client)
          .db_path("./polynode-cache.db")
          .watchlist_path("./polynode.watch.json")
          .build()?;

      cache.start().await?;
      let trades = cache.wallet_trades(
          "0xabc...",
          &QueryOptions { limit: Some(50), ..Default::default() },
      )?;
      let positions = cache.wallet_positions("0xabc...")?;
      println!("{} {} {:?}", trades.len(), positions.len(), cache.stats()?);

      cache.stop().await?;
      Ok(())
  }
  ```
</CodeGroup>

## Operational guidance

* Put the SQLite file on persistent storage and back it up according to your application's needs.
* Keep one writer per database file unless your own storage design guarantees otherwise.
* Observe backfill progress and rate-limit errors instead of starting many simultaneous backfills.
* Stop the cache cleanly so its live subscription and database handles are released.
* Use V3 as the source of truth for data outside the documented cache model.

For current V3 reads, see [Complete V3 API](/sdks/v3-api).
