@valve-tech/trueblocks-sdk 0.10.1 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md ADDED
@@ -0,0 +1,225 @@
1
+ # AGENTS.md
2
+
3
+ Terse reference for AI agents (Claude Code, Cursor, Aider, etc.) integrating
4
+ `@valve-tech/trueblocks-sdk`. The full README is for humans; this file is for
5
+ agents that need to ground their work in the package's actual surface
6
+ quickly.
7
+
8
+ (For contributor-facing notes — codegen pipeline, file map,
9
+ clean-room rule, test pattern — see `INTERNALS.md` in the package
10
+ root, not shipped in the npm tarball.)
11
+
12
+ ## What this package does
13
+
14
+ Typed TypeScript HTTP client to a running [TrueBlocks](https://trueblocks.io)
15
+ `chifra daemon`. Same verb surface as the upstream Go SDK, delivered
16
+ as `fetch`-based REST calls — no Go runtime, no subprocess spawning,
17
+ browser/mobile safe.
18
+
19
+ 54 methods total: 18 base methods (one per chifra HTTP endpoint) +
20
+ 36 narrowed variant accessors on the polymorphic ones (e.g.
21
+ `client.blocks.logs(...)` returns `Log[]` instead of the polymorphic
22
+ `(Block | LightBlock | Log | …)[]` union).
23
+
24
+ **No peer dependencies.** Uses `globalThis.fetch` (Node 18+, every
25
+ modern browser).
26
+
27
+ **Prerequisite:** a running `chifra daemon` somewhere this client
28
+ can reach over HTTP. This package does NOT bundle or invoke chifra —
29
+ the user installs `trueblocks-core` separately and indexes the chains
30
+ they care about. If they can't run chifra, this package isn't for
31
+ them.
32
+
33
+ ## Public API
34
+
35
+ All exports live under `src/index.ts`. Single subpath; no sub-exports.
36
+
37
+ ```ts
38
+ import {
39
+ createTrueblocksClient, // primary constructor
40
+ TrueblocksError, // typed error class
41
+ // verb-machinery exports (rare to import directly)
42
+ createVerbs,
43
+ makeVerb,
44
+ // types
45
+ type CreateTrueblocksClientOptions,
46
+ type TrueblocksClient,
47
+ type FetchFn,
48
+ type RequestFn,
49
+ type Query,
50
+ type Response,
51
+ type VerbFn,
52
+ type Verbs,
53
+ type IsRequiredQuery,
54
+ // raw OpenAPI types (escape hatch when the verb wrapper isn't enough)
55
+ type components,
56
+ type operations,
57
+ type paths,
58
+ } from '@valve-tech/trueblocks-sdk'
59
+ ```
60
+
61
+ ## Three things you must know
62
+
63
+ | | |
64
+ |---|---|
65
+ | **Constructor** | `createTrueblocksClient({ baseUrl: 'http://localhost:8080' })` returns a `TrueblocksClient` with one method per chifra endpoint. Optional `fetch` override for testing or custom transport. |
66
+ | **Verb shape** | Every chifra HTTP endpoint is a typed method on the client. Method names match the chifra CLI verbs (`list`, `export`, `blocks`, `transactions`, etc.). |
67
+ | **Polymorphic vs variant** | Base methods return the OpenAPI polymorphic union (useful when flag combinations are constructed at runtime). Variants (`client.blocks.logs(...)`) preselect a flag and narrow the return type to the single concrete shape that flag produces. Mirrors the Go SDK's `XxxOptions.XxxFlag()` pattern. |
68
+
69
+ ## The verb surface (54 methods)
70
+
71
+ | Group | Method | Endpoint | Variants |
72
+ |---|---|---|---|
73
+ | Accounts | `client.list(...)` | `GET /list` | — |
74
+ | Accounts | `client.export(...)` | `GET /export` | `.appearances` `.receipts` `.logs` `.approvals` `.traces` `.neighbors` `.statements` `.transfers` `.assets` `.balances` `.withdrawals` `.count` |
75
+ | Accounts | `client.monitors(...)` | `GET /monitors` | — |
76
+ | Accounts | `client.names(...)` | `GET /names` | — |
77
+ | Accounts | `client.abis(...)` | `GET /abis` | — |
78
+ | Chain Data | `client.blocks(...)` | `GET /blocks` | `.hashes` `.uncles` `.traces` `.uniq` `.logs` `.withdrawals` `.count` |
79
+ | Chain Data | `client.transactions(...)` | `GET /transactions` | `.traces` `.uniq` `.logs` |
80
+ | Chain Data | `client.receipts(...)` | `GET /receipts` | — |
81
+ | Chain Data | `client.logs(...)` | `GET /logs` | — |
82
+ | Chain Data | `client.traces(...)` | `GET /traces` | `.count` |
83
+ | Chain State | `client.when(...)` | `GET /when` | — |
84
+ | Chain State | `client.state(...)` | `GET /state` | `.call` |
85
+ | Chain State | `client.tokens(...)` | `GET /tokens` | — |
86
+ | Admin | `client.config(...)` | `GET /config` | — |
87
+ | Admin | `client.status(...)` | `GET /status` | — |
88
+ | Admin | `client.chunks(...)` | `GET /chunks` | `.manifest` `.index` `.blooms` `.pins` `.addresses` `.appearances` `.stats` |
89
+ | Admin | `client.init(...)` | `GET /init` | — |
90
+ | Other | `client.slurp(...)` | `GET /slurp` | `.appearances` `.count` |
91
+
92
+ `client.send(...)` (`chifra send`) is NOT exposed — the upstream
93
+ OpenAPI spec doesn't currently cover it, and this package is
94
+ codegen-driven so unspec'd endpoints are not in the surface. To send
95
+ transactions, use a wallet library (viem/ethers/wagmi) or
96
+ `@valve-tech/wallet-adapter` directly.
97
+
98
+ ## Polymorphic vs variant — when to use which
99
+
100
+ ```ts
101
+ // Polymorphic — narrow at the call site:
102
+ const result = await client.blocks({ blocks: ['18000000'], logs: true })
103
+ // result.data is (Block | LightBlock | Log | …)[]
104
+ if (result.data[0]?.address) {
105
+ // narrowed to Log
106
+ }
107
+
108
+ // Variant — concrete return type, no narrowing needed:
109
+ const result = await client.blocks.logs({ blocks: ['18000000'] })
110
+ // result.data is Log[]
111
+ result.data[0]?.address // ✓ already narrowed
112
+ ```
113
+
114
+ Use the variant when the flag is known statically. Use the polymorphic
115
+ shape when flag combinations are computed at runtime (e.g. building a
116
+ chifra query from a UI toggle).
117
+
118
+ ## Errors
119
+
120
+ Every chifra-side failure throws a `TrueblocksError`:
121
+
122
+ ```ts
123
+ try {
124
+ await client.status()
125
+ } catch (err) {
126
+ if (err instanceof TrueblocksError) {
127
+ err.path // chifra endpoint that failed (e.g. '/status')
128
+ err.status // HTTP status if applicable
129
+ }
130
+ }
131
+ ```
132
+
133
+ No silent fallbacks: if the daemon returns an error or an unexpected
134
+ shape, you get a typed throw.
135
+
136
+ ## Pitfalls (read these)
137
+
138
+ 1. **Forgetting the daemon prerequisite.** This package is a *client* —
139
+ it talks to a running `chifra daemon`. If `baseUrl` doesn't have a
140
+ chifra serving on the other end, every call throws a
141
+ `TrueblocksError` with a connection failure. The package can't help
142
+ the user install or run chifra; redirect them to
143
+ https://trueblocks.io/docs/install/install-core/.
144
+
145
+ 2. **Calling `client.send(...)`.** It doesn't exist — chifra's send
146
+ surface isn't in the upstream OpenAPI spec, so it's not in the
147
+ typed client. To send a transaction, use viem/ethers/wagmi or
148
+ `@valve-tech/wallet-adapter`. Use trueblocks-sdk for the *read*
149
+ side (history, receipts, traces, balances).
150
+
151
+ 3. **Mixing `client.blocks(...)` polymorphic with branch-by-shape
152
+ logic.** When the result is the polymorphic union, narrow with a
153
+ type guard or an `if (data[0]?.specificField)` check. Use the
154
+ variant accessor (`client.blocks.logs(...)`) instead if the
155
+ polymorphism isn't load-bearing — it removes the narrowing
156
+ ceremony.
157
+
158
+ 4. **Treating `client.list(...)` results as full transactions.**
159
+ `list` returns *appearances* (lightweight pointers — `bn`/`tx_id`/
160
+ `address` triples), not full transactions or receipts. To go from
161
+ appearance to data, follow up with `client.transactions(...)` /
162
+ `client.receipts(...)`.
163
+
164
+ 5. **Calling `client.export(...)` without `addrs`.** Most `export`
165
+ variants are address-scoped — the request shape will be a TS
166
+ error if `addrs` is required, but worth flagging because the
167
+ error message points at the codegen'd schema, not the
168
+ human-readable docs.
169
+
170
+ 6. **Building URLs by hand to add a flag the SDK doesn't expose.**
171
+ The codegen'd types reflect the spec — every flag the spec
172
+ declares is on the verb method's `Query` type. If something
173
+ appears missing, check the chifra version pinned in
174
+ `scripts/codegen.mjs` (in the source repo) — the spec may be
175
+ newer than the pin.
176
+
177
+ 7. **bigint vs string at numeric boundaries.** Generated types
178
+ carry whatever the spec said (often `string` for safety —
179
+ block numbers, gas, fees can exceed 2^53). The verb wrappers
180
+ convert at the boundary where appropriate, but always-string
181
+ fields stay strings. Test before assuming a `bigint` arrived.
182
+
183
+ 8. **No retry / backoff built in.** The client makes one fetch call
184
+ per verb invocation. If the user wants retries, they wrap the
185
+ call themselves or pass a custom `fetch` that retries.
186
+
187
+ ## Composition
188
+
189
+ trueblocks-sdk is read-side history/state. It composes with:
190
+
191
+ - **`@valve-tech/wallet-adapter`** — for the write/send side, since
192
+ the SDK doesn't expose `send`.
193
+ - **`@valve-tech/tx-tracker`** — for live per-tx state-machine work.
194
+ trueblocks gives you historical reads; tx-tracker watches
195
+ in-flight txs as they confirm. Different layers, complementary.
196
+ - **`@valve-tech/chain-source`** — for raw block/mempool streams.
197
+ trueblocks is server-side indexed history; chain-source is local
198
+ RPC observation.
199
+
200
+ ## When to skip this package
201
+
202
+ - **No running chifra daemon.** Use viem/ethers directly against an
203
+ RPC. Chifra's value is precomputed indexes (appearances,
204
+ monitors); without the daemon, this package is just an HTTP
205
+ client to an endpoint that won't respond.
206
+ - **Live in-flight tx tracking.** Use `@valve-tech/tx-tracker`.
207
+ trueblocks is for historical reads, not push-style observation
208
+ of new chain events.
209
+ - **Sending transactions.** Use a wallet library (or
210
+ `@valve-tech/wallet-adapter`). chifra's send surface isn't
211
+ exposed here.
212
+
213
+ ## Skills (for AI agents)
214
+
215
+ `skills/` ships in the npm tarball. If you're an AI agent working in a
216
+ project that has installed this package, look in
217
+ `node_modules/@valve-tech/trueblocks-sdk/skills/trueblocks-sdk-integration/SKILL.md`
218
+ for trigger conditions, anti-pattern flags, and integration recipes.
219
+
220
+ ## Verifying provenance
221
+
222
+ ```bash
223
+ npm view @valve-tech/trueblocks-sdk@latest --json | jq .dist.attestations
224
+ npm audit signatures
225
+ ```
package/CHANGELOG.md CHANGED
@@ -6,6 +6,29 @@ this file.
6
6
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
7
  and this project adheres to [Semantic Versioning](https://semver.org/).
8
8
 
9
+ ## [0.11.1] — 2026-05-11
10
+
11
+ ### Notes
12
+
13
+ - Synchronized release — no changes to this package. Republished at
14
+ 0.11.1 alongside the rest of the toolkit; the substantive fix is
15
+ in `@valve-tech/tx-tracker` (upgrade-path crash on the first
16
+ block tick after upgrading a persistent store from ≤0.10 to
17
+ 0.11.0). See `@valve-tech/tx-tracker`'s CHANGELOG for details.
18
+
19
+ ## [0.11.0] — 2026-05-11
20
+
21
+ ### Notes
22
+
23
+ - Synchronized release — no changes to this package. Bumped in
24
+ lockstep with the rest of the toolkit alongside the v0.11.0
25
+ feature work in `@valve-tech/gas-oracle` (20-block ring lifecycle,
26
+ reorg detection, gap bridging), `@valve-tech/tx-tracker` (audit
27
+ fixes — durable rehydrate, retention enforcement, replaced-by
28
+ dedup, receipt-poll race, helper extraction), `@valve-tech/
29
+ wallet-adapter` (five wallet bridge examples), and
30
+ `@valve-tech/chain-source` (canonical-owner docs for wire types).
31
+
9
32
  ## [0.10.1] — 2026-05-08
10
33
 
11
34
  **First successful npm publish at the v0.10.x line.** v0.10.0's
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valve-tech/trueblocks-sdk",
3
- "version": "0.10.1",
3
+ "version": "0.11.1",
4
4
  "description": "Typed TypeScript HTTP client to a running TrueBlocks chifra daemon. Wraps chifra's REST surface (the same one served by `chifra daemon`) with TS types generated from the upstream OpenAPI spec; no Go runtime, no shelling-out.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/valve-tech/evm-toolkit/tree/main/packages/trueblocks-sdk#readme",
@@ -32,7 +32,9 @@
32
32
  },
33
33
  "files": [
34
34
  "dist",
35
+ "skills",
35
36
  "README.md",
37
+ "AGENTS.md",
36
38
  "CHANGELOG.md",
37
39
  "LICENSE"
38
40
  ],
@@ -0,0 +1,228 @@
1
+ ---
2
+ name: trueblocks-sdk-integration
3
+ description: Integrate `@valve-tech/trueblocks-sdk` — typed TypeScript HTTP client to a running TrueBlocks `chifra daemon` — into a dapp, indexer, analytics tool, or backend. Use when the user wants to query historical chain data via chifra (`list` appearances, `export` receipts/logs/transfers/balances, `blocks` / `transactions` / `receipts` / `traces` / `logs` reads, `monitors` / `names` / `abis` lookups, `when` / `state` / `tokens` chain-state queries, or `chunks` / `init` / `config` / `status` admin endpoints), is asking how to wire a chifra daemon URL into TS code, needs to discriminate the polymorphic `client.blocks(...)` return vs use a variant accessor like `client.blocks.logs(...)`, or sees imports from `@valve-tech/trueblocks-sdk`. Also fires for "how do I get all transfers for an address", "list ERC-20 holders", "address appearances", "decode receipts via chifra", or questions about `TrueblocksError`, the `baseUrl` option, the `fetch` override, the 54-method/36-variant surface, or why `client.send(...)` doesn't exist (the upstream OpenAPI spec doesn't cover chifra's send surface — that's intentional). Skip when the user wants to SEND transactions (delegate to wallet-adapter-integration — chifra's send isn't in the typed surface), wants live in-flight tx tracking via push/poll (delegate to tx-tracker-integration — trueblocks is historical reads, not live observation), wants raw RPC block/mempool streams (delegate to chain-source-integration), or doesn't have a running chifra daemon and isn't planning to install trueblocks-core (the SDK requires it; recommend they install or use a different read source like viem `client.getLogs` / The Graph / Alchemy enhanced APIs).
4
+ ---
5
+
6
+ # Integrating `@valve-tech/trueblocks-sdk`
7
+
8
+ Typed TypeScript HTTP client to a running TrueBlocks `chifra daemon`.
9
+ Same verb surface as the upstream Go SDK, delivered as `fetch`-based
10
+ REST calls. This skill is for AI agents working in a project that
11
+ imports the package — especially helping the user pick the right verb
12
+ + variant for what they're trying to read.
13
+
14
+ ## Hard prerequisite — flag this first
15
+
16
+ The user **must** have a running `chifra daemon` reachable from their
17
+ runtime. This package is a CLIENT, not a server. It does NOT bundle,
18
+ spawn, or install chifra. If the user doesn't have chifra running,
19
+ no amount of TS-side configuration helps.
20
+
21
+ Before recommending integration code, confirm:
22
+ - [ ] User has installed `trueblocks-core` (https://trueblocks.io/docs/install/install-core/).
23
+ - [ ] User has indexed the chain(s) they care about (`chifra init`).
24
+ - [ ] User has the daemon running (`chifra daemon`) and knows the URL
25
+ it's serving on (default `http://localhost:8080`).
26
+
27
+ If any of these are unclear, ASK before writing code. A working
28
+ client wired to a non-running daemon throws `TrueblocksError` on
29
+ every call — frustrating, and the SDK can't help.
30
+
31
+ ## Decision tree: which verb to use
32
+
33
+ ```
34
+ What does the user want to know?
35
+ ├── "Which transactions involve this address?"
36
+ │ → client.list({ addrs: [address] }) (lightweight appearances)
37
+
38
+ ├── "Full transactions / receipts / logs / transfers / balances for this address"
39
+ │ → client.export(...) + the variant they want:
40
+ │ .receipts / .logs / .transfers / .balances / .approvals / etc.
41
+
42
+ ├── "Block X" / "blocks N..M"
43
+ │ → client.blocks({ blocks: [...] }) + variant:
44
+ │ .logs / .uncles / .traces / .withdrawals / .uniq / .count
45
+
46
+ ├── "Transaction by hash"
47
+ │ → client.transactions({ transactions: [...] }) + variant:
48
+ │ .traces / .uniq / .logs
49
+
50
+ ├── "Receipt(s) by hash"
51
+ │ → client.receipts({ transactions: [...] })
52
+
53
+ ├── "When did block X happen / what block was at timestamp T"
54
+ │ → client.when({ blocks: [...] | timestamps: [...] })
55
+
56
+ ├── "Read contract state / call view function"
57
+ │ → client.state({ addrs, parts }) or client.state.call({ addrs, call })
58
+
59
+ ├── "Token balances / transfers"
60
+ │ → client.tokens({ addrs, blocks }) or client.export.balances(...)
61
+
62
+ ├── "Daemon status / config / chunks"
63
+ │ → client.status() / client.config() / client.chunks(...)
64
+
65
+ └── "Send a transaction"
66
+ → NOT in this SDK. Delegate to wallet-adapter-integration.
67
+ ```
68
+
69
+ ## How to recognize this package in the user's code
70
+
71
+ ```ts
72
+ import {
73
+ createTrueblocksClient,
74
+ TrueblocksError,
75
+ } from '@valve-tech/trueblocks-sdk'
76
+ ```
77
+
78
+ `package.json` will show `"@valve-tech/trueblocks-sdk": "^0.10.x"`. No peer deps.
79
+
80
+ ## Canonical setup
81
+
82
+ ```ts
83
+ import { createTrueblocksClient, TrueblocksError } from '@valve-tech/trueblocks-sdk'
84
+
85
+ const client = createTrueblocksClient({
86
+ baseUrl: process.env.CHIFRA_URL ?? 'http://localhost:8080',
87
+ // optional: pass a custom fetch for retry/auth/logging
88
+ // fetch: myCustomFetch,
89
+ })
90
+
91
+ try {
92
+ const status = await client.status()
93
+ if (!status.is_responding) {
94
+ throw new Error('chifra daemon not ready')
95
+ }
96
+ } catch (err) {
97
+ if (err instanceof TrueblocksError) {
98
+ console.error('chifra error', err.path, err.status, err.message)
99
+ }
100
+ throw err
101
+ }
102
+ ```
103
+
104
+ ## Polymorphic vs variant — the most-likely-to-confuse decision
105
+
106
+ `client.blocks(...)` (polymorphic) returns a union of every shape the
107
+ flag combination COULD produce:
108
+
109
+ ```ts
110
+ const result = await client.blocks({ blocks: ['18000000'], logs: true })
111
+ // result.data is (Block | LightBlock | Log | Withdrawal | …)[]
112
+ // — narrow with a type guard before accessing fields
113
+ ```
114
+
115
+ `client.blocks.logs(...)` (variant) preselects the `logs` flag and
116
+ narrows to the single concrete shape:
117
+
118
+ ```ts
119
+ const result = await client.blocks.logs({ blocks: ['18000000'] })
120
+ // result.data is Log[] — no narrowing needed
121
+ ```
122
+
123
+ Use the variant when the flag is known at code-time. Use the
124
+ polymorphic when flag combinations are computed at runtime (UI toggles,
125
+ config-driven queries).
126
+
127
+ ## Anti-patterns to flag
128
+
129
+ When reviewing user code, watch for these and suggest fixes:
130
+
131
+ 1. **Calling `client.send(...)`.** Doesn't exist. Chifra's send
132
+ surface isn't in the upstream OpenAPI spec, so it's not in the
133
+ typed client. Redirect: use viem / ethers / wagmi or
134
+ `@valve-tech/wallet-adapter` for the write side. Trueblocks is
135
+ read-only history.
136
+
137
+ 2. **No daemon URL guard.** A `createTrueblocksClient({ baseUrl })`
138
+ call to a non-running daemon doesn't fail at construction — it
139
+ fails on the first verb call. Add a `client.status()` probe at
140
+ startup if your code path needs early failure (boot, healthcheck,
141
+ smoke test).
142
+
143
+ 3. **Treating `client.list(...)` results as full transactions.**
144
+ `list` returns *appearances* — lightweight pointers (`bn`,
145
+ `tx_id`, `address`). To get full data, chain through
146
+ `client.transactions(...)` or `client.export(...)`:
147
+ ```ts
148
+ const apps = await client.list({ addrs: [address] })
149
+ const txs = await client.transactions({
150
+ transactions: apps.data.map(a => `${a.bn}.${a.tx_id}`),
151
+ })
152
+ ```
153
+
154
+ 4. **Polymorphic `client.blocks(...)` when a variant exists.** If
155
+ the flag is known statically, use the variant — narrower types,
156
+ no in-place narrowing required:
157
+ ```ts
158
+ // ❌ then narrows in user code
159
+ const r = await client.blocks({ blocks, logs: true })
160
+ const logs = (r.data as Log[]).filter(...)
161
+
162
+ // ✅ already narrowed
163
+ const r = await client.blocks.logs({ blocks })
164
+ r.data.filter(...)
165
+ ```
166
+
167
+ 5. **`client.export(...)` without `addrs`.** Most export variants
168
+ are address-scoped — TS will catch missing `addrs`, but the
169
+ error points at the generated schema. Reframe: "you need to
170
+ pass `addrs: [...]`".
171
+
172
+ 6. **Hand-building URLs to access a missing flag.** The codegen'd
173
+ types reflect the OpenAPI spec at the pinned chifra commit. If
174
+ a flag appears missing, check the spec version — chifra may
175
+ have advanced past the pin. The SDK doesn't expose runtime
176
+ escape-hatch URL building (deliberately, to keep the surface
177
+ typed).
178
+
179
+ 7. **bigint vs string at numeric boundaries.** Generated types
180
+ carry the spec's choice (often `string` for safety — block
181
+ numbers, gas, fees can exceed 2^53). The verb wrappers
182
+ convert at the boundary where appropriate, but always-string
183
+ fields stay strings. Don't `BigInt(field)` without checking
184
+ the type.
185
+
186
+ 8. **No retry / backoff for flaky daemon connections.** The
187
+ client makes one fetch call per verb. If the daemon is
188
+ intermittent, wrap the call (or pass a `fetch` override that
189
+ retries):
190
+ ```ts
191
+ createTrueblocksClient({
192
+ baseUrl,
193
+ fetch: async (url, init) => {
194
+ for (let attempt = 0; attempt < 3; attempt++) {
195
+ try { return await fetch(url, init) }
196
+ catch (e) { if (attempt === 2) throw e; await sleep(100 * 2**attempt) }
197
+ }
198
+ throw new Error('unreachable')
199
+ },
200
+ })
201
+ ```
202
+
203
+ 9. **Querying chains the daemon hasn't indexed.** chifra serves
204
+ only chains the user has run `chifra init` for. If they ask
205
+ about a new chain (e.g. they indexed mainnet but query
206
+ PulseChain), every call returns empty / errors. Confirm
207
+ indexed chains via `client.config()` if uncertain.
208
+
209
+ ## When to skip this package
210
+
211
+ - **Sending transactions** — use wallet-adapter / viem / ethers.
212
+ - **Live in-flight tx state-machine** — use `@valve-tech/tx-tracker`
213
+ (trueblocks is historical reads, not push observation).
214
+ - **Raw block/mempool streams** — use `@valve-tech/chain-source`.
215
+ - **No chifra daemon and not installing one** — recommend viem
216
+ `client.getLogs` / The Graph / Alchemy enhanced APIs / Etherscan
217
+ API instead. Don't try to make trueblocks work without its server.
218
+
219
+ ## Where to find more
220
+
221
+ - Full API + types: `node_modules/@valve-tech/trueblocks-sdk/AGENTS.md`
222
+ - Human-facing docs: `node_modules/@valve-tech/trueblocks-sdk/README.md`
223
+ - Compiled output: `node_modules/@valve-tech/trueblocks-sdk/dist/`
224
+ - Upstream chifra docs: https://trueblocks.io/docs/
225
+ - Sibling skills:
226
+ - wallet-adapter-integration for the write/send side
227
+ - tx-tracker-integration for live tx watching
228
+ - chain-source-integration for raw RPC streams