@valve-tech/chain-source 0.15.0 → 0.16.0

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/CHANGELOG.md CHANGED
@@ -6,6 +6,74 @@ 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.16.0] — 2026-05-15
10
+
11
+ ### Added
12
+
13
+ - **Adaptive polling.** Replaces the static `setInterval(pollIntervalMs)`
14
+ with a recursive `setTimeout` chain that schedules each subsequent
15
+ tick based on the measured block time + exponential backoff. On
16
+ start, the source samples `latest` + `latest - 256` to derive the
17
+ chain's average block time. After each head-move tick the next is
18
+ scheduled at that expected interval; when the head hasn't moved on
19
+ schedule, backoff (2s → 4s → 8s → 16s → 30s capped) kicks in
20
+ until movement resumes. The existing `eth_blockNumber` head-probe
21
+ gate is preserved — combined effect is dramatic RPC traffic
22
+ reduction on idle chains while consumer-observed event cadence
23
+ (one `subscribeBlocks` emit per actual new block) stays identical.
24
+ - **`AdaptivePollOptions`** — tuning knobs via
25
+ `CreateChainSourceOptions.adaptivePolling`:
26
+ - `estimationLookbackBlocks` (default 256) — sample size for the
27
+ block-time estimate.
28
+ - `retryInitialMs` (default 2_000) — initial backoff when head
29
+ doesn't move.
30
+ - `retryMaxMs` (default 30_000) — cap on exponential backoff.
31
+ - `enabled` (default true) — pass `false` to revert to v0.15
32
+ dumb-interval semantics.
33
+ - **`estimateBlockTimeMs(client, lookback?, onError?)`** — new
34
+ transport-layer helper exported from the package root. Samples
35
+ `latest` + `latest - lookback` and returns the average ms/block,
36
+ or `null` on transport error / insufficient history / invalid
37
+ timestamps / non-positive lookback. Stateless, safe to call
38
+ independently of the source.
39
+ - **`Logger`** type and **`logger`** option on
40
+ `CreateChainSourceOptions` — `(level, message, meta?) => void`
41
+ single-callback shape. Called at narrowly-chosen decision points:
42
+ source start/stop, capability probe completion, block-time
43
+ estimation outcome, adaptive scheduler decisions (next-tick-in-Xms),
44
+ WS subscription open/close/failure. RPC-call-level logging stays
45
+ on the viem transport layer (see README).
46
+
47
+ ### Changed
48
+
49
+ - Removed two unreachable defensive branches that previously hurt
50
+ coverage without protecting any real failure mode:
51
+ - The `Number.isFinite(ms) || ms <= 0` post-check in
52
+ `estimateBlockTimeMs` was preceded by guards (`latestTs > oldTs`,
53
+ `lookback > 0`) that ensure the result is always a finite
54
+ positive number. Replaced by an entry-time `lookback <= 0`
55
+ guard that the rest of the function depends on.
56
+ - The first `if (!started) return` in
57
+ `runAdaptiveTickAndSchedule` was redundant — `start()` sets
58
+ `started = true` before invoking the function synchronously, and
59
+ setTimeout callbacks queued after stop() are explicitly cleared.
60
+ The post-await guard at the same name stays (the one that
61
+ catches `stop()` happening during the tick's async work).
62
+
63
+ ### Notes
64
+
65
+ - New README section "Overriding RPC dispatch" documents that
66
+ consumers control RPC dispatch via viem's `Transport` when
67
+ constructing the `PublicClient` — `http(url, { onFetchRequest,
68
+ onFetchResponse, retryCount, ... })`, `webSocket()`, `fallback([])`,
69
+ custom auth headers. The toolkit does not wrap or replace this; viem
70
+ is the single point of RPC control. No new toolkit-level transport
71
+ option needed.
72
+ - 21 new tests covering adaptive scheduler behavior, estimator edge
73
+ cases, logger plumbing, and the WS handleHeadNotification fresh-
74
+ path emit branch. 128 total chain-source tests (was 107). Coverage
75
+ remains 100/100/100/100.
76
+
9
77
  ## [0.15.0] — 2026-05-14
10
78
 
11
79
  ### Added
package/README.md CHANGED
@@ -99,6 +99,130 @@ tracker.start()
99
99
  Stopping a derived view does not stop the source — the consumer that
100
100
  constructed the source is the one who calls `source.stop()`.
101
101
 
102
+ ## Overriding RPC dispatch
103
+
104
+ `createChainSource` does not wrap or replace your viem client — it
105
+ calls `client.request(...)` (and the higher-level viem methods built
106
+ on it) directly. **All RPC dispatch goes through your viem
107
+ `PublicClient`**, so the override seam is the viem `Transport` you
108
+ construct, not a chain-source-level option.
109
+
110
+ Common things consumers want here, and how to do them via viem:
111
+
112
+ ```ts
113
+ import { createPublicClient, http, webSocket, fallback } from 'viem'
114
+
115
+ // 1. Log every RPC request/response.
116
+ const client = createPublicClient({
117
+ chain: mainnet,
118
+ transport: http(rpcUrl, {
119
+ onFetchRequest: (req) => logger.debug('rpc request', { url: req.url }),
120
+ onFetchResponse: (res) => logger.debug('rpc response', { status: res.status }),
121
+ }),
122
+ })
123
+
124
+ // 2. Retry + timeout policy at the transport layer.
125
+ const client = createPublicClient({
126
+ chain: mainnet,
127
+ transport: http(rpcUrl, {
128
+ retryCount: 3,
129
+ retryDelay: 250, // ms
130
+ timeout: 8_000,
131
+ }),
132
+ })
133
+
134
+ // 3. Multi-RPC fan-out (try primary, fall back to backups).
135
+ const client = createPublicClient({
136
+ chain: mainnet,
137
+ transport: fallback([
138
+ http(primaryUrl),
139
+ http(backupUrl1),
140
+ http(backupUrl2),
141
+ ]),
142
+ })
143
+
144
+ // 4. Custom auth headers / cookies.
145
+ const client = createPublicClient({
146
+ chain: mainnet,
147
+ transport: http(rpcUrl, {
148
+ fetchOptions: {
149
+ headers: { authorization: `Bearer ${token}` },
150
+ },
151
+ }),
152
+ })
153
+
154
+ // 5. Mixed WS + HTTP (WS preferred, HTTP fallback). chain-source
155
+ // auto-detects WS capability and opens a `newHeads` subscription
156
+ // when available; `fallback` keeps the source running on HTTP if
157
+ // the WS connection drops.
158
+ const client = createPublicClient({
159
+ chain: mainnet,
160
+ transport: fallback([
161
+ webSocket(wsUrl),
162
+ http(httpUrl),
163
+ ]),
164
+ })
165
+ ```
166
+
167
+ The chain-source surface above this (block subscription, mempool
168
+ snapshot, on-demand RPCs) is consistent regardless of which transport
169
+ you choose — the source picks WS-vs-HTTP behavior based on the
170
+ capability probe (`source.capabilities()`), not on what kind of
171
+ transport you constructed.
172
+
173
+ For toolkit-level events that don't correspond to individual RPC calls
174
+ (capability probe outcomes, adaptive scheduler decisions, subscription
175
+ lifecycle), pass a `logger` to `createChainSource` directly — see the
176
+ "Logger" section below.
177
+
178
+ ## Logger
179
+
180
+ Optional `logger` callback for observability above the RPC layer:
181
+
182
+ ```ts
183
+ const source = createChainSource({
184
+ client,
185
+ logger: (level, message, meta) => {
186
+ console.log(`[chain-source ${level}]`, message, meta)
187
+ },
188
+ })
189
+ ```
190
+
191
+ Signature: `(level: 'debug' | 'info' | 'warn' | 'error', message: string, meta?: Record<string, unknown>) => void`.
192
+
193
+ The toolkit calls this at narrowly-chosen decision points — capability
194
+ probe completion, block-time estimation, adaptive scheduler intervals,
195
+ WS subscription open/close, head-probe gate skips. RPC-call-level
196
+ logging belongs on your viem transport (see above); the chain-source
197
+ logger covers the "what is the source deciding right now" question.
198
+
199
+ ## Adaptive polling
200
+
201
+ When push subscriptions aren't available (RPC doesn't expose
202
+ `eth_subscribe('newHeads')`), the source falls back to a poll loop.
203
+ Since v0.16 this loop is adaptive: at construction the source samples
204
+ `latest` + `latest - 256` to estimate the chain's block time, then
205
+ schedules each subsequent poll around the expected next-block moment.
206
+ If the head doesn't move on schedule, exponential backoff kicks in
207
+ (2s → 4s → 8s → … capped at 30s) until a new block lands, then resets.
208
+
209
+ Tune via `adaptivePolling`:
210
+
211
+ ```ts
212
+ createChainSource({
213
+ client,
214
+ adaptivePolling: {
215
+ estimationLookbackBlocks: 512, // larger sample, smoother estimate
216
+ retryInitialMs: 1_000, // tighter initial retry
217
+ retryMaxMs: 15_000, // shorter cap
218
+ },
219
+ })
220
+ ```
221
+
222
+ Set `adaptivePolling: { enabled: false }` to revert to the v0.15
223
+ dumb-interval behavior (one tick per `pollIntervalMs` regardless of
224
+ chain state).
225
+
102
226
  ## License
103
227
 
104
228
  MIT
package/dist/index.d.ts CHANGED
@@ -24,10 +24,10 @@
24
24
  * source.start()
25
25
  */
26
26
  export { createChainSource } from './source.js';
27
- export type { ChainSource, CreateChainSourceOptions } from './source.js';
27
+ export type { AdaptivePollOptions, ChainSource, CreateChainSourceOptions, Logger, } from './source.js';
28
28
  export { Subscriptions } from './subscriptions.js';
29
29
  export { normalizeMempool } from './mempool.js';
30
30
  export { probeCapabilities } from './capabilities.js';
31
- export { safeRequest, fetchBlock, fetchBlockByHash, fetchHeadBlockNumber, fetchFeeHistory, fetchTxPool, fetchReceipt, fetchTransaction, zeroHash, } from './transport.js';
31
+ export { safeRequest, estimateBlockTimeMs, fetchBlock, fetchBlockByHash, fetchHeadBlockNumber, fetchFeeHistory, fetchTxPool, fetchReceipt, fetchTransaction, zeroHash, } from './transport.js';
32
32
  export type { BlockResult, Capabilities, EventSource, FeeHistoryResult, NormalizedMempool, PollOptions, RawTx, TransactionReceipt, TxPoolContent, } from './types.js';
33
33
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,YAAY,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,EACL,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,QAAQ,GACT,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,KAAK,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,YAAY,EACV,mBAAmB,EACnB,WAAW,EACX,wBAAwB,EACxB,MAAM,GACP,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,QAAQ,GACT,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,KAAK,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -27,5 +27,5 @@ export { createChainSource } from './source.js';
27
27
  export { Subscriptions } from './subscriptions.js';
28
28
  export { normalizeMempool } from './mempool.js';
29
29
  export { probeCapabilities } from './capabilities.js';
30
- export { safeRequest, fetchBlock, fetchBlockByHash, fetchHeadBlockNumber, fetchFeeHistory, fetchTxPool, fetchReceipt, fetchTransaction, zeroHash, } from './transport.js';
30
+ export { safeRequest, estimateBlockTimeMs, fetchBlock, fetchBlockByHash, fetchHeadBlockNumber, fetchFeeHistory, fetchTxPool, fetchReceipt, fetchTransaction, zeroHash, } from './transport.js';
31
31
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAG/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,EACL,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,QAAQ,GACT,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAQ/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,QAAQ,GACT,MAAM,gBAAgB,CAAA"}
package/dist/source.d.ts CHANGED
@@ -47,14 +47,76 @@
47
47
  */
48
48
  import type { PublicClient } from 'viem';
49
49
  import type { BlockResult, Capabilities, FeeHistoryResult, NormalizedMempool, PollOptions, RawTx, TransactionReceipt } from './types.js';
50
+ /**
51
+ * Logger callback shape — single function, level + message + optional
52
+ * meta. Caller decides routing and formatting; the toolkit just calls
53
+ * it at the decision points it cares about. Same shape used on
54
+ * `createChainSource` and `createTxTracker` so consumers wire one
55
+ * callback for both.
56
+ */
57
+ export type Logger = (level: 'debug' | 'info' | 'warn' | 'error', message: string, meta?: Record<string, unknown>) => void;
58
+ /**
59
+ * Tuning knobs for the v0.16+ adaptive tick scheduler. Replaces the
60
+ * dumb-interval `setInterval` from v0.15 and earlier. The new loop
61
+ * schedules each subsequent tick based on the chain's measured block
62
+ * time + a backoff schedule when the head hasn't moved on time.
63
+ *
64
+ * Default behavior (everything `undefined`): the source estimates
65
+ * block time on `start()` via `latest` + `latest - 256`. After each
66
+ * successful head-move, the next tick is scheduled at
67
+ * `estimatedBlockTimeMs` from now. When a tick fires and the head
68
+ * hasn't moved, the next interval applies exponential backoff
69
+ * (`retryInitialMs * 2^attempts`, capped at `retryMaxMs`) until the
70
+ * head moves again, then resets.
71
+ *
72
+ * For chains where block-time estimation fails (no historical depth,
73
+ * gated `eth_getBlockByNumber`), the scheduler falls back to the
74
+ * static `pollIntervalMs` and runs the v0.15 cadence — no regression
75
+ * from the prior behavior.
76
+ */
77
+ export interface AdaptivePollOptions {
78
+ /**
79
+ * Number of blocks to sample when estimating block time at start.
80
+ * Default 256. Larger = smoother estimate, but reaches farther
81
+ * back where actual block time may have changed. Smaller = fresher
82
+ * but noisier.
83
+ */
84
+ estimationLookbackBlocks?: number;
85
+ /**
86
+ * Initial backoff in ms when the head doesn't move on the expected
87
+ * tick. Default 2_000. Doubles on each subsequent miss until
88
+ * capped at `retryMaxMs`.
89
+ */
90
+ retryInitialMs?: number;
91
+ /**
92
+ * Cap on the exponential retry backoff. Default 30_000. The
93
+ * scheduler never waits longer than this between attempts on a
94
+ * stuck head.
95
+ */
96
+ retryMaxMs?: number;
97
+ /**
98
+ * Set `false` to disable the adaptive scheduler entirely and use
99
+ * `pollIntervalMs` for every tick (matches v0.15 behavior). Default
100
+ * `true`. Useful for testing or for consumers who prefer dumb-
101
+ * interval semantics.
102
+ */
103
+ enabled?: boolean;
104
+ }
50
105
  export interface CreateChainSourceOptions {
51
106
  /** viem PublicClient pointed at the upstream RPC. */
52
107
  client: PublicClient;
53
108
  /**
54
- * Polling interval in ms when push subscriptions aren't available
55
- * (or aren't preferred). Default 10_000.
109
+ * Polling interval in ms used as a fallback when adaptive scheduling
110
+ * is disabled OR when block-time estimation fails (e.g. RPC gates
111
+ * the historical lookup). Default 10_000.
56
112
  */
57
113
  pollIntervalMs?: number;
114
+ /**
115
+ * Adaptive scheduler knobs. See {@link AdaptivePollOptions}. Default
116
+ * behavior is adaptive on with sensible defaults; pass
117
+ * `{ enabled: false }` to revert to v0.15 dumb-interval behavior.
118
+ */
119
+ adaptivePolling?: AdaptivePollOptions;
58
120
  /**
59
121
  * Producer-side toggles: which RPCs the source's tick fans out.
60
122
  * Disabling `mempool` here disables `subscribeMempool` for every
@@ -70,6 +132,15 @@ export interface CreateChainSourceOptions {
70
132
  * (the source keeps running on partial data).
71
133
  */
72
134
  onError?: (method: string, err: unknown) => void;
135
+ /**
136
+ * Optional logger callback. See {@link Logger}. Receives non-fatal
137
+ * observability events the consumer might want to surface: capability
138
+ * probe outcomes, adaptive scheduler decisions, subscription
139
+ * lifecycle, head-probe-gate skips. Errors continue to flow through
140
+ * `onError`; the logger handles the "what's the source doing right
141
+ * now" question.
142
+ */
143
+ logger?: Logger;
73
144
  }
74
145
  export interface ChainSource {
75
146
  /** Begin the poll loop. Idempotent. */
@@ -1 +1 @@
1
- {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAcxC,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,KAAK,EACL,kBAAkB,EACnB,MAAM,YAAY,CAAA;AAqBnB,MAAM,WAAW,wBAAwB;IACvC,qDAAqD;IACrD,MAAM,EAAE,YAAY,CAAA;IACpB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;CACjD;AAED,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,+EAA+E;IAC/E,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB;;;;;;;;;;OAUG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7B;;;;;OAKG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,mEAAmE;IACnE,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;IACjE,oEAAoE;IACpE,gBAAgB,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,KAAK,MAAM,IAAI,CAAA;IAC3E,2DAA2D;IAC3D,QAAQ,EAAE,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IACjE;;;;;;;OAOG;IACH,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAC7D,8BAA8B;IAC9B,aAAa,EAAE,CACb,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EAAE,KAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IACrC;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAA;IAC3D,qCAAqC;IACrC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAA;IAChE,4EAA4E;IAC5E,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAA;IACvD,yCAAyC;IACzC,YAAY,EAAE,MAAM,YAAY,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,wBAAwB,KAChC,WAuUF,CAAA"}
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
package/dist/source.js CHANGED
@@ -48,7 +48,7 @@
48
48
  import { probeCapabilities } from './capabilities.js';
49
49
  import { normalizeMempool } from './mempool.js';
50
50
  import { Subscriptions } from './subscriptions.js';
51
- import { fetchBlock, fetchBlockByHash, fetchFeeHistory, fetchHeadBlockNumber, fetchReceipt, fetchTransaction, fetchTxPool, } from './transport.js';
51
+ import { estimateBlockTimeMs, fetchBlock, fetchBlockByHash, fetchFeeHistory, fetchHeadBlockNumber, fetchReceipt, fetchTransaction, fetchTxPool, } from './transport.js';
52
52
  const DEFAULT_POLL_INTERVAL_MS = 10000;
53
53
  /**
54
54
  * Conservative capability default returned by `capabilities()` before
@@ -87,11 +87,32 @@ const PROBING_DEFAULT = {
87
87
  export const createChainSource = (options) => {
88
88
  const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
89
89
  const fetchMempool = options.poll?.mempool !== false;
90
+ const adaptive = options.adaptivePolling;
91
+ const adaptiveEnabled = adaptive?.enabled !== false;
92
+ const estimationLookbackBlocks = adaptive?.estimationLookbackBlocks ?? 256;
93
+ const retryInitialMs = adaptive?.retryInitialMs ?? 2000;
94
+ const retryMaxMs = adaptive?.retryMaxMs ?? 30000;
95
+ // `log` always callable; consumers can omit `logger` without us
96
+ // peppering the code with optional-chaining. The toolkit calls this
97
+ // at narrowly-chosen points — see DEV_NOTES in the module docstring
98
+ // for the policy.
99
+ const log = options.logger ?? (() => { });
90
100
  const blockSubs = new Subscriptions();
91
101
  const mempoolSubs = new Subscriptions();
102
+ // The adaptive scheduler uses recursive setTimeout; the static
103
+ // fallback uses setInterval. We hold a single handle and clear
104
+ // whichever type was set on stop().
92
105
  let timer = null;
106
+ let timerKind = null;
93
107
  let started = false;
94
108
  let cachedCapabilities = PROBING_DEFAULT;
109
+ // Adaptive scheduler state. `estimatedBlockTimeMs` is `null` until
110
+ // estimation completes (or never, if estimation fails — the
111
+ // scheduler then falls back to `pollIntervalMs`). `retryAttempts`
112
+ // tracks consecutive head-didn't-move ticks for exponential backoff;
113
+ // resets to 0 on every successful head-move.
114
+ let estimatedBlockTimeMs = null;
115
+ let retryAttempts = 0;
95
116
  /**
96
117
  * Narrow the viem transport to its WebSocket-specific `subscribe` shape once.
97
118
  * viem's `Transport` type does not model this method; we structurally narrow
@@ -164,9 +185,13 @@ export const createChainSource = (options) => {
164
185
  onData: () => void handleHeadNotification(),
165
186
  onError: (err) => options.onError?.('eth_subscribe.newHeads', err),
166
187
  });
188
+ log('info', 'WS subscription opened', { type: 'newHeads' });
167
189
  }
168
190
  catch (err) {
169
191
  options.onError?.('eth_subscribe.newHeads', err);
192
+ log('warn', 'WS subscription failed; falling back to poll', {
193
+ type: 'newHeads',
194
+ });
170
195
  cachedCapabilities = { ...cachedCapabilities, newHeads: 'poll-only' };
171
196
  }
172
197
  };
@@ -235,9 +260,15 @@ export const createChainSource = (options) => {
235
260
  },
236
261
  onError: (err) => options.onError?.('eth_subscribe.newPendingTransactions', err),
237
262
  });
263
+ log('info', 'WS subscription opened', {
264
+ type: 'newPendingTransactions',
265
+ });
238
266
  }
239
267
  catch (err) {
240
268
  options.onError?.('eth_subscribe.newPendingTransactions', err);
269
+ log('warn', 'WS subscription failed; falling back to poll', {
270
+ type: 'newPendingTransactions',
271
+ });
241
272
  cachedCapabilities = {
242
273
  ...cachedCapabilities,
243
274
  newPendingTransactions: cachedCapabilities.txpoolContent === 'available'
@@ -256,6 +287,12 @@ export const createChainSource = (options) => {
256
287
  // updates field values in place, no flipping back to "probing"
257
288
  // since downstream gates would briefly stall.
258
289
  cachedCapabilities = { ...caps, ready: true };
290
+ log('info', 'capability probe complete', {
291
+ newHeads: caps.newHeads,
292
+ newPendingTransactions: caps.newPendingTransactions,
293
+ txpoolContent: caps.txpoolContent,
294
+ receiptByHash: caps.receiptByHash,
295
+ });
259
296
  });
260
297
  // One poll cycle. Cheap `eth_blockNumber` probe + (optionally)
261
298
  // mempool fetch in parallel; if the probe shows the head has
@@ -281,6 +318,13 @@ export const createChainSource = (options) => {
281
318
  const block = headChanged
282
319
  ? await fetchBlock(options.client, 'latest', errSink('eth_getBlockByNumber'))
283
320
  : null;
321
+ // Track whether we actually saw a new canonical head this tick.
322
+ // The scheduler uses this to decide between the expected-block-
323
+ // time interval and the retry-backoff interval. We treat
324
+ // `headChanged && block !== null && block.hash !== lastEmittedBlockHash`
325
+ // as the "real head moved" criterion — the cheap eth_blockNumber
326
+ // probe alone isn't enough since it could be transiently wrong.
327
+ let headMoved = false;
284
328
  if (block) {
285
329
  // Update the gate state from the actually-fetched block, not
286
330
  // from the probe's number — keeps the gate consistent with
@@ -294,6 +338,7 @@ export const createChainSource = (options) => {
294
338
  }
295
339
  if (block.hash !== lastEmittedBlockHash) {
296
340
  lastEmittedBlockHash = block.hash;
341
+ headMoved = true;
297
342
  blockSubs.emit(block);
298
343
  }
299
344
  }
@@ -303,19 +348,108 @@ export const createChainSource = (options) => {
303
348
  if (txPool && fetchMempool) {
304
349
  mempoolSubs.emit(normalizeMempool(txPool));
305
350
  }
351
+ return { headMoved };
352
+ };
353
+ /**
354
+ * Adaptive scheduler — computes the next tick delay from current
355
+ * state and runs the tick. Recursive `setTimeout` chain rather than
356
+ * `setInterval` so we can pick a fresh delay each iteration based on
357
+ * whether the head moved.
358
+ *
359
+ * Delay rules:
360
+ *
361
+ * - Head moved this tick → reset `retryAttempts = 0` and schedule
362
+ * next at `estimatedBlockTimeMs` (or `pollIntervalMs` if
363
+ * estimation failed).
364
+ * - Head didn't move → increment `retryAttempts`, schedule next at
365
+ * `min(retryInitialMs * 2^(retryAttempts-1), retryMaxMs)`.
366
+ *
367
+ * The exponential backoff hits the user's "request at t=10, retry at
368
+ * t=12 if nothing changed" pattern. With the default
369
+ * `retryInitialMs: 2000`, retry intervals are 2s → 4s → 8s → 16s →
370
+ * 30s (capped). Most chains recover well within the first 1-2
371
+ * retries; the cap protects against runaway tickers on a stalled
372
+ * chain.
373
+ */
374
+ const runAdaptiveTickAndSchedule = async () => {
375
+ // `tick()` is engineered to never throw — its inner fetches go
376
+ // through `safeRequest` (catches transport errors), `BigInt(...)`
377
+ // calls sit inside inner try/catch arms, and the `Subscriptions`
378
+ // pub/sub helper swallows per-subscriber throws. Wrapping the
379
+ // await in another try/catch would mask future regressions; if a
380
+ // change ever does cause tick to throw, we'd rather see the
381
+ // unhandled-rejection trail than silently retry under cover.
382
+ const result = await tick();
383
+ // `started` may have flipped to false during the await — `stop()`
384
+ // ran while the tick's inner fetches were in flight. Bailing here
385
+ // prevents the tick's already-mutated state from triggering a
386
+ // new setTimeout chain that races stop()'s cleared timer.
387
+ if (!started)
388
+ return;
389
+ let nextMs;
390
+ if (result.headMoved) {
391
+ retryAttempts = 0;
392
+ nextMs = estimatedBlockTimeMs ?? pollIntervalMs;
393
+ log('debug', 'tick: head moved, scheduling next at expected block time', {
394
+ nextMs,
395
+ usingEstimate: estimatedBlockTimeMs !== null,
396
+ });
397
+ }
398
+ else {
399
+ retryAttempts += 1;
400
+ const exp = retryInitialMs * Math.pow(2, retryAttempts - 1);
401
+ nextMs = Math.min(exp, retryMaxMs);
402
+ log('debug', 'tick: head did not move, backing off', {
403
+ attempt: retryAttempts,
404
+ nextMs,
405
+ });
406
+ }
407
+ timer = setTimeout(() => {
408
+ void runAdaptiveTickAndSchedule();
409
+ }, nextMs);
410
+ timerKind = 'timeout';
306
411
  };
307
412
  return {
308
413
  start: () => {
309
414
  if (started)
310
415
  return;
311
416
  started = true;
312
- // Fire the first tick immediately so consumers don't wait one
313
- // full interval for their first event. The interval timer
314
- // takes over from there.
315
- void tick();
316
- timer = setInterval(() => {
417
+ log('info', 'chain-source started', {
418
+ pollIntervalMs,
419
+ adaptiveEnabled,
420
+ });
421
+ if (adaptiveEnabled) {
422
+ // Kick off block-time estimation in parallel with the first
423
+ // tick. The first few ticks use `pollIntervalMs` (since
424
+ // `estimatedBlockTimeMs` is null until the estimate resolves);
425
+ // once estimation lands, subsequent ticks pick it up
426
+ // automatically because the scheduler reads the variable each
427
+ // iteration.
428
+ void estimateBlockTimeMs(options.client, estimationLookbackBlocks, options.onError).then((estimate) => {
429
+ if (estimate !== null) {
430
+ estimatedBlockTimeMs = estimate;
431
+ log('info', 'block time estimated', {
432
+ estimatedBlockTimeMs: estimate,
433
+ lookbackBlocks: estimationLookbackBlocks,
434
+ });
435
+ }
436
+ else {
437
+ log('warn', 'block time estimation failed; using pollIntervalMs fallback', { pollIntervalMs });
438
+ }
439
+ });
440
+ // Fire the first tick immediately so consumers don't wait one
441
+ // full interval for their first event. The scheduler chain
442
+ // takes over from there.
443
+ void runAdaptiveTickAndSchedule();
444
+ }
445
+ else {
446
+ // Legacy dumb-interval path — kept as an explicit opt-out.
317
447
  void tick();
318
- }, pollIntervalMs);
448
+ timer = setInterval(() => {
449
+ void tick();
450
+ }, pollIntervalMs);
451
+ timerKind = 'interval';
452
+ }
319
453
  // Open WS subscribes lazily once the probe has landed. Fire-and-
320
454
  // forget; failures fall through to the existing poll loop.
321
455
  void readyPromise.then(() => tryOpenBlockSubscription());
@@ -341,8 +475,14 @@ export const createChainSource = (options) => {
341
475
  mempoolSubscriptionHandle = null;
342
476
  }
343
477
  if (timer !== null) {
344
- clearInterval(timer);
478
+ if (timerKind === 'interval') {
479
+ clearInterval(timer);
480
+ }
481
+ else {
482
+ clearTimeout(timer);
483
+ }
345
484
  timer = null;
485
+ timerKind = null;
346
486
  }
347
487
  started = false;
348
488
  // Subscriber registry is intentionally preserved across stop —
@@ -355,8 +495,11 @@ export const createChainSource = (options) => {
355
495
  // (or reorged) during the pause.
356
496
  lastEmittedBlockHash = undefined;
357
497
  lastSeenBlockNumber = undefined;
498
+ // Retry attempts reset too — a fresh start shouldn't carry over
499
+ // backoff state from a paused session.
500
+ retryAttempts = 0;
358
501
  },
359
- pollOnce: () => tick(),
502
+ pollOnce: () => tick().then(() => undefined),
360
503
  ready: () => readyPromise,
361
504
  subscribeBlocks: (cb) => blockSubs.subscribe(cb),
362
505
  subscribeMempool: (cb) => mempoolSubs.subscribe(cb),
@@ -1 +1 @@
1
- {"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}
@@ -95,4 +95,34 @@ export declare const fetchReceipt: (client: PublicClient, hash: string, onError?
95
95
  * tracker can detect a different hash with the same nonce mining).
96
96
  */
97
97
  export declare const fetchTransaction: (client: PublicClient, hash: string, onError?: (err: unknown) => void) => Promise<RawTx | null>;
98
+ /**
99
+ * Estimate the average block time (ms/block) by sampling `latest` and
100
+ * `latest - lookback`. Returns null when either fetch fails, the
101
+ * sampled blocks don't decode, or the computed interval is non-positive
102
+ * (consumer is responsible for falling back to a static interval).
103
+ *
104
+ * Why this exists: the v0.15 source polled on a fixed `pollIntervalMs`,
105
+ * which is wasteful on chains where the actual block time is known —
106
+ * a tick that fires during the expected gap between blocks just hits
107
+ * `eth_blockNumber` to learn nothing has changed. The v0.16 adaptive
108
+ * scheduler uses this estimate to time the next tick around the
109
+ * expected next-block moment, with backoff retries when the head
110
+ * doesn't move on schedule.
111
+ *
112
+ * Implementation notes:
113
+ *
114
+ * - Both blocks fetched with `fullTransactions: false` (false because
115
+ * we only need `number` + `timestamp`; the full tx list would be
116
+ * wasted bytes). The shape we deserialize keeps only those two
117
+ * fields rather than the full BlockResult.
118
+ * - 256 is the default lookback. Larger samples smooth out short-term
119
+ * variance (mempool turmoil, validator outages) but stretch farther
120
+ * back where average block time may have actually changed. For
121
+ * chains with sub-block-second cadence (some L2s), the caller may
122
+ * want a larger lookback; for chains with very slow blocks
123
+ * (Bitcoin-style), smaller.
124
+ * - The same `onError` sink the consumer wires for other RPC calls
125
+ * gets invoked here, tagged with the appropriate method name.
126
+ */
127
+ export declare const estimateBlockTimeMs: (client: PublicClient, lookback?: number, onError?: (method: string, err: unknown) => void) => Promise<number | null>;
98
128
  //# sourceMappingURL=transport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAExC,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,kBAAkB,EAClB,aAAa,EACd,MAAM,YAAY,CAAA;AAEnB,uEAAuE;AACvE,eAAO,MAAM,QAAQ,QAAyB,CAAA;AAE9C;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAU,CAAC,EACjC,QAAQ,YAAY,EACpB,QAAQ,MAAM,EACd,QAAQ,OAAO,EAAE,EACjB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,CAAC,GAAG,IAAI,CAWlB,CAAA;AAKD;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,YAAY,EACpB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAQvB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,QAAQ,YAAY,EACpB,KAAK,QAAQ,GAAG,MAAM,EACtB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,WAAW,GAAG,IAAI,CAM1B,CAAA;AAEH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,YAAY,EACpB,MAAM,MAAM,EACZ,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,WAAW,GAAG,IAAI,CAM1B,CAAA;AAEH;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,QAAQ,YAAY,EACpB,YAAY,MAAM,EAClB,aAAa,MAAM,EAAE,EACrB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAM/B,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,YAAY,EACpB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,aAAa,GAAG,IAAI,CACoC,CAAA;AAEnE;;;;GAIG;AACH,eAAO,MAAM,YAAY,GACvB,QAAQ,YAAY,EACpB,MAAM,MAAM,EACZ,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAMjC,CAAA;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,YAAY,EACpB,MAAM,MAAM,EACZ,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,KAAK,GAAG,IAAI,CACkD,CAAA"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAExC,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,kBAAkB,EAClB,aAAa,EACd,MAAM,YAAY,CAAA;AAEnB,uEAAuE;AACvE,eAAO,MAAM,QAAQ,QAAyB,CAAA;AAE9C;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAU,CAAC,EACjC,QAAQ,YAAY,EACpB,QAAQ,MAAM,EACd,QAAQ,OAAO,EAAE,EACjB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,CAAC,GAAG,IAAI,CAWlB,CAAA;AAKD;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,YAAY,EACpB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAQvB,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,QAAQ,YAAY,EACpB,KAAK,QAAQ,GAAG,MAAM,EACtB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,WAAW,GAAG,IAAI,CAM1B,CAAA;AAEH;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,YAAY,EACpB,MAAM,MAAM,EACZ,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,WAAW,GAAG,IAAI,CAM1B,CAAA;AAEH;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,QAAQ,YAAY,EACpB,YAAY,MAAM,EAClB,aAAa,MAAM,EAAE,EACrB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAM/B,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,YAAY,EACpB,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,aAAa,GAAG,IAAI,CACoC,CAAA;AAEnE;;;;GAIG;AACH,eAAO,MAAM,YAAY,GACvB,QAAQ,YAAY,EACpB,MAAM,MAAM,EACZ,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAMjC,CAAA;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,YAAY,EACpB,MAAM,MAAM,EACZ,UAAU,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/B,OAAO,CAAC,KAAK,GAAG,IAAI,CACkD,CAAA;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,YAAY,EACpB,WAAU,MAAY,EACtB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,KAC/C,OAAO,CAAC,MAAM,GAAG,IAAI,CAyDvB,CAAA"}
package/dist/transport.js CHANGED
@@ -117,4 +117,81 @@ export const fetchReceipt = async (client, hash, onError) => safeRequest(client,
117
117
  * tracker can detect a different hash with the same nonce mining).
118
118
  */
119
119
  export const fetchTransaction = async (client, hash, onError) => safeRequest(client, 'eth_getTransactionByHash', [hash], onError);
120
+ /**
121
+ * Estimate the average block time (ms/block) by sampling `latest` and
122
+ * `latest - lookback`. Returns null when either fetch fails, the
123
+ * sampled blocks don't decode, or the computed interval is non-positive
124
+ * (consumer is responsible for falling back to a static interval).
125
+ *
126
+ * Why this exists: the v0.15 source polled on a fixed `pollIntervalMs`,
127
+ * which is wasteful on chains where the actual block time is known —
128
+ * a tick that fires during the expected gap between blocks just hits
129
+ * `eth_blockNumber` to learn nothing has changed. The v0.16 adaptive
130
+ * scheduler uses this estimate to time the next tick around the
131
+ * expected next-block moment, with backoff retries when the head
132
+ * doesn't move on schedule.
133
+ *
134
+ * Implementation notes:
135
+ *
136
+ * - Both blocks fetched with `fullTransactions: false` (false because
137
+ * we only need `number` + `timestamp`; the full tx list would be
138
+ * wasted bytes). The shape we deserialize keeps only those two
139
+ * fields rather than the full BlockResult.
140
+ * - 256 is the default lookback. Larger samples smooth out short-term
141
+ * variance (mempool turmoil, validator outages) but stretch farther
142
+ * back where average block time may have actually changed. For
143
+ * chains with sub-block-second cadence (some L2s), the caller may
144
+ * want a larger lookback; for chains with very slow blocks
145
+ * (Bitcoin-style), smaller.
146
+ * - The same `onError` sink the consumer wires for other RPC calls
147
+ * gets invoked here, tagged with the appropriate method name.
148
+ */
149
+ export const estimateBlockTimeMs = async (client, lookback = 256, onError) => {
150
+ // Validate the caller's lookback up front — a zero or negative value
151
+ // would divide-by-zero or invert the math below. Better to fail
152
+ // cheaply here than mint Infinity / negative durations downstream.
153
+ if (!Number.isInteger(lookback) || lookback <= 0)
154
+ return null;
155
+ const sinkLatest = onError
156
+ ? (err) => onError('eth_getBlockByNumber:latest', err)
157
+ : undefined;
158
+ const latest = await safeRequest(client, 'eth_getBlockByNumber', ['latest', false], sinkLatest);
159
+ if (!latest || !latest.number || !latest.timestamp)
160
+ return null;
161
+ let latestNumber;
162
+ let latestTs;
163
+ try {
164
+ latestNumber = BigInt(latest.number);
165
+ latestTs = BigInt(latest.timestamp);
166
+ }
167
+ catch {
168
+ return null;
169
+ }
170
+ // The target block must exist. If lookback overshoots genesis,
171
+ // clamp to a positive height; if that's still 0 we can't sample.
172
+ const targetHeight = latestNumber - BigInt(lookback);
173
+ if (targetHeight <= 0n)
174
+ return null;
175
+ const sinkOld = onError
176
+ ? (err) => onError('eth_getBlockByNumber:lookback', err)
177
+ : undefined;
178
+ const old = await safeRequest(client, 'eth_getBlockByNumber', [`0x${targetHeight.toString(16)}`, false], sinkOld);
179
+ if (!old || !old.number || !old.timestamp)
180
+ return null;
181
+ let oldTs;
182
+ try {
183
+ oldTs = BigInt(old.timestamp);
184
+ }
185
+ catch {
186
+ return null;
187
+ }
188
+ if (latestTs <= oldTs)
189
+ return null;
190
+ // Both block timestamps are in seconds; convert to ms and divide by
191
+ // the lookback span (always `lookback` blocks since we asked by
192
+ // height — no gaps possible). Earlier guards ensure deltaSeconds > 0
193
+ // and lookback > 0, so `ms` is always a finite positive number.
194
+ const deltaSeconds = Number(latestTs - oldTs);
195
+ return (deltaSeconds * 1000) / lookback;
196
+ };
120
197
  //# sourceMappingURL=transport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valve-tech/chain-source",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "Canonical EVM chain-observation primitive: a unified push-or-poll source for new blocks, mempool snapshots, on-demand receipt + tx lookups, and capability disclosure (HTTP / WS / per-method gating). Used as the shared foundation by @valve-tech/gas-oracle and @valve-tech/tx-tracker; consumable directly by anyone building their own derived view on chain state. viem-native. Part of the valve-tech/evm-toolkit synchronized release line — implementation lands in subsequent 0.3.x releases per docs/tx-tracker-spec.md.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/valve-tech/evm-toolkit/tree/main/packages/chain-source#readme",