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

# Pool State Indexing

> How to index, query, and subscribe to Bolt pool state for real-time integration.

Indexing Bolt pool state is essential for off-chain quoting, trade validation, and real-time integration. Pool state includes current inventory, fee parameters, oracle reference data, and thresholds. By maintaining a local cache of pool state, you can pre-validate trades, compute deterministic quotes, and detect when inventory is insufficient before submitting on-chain transactions.

<Info>
  Pool depth does not affect price in Bolt. However, available inventory determines whether a trade can settle. Indexing pool state lets you pre-validate trades before submission and detect failed swaps in advance.
</Info>

## What to Index

The following table summarizes the critical pool state fields you should index:

| Field                   | Description                                                        | Why It Matters                                                                                                      |
| ----------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| **Available Inventory** | The current balance of each asset in the pool                      | Determines whether a specific amountOut can be settled. If you request more output than available, the trade fails. |
| **Fee Parameters**      | The swap fee rate (e.g., 0.0025 for 0.25%)                         | Required to compute amountOut in off-chain quoting. Fees are applied to the oracle price before settlement.         |
| **Oracle Reference ID** | The authoritative oracle feed ID for the asset pair                | Tells you which oracle publishes the reference price. Multiple pools may use different oracles for the same pair.   |
| **Minimum Swap Amount** | The minimum amountIn required for any trade                        | Prevents spam and ensures meaningful trades. Swaps below this threshold are rejected by the contract.               |
| **Pool Thresholds**     | Inventory levels at which rebalancing or constraints are triggered | Some pools have dynamic behavior when inventory drops below a threshold.                                            |

## Querying Pool State by Blockchain

<Tabs>
  <Tab title="Sui">
    On Sui, query pool state using the Sui TypeScript SDK or JSON-RPC directly.

    ```typescript Sui Example theme={null}
    import { SuiClient, getFullyQualifiedTypeTag } from "@mysten/sui/client";

    const client = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });

    // Query a specific Bolt pool object
    const poolObject = await client.getObject({
      id: "0xpool123...",
      options: {
        showContent: true,
        showBcs: false,
      },
    });

    // Extract pool state from the object
    const poolState = poolObject.data?.content?.fields;
    console.log("Available Inventory:", poolState?.inventory);
    console.log("Fee Rate:", poolState?.feeRate);
    console.log("Oracle ID:", poolState?.oracleId);
    ```

    **Key points for Sui:**

    * Use `getObject` to fetch the pool object by its ID
    * Pool fields are nested under `content.fields`
    * Parse inventory and fee rate from the field values
    * Subscribe to events using `subscribeEvent` for real-time updates
  </Tab>

  <Tab title="Archway">
    On Archway, query pool state using CosmWasm query messages.

    ```typescript Archway Example theme={null}
    import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";

    const client = new CosmWasmClient(
      await Tendermint37Client.connect("https://rpc.mainnet.archway.io")
    );

    // Query the pool state
    const poolState = await client.queryContractSmart(
      "archway1pool123...",
      {
        pool_state: {},
      }
    );

    console.log("Available Inventory:", poolState.inventory);
    console.log("Fee Rate:", poolState.fee_rate);
    console.log("Oracle ID:", poolState.oracle_id);
    ```

    **Key points for Archway:**

    * Use `queryContractSmart` to invoke a read-only contract method
    * The pool contract exposes a `pool_state` query message
    * Parse the JSON response to extract inventory, fees, and oracle reference
    * Subscribe to events using event filters for real-time updates
  </Tab>
</Tabs>

## Setting Up a State Indexer

<Steps>
  <Step title="Connect to RPC">
    Establish a connection to a public or private RPC node for the blockchain where Bolt pools are deployed. Use a WebSocket connection for real-time updates if available.
  </Step>

  <Step title="Query Initial State">
    Fetch the initial pool state by querying each pool object or contract. Store the result in memory or a local database with a timestamp.
  </Step>

  <Step title="Subscribe to Events">
    Subscribe to swap events, rebalance events, and inventory updates emitted by Bolt pools. Events indicate when pool state changes.
  </Step>

  <Step title="Handle State Updates">
    When an event is received, parse it and update your local cache. Ensure your cache remains consistent with on-chain state.
  </Step>

  <Step title="Validate Before Quoting">
    Before quoting a trade, verify that your cached pool state is recent and that available inventory exceeds the requested amountOut. If inventory is insufficient, reject the quote.
  </Step>
</Steps>

## Caching Strategy

<Tip>
  Pool state changes infrequently between swaps. Instead of querying the RPC on every user interaction, cache pool state and refresh on a schedule, for example every 10 seconds. For critical trades, re-validate inventory immediately before submission to account for recent swaps.

  A tiered caching strategy works well:

  * **Tier 1: Local memory cache**: Updated on-chain events, very low latency
  * **Tier 2: Periodic refresh**: Every 10-30 seconds via RPC query
  * **Tier 3: Pre-trade validation**: Re-query RPC immediately before submitting a trade
</Tip>

## Advanced Indexing Patterns

<AccordionGroup>
  <Accordion title="Event-Driven vs Polling">
    **Event-driven indexing** subscribes to on-chain events and updates state immediately when an event is received. This provides the lowest latency and most accurate state.

    * Pros: Real-time updates, low computational overhead
    * Cons: Requires WebSocket support, more complex event parsing

    **Polling-based indexing** periodically queries the RPC to fetch the latest pool state.

    * Pros: Simple to implement, no WebSocket dependency
    * Cons: Higher latency, higher RPC load, potential stale state

    **Recommended approach**: Combine both. Subscribe to events for real-time updates and poll on a schedule (e.g., every 30 seconds) as a fallback if events are missed.
  </Accordion>

  <Accordion title="Handling Rebalance Events">
    When a market maker rebalances a Bolt pool, inventory shifts significantly. Your indexer must detect and apply rebalance events immediately:

    * Monitor for `PoolRebalance` or equivalent events
    * Parse the new inventory levels from the event
    * Update your local cache synchronously
    * If a pending quote was based on pre-rebalance inventory, consider it stale

    Rebalancing is infrequent but critical to catch; a stale inventory assumption can cause trades to fail on-chain.
  </Accordion>

  <Accordion title="Multi-Pool Indexing">
    If you're integrating multiple Bolt pools, index all of them in parallel:

    * Query all pool objects in a single batch RPC call to reduce latency
    * Subscribe to events from all pools simultaneously
    * Maintain a map of pool ID to cached state for O(1) lookup
    * Periodically refresh all pools together to amortize RPC overhead

    For aggregators evaluating many routes, multi-pool indexing is essential for efficient route evaluation.
  </Accordion>
</AccordionGroup>

## Detecting State Staleness

Monitor the timestamp or block height of your cached pool state. If your cache exceeds the staleness threshold:

* **Soft staleness** (1-2 minutes old): Safe for most use cases; consider refreshing on the next RPC query window
* **Hard staleness** (5+ minutes old): Refresh immediately before submitting any trades
* **Event-driven only**: If you rely entirely on events and haven't received an update in 10+ minutes, force a full state refresh as a sanity check

Always include the cache timestamp when storing pool state, and check it before using the cache for critical trading decisions.

## Related Documentation

<CardGroup cols={2}>
  <Card title="Off-Chain Quoting" icon="code" href="/off-chain-quoting">
    Use pool state to compute deterministic quotes off-chain.
  </Card>

  <Card title="Contract Math" icon="sigma" href="/contract-math">
    Understand the pricing formulas that depend on pool parameters.
  </Card>
</CardGroup>

## Support

For RPC endpoint recommendations, event subscription patterns, and sample indexer code, contact the Bolt team via our [support Telegram](https://t.me/BoltOnboarding) or [schedule a call](https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ0h8Dz0XD9uiYnrWu6PUHvRfnuoNjXyCJYnzFX8t548I1YO-qnJxJSOrvuWeenqacByagNyyB0E). We can provide reference implementations and help you optimize your indexing strategy for scale.
