Quickstart
Node ≥ 20. hoodchain and viem are peer dependencies. better-sqlite3, react, and ws are optional — only needed for the modules that use them.
npm install hoodkit hoodchain viem
import { createHoodClient } from 'hoodchain'
import { streamSwaps, createHoodCache, plan, createIndexer } from 'hoodkit'
const hood = createHoodClient()
// Reconnecting, gap-filled swap stream
const swaps = await streamSwaps(hood, { token: '0x…WEN' })
swaps.on('data', (s) => console.log(s.buysToken0 ? 'BUY' : 'SELL', s.price))
// Request-coalescing cache — 100 concurrent reads, 1 RPC call
const cache = createHoodCache(hood)
await Promise.all(Array.from({ length: 100 }, () => cache.getQuote('AAPL')))
// Local SQLite index: holders, OHLCV candles, 24h volume
const indexer = await createIndexer({ client: hood, path: './hood.sqlite', tokens: ['0x…'] })
await indexer.sync({ fromBlock: 0n })
console.log(indexer.holderCount('0x…'), indexer.candles('0x…', '1h'))
React hooks live at the hoodkit/react subpath:
import { HoodProvider, useQuote, useLaunches } from 'hoodkit/react'
function Ticker() {
const { data } = useQuote('AAPL')
return <span>{data ? `$${data.priceUsd.toFixed(2)}` : '…'}</span>
}
Modules
Import only what you use. Heavy deps (better-sqlite3, react) are optional peers — the core install stays light.
stream
Backpressure-safe Stream<T> (event-emitter AND async-iterator) over prices, swaps, launches, and portfolio changes. Gap-fill log cursor: a dropped connection re-scans the missed block range, never silently skips it.
cache
Read-through cache with request coalescing — N concurrent identical reads become 1 upstream call — and per-datatype TTLs. Pluggable store: in-memory LRU by default, bring your own Redis adapter.
Guide →batch
plan() batches arbitrary reads into the fewest Multicall3 round-trips, chunked and failure-isolated. createBatcher() is a DataLoader-style batcher: unrelated call sites sharing one tick collapse into one multicall automatically.
indexer
A local SQLite indexer: incremental sync from the last synced block, holders(), candles() (real OHLCV from swap events), volume24h() — all answered with zero RPC once synced.
strategy
What autonomous agents need: multiplier-aware Position PnL tracking, a TwapExecutor with per-slice slippage bounds and a hard SpendCap, price-cross triggers, and a real eth_call dry-run mode.
react
hoodkit/react: useQuote, usePortfolio, useLaunches, useSwap over the stream/cache layers. SSR-safe — every subscription lives inside useEffect.
acknowledgeStockTokenEligibility: true. Stock Tokens are
tokenized debt securities and may not be offered, sold, or delivered to US persons (additional
limits: Canada, UK, Switzerland).
hoodkit vs hood-js vs the core SDK
An honest decision table. Most apps start with hood-js and never need more.
| You need | Reach for |
|---|---|
| A quote, a swap, a portfolio read — one-off scripts, simple UIs | hoodchain directly |
| The friendliest possible API surface, sane defaults baked in | hood-js |
| Real-time UI that must survive dropped connections without missing events | hoodkit (stream) |
| A backend serving many users hitting the same hot reads | hoodkit (cache + batch) |
| Holder counts, price charts, or trade history without re-scanning logs every request | hoodkit (indexer) |
| An autonomous agent that trades, tracks PnL, and must never overspend | hoodkit (strategy) |
| A React dashboard wired to live chain data | hoodkit/react |
hoodkit depends on hoodchain for every primitive (addresses, ABIs, the client, the registry) — it never re-implements chain plumbing, only the operational layer around it: what happens when a socket drops, when 100 requests want the same data at once, or when you need six months of trade history without paying for it in RPC calls every time.