npm package: @steerprotocol/liquidity-meter
Description: CLI to compute Uniswap v3 market depth bands using real on-chain/subgraph data
Latest version: 2.0.6

Liquidity Depth CLI

- Compute Uniswap v3 market depth bands (±1/2/5/10% by default) using live on-chain state or subgraph.
- Estimate price impact for given USD trade sizes.
- Batch over many pools from CSV.
- Simulate Steer vault withdrawals on a fork and re-run the analysis “after” to see slippage effects.
- Published package surface:
  - `@steerprotocol/liquidity-meter` exports pure depth helpers only.
  - `@steerprotocol/liquidity-meter/api` exports `analyzePool`.
  - `@steerprotocol/liquidity-meter/withdraw` exports withdraw simulation helpers.

Requirements

- Node.js 18+ (uses global fetch and BigInt)
- For on-chain mode: an Ethereum RPC URL in `--rpc` (or env `RPC_URL`) capable of eth_getProof. For Base, prefer `https://developer-access-mainnet.base.org`.

Install

- From the repo root:
  - `npm install`
  - `npm link` (optional; installs `liquidity-depth` in your PATH)
- As a package dependency:
  - `npm install @steerprotocol/liquidity-meter`

Release Workflow

- Releases are automated with `semantic-release` on pushes to `master` or `main`.
- Commit messages are validated with `commitlint` using the Conventional Commits spec.
- CI runs unit tests on Node.js 20 and 22, then enforces coverage thresholds on Node.js 22.
- Required repository secrets:
  - `NPM_TOKEN` for npm publishing.
- GitHub releases use the default `GITHUB_TOKEN` provided by Actions.

Library Usage

```js
import { computeMarketDepthBands } from '@steerprotocol/liquidity-meter';
import { analyzePool } from '@steerprotocol/liquidity-meter/api';
import { simulateVaultWithdraw } from '@steerprotocol/liquidity-meter/withdraw';
```

Breaking Change

- `analyzePool` is no longer exported from `@steerprotocol/liquidity-meter`.
- Migrate root imports to `@steerprotocol/liquidity-meter/api`.

Quick Start

- Single pool (on-chain via Tevm fork):
  - `liquidity-depth --pool 0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8 --rpc https://mainnet.infura.io/v3/<KEY>`
- Same with JSON output:
  - `liquidity-depth --pool 0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8 --rpc <URL> --json`
- Subgraph fallback:
  - `liquidity-depth --pool 0x... --source subgraph`

- Single pool with withdraw simulation (Tevm fork):
  - `liquidity-depth --pool 0xPOOL --vault 0xVAULT --owner 0xOWNER --withdraw-pct 25 --rpc https://developer-access-mainnet.base.org --usd-sizes 1000,5000,10000`

Tevm (On-Chain Fork)

- Default source is `tevm`. The tool forks at `latest` from `--rpc` and reads the pool directly.
- We suppress EVM logs in reports and mine blocks deterministically for post-action state.
- If you see “distance to target block exceeds maximum proof window,” use a provider with proof support or a more recent block (we default to `latest`).

Batch via CSV

- Run the CLI over many pools and write a per-pool report:
  - `liquidity-depth --csv "/path/to/file.csv" --outdir ./reports --rpc <URL>`
- CSV header expectations:
  - Pool address: prefer one of `pool`, `address`, `pool_address`, `id` (addresses embedded in URLs are auto-detected).
  - If no pool address is present, provide `token0`, `token1`, and `fee`, and with `--rpc` the tool will resolve the pool using the Uniswap v3 factory.
  - Optional per-row overrides: `rpc`, `source`, `percent`, `token0_usd`, `token1_usd`, `usd_sizes`, `assume_stable`, `prices`.
  - Steer vault simulation columns (optional):
    - `vault` (aliases: `vault_address`, `vault address`, `strategy`)
    - `owner` (aliases: `owner_address`, `owner address`, `withdraw_owner`, `account`, `user`, `recipient`, `to`)
    - `withdraw_pct` (aliases: `withdraw percent`, `withdraw_percent`, `withdrawPercentage`, `withdrawPercent`, `pct_withdraw`, `percent_withdraw`)
    - `withdraw_shares` (aliases: `withdraw shares`, `withdrawShares`, `shares_to_withdraw`, `withdraw_share_amount`)
- Output:
  - Writes one file per pool in `--outdir` (default `reports`), named `<pool>.txt` or `<pool>.json` when `--json` is set.

CSV example

```
pool,vault,owner,withdraw_pct,usd_sizes
0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8,0xYourVault,0xYourOwner,25,"1000,5000,10000"
```

Simulating Steer Vault Withdrawals (Before/After)

- Adds an “after” section by impersonating an owner on a Tevm fork, withdrawing shares from the Steer vault, mining, then re-running the analysis.
- Global flags:
  - `--vault <VAULT_ADDRESS>`: Vault to withdraw from (per-row CSV overrides supported).
  - `--owner <ADDRESS>`: Address whose shares are withdrawn (or env `OWNER`).
  - `--withdraw-pct <N>`: Percent of owner’s current share balance to withdraw (e.g., 25).
  - `--withdraw-shares <RAW>`: Raw share amount (overrides percent).
- The withdraw is simulated on the fork only. We top up owner gas, impersonate the owner, call `withdraw(shares,0,0,owner)`, then mine 1 block.
- Example (CSV with a `vault` column):
  - `OWNER=0xYourOwner liquidity-depth --csv "/path/file.csv" --outdir ./reports --rpc <URL> --withdraw-pct 25`

Debug logging for withdraws

- Pass `--debug` to print a concise audit trail to stderr without polluting report files:
  - Planned shares and percent, owner’s current shares and vault total supply.
  - Owner and vault token balances before/after (formatted with decimals + symbol).
  - Owner deltas received for token0/token1.
  - Transaction hash on submit, then `[after]` changes to tick and in-range liquidity.
  - A pool mismatch notice if `vault.pool()` differs from CLI `--pool`.

Text Output (Summary)

- Shows pool, token symbols/addresses, tick, fee, inferred or fetched USD prices, range of examined ticks, cumulative USD depth per bucket, headline ±2% depth, and optional price impact lines for USD sizes.
- If a withdrawal is simulated, an “— After Withdraw —” section prints the same summary after state changes.

JSON Output

- Without simulation: prints a single object with fields:
  - `pool`, `tokens.token0/1`, `ethPriceUSD`, `tick`, `sqrtPriceX96`, `liquidity`, `feePips`, `range`, `percentBuckets`, `prices`, `buyCumToken1[]`, `sellCumToken0[]`, and metrics from `computeMarketDepthBands` plus optional `priceImpacts`.
- With simulation: prints `{ before: {...}, after: {...} }` with the same structure on each side. BigInts are stringified in arrays.

Options (Reference)

- `--pool` / `-p`: Uniswap v3 pool address.
- `--percent` / `-b`: Comma-separated percent buckets (default: `1,2,5,10`).
- `--source`: `tevm|subgraph|auto` (default: `tevm`).
- `--rpc` / `-r`: RPC URL for Tevm fork (or env `RPC_URL`).
- `--subgraph` / `-s`: Subgraph URL (defaults to Uniswap v3 mainnet).
- `--token0-usd` / `--token1-usd`: Manual USD prices.
- `--assume-stable 0|1`: Assume token index is $1 stable when USD not supplied/inferred.
- `--usd-sizes`: Comma-separated USD sizes for price impact (token1 buys, token0 sells).
- `--prices`: `reserve|dexscreener|llama|coingecko|auto` (default: `auto`; env `PRICES_SOURCE`).
- `--reserve-limit`: Limit for Reserve API (default: `100`; env `RESERVE_LIMIT`).
- `--csv`: CSV file with pool/vault rows.
- `--outdir`: Output directory (default: `reports`).
- `--json` / `-j`: Emit machine-readable JSON.
- `--debug`: Print pricing/inference debug logs to stderr.
- `--vault`, `--owner`, `--withdraw-pct`, `--withdraw-shares`: Steer vault withdraw simulation (see above).

Pricing Sources

- If manual USD prices aren’t provided, the tool tries (in `auto` mode): Reserve (if chainId known), Dexscreener (if chainId known), DeFiLlama, Coingecko.
- ChainId is resolved via the provided RPC. Coingecko can be rate-limited without an API key.

RPC Guidance (Proof Window)

- Tevm forks and then reads state using proofs from your RPC. Some providers only serve proofs for a recent block window.
- If you see: “distance to target block exceeds maximum proof window,” switch to a proof-capable provider or ensure you fork at `latest` (default).
- Recommended for Base: `https://developer-access-mainnet.base.org`.

Troubleshooting

- Missing `--rpc` in tevm mode: supply `--rpc` or set `RPC_URL`.
- CSV row errors write a file named `error-<pool>.txt` in `--outdir`.
- If owner has 0 vault shares at the forked block, the withdraw step is skipped.
- If a vault does not expose `pool()` or withdraw reverts, the run fails for that row only.
- Logs: Reports strip noisy EVM logs; use `--debug` for pricing diagnostics.

Examples

- Single pool on-chain:
  - `liquidity-depth --pool 0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8 --rpc https://mainnet.infura.io/v3/<KEY> --usd-sizes 1000,5000,10000`
- Batch CSV:
  - `liquidity-depth --csv "/path/to/file.csv" --outdir ./reports --rpc https://developer-access-mainnet.base.org --usd-sizes 1000,5000,10000,25000,50000,100000`
- Batch with withdraw simulation for a single owner across all rows:
  - `OWNER=0xYourOwner liquidity-depth --csv "/path/to/file.csv" --outdir ./reports --rpc https://developer-access-mainnet.base.org --withdraw-pct 25 --usd-sizes 1000,5000,10000`

Notes & Limitations

- No transactions are sent to mainnet; all simulations run on a local fork.
- Certain deposit transaction types (e.g., EIP-7702/OP Stack deposits) may be filtered in forked blocks; this does not affect pool state reads.
- The tool does not model MEV or off-range liquidity changes between snapshots.

Templates

- This repo includes ready-to-edit CSV templates under `templates/`:
  - `templates/pools_minimal.csv`
  - `templates/pools_with_vault.csv`
- Copy one and fill in your addresses, then run (example):
  - `liquidity-depth --csv ./templates/pools_with_vault.csv --outdir ./reports --rpc https://developer-access-mainnet.base.org`