@secondlayer/sdk 6.46.1 → 6.48.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/dist/index.d.ts +1305 -1202
- package/dist/index.js +12 -1
- package/dist/index.js.map +7 -7
- package/dist/sinks/bun-sqlite.d.ts +158 -0
- package/dist/sinks/bun-sqlite.js +255 -0
- package/dist/sinks/bun-sqlite.js.map +12 -0
- package/dist/sinks/core.d.ts +195 -0
- package/dist/sinks/core.js +215 -0
- package/dist/sinks/core.js.map +11 -0
- package/dist/sinks/drizzle.d.ts +184 -0
- package/dist/sinks/drizzle.js +309 -0
- package/dist/sinks/drizzle.js.map +12 -0
- package/dist/sinks/kysely.d.ts +87 -2
- package/dist/sinks/kysely.js +91 -54
- package/dist/sinks/kysely.js.map +6 -5
- package/dist/sinks/testing.d.ts +183 -0
- package/dist/sinks/testing.js +194 -0
- package/dist/sinks/testing.js.map +10 -0
- package/dist/streams/index.d.ts +577 -473
- package/dist/streams/index.js +11 -1
- package/dist/streams/index.js.map +6 -6
- package/dist/streams/rows.d.ts +208 -208
- package/dist/streams/rows.js +1 -1
- package/dist/streams/rows.js.map +2 -2
- package/dist/subgraphs/index.d.ts +1063 -959
- package/dist/subgraphs/index.js +12 -1
- package/dist/subgraphs/index.js.map +6 -6
- package/dist/x402.d.ts +49 -49
- package/dist/x402.js +1 -1
- package/dist/x402.js.map +2 -2
- package/package.json +26 -4
package/dist/streams/index.d.ts
CHANGED
|
@@ -14,12 +14,83 @@ import { STREAMS_EVENT_TYPES, StreamsEventType } from "@secondlayer/shared";
|
|
|
14
14
|
* The interface is dependency-free on purpose: implementations with real
|
|
15
15
|
* database drivers live behind subpath exports (`@secondlayer/sdk/sinks/*`)
|
|
16
16
|
* so the root entry ships no DB dependency.
|
|
17
|
+
*
|
|
18
|
+
* ## The contract
|
|
19
|
+
*
|
|
20
|
+
* Binding on every implementation; the conformance kit
|
|
21
|
+
* (`@secondlayer/sdk/sinks/testing`) probes each one. Violations are SILENT
|
|
22
|
+
* in production — they surface as gaps or duplicates weeks later, never as
|
|
23
|
+
* errors at the violation site — which is why they are spelled out here and
|
|
24
|
+
* mechanically tested.
|
|
25
|
+
*
|
|
26
|
+
* What the loop guarantees the sink:
|
|
27
|
+
*
|
|
28
|
+
* 1. **Init-before-first-page.** `loadCursor` is called exactly once, before
|
|
29
|
+
* the first fetch — even when the caller passed an explicit `fromCursor`.
|
|
30
|
+
* It is the sink's init hook: create checkpoint storage, validate
|
|
31
|
+
* rollback preconditions.
|
|
32
|
+
* 2. **Deterministic replay.** Re-reading from the same cursor yields the
|
|
33
|
+
* same rows in the same order. `cursor` is therefore a valid idempotency
|
|
34
|
+
* key: an append-only sink can dedup on it with no contract change.
|
|
35
|
+
* 3. **At-least-once delivery.** A batch whose commit outcome was lost (crash
|
|
36
|
+
* after commit, before the loop observed it) is re-committed on restart
|
|
37
|
+
* with the SAME cursor and the same rows.
|
|
38
|
+
*
|
|
39
|
+
* What the sink must guarantee — `commitBatch`:
|
|
40
|
+
*
|
|
41
|
+
* 4. **Rows+cursor atomicity.** The handler's writes and `cursor` commit in
|
|
42
|
+
* ONE transaction. Committing them separately is the classic torn-batch
|
|
43
|
+
* bug: a crash between the two either re-delivers (duplicates) or skips
|
|
44
|
+
* (gap) depending on the order.
|
|
45
|
+
* 5. **Abort on throw.** A throw from `write` aborts the WHOLE transaction —
|
|
46
|
+
* neither rows nor cursor land — so a crashed batch is simply re-read.
|
|
47
|
+
* 6. **The lent transaction is the real one.** `write(tx)` receives the same
|
|
48
|
+
* live transaction the cursor commits in; every handler write must go
|
|
49
|
+
* through it. Writes outside `tx` escape atomicity AND rollback.
|
|
50
|
+
* 7. **Replay safety.** Committing the same cursor twice must not corrupt
|
|
51
|
+
* state (per #3 the rows are identical; upsert/dedup make it exact).
|
|
52
|
+
*
|
|
53
|
+
* What the sink must guarantee — `rollback`:
|
|
54
|
+
*
|
|
55
|
+
* 8. **Delete+rewind atomicity.** Undoing rows at/above the fork and
|
|
56
|
+
* committing `rewindCursor` happen in ONE transaction. A crash between
|
|
57
|
+
* them resumes above the fork and the deleted range is never re-read —
|
|
58
|
+
* the silent-gap bug.
|
|
59
|
+
* 9. **Inclusive fork point.** Undo AT OR ABOVE `forkPointHeight` (`>=`) —
|
|
60
|
+
* the new canonical chain re-supplies the fork block itself.
|
|
61
|
+
* 10. **Idempotent.** The loop may re-apply the same rollback after a crash
|
|
62
|
+
* (reorgs are deduped in memory only); a second application must be a
|
|
63
|
+
* harmless no-op.
|
|
64
|
+
* 11. **Scope by height, not cursor.** On a page reporting several forks the
|
|
65
|
+
* loop calls `rollback` once per fork: each call carries its own
|
|
66
|
+
* `forkPointHeight` but ALL carry the same `rewindCursor` (the lowest
|
|
67
|
+
* fork point). Derive the undo range from `forkPointHeight` only; a
|
|
68
|
+
* sink that derives it from `rewindCursor` under-deletes silently.
|
|
69
|
+
*
|
|
70
|
+
* Error semantics and concurrency:
|
|
71
|
+
*
|
|
72
|
+
* 12. **Throw, don't swallow; no internal retry.** The loop owns retry
|
|
73
|
+
* policy. A swallowed commit error advances the loop past unwritten
|
|
74
|
+
* data; an internal retry can double-apply around a partial failure.
|
|
75
|
+
* 13. **Single writer per checkpoint id.** The loop assumes one live
|
|
76
|
+
* consumer per checkpoint identity. A sink that can detect a second
|
|
77
|
+
* writer (e.g. a lock) must fail loudly — never block or interleave.
|
|
17
78
|
*/
|
|
18
79
|
interface ConsumerSink<Tx = unknown> {
|
|
19
80
|
/** Phantom marker carrying `Tx` in a directly-inferable position, so the
|
|
20
81
|
* consume loops' `TTx` type parameter resolves from the `sink` option
|
|
21
82
|
* (never set at runtime). */
|
|
22
83
|
readonly _tx?: Tx;
|
|
84
|
+
/** Static capabilities, read by the loop before the first fetch to fail
|
|
85
|
+
* fast on impossible pairings. */
|
|
86
|
+
readonly capabilities?: {
|
|
87
|
+
/** This sink cannot undo committed rows (append-only store, ClickHouse,
|
|
88
|
+
* parquet, …), so `rollback` is unimplementable and following the
|
|
89
|
+
* unfinalized tip would corrupt it on the first fork. The loop throws
|
|
90
|
+
* loudly unless consuming with `finalizedOnly: true` — in that mode
|
|
91
|
+
* reorgs never reach the sink and `rollback` may simply throw. */
|
|
92
|
+
finalizedOnly?: boolean;
|
|
93
|
+
};
|
|
23
94
|
/** The committed checkpoint, or `null` on first run. Called once, before
|
|
24
95
|
* the first page. Implementations may create their checkpoint storage
|
|
25
96
|
* here and SHOULD validate their rollback preconditions (e.g. that every
|
|
@@ -39,6 +110,11 @@ interface ConsumerSink<Tx = unknown> {
|
|
|
39
110
|
* without the rewound cursor is the classic silent-gap bug: a crash
|
|
40
111
|
* between the two writes resumes above the fork and the deleted range is
|
|
41
112
|
* never re-read.
|
|
113
|
+
*
|
|
114
|
+
* On a multi-fork page this is called once PER fork, every call with the
|
|
115
|
+
* same `rewindCursor` (the lowest fork point) but its own
|
|
116
|
+
* `forkPointHeight` — scope the undo by `forkPointHeight` only (contract
|
|
117
|
+
* invariant #11), and expect re-application after a crash (#10).
|
|
42
118
|
*/
|
|
43
119
|
rollback(forkPointHeight: number, rewindCursor: string): Promise<void>;
|
|
44
120
|
}
|
|
@@ -46,97 +122,97 @@ interface ConsumerSink<Tx = unknown> {
|
|
|
46
122
|
* is unchanged (an intersection with `unknown` is an identity, so
|
|
47
123
|
* contextual typing of `onBatch` callbacks never degrades to a union). */
|
|
48
124
|
type WithSinkTx<TTx> = [TTx] extends [never] ? unknown : {
|
|
49
|
-
tx: TTx
|
|
125
|
+
tx: TTx;
|
|
50
126
|
};
|
|
51
127
|
type IndexEventBase = {
|
|
52
|
-
cursor: string
|
|
53
|
-
block_height: number
|
|
54
|
-
block_time?: string | null
|
|
55
|
-
tx_id: string
|
|
56
|
-
tx_index: number
|
|
57
|
-
event_index: number
|
|
58
|
-
contract_id: string | null
|
|
128
|
+
cursor: string;
|
|
129
|
+
block_height: number;
|
|
130
|
+
block_time?: string | null;
|
|
131
|
+
tx_id: string;
|
|
132
|
+
tx_index: number;
|
|
133
|
+
event_index: number;
|
|
134
|
+
contract_id: string | null;
|
|
59
135
|
/** Submitting-transaction context, present only when `txContext: true` was
|
|
60
136
|
* requested. `tx_sender` is the real tx sender — distinct from a transfer's
|
|
61
137
|
* asset `sender`, and the only place a `print` event's sender is available.
|
|
62
138
|
* Lets a consumer build per-event tx context without a `/v1/index/transactions`
|
|
63
139
|
* call per event. */
|
|
64
|
-
tx_sender?: string | null
|
|
65
|
-
tx_type?: string | null
|
|
66
|
-
tx_status?: string | null
|
|
67
|
-
tx_contract_id?: string | null
|
|
68
|
-
tx_function_name?: string | null
|
|
140
|
+
tx_sender?: string | null;
|
|
141
|
+
tx_type?: string | null;
|
|
142
|
+
tx_status?: string | null;
|
|
143
|
+
tx_contract_id?: string | null;
|
|
144
|
+
tx_function_name?: string | null;
|
|
69
145
|
};
|
|
70
146
|
type IndexFtTransfer = IndexEventBase & {
|
|
71
|
-
event_type: "ft_transfer"
|
|
72
|
-
asset_identifier: string
|
|
73
|
-
sender: string
|
|
74
|
-
recipient: string
|
|
75
|
-
amount: string
|
|
147
|
+
event_type: "ft_transfer";
|
|
148
|
+
asset_identifier: string;
|
|
149
|
+
sender: string;
|
|
150
|
+
recipient: string;
|
|
151
|
+
amount: string;
|
|
76
152
|
};
|
|
77
153
|
type IndexNftTransfer = IndexEventBase & {
|
|
78
|
-
event_type: "nft_transfer"
|
|
79
|
-
asset_identifier: string
|
|
80
|
-
sender: string
|
|
81
|
-
recipient: string
|
|
82
|
-
value: string
|
|
154
|
+
event_type: "nft_transfer";
|
|
155
|
+
asset_identifier: string;
|
|
156
|
+
sender: string;
|
|
157
|
+
recipient: string;
|
|
158
|
+
value: string;
|
|
83
159
|
};
|
|
84
160
|
type IndexStxTransfer = IndexEventBase & {
|
|
85
|
-
event_type: "stx_transfer"
|
|
86
|
-
sender: string
|
|
87
|
-
recipient: string
|
|
88
|
-
amount: string
|
|
89
|
-
memo: string | null
|
|
161
|
+
event_type: "stx_transfer";
|
|
162
|
+
sender: string;
|
|
163
|
+
recipient: string;
|
|
164
|
+
amount: string;
|
|
165
|
+
memo: string | null;
|
|
90
166
|
};
|
|
91
167
|
type IndexStxMint = IndexEventBase & {
|
|
92
|
-
event_type: "stx_mint"
|
|
93
|
-
recipient: string
|
|
94
|
-
amount: string
|
|
168
|
+
event_type: "stx_mint";
|
|
169
|
+
recipient: string;
|
|
170
|
+
amount: string;
|
|
95
171
|
};
|
|
96
172
|
type IndexStxBurn = IndexEventBase & {
|
|
97
|
-
event_type: "stx_burn"
|
|
98
|
-
sender: string
|
|
99
|
-
amount: string
|
|
173
|
+
event_type: "stx_burn";
|
|
174
|
+
sender: string;
|
|
175
|
+
amount: string;
|
|
100
176
|
};
|
|
101
177
|
type IndexStxLock = IndexEventBase & {
|
|
102
|
-
event_type: "stx_lock"
|
|
103
|
-
sender: string
|
|
104
|
-
amount: string
|
|
178
|
+
event_type: "stx_lock";
|
|
179
|
+
sender: string;
|
|
180
|
+
amount: string;
|
|
105
181
|
payload: {
|
|
106
|
-
unlock_height: string | null
|
|
107
|
-
}
|
|
182
|
+
unlock_height: string | null;
|
|
183
|
+
};
|
|
108
184
|
};
|
|
109
185
|
type IndexFtMint = IndexEventBase & {
|
|
110
|
-
event_type: "ft_mint"
|
|
111
|
-
asset_identifier: string
|
|
112
|
-
recipient: string
|
|
113
|
-
amount: string
|
|
186
|
+
event_type: "ft_mint";
|
|
187
|
+
asset_identifier: string;
|
|
188
|
+
recipient: string;
|
|
189
|
+
amount: string;
|
|
114
190
|
};
|
|
115
191
|
type IndexFtBurn = IndexEventBase & {
|
|
116
|
-
event_type: "ft_burn"
|
|
117
|
-
asset_identifier: string
|
|
118
|
-
sender: string
|
|
119
|
-
amount: string
|
|
192
|
+
event_type: "ft_burn";
|
|
193
|
+
asset_identifier: string;
|
|
194
|
+
sender: string;
|
|
195
|
+
amount: string;
|
|
120
196
|
};
|
|
121
197
|
type IndexNftMint = IndexEventBase & {
|
|
122
|
-
event_type: "nft_mint"
|
|
123
|
-
asset_identifier: string
|
|
124
|
-
recipient: string
|
|
125
|
-
value: string
|
|
198
|
+
event_type: "nft_mint";
|
|
199
|
+
asset_identifier: string;
|
|
200
|
+
recipient: string;
|
|
201
|
+
value: string;
|
|
126
202
|
};
|
|
127
203
|
type IndexNftBurn = IndexEventBase & {
|
|
128
|
-
event_type: "nft_burn"
|
|
129
|
-
asset_identifier: string
|
|
130
|
-
sender: string
|
|
131
|
-
value: string
|
|
204
|
+
event_type: "nft_burn";
|
|
205
|
+
asset_identifier: string;
|
|
206
|
+
sender: string;
|
|
207
|
+
value: string;
|
|
132
208
|
};
|
|
133
209
|
type IndexPrint = IndexEventBase & {
|
|
134
|
-
event_type: "print"
|
|
210
|
+
event_type: "print";
|
|
135
211
|
payload: {
|
|
136
|
-
topic: string | null
|
|
137
|
-
value: unknown
|
|
138
|
-
raw_value: string | null
|
|
139
|
-
}
|
|
212
|
+
topic: string | null;
|
|
213
|
+
value: unknown;
|
|
214
|
+
raw_value: string | null;
|
|
215
|
+
};
|
|
140
216
|
};
|
|
141
217
|
/** Decoded chain event, discriminated by `event_type`. */
|
|
142
218
|
type IndexEvent = IndexFtTransfer | IndexNftTransfer | IndexStxTransfer | IndexStxMint | IndexStxBurn | IndexStxLock | IndexFtMint | IndexFtBurn | IndexNftMint | IndexNftBurn | IndexPrint;
|
|
@@ -144,68 +220,68 @@ type IndexEvent = IndexFtTransfer | IndexNftTransfer | IndexStxTransfer | IndexS
|
|
|
144
220
|
* object carrying that hex (`{ hex }`), or a decoded Clarity-JSON object.
|
|
145
221
|
* Decode helpers (`decodeNftTransfer`, etc.) resolve it to a concrete value. */
|
|
146
222
|
type StreamsClarityValue = string | {
|
|
147
|
-
hex: string
|
|
223
|
+
hex: string;
|
|
148
224
|
} | Record<string, unknown>;
|
|
149
225
|
type StxTransferPayload = {
|
|
150
|
-
sender: string
|
|
151
|
-
recipient: string
|
|
152
|
-
amount: string
|
|
153
|
-
memo?: string
|
|
226
|
+
sender: string;
|
|
227
|
+
recipient: string;
|
|
228
|
+
amount: string;
|
|
229
|
+
memo?: string;
|
|
154
230
|
};
|
|
155
231
|
type StxMintPayload = {
|
|
156
|
-
recipient: string
|
|
157
|
-
amount: string
|
|
232
|
+
recipient: string;
|
|
233
|
+
amount: string;
|
|
158
234
|
};
|
|
159
235
|
type StxBurnPayload = {
|
|
160
|
-
sender: string
|
|
161
|
-
amount: string
|
|
236
|
+
sender: string;
|
|
237
|
+
amount: string;
|
|
162
238
|
};
|
|
163
239
|
type StxLockPayload = {
|
|
164
|
-
locked_address: string
|
|
165
|
-
locked_amount: string
|
|
166
|
-
unlock_height: string
|
|
240
|
+
locked_address: string;
|
|
241
|
+
locked_amount: string;
|
|
242
|
+
unlock_height: string;
|
|
167
243
|
};
|
|
168
244
|
type FtTransferPayload = {
|
|
169
|
-
asset_identifier: string
|
|
170
|
-
sender: string
|
|
171
|
-
recipient: string
|
|
172
|
-
amount: string
|
|
245
|
+
asset_identifier: string;
|
|
246
|
+
sender: string;
|
|
247
|
+
recipient: string;
|
|
248
|
+
amount: string;
|
|
173
249
|
};
|
|
174
250
|
type FtMintPayload = {
|
|
175
|
-
asset_identifier: string
|
|
176
|
-
recipient: string
|
|
177
|
-
amount: string
|
|
251
|
+
asset_identifier: string;
|
|
252
|
+
recipient: string;
|
|
253
|
+
amount: string;
|
|
178
254
|
};
|
|
179
255
|
type FtBurnPayload = {
|
|
180
|
-
asset_identifier: string
|
|
181
|
-
sender: string
|
|
182
|
-
amount: string
|
|
256
|
+
asset_identifier: string;
|
|
257
|
+
sender: string;
|
|
258
|
+
amount: string;
|
|
183
259
|
};
|
|
184
260
|
type NftTransferPayload = {
|
|
185
|
-
asset_identifier: string
|
|
186
|
-
sender: string
|
|
187
|
-
recipient: string
|
|
188
|
-
value: StreamsClarityValue
|
|
261
|
+
asset_identifier: string;
|
|
262
|
+
sender: string;
|
|
263
|
+
recipient: string;
|
|
264
|
+
value: StreamsClarityValue;
|
|
189
265
|
/** Canonical serialized hex of `value`, when the stream carries it. */
|
|
190
|
-
raw_value?: string
|
|
266
|
+
raw_value?: string;
|
|
191
267
|
};
|
|
192
268
|
type NftMintPayload = {
|
|
193
|
-
asset_identifier: string
|
|
194
|
-
recipient: string
|
|
195
|
-
value: StreamsClarityValue
|
|
196
|
-
raw_value?: string
|
|
269
|
+
asset_identifier: string;
|
|
270
|
+
recipient: string;
|
|
271
|
+
value: StreamsClarityValue;
|
|
272
|
+
raw_value?: string;
|
|
197
273
|
};
|
|
198
274
|
type NftBurnPayload = {
|
|
199
|
-
asset_identifier: string
|
|
200
|
-
sender: string
|
|
201
|
-
value: StreamsClarityValue
|
|
202
|
-
raw_value?: string
|
|
275
|
+
asset_identifier: string;
|
|
276
|
+
sender: string;
|
|
277
|
+
value: StreamsClarityValue;
|
|
278
|
+
raw_value?: string;
|
|
203
279
|
};
|
|
204
280
|
type PrintPayload = {
|
|
205
|
-
contract_id?: string | null
|
|
206
|
-
topic?: string
|
|
207
|
-
value?: unknown
|
|
208
|
-
raw_value?: string
|
|
281
|
+
contract_id?: string | null;
|
|
282
|
+
topic?: string;
|
|
283
|
+
value?: unknown;
|
|
284
|
+
raw_value?: string;
|
|
209
285
|
};
|
|
210
286
|
/** Union of every Streams payload shape, discriminated by `event_type` on the
|
|
211
287
|
* parent `StreamsEvent`. */
|
|
@@ -216,92 +292,97 @@ type StreamsEventBase = {
|
|
|
216
292
|
* it as the primary key of your projection rows — replaying a batch then
|
|
217
293
|
* upserts cleanly. Don't synthesize your own id from `tx_id`/`event_index`.
|
|
218
294
|
*/
|
|
219
|
-
cursor: string
|
|
220
|
-
block_height: number
|
|
221
|
-
block_hash: string
|
|
222
|
-
burn_block_height: number
|
|
223
|
-
tx_id: string
|
|
224
|
-
tx_index: number
|
|
225
|
-
event_index: number
|
|
226
|
-
contract_id: string | null
|
|
227
|
-
ts: string
|
|
295
|
+
cursor: string;
|
|
296
|
+
block_height: number;
|
|
297
|
+
block_hash: string;
|
|
298
|
+
burn_block_height: number;
|
|
299
|
+
tx_id: string;
|
|
300
|
+
tx_index: number;
|
|
301
|
+
event_index: number;
|
|
302
|
+
contract_id: string | null;
|
|
303
|
+
ts: string;
|
|
228
304
|
/**
|
|
229
305
|
* True when this event's block is past the finality boundary (immutable).
|
|
230
306
|
* Optional for back-compat; the API always sets it on Streams responses.
|
|
231
307
|
*/
|
|
232
|
-
finalized?: boolean
|
|
308
|
+
finalized?: boolean;
|
|
233
309
|
/**
|
|
234
310
|
* Labels whose filter group this event satisfied, present only when the
|
|
235
311
|
* request used a labelled `filters` map. The SDK dispatches on it for you
|
|
236
312
|
* (`on.<label>`), so handlers rarely read it directly.
|
|
237
313
|
*/
|
|
238
|
-
matched?: string[]
|
|
314
|
+
matched?: string[];
|
|
239
315
|
};
|
|
240
316
|
type StreamsEventOf<
|
|
241
317
|
T extends StreamsEventType,
|
|
242
318
|
P
|
|
243
319
|
> = StreamsEventBase & {
|
|
244
|
-
event_type: T
|
|
245
|
-
payload: P
|
|
320
|
+
event_type: T;
|
|
321
|
+
payload: P;
|
|
246
322
|
};
|
|
247
323
|
/** A raw Streams event. Discriminated on `event_type`, so `event.payload`
|
|
248
324
|
* narrows to the matching payload shape once the type is checked. */
|
|
249
325
|
type StreamsEvent = StreamsEventOf<"stx_transfer", StxTransferPayload> | StreamsEventOf<"stx_mint", StxMintPayload> | StreamsEventOf<"stx_burn", StxBurnPayload> | StreamsEventOf<"stx_lock", StxLockPayload> | StreamsEventOf<"ft_transfer", FtTransferPayload> | StreamsEventOf<"ft_mint", FtMintPayload> | StreamsEventOf<"ft_burn", FtBurnPayload> | StreamsEventOf<"nft_transfer", NftTransferPayload> | StreamsEventOf<"nft_mint", NftMintPayload> | StreamsEventOf<"nft_burn", NftBurnPayload> | StreamsEventOf<"print", PrintPayload>;
|
|
250
326
|
type StreamsTip = {
|
|
251
|
-
block_height: number
|
|
252
|
-
block_hash: string
|
|
253
|
-
burn_block_height: number
|
|
327
|
+
block_height: number;
|
|
328
|
+
block_hash: string;
|
|
329
|
+
burn_block_height: number;
|
|
254
330
|
/**
|
|
255
331
|
* Highest Stacks block past the burn-confirmation finality boundary.
|
|
256
332
|
* Optional for back-compat; the API always sets it.
|
|
257
333
|
*/
|
|
258
|
-
finalized_height?: number
|
|
259
|
-
lag_seconds: number
|
|
334
|
+
finalized_height?: number;
|
|
335
|
+
lag_seconds: number;
|
|
260
336
|
/**
|
|
261
337
|
* Oldest height still seekable on the live API for the caller's tier
|
|
262
338
|
* (`tip - retention`). `null` = unlimited retention. Older reads must use the
|
|
263
339
|
* cold dumps lane. Optional for back-compat.
|
|
264
340
|
*/
|
|
265
|
-
oldest_seekable_height?: number | null
|
|
341
|
+
oldest_seekable_height?: number | null;
|
|
266
342
|
/** Oldest seekable cursor (`<oldest_seekable_height>:0`); `null` = unlimited. */
|
|
267
|
-
oldest_cursor?: string | null
|
|
343
|
+
oldest_cursor?: string | null;
|
|
268
344
|
};
|
|
269
345
|
type StreamsCanonicalBlock = {
|
|
270
|
-
block_height: number
|
|
271
|
-
block_hash: string
|
|
272
|
-
burn_block_height: number
|
|
273
|
-
burn_block_hash: string | null
|
|
274
|
-
is_canonical: true
|
|
346
|
+
block_height: number;
|
|
347
|
+
block_hash: string;
|
|
348
|
+
burn_block_height: number;
|
|
349
|
+
burn_block_hash: string | null;
|
|
350
|
+
is_canonical: true;
|
|
275
351
|
};
|
|
276
352
|
type StreamsReorg = {
|
|
277
|
-
detected_at: string
|
|
278
|
-
fork_point_height: number
|
|
353
|
+
detected_at: string;
|
|
354
|
+
fork_point_height: number;
|
|
279
355
|
orphaned_range: {
|
|
280
|
-
from: string
|
|
281
|
-
to: string
|
|
282
|
-
}
|
|
356
|
+
from: string;
|
|
357
|
+
to: string;
|
|
358
|
+
};
|
|
283
359
|
/**
|
|
284
360
|
* First position of the new canonical chain at the fork, `fork:0`
|
|
285
361
|
* (INCLUSIVE). Not an exclusive resume token — resuming directly from it
|
|
286
362
|
* skips `fork:0`. The consumer rewinds to the foot of `fork_point_height`
|
|
287
363
|
* (`Cursor.atHeight`) to re-read the new run from `fork:0` inclusive.
|
|
288
364
|
*/
|
|
289
|
-
new_canonical_tip: string
|
|
365
|
+
new_canonical_tip: string;
|
|
290
366
|
};
|
|
291
|
-
type StreamsEventsEnvelope = {
|
|
292
|
-
events:
|
|
293
|
-
next_cursor: string | null
|
|
294
|
-
tip: StreamsTip
|
|
295
|
-
reorgs: StreamsReorg[]
|
|
367
|
+
type StreamsEventsEnvelope<TEvent = StreamsEvent> = {
|
|
368
|
+
events: TEvent[];
|
|
369
|
+
next_cursor: string | null;
|
|
370
|
+
tip: StreamsTip;
|
|
371
|
+
reorgs: StreamsReorg[];
|
|
296
372
|
};
|
|
297
373
|
type StreamsEventsListEnvelope = Omit<StreamsEventsEnvelope, "next_cursor">;
|
|
374
|
+
/** The StreamsEvent union narrowed to a `types` selection — what a
|
|
375
|
+
* const-generic `types: ["ft_transfer"]` buys at the type level. */
|
|
376
|
+
type StreamsEventOfTypes<T extends readonly StreamsEventType[]> = Extract<StreamsEvent, {
|
|
377
|
+
event_type: T[number];
|
|
378
|
+
}>;
|
|
298
379
|
type StreamsReorgsListParams = {
|
|
299
|
-
since: string
|
|
300
|
-
limit?: number
|
|
380
|
+
since: string;
|
|
381
|
+
limit?: number;
|
|
301
382
|
};
|
|
302
383
|
type StreamsReorgsListEnvelope = {
|
|
303
|
-
reorgs: StreamsReorg[]
|
|
304
|
-
next_since: string | null
|
|
384
|
+
reorgs: StreamsReorg[];
|
|
385
|
+
next_since: string | null;
|
|
305
386
|
};
|
|
306
387
|
/** A filter that matches a single value or any value in a list. */
|
|
307
388
|
type StreamsFilterValue = string | readonly string[];
|
|
@@ -310,11 +391,11 @@ type StreamsFilterValue = string | readonly string[];
|
|
|
310
391
|
* map OR together server-side.
|
|
311
392
|
*/
|
|
312
393
|
type StreamsLabelledFilter = {
|
|
313
|
-
types?: readonly StreamsEventType[]
|
|
314
|
-
contractId?: StreamsFilterValue
|
|
315
|
-
sender?: StreamsFilterValue
|
|
316
|
-
recipient?: StreamsFilterValue
|
|
317
|
-
assetIdentifier?: string
|
|
394
|
+
types?: readonly StreamsEventType[];
|
|
395
|
+
contractId?: StreamsFilterValue;
|
|
396
|
+
sender?: StreamsFilterValue;
|
|
397
|
+
recipient?: StreamsFilterValue;
|
|
398
|
+
assetIdentifier?: string;
|
|
318
399
|
};
|
|
319
400
|
/** A map of label → filter group. Labels are yours; the server echoes them. */
|
|
320
401
|
type StreamsFilterMap = Record<string, StreamsLabelledFilter>;
|
|
@@ -327,65 +408,65 @@ type StreamsEventForFilter<
|
|
|
327
408
|
F,
|
|
328
409
|
D extends boolean = false
|
|
329
410
|
> = F extends {
|
|
330
|
-
types: readonly (infer T extends StreamsEventType)[]
|
|
411
|
+
types: readonly (infer T extends StreamsEventType)[];
|
|
331
412
|
} ? D extends true ? Extract<IndexEvent, {
|
|
332
|
-
event_type: T
|
|
413
|
+
event_type: T;
|
|
333
414
|
}> : Extract<StreamsEvent, {
|
|
334
|
-
event_type: T
|
|
415
|
+
event_type: T;
|
|
335
416
|
}> : D extends true ? IndexEvent : StreamsEvent;
|
|
336
417
|
type StreamsEventsListParams = {
|
|
337
|
-
cursor?: string | null
|
|
338
|
-
fromHeight?: number
|
|
339
|
-
toHeight?: number
|
|
340
|
-
types?: readonly StreamsEventType[]
|
|
418
|
+
cursor?: string | null;
|
|
419
|
+
fromHeight?: number;
|
|
420
|
+
toHeight?: number;
|
|
421
|
+
types?: readonly StreamsEventType[];
|
|
341
422
|
/** Event types to exclude (applied after `types`). */
|
|
342
|
-
notTypes?: readonly StreamsEventType[]
|
|
343
|
-
contractId?: StreamsFilterValue
|
|
344
|
-
sender?: StreamsFilterValue
|
|
345
|
-
recipient?: StreamsFilterValue
|
|
346
|
-
assetIdentifier?: string
|
|
423
|
+
notTypes?: readonly StreamsEventType[];
|
|
424
|
+
contractId?: StreamsFilterValue;
|
|
425
|
+
sender?: StreamsFilterValue;
|
|
426
|
+
recipient?: StreamsFilterValue;
|
|
427
|
+
assetIdentifier?: string;
|
|
347
428
|
/**
|
|
348
429
|
* Labelled filter groups. The groups OR together in one scan and each
|
|
349
430
|
* returned event carries the labels it matched (`event.matched`) — two
|
|
350
431
|
* unrelated concerns share one page, one cursor, one checkpoint.
|
|
351
432
|
*/
|
|
352
|
-
filters?: StreamsFilterMap
|
|
353
|
-
limit?: number
|
|
433
|
+
filters?: StreamsFilterMap;
|
|
434
|
+
limit?: number;
|
|
354
435
|
};
|
|
355
436
|
type StreamsEventsStreamParams = {
|
|
356
|
-
fromCursor?: string | null
|
|
357
|
-
types?: readonly StreamsEventType[]
|
|
358
|
-
notTypes?: readonly StreamsEventType[]
|
|
359
|
-
contractId?: StreamsFilterValue
|
|
360
|
-
sender?: StreamsFilterValue
|
|
361
|
-
recipient?: StreamsFilterValue
|
|
362
|
-
assetIdentifier?: string
|
|
437
|
+
fromCursor?: string | null;
|
|
438
|
+
types?: readonly StreamsEventType[];
|
|
439
|
+
notTypes?: readonly StreamsEventType[];
|
|
440
|
+
contractId?: StreamsFilterValue;
|
|
441
|
+
sender?: StreamsFilterValue;
|
|
442
|
+
recipient?: StreamsFilterValue;
|
|
443
|
+
assetIdentifier?: string;
|
|
363
444
|
/** Labelled filter groups; see {@link StreamsEventsListParams.filters}. */
|
|
364
|
-
filters?: StreamsFilterMap
|
|
365
|
-
batchSize?: number
|
|
366
|
-
emptyBackoffMs?: number
|
|
367
|
-
maxPages?: number
|
|
368
|
-
maxEmptyPolls?: number
|
|
369
|
-
signal?: AbortSignal
|
|
445
|
+
filters?: StreamsFilterMap;
|
|
446
|
+
batchSize?: number;
|
|
447
|
+
emptyBackoffMs?: number;
|
|
448
|
+
maxPages?: number;
|
|
449
|
+
maxEmptyPolls?: number;
|
|
450
|
+
signal?: AbortSignal;
|
|
370
451
|
};
|
|
371
452
|
type StreamsEventsSubscribeParams = {
|
|
372
453
|
/** Resume strictly after this cursor; omit to live-tail from the tip. */
|
|
373
|
-
fromCursor?: string | null
|
|
374
|
-
types?: readonly StreamsEventType[]
|
|
375
|
-
notTypes?: readonly StreamsEventType[]
|
|
376
|
-
contractId?: StreamsFilterValue
|
|
377
|
-
sender?: StreamsFilterValue
|
|
378
|
-
recipient?: StreamsFilterValue
|
|
379
|
-
assetIdentifier?: string
|
|
454
|
+
fromCursor?: string | null;
|
|
455
|
+
types?: readonly StreamsEventType[];
|
|
456
|
+
notTypes?: readonly StreamsEventType[];
|
|
457
|
+
contractId?: StreamsFilterValue;
|
|
458
|
+
sender?: StreamsFilterValue;
|
|
459
|
+
recipient?: StreamsFilterValue;
|
|
460
|
+
assetIdentifier?: string;
|
|
380
461
|
/** Labelled filter groups; see {@link StreamsEventsListParams.filters}. */
|
|
381
|
-
filters?: StreamsFilterMap
|
|
462
|
+
filters?: StreamsFilterMap;
|
|
382
463
|
/** Abort to unsubscribe (the returned function does the same). */
|
|
383
|
-
signal?: AbortSignal
|
|
464
|
+
signal?: AbortSignal;
|
|
384
465
|
/** Called for each pushed event, in order. */
|
|
385
|
-
onEvent: (event: StreamsEvent) => void | Promise<void
|
|
466
|
+
onEvent: (event: StreamsEvent) => void | Promise<void>;
|
|
386
467
|
/** Called on a connection error; the subscription auto-reconnects from the
|
|
387
468
|
* last delivered cursor unless the signal has aborted. */
|
|
388
|
-
onError?: (err: unknown) => void
|
|
469
|
+
onError?: (err: unknown) => void;
|
|
389
470
|
};
|
|
390
471
|
/**
|
|
391
472
|
* The checkpoint the SDK computes for a batch. Persist `cursor` inside the same
|
|
@@ -412,14 +493,14 @@ type ConsumerBatchContext<
|
|
|
412
493
|
TReorg = unknown
|
|
413
494
|
> = {
|
|
414
495
|
/** Checkpoint to commit alongside your rows. */
|
|
415
|
-
cursor: string | null
|
|
496
|
+
cursor: string | null;
|
|
416
497
|
/** Highest canonical block the sweep has reached. `null` before the first
|
|
417
498
|
* row of a fresh consume. */
|
|
418
|
-
height: number | null
|
|
499
|
+
height: number | null;
|
|
419
500
|
/** Chain tip as of this page's read. */
|
|
420
|
-
tipHeight: number
|
|
501
|
+
tipHeight: number;
|
|
421
502
|
/** `tipHeight - height`, floored at 0. `null` until `height` is known. */
|
|
422
|
-
blocksBehind: number | null
|
|
503
|
+
blocksBehind: number | null;
|
|
423
504
|
/**
|
|
424
505
|
* The full tip for this page — `StreamsTip` or `IndexTip` depending on the
|
|
425
506
|
* surface. Exposed here so a handler never needs the `envelope` parameter,
|
|
@@ -427,12 +508,12 @@ type ConsumerBatchContext<
|
|
|
427
508
|
* `finalizedOnly` mistake becomes reachable (`return envelope.next_cursor`
|
|
428
509
|
* jumps the cursor past events that were filtered out and never delivered).
|
|
429
510
|
*/
|
|
430
|
-
tip: TTip
|
|
511
|
+
tip: TTip;
|
|
431
512
|
/**
|
|
432
513
|
* Reorgs reported alongside this page; empty when none. Rollback still
|
|
433
514
|
* belongs in `onReorg` — this is for observability inside a batch.
|
|
434
515
|
*/
|
|
435
|
-
reorgs: readonly TReorg[]
|
|
516
|
+
reorgs: readonly TReorg[];
|
|
436
517
|
};
|
|
437
518
|
/** @deprecated Use {@link ConsumerBatchContext} — the Index and Streams loops
|
|
438
519
|
* share one shape now. Kept as an alias so existing annotations compile. */
|
|
@@ -442,20 +523,20 @@ type StreamsBatchContext = ConsumerBatchContext;
|
|
|
442
523
|
* inside the same transaction as your rollback so the two commit atomically.
|
|
443
524
|
*/
|
|
444
525
|
type StreamsReorgContext = {
|
|
445
|
-
cursor: string
|
|
526
|
+
cursor: string;
|
|
446
527
|
};
|
|
447
528
|
type StreamsEventsConsumeParams<
|
|
448
529
|
TTx = never,
|
|
449
530
|
D extends boolean = false,
|
|
450
531
|
F extends StreamsFilterMap = Record<never, never>
|
|
451
532
|
> = {
|
|
452
|
-
fromCursor?: string | null
|
|
533
|
+
fromCursor?: string | null;
|
|
453
534
|
/**
|
|
454
535
|
* Deliver events pre-decoded as the flat, `event_type`-discriminated rows
|
|
455
536
|
* Index serves (`IndexEvent`), so Streams consumption reads identically
|
|
456
537
|
* to Index consumption — no guard+decode pairs in your handler.
|
|
457
538
|
*/
|
|
458
|
-
decoded?: D
|
|
539
|
+
decoded?: D;
|
|
459
540
|
/**
|
|
460
541
|
* Destination adapter that owns the checkpoint + rollback transaction
|
|
461
542
|
* (e.g. `kyselySink` from `@secondlayer/sdk/sinks/kysely`). With a sink:
|
|
@@ -464,29 +545,29 @@ type StreamsEventsConsumeParams<
|
|
|
464
545
|
* transaction), reorg rollback is automatic, and `onBatch`'s return value
|
|
465
546
|
* is ignored.
|
|
466
547
|
*/
|
|
467
|
-
sink?: ConsumerSink<TTx
|
|
548
|
+
sink?: ConsumerSink<TTx>;
|
|
468
549
|
/** Fires once per page, before `onBatch` and before any early return. */
|
|
469
|
-
onProgress?: (ctx: ConsumerBatchContext) => void
|
|
470
|
-
mode?: "tail" | "bounded"
|
|
550
|
+
onProgress?: (ctx: ConsumerBatchContext) => void;
|
|
551
|
+
mode?: "tail" | "bounded";
|
|
471
552
|
/**
|
|
472
553
|
* Emit only finalized (immutable) events and never surface reorgs. The SDK
|
|
473
554
|
* checkpoints at the last finalized event and re-reads the unfinalized tail
|
|
474
555
|
* until it settles. Trades finality lag for zero reorg handling; `onReorg` is
|
|
475
556
|
* ignored.
|
|
476
557
|
*/
|
|
477
|
-
finalizedOnly?: boolean
|
|
478
|
-
types?: readonly StreamsEventType[]
|
|
479
|
-
notTypes?: readonly StreamsEventType[]
|
|
480
|
-
contractId?: StreamsFilterValue
|
|
481
|
-
sender?: StreamsFilterValue
|
|
482
|
-
recipient?: StreamsFilterValue
|
|
483
|
-
assetIdentifier?: string
|
|
558
|
+
finalizedOnly?: boolean;
|
|
559
|
+
types?: readonly StreamsEventType[];
|
|
560
|
+
notTypes?: readonly StreamsEventType[];
|
|
561
|
+
contractId?: StreamsFilterValue;
|
|
562
|
+
sender?: StreamsFilterValue;
|
|
563
|
+
recipient?: StreamsFilterValue;
|
|
564
|
+
assetIdentifier?: string;
|
|
484
565
|
/**
|
|
485
566
|
* Labelled filter groups. The groups OR together in ONE server-side scan,
|
|
486
567
|
* so two unrelated concerns share one page, one cursor, and one checkpoint
|
|
487
568
|
* instead of two consume loops. Pair with `on` to handle each label.
|
|
488
569
|
*/
|
|
489
|
-
filters?: F
|
|
570
|
+
filters?: F;
|
|
490
571
|
/**
|
|
491
572
|
* One handler per label in `filters`. Every label must be handled, so
|
|
492
573
|
* adding a label is a compile error until its handler exists.
|
|
@@ -497,8 +578,8 @@ type StreamsEventsConsumeParams<
|
|
|
497
578
|
* labels do not interleave within a page — add `onBatch` when you need
|
|
498
579
|
* strict global order across labels.
|
|
499
580
|
*/
|
|
500
|
-
on?: { [K in keyof F] : (events: StreamsEventForFilter<F[K], D>[], ctx: StreamsBatchContext & WithSinkTx<TTx>) => void | Promise<void> }
|
|
501
|
-
batchSize?: number
|
|
581
|
+
on?: { [K in keyof F] : (events: StreamsEventForFilter<F[K], D>[], ctx: StreamsBatchContext & WithSinkTx<TTx>) => void | Promise<void> };
|
|
582
|
+
batchSize?: number;
|
|
502
583
|
/**
|
|
503
584
|
* Apply a page of canonical events. Persist `ctx.cursor` in the same
|
|
504
585
|
* transaction as your writes. Returning a cursor overrides `ctx.cursor` as
|
|
@@ -507,7 +588,7 @@ type StreamsEventsConsumeParams<
|
|
|
507
588
|
* Optional only when `on` handles the page instead; a consume call with
|
|
508
589
|
* neither throws.
|
|
509
590
|
*/
|
|
510
|
-
onBatch?: (events: D extends true ? IndexEvent[] : StreamsEvent[], envelope: StreamsEventsEnvelope, ctx: StreamsBatchContext & WithSinkTx<TTx>) => void | string | null | undefined | Promise<void> | Promise<string | null | undefined
|
|
591
|
+
onBatch?: (events: D extends true ? IndexEvent[] : StreamsEvent[], envelope: StreamsEventsEnvelope, ctx: StreamsBatchContext & WithSinkTx<TTx>) => void | string | null | undefined | Promise<void> | Promise<string | null | undefined>;
|
|
511
592
|
/**
|
|
512
593
|
* Roll your projection back to `reorg.fork_point_height`, persisting
|
|
513
594
|
* `ctx.cursor` in the same transaction. Called once per *new* reorg
|
|
@@ -515,127 +596,137 @@ type StreamsEventsConsumeParams<
|
|
|
515
596
|
* now-canonical events. Omit it to ignore reorgs (events stay canonical, but
|
|
516
597
|
* stale rows from an orphaned fork are left in place).
|
|
517
598
|
*/
|
|
518
|
-
onReorg?: (reorg: StreamsReorg, ctx: StreamsReorgContext) => Promise<void> | void
|
|
599
|
+
onReorg?: (reorg: StreamsReorg, ctx: StreamsReorgContext) => Promise<void> | void;
|
|
519
600
|
/** Page-fetch retries after the first failure (429/5xx/network only —
|
|
520
601
|
* 4xx and handler throws always propagate). Default 3; `0` disables. */
|
|
521
|
-
retryCount?: number
|
|
602
|
+
retryCount?: number;
|
|
522
603
|
/** Base retry delay in ms; the n-th retry waits `retryDelay * n`. A server
|
|
523
604
|
* `Retry-After` overrides it. Default 1000. */
|
|
524
|
-
retryDelay?: number
|
|
605
|
+
retryDelay?: number;
|
|
525
606
|
/** Void observer, called before each retry sleep (metrics/logging). */
|
|
526
607
|
onError?: (err: unknown, ctx: {
|
|
527
|
-
attempt: number
|
|
528
|
-
retriesLeft: number
|
|
529
|
-
delayMs: number
|
|
530
|
-
}) => void
|
|
531
|
-
emptyBackoffMs?: number
|
|
532
|
-
maxPages?: number
|
|
533
|
-
maxEmptyPolls?: number
|
|
534
|
-
signal?: AbortSignal
|
|
608
|
+
attempt: number;
|
|
609
|
+
retriesLeft: number;
|
|
610
|
+
delayMs: number;
|
|
611
|
+
}) => void;
|
|
612
|
+
emptyBackoffMs?: number;
|
|
613
|
+
maxPages?: number;
|
|
614
|
+
maxEmptyPolls?: number;
|
|
615
|
+
signal?: AbortSignal;
|
|
535
616
|
};
|
|
536
617
|
/**
|
|
537
618
|
* One yielded page from {@link StreamsClient.consume} — the
|
|
538
619
|
* `GET /v1/streams/events` envelope verbatim, with `next_cursor` renamed to
|
|
539
620
|
* `cursor` (the checkpoint to persist and resume from).
|
|
540
621
|
*/
|
|
541
|
-
type StreamsBatch = {
|
|
622
|
+
type StreamsBatch<TEvent = StreamsEvent> = {
|
|
542
623
|
/** Canonical events of this page, in cursor order. */
|
|
543
|
-
events:
|
|
624
|
+
events: TEvent[];
|
|
544
625
|
/** Checkpoint after this page — pass back as `consume({ cursor })` to resume. */
|
|
545
|
-
cursor: string | null
|
|
546
|
-
tip: StreamsTip
|
|
626
|
+
cursor: string | null;
|
|
627
|
+
tip: StreamsTip;
|
|
547
628
|
/** Chain reorgs reported alongside this page; empty when none. */
|
|
548
|
-
reorgs: StreamsReorg[]
|
|
629
|
+
reorgs: StreamsReorg[];
|
|
549
630
|
};
|
|
550
631
|
type StreamsConsumeParams = {
|
|
551
632
|
/** Resume strictly after this cursor; omit to start from the oldest seekable page. */
|
|
552
|
-
cursor?: string | null
|
|
553
|
-
types?: readonly StreamsEventType[]
|
|
554
|
-
notTypes?: readonly StreamsEventType[]
|
|
555
|
-
contractId?: StreamsFilterValue
|
|
556
|
-
sender?: StreamsFilterValue
|
|
557
|
-
recipient?: StreamsFilterValue
|
|
558
|
-
assetIdentifier?: string
|
|
633
|
+
cursor?: string | null;
|
|
634
|
+
types?: readonly StreamsEventType[];
|
|
635
|
+
notTypes?: readonly StreamsEventType[];
|
|
636
|
+
contractId?: StreamsFilterValue;
|
|
637
|
+
sender?: StreamsFilterValue;
|
|
638
|
+
recipient?: StreamsFilterValue;
|
|
639
|
+
assetIdentifier?: string;
|
|
640
|
+
/** Labelled OR-groups — same semantics as `events.consume`; each returned
|
|
641
|
+
* event echoes the labels it matched. */
|
|
642
|
+
filters?: StreamsFilterMap;
|
|
559
643
|
/** Events per page (the `limit` query param). Default 100. */
|
|
560
|
-
batchSize?: number
|
|
644
|
+
batchSize?: number;
|
|
561
645
|
/** Poll interval while caught up at the tip, in ms. Default 2000. */
|
|
562
|
-
intervalMs?: number
|
|
646
|
+
intervalMs?: number;
|
|
563
647
|
/** Abort to end the iteration. */
|
|
564
|
-
signal?: AbortSignal
|
|
648
|
+
signal?: AbortSignal;
|
|
565
649
|
};
|
|
566
650
|
type StreamsEventsConsumeResult = {
|
|
567
|
-
cursor: string | null
|
|
568
|
-
pages: number
|
|
569
|
-
emptyPolls: number
|
|
651
|
+
cursor: string | null;
|
|
652
|
+
pages: number;
|
|
653
|
+
emptyPolls: number;
|
|
570
654
|
};
|
|
571
655
|
type StreamsEventsReplayParams = {
|
|
572
656
|
/** Start point: `"genesis"` (default) or a `<block>:<index>` cursor. */
|
|
573
|
-
from?: "genesis" | string
|
|
657
|
+
from?: "genesis" | string;
|
|
574
658
|
/**
|
|
575
659
|
* Called once per finalized dump file, in block order, before live tailing.
|
|
576
660
|
* Process the parquet with your own tooling (e.g. DuckDB) — the SDK does not
|
|
577
661
|
* decode parquet. Use `client.dumps.download(file)` to fetch + verify bytes.
|
|
578
662
|
*/
|
|
579
|
-
onDumpFile: (file: StreamsDumpFile) => Promise<void> | void
|
|
663
|
+
onDumpFile: (file: StreamsDumpFile) => Promise<void> | void;
|
|
580
664
|
/** Called per live page after the dump phase, like `consume`. */
|
|
581
|
-
onBatch: (events: StreamsEvent[], envelope: StreamsEventsEnvelope) => Promise<string | null | undefined> | string | null | undefined
|
|
665
|
+
onBatch: (events: StreamsEvent[], envelope: StreamsEventsEnvelope) => Promise<string | null | undefined> | string | null | undefined;
|
|
582
666
|
/**
|
|
583
667
|
* Called when the live-tail phase (after the dump backfill) crosses a reorg,
|
|
584
668
|
* before the cursor rewinds and re-reads the now-canonical events — same
|
|
585
669
|
* contract as `consume`. The dump-backfill phase is finalized and never
|
|
586
670
|
* reorgs; omit this to leave stale rows from an orphaned fork in place.
|
|
587
671
|
*/
|
|
588
|
-
onReorg?: (reorg: StreamsReorg, ctx: StreamsReorgContext) => Promise<void> | void
|
|
589
|
-
mode?: "tail" | "bounded"
|
|
590
|
-
batchSize?: number
|
|
591
|
-
emptyBackoffMs?: number
|
|
592
|
-
maxPages?: number
|
|
593
|
-
maxEmptyPolls?: number
|
|
594
|
-
signal?: AbortSignal
|
|
672
|
+
onReorg?: (reorg: StreamsReorg, ctx: StreamsReorgContext) => Promise<void> | void;
|
|
673
|
+
mode?: "tail" | "bounded";
|
|
674
|
+
batchSize?: number;
|
|
675
|
+
emptyBackoffMs?: number;
|
|
676
|
+
maxPages?: number;
|
|
677
|
+
maxEmptyPolls?: number;
|
|
678
|
+
signal?: AbortSignal;
|
|
679
|
+
/** Narrow the LIVE TAIL after the dump phase. The dump files themselves are
|
|
680
|
+
* always all-type (block-partitioned parquet) — filter those in your own
|
|
681
|
+
* tooling while processing each file. */
|
|
682
|
+
types?: readonly StreamsEventType[];
|
|
683
|
+
notTypes?: readonly StreamsEventType[];
|
|
684
|
+
/** Labelled OR-groups for the live tail, like `consume`. */
|
|
685
|
+
filters?: StreamsFilterMap;
|
|
595
686
|
};
|
|
596
687
|
type FetchLike2 = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
597
688
|
/** One bulk parquet file in the dumps manifest. `path` is the object key under
|
|
598
689
|
* the dumps base URL. */
|
|
599
690
|
type StreamsDumpFile = {
|
|
600
|
-
path: string
|
|
601
|
-
from_block: number
|
|
602
|
-
to_block: number
|
|
603
|
-
min_cursor: string | null
|
|
604
|
-
max_cursor: string | null
|
|
605
|
-
row_count: number
|
|
606
|
-
byte_size: number
|
|
607
|
-
sha256: string
|
|
608
|
-
schema_version: number
|
|
609
|
-
created_at: string
|
|
691
|
+
path: string;
|
|
692
|
+
from_block: number;
|
|
693
|
+
to_block: number;
|
|
694
|
+
min_cursor: string | null;
|
|
695
|
+
max_cursor: string | null;
|
|
696
|
+
row_count: number;
|
|
697
|
+
byte_size: number;
|
|
698
|
+
sha256: string;
|
|
699
|
+
schema_version: number;
|
|
700
|
+
created_at: string;
|
|
610
701
|
};
|
|
611
702
|
type StreamsDumpsManifest = {
|
|
612
|
-
dataset: string
|
|
613
|
-
network: string
|
|
614
|
-
version: string
|
|
615
|
-
schema_version: number
|
|
616
|
-
generated_at: string
|
|
617
|
-
producer_version: string
|
|
618
|
-
finality_lag_blocks: number
|
|
703
|
+
dataset: string;
|
|
704
|
+
network: string;
|
|
705
|
+
version: string;
|
|
706
|
+
schema_version: number;
|
|
707
|
+
generated_at: string;
|
|
708
|
+
producer_version: string;
|
|
709
|
+
finality_lag_blocks: number;
|
|
619
710
|
/** Cursor at the end of the finalized bulk coverage — hand to live tailing. */
|
|
620
|
-
latest_finalized_cursor: string | null
|
|
711
|
+
latest_finalized_cursor: string | null;
|
|
621
712
|
coverage: {
|
|
622
|
-
from_block: number
|
|
623
|
-
to_block: number
|
|
624
|
-
}
|
|
625
|
-
files: StreamsDumpFile[]
|
|
713
|
+
from_block: number;
|
|
714
|
+
to_block: number;
|
|
715
|
+
};
|
|
716
|
+
files: StreamsDumpFile[];
|
|
626
717
|
/** ed25519 signature over the manifest's canonical bytes. Absent on legacy
|
|
627
718
|
* unsigned manifests. Verified by `list()` when `verifyDumpsManifest` is on. */
|
|
628
|
-
signature?: string
|
|
719
|
+
signature?: string;
|
|
629
720
|
/** Short id of the signing public key. */
|
|
630
|
-
key_id?: string
|
|
721
|
+
key_id?: string;
|
|
631
722
|
};
|
|
632
723
|
type StreamsDumps = {
|
|
633
724
|
/** Fetch and parse the latest dumps manifest. */
|
|
634
|
-
list(): Promise<StreamsDumpsManifest
|
|
725
|
+
list(): Promise<StreamsDumpsManifest>;
|
|
635
726
|
/** Absolute URL for a manifest file. */
|
|
636
|
-
fileUrl(file: StreamsDumpFile): string
|
|
727
|
+
fileUrl(file: StreamsDumpFile): string;
|
|
637
728
|
/** Download a parquet file and verify its sha256 against the manifest. */
|
|
638
|
-
download(file: StreamsDumpFile): Promise<Uint8Array
|
|
729
|
+
download(file: StreamsDumpFile): Promise<Uint8Array>;
|
|
639
730
|
};
|
|
640
731
|
type StreamsClient = {
|
|
641
732
|
/**
|
|
@@ -652,10 +743,19 @@ type StreamsClient = {
|
|
|
652
743
|
* rewound automatically — use `events.consume` with `onReorg` for managed
|
|
653
744
|
* rollback semantics.
|
|
654
745
|
*/
|
|
655
|
-
|
|
746
|
+
/** Narrowing overload: a literal `types` array narrows every batch's
|
|
747
|
+
* event union to exactly those members. */
|
|
748
|
+
consume<const T extends readonly StreamsEventType[]>(params: StreamsConsumeParams & {
|
|
749
|
+
types: T;
|
|
750
|
+
}): AsyncIterableIterator<StreamsBatch<StreamsEventOfTypes<T>>>;
|
|
751
|
+
consume(params?: StreamsConsumeParams): AsyncIterableIterator<StreamsBatch>;
|
|
656
752
|
events: {
|
|
657
|
-
|
|
658
|
-
|
|
753
|
+
/** Narrowing overload, matching `consume`. */
|
|
754
|
+
list<const T extends readonly StreamsEventType[]>(params: StreamsEventsListParams & {
|
|
755
|
+
types: T;
|
|
756
|
+
}): Promise<StreamsEventsEnvelope<StreamsEventOfTypes<T>>>;
|
|
757
|
+
list(params?: StreamsEventsListParams): Promise<StreamsEventsEnvelope>;
|
|
758
|
+
byTxId(txId: string): Promise<StreamsEventsListEnvelope>;
|
|
659
759
|
/**
|
|
660
760
|
* Pull pages from Streams and call `onBatch` after each page.
|
|
661
761
|
*
|
|
@@ -670,8 +770,8 @@ type StreamsClient = {
|
|
|
670
770
|
TTx = never,
|
|
671
771
|
D extends boolean = false
|
|
672
772
|
>(params: StreamsEventsConsumeParams<TTx, D, F> & {
|
|
673
|
-
sink?: ConsumerSink<TTx
|
|
674
|
-
}): Promise<StreamsEventsConsumeResult
|
|
773
|
+
sink?: ConsumerSink<TTx>;
|
|
774
|
+
}): Promise<StreamsEventsConsumeResult>;
|
|
675
775
|
/**
|
|
676
776
|
* Backfill from bulk dumps, then continue live from the dump→live seam in
|
|
677
777
|
* one call. Iterates finalized dump files (via `onDumpFile`) in block
|
|
@@ -679,7 +779,7 @@ type StreamsClient = {
|
|
|
679
779
|
* (exclusive input → no gap or duplicate at the seam). Requires
|
|
680
780
|
* `dumpsBaseUrl`.
|
|
681
781
|
*/
|
|
682
|
-
replay(params: StreamsEventsReplayParams): Promise<StreamsEventsConsumeResult
|
|
782
|
+
replay(params: StreamsEventsReplayParams): Promise<StreamsEventsConsumeResult>;
|
|
683
783
|
/**
|
|
684
784
|
* Follow Streams as an async iterator.
|
|
685
785
|
*
|
|
@@ -687,49 +787,53 @@ type StreamsClient = {
|
|
|
687
787
|
* indefinitely by default and stops when its `AbortSignal`, `maxPages`, or
|
|
688
788
|
* `maxEmptyPolls` stops it.
|
|
689
789
|
*/
|
|
690
|
-
|
|
790
|
+
/** Narrowing overload, matching `consume`. */
|
|
791
|
+
stream<const T extends readonly StreamsEventType[]>(params: StreamsEventsStreamParams & {
|
|
792
|
+
types: T;
|
|
793
|
+
}): AsyncIterable<StreamsEventOfTypes<T>>;
|
|
794
|
+
stream(params?: StreamsEventsStreamParams): AsyncIterable<StreamsEvent>;
|
|
691
795
|
/**
|
|
692
796
|
* Subscribe to the real-time SSE push surface. Calls `onEvent` for each new
|
|
693
797
|
* canonical event as the server pushes it (chain cadence, not poll-bounded),
|
|
694
798
|
* and verifies each frame's inline ed25519 signature when the client was
|
|
695
799
|
* created with `verify`. Returns an unsubscribe function.
|
|
696
800
|
*/
|
|
697
|
-
subscribe(params: StreamsEventsSubscribeParams): () => void
|
|
698
|
-
}
|
|
801
|
+
subscribe(params: StreamsEventsSubscribeParams): () => void;
|
|
802
|
+
};
|
|
699
803
|
blocks: {
|
|
700
|
-
events(heightOrHash: number | string): Promise<StreamsEventsListEnvelope
|
|
701
|
-
}
|
|
804
|
+
events(heightOrHash: number | string): Promise<StreamsEventsListEnvelope>;
|
|
805
|
+
};
|
|
702
806
|
reorgs: {
|
|
703
|
-
list(params: StreamsReorgsListParams): Promise<StreamsReorgsListEnvelope
|
|
704
|
-
}
|
|
807
|
+
list(params: StreamsReorgsListParams): Promise<StreamsReorgsListEnvelope>;
|
|
808
|
+
};
|
|
705
809
|
/** Bulk parquet dumps. Requires `dumpsBaseUrl` on the client. */
|
|
706
|
-
dumps: StreamsDumps
|
|
707
|
-
canonical(height: number): Promise<StreamsCanonicalBlock
|
|
708
|
-
tip(): Promise<StreamsTip
|
|
810
|
+
dumps: StreamsDumps;
|
|
811
|
+
canonical(height: number): Promise<StreamsCanonicalBlock>;
|
|
812
|
+
tip(): Promise<StreamsTip>;
|
|
709
813
|
/** Your own Streams consumption (events today + this month) and tier limits. */
|
|
710
|
-
usage(): Promise<StreamsUsage
|
|
814
|
+
usage(): Promise<StreamsUsage>;
|
|
711
815
|
};
|
|
712
816
|
type StreamsUsage = {
|
|
713
|
-
product: "streams"
|
|
714
|
-
tier: string
|
|
817
|
+
product: "streams";
|
|
818
|
+
tier: string;
|
|
715
819
|
limits: {
|
|
716
|
-
rate_limit_per_second: number | null
|
|
717
|
-
retention_days: number | null
|
|
718
|
-
}
|
|
820
|
+
rate_limit_per_second: number | null;
|
|
821
|
+
retention_days: number | null;
|
|
822
|
+
};
|
|
719
823
|
usage: {
|
|
720
|
-
events_today: number
|
|
721
|
-
events_this_month: number
|
|
722
|
-
}
|
|
824
|
+
events_today: number;
|
|
825
|
+
events_this_month: number;
|
|
826
|
+
};
|
|
723
827
|
};
|
|
724
828
|
type CreateStreamsClientOptions = {
|
|
725
|
-
apiKey: string
|
|
726
|
-
baseUrl?: string
|
|
727
|
-
fetchImpl?: FetchLike2
|
|
829
|
+
apiKey: string;
|
|
830
|
+
baseUrl?: string;
|
|
831
|
+
fetchImpl?: FetchLike2;
|
|
728
832
|
/**
|
|
729
833
|
* Public base URL for bulk parquet dumps (the R2/CDN bucket root). Required
|
|
730
834
|
* to use `client.dumps`. See `GET /public/streams/dumps/manifest`.
|
|
731
835
|
*/
|
|
732
|
-
dumpsBaseUrl?: string
|
|
836
|
+
dumpsBaseUrl?: string;
|
|
733
837
|
/**
|
|
734
838
|
* Verify the ed25519 `X-Signature` on every REST response and per-frame SSE
|
|
735
839
|
* signature. Three states:
|
|
@@ -748,8 +852,8 @@ type CreateStreamsClientOptions = {
|
|
|
748
852
|
* rotated `X-Signature-KeyId` triggers one refresh) unless a PEM is pinned.
|
|
749
853
|
*/
|
|
750
854
|
verify?: boolean | {
|
|
751
|
-
publicKey: string
|
|
752
|
-
}
|
|
855
|
+
publicKey: string;
|
|
856
|
+
};
|
|
753
857
|
/**
|
|
754
858
|
* Verify the bulk dumps manifest's ed25519 signature in `client.dumps.list()`
|
|
755
859
|
* before trusting any file sha256 (default ON). Uses the same key source as
|
|
@@ -757,7 +861,7 @@ type CreateStreamsClientOptions = {
|
|
|
757
861
|
* `false` to opt out. A missing or invalid signature throws
|
|
758
862
|
* `StreamsSignatureError`.
|
|
759
863
|
*/
|
|
760
|
-
verifyDumpsManifest?: boolean
|
|
864
|
+
verifyDumpsManifest?: boolean;
|
|
761
865
|
};
|
|
762
866
|
declare function createStreamsClient(options: CreateStreamsClientOptions): StreamsClient;
|
|
763
867
|
/**
|
|
@@ -820,14 +924,14 @@ declare class SecondLayerError extends Error {
|
|
|
820
924
|
*/
|
|
821
925
|
walk(fn?: (err: unknown) => boolean): unknown;
|
|
822
926
|
toJSON(): {
|
|
823
|
-
name: string
|
|
824
|
-
message: string
|
|
825
|
-
shortMessage: string
|
|
826
|
-
cause: string | undefined
|
|
827
|
-
code: string | undefined
|
|
828
|
-
docsUrl: string | undefined
|
|
829
|
-
retryable: boolean
|
|
830
|
-
retryAfterSeconds: number | undefined
|
|
927
|
+
name: string;
|
|
928
|
+
message: string;
|
|
929
|
+
shortMessage: string;
|
|
930
|
+
cause: string | undefined;
|
|
931
|
+
code: string | undefined;
|
|
932
|
+
docsUrl: string | undefined;
|
|
933
|
+
retryable: boolean;
|
|
934
|
+
retryAfterSeconds: number | undefined;
|
|
831
935
|
};
|
|
832
936
|
}
|
|
833
937
|
/**
|
|
@@ -861,9 +965,9 @@ declare class AuthError extends ApiError {
|
|
|
861
965
|
* with `retryAfterSeconds` parsed from the `Retry-After` header when sent. */
|
|
862
966
|
declare class RateLimitError extends ApiError {
|
|
863
967
|
/** Raw `Retry-After` header value (seconds or HTTP-date). */
|
|
864
|
-
readonly retryAfter?: string;
|
|
968
|
+
readonly retryAfter?: string | undefined;
|
|
865
969
|
readonly status: 429;
|
|
866
|
-
constructor(message?: string, retryAfter?: string);
|
|
970
|
+
constructor(message?: string, retryAfter?: string | undefined);
|
|
867
971
|
}
|
|
868
972
|
/** Thrown on a 4xx the caller can fix (bad cursor, bad params). Never retried. */
|
|
869
973
|
declare class ValidationError extends ApiError {
|
|
@@ -878,210 +982,210 @@ declare class StreamsSignatureError extends SecondLayerError {
|
|
|
878
982
|
constructor(message?: string);
|
|
879
983
|
}
|
|
880
984
|
type FtTransferEvent = Extract<StreamsEvent, {
|
|
881
|
-
event_type: "ft_transfer"
|
|
985
|
+
event_type: "ft_transfer";
|
|
882
986
|
}>;
|
|
883
987
|
type DecodedFtTransferPayload = {
|
|
884
|
-
asset_identifier: string
|
|
885
|
-
contract_id: string
|
|
886
|
-
token_name: string | null
|
|
887
|
-
sender: string
|
|
888
|
-
recipient: string
|
|
889
|
-
amount: string
|
|
988
|
+
asset_identifier: string;
|
|
989
|
+
contract_id: string;
|
|
990
|
+
token_name: string | null;
|
|
991
|
+
sender: string;
|
|
992
|
+
recipient: string;
|
|
993
|
+
amount: string;
|
|
890
994
|
};
|
|
891
995
|
type DecodedFtTransfer = {
|
|
892
|
-
cursor: string
|
|
893
|
-
block_height: number
|
|
894
|
-
tx_id: string
|
|
895
|
-
tx_index: number
|
|
896
|
-
event_index: number
|
|
897
|
-
event_type: "ft_transfer"
|
|
898
|
-
decoded_payload: DecodedFtTransferPayload
|
|
899
|
-
source_cursor: string
|
|
996
|
+
cursor: string;
|
|
997
|
+
block_height: number;
|
|
998
|
+
tx_id: string;
|
|
999
|
+
tx_index: number;
|
|
1000
|
+
event_index: number;
|
|
1001
|
+
event_type: "ft_transfer";
|
|
1002
|
+
decoded_payload: DecodedFtTransferPayload;
|
|
1003
|
+
source_cursor: string;
|
|
900
1004
|
};
|
|
901
1005
|
declare function isFtTransfer(event: StreamsEvent): event is FtTransferEvent;
|
|
902
1006
|
declare function decodeFtTransfer(event: StreamsEvent): DecodedFtTransfer;
|
|
903
1007
|
type NftTransferEvent = Extract<StreamsEvent, {
|
|
904
|
-
event_type: "nft_transfer"
|
|
1008
|
+
event_type: "nft_transfer";
|
|
905
1009
|
}>;
|
|
906
1010
|
type DecodedNftTransferPayload = {
|
|
907
|
-
asset_identifier: string
|
|
908
|
-
contract_id: string
|
|
909
|
-
token_name: string | null
|
|
910
|
-
sender: string
|
|
911
|
-
recipient: string
|
|
912
|
-
value: string
|
|
1011
|
+
asset_identifier: string;
|
|
1012
|
+
contract_id: string;
|
|
1013
|
+
token_name: string | null;
|
|
1014
|
+
sender: string;
|
|
1015
|
+
recipient: string;
|
|
1016
|
+
value: string;
|
|
913
1017
|
};
|
|
914
1018
|
type DecodedNftTransfer = {
|
|
915
|
-
cursor: string
|
|
916
|
-
block_height: number
|
|
917
|
-
tx_id: string
|
|
918
|
-
tx_index: number
|
|
919
|
-
event_index: number
|
|
920
|
-
event_type: "nft_transfer"
|
|
921
|
-
decoded_payload: DecodedNftTransferPayload
|
|
922
|
-
source_cursor: string
|
|
1019
|
+
cursor: string;
|
|
1020
|
+
block_height: number;
|
|
1021
|
+
tx_id: string;
|
|
1022
|
+
tx_index: number;
|
|
1023
|
+
event_index: number;
|
|
1024
|
+
event_type: "nft_transfer";
|
|
1025
|
+
decoded_payload: DecodedNftTransferPayload;
|
|
1026
|
+
source_cursor: string;
|
|
923
1027
|
};
|
|
924
1028
|
declare function isNftTransfer(event: StreamsEvent): event is NftTransferEvent;
|
|
925
1029
|
declare function decodeNftTransfer(event: StreamsEvent): DecodedNftTransfer;
|
|
926
1030
|
type DecodedStxTransferPayload = {
|
|
927
|
-
sender: string
|
|
928
|
-
recipient: string
|
|
929
|
-
amount: string
|
|
930
|
-
memo: string | null
|
|
1031
|
+
sender: string;
|
|
1032
|
+
recipient: string;
|
|
1033
|
+
amount: string;
|
|
1034
|
+
memo: string | null;
|
|
931
1035
|
};
|
|
932
1036
|
type DecodedStxTransfer = {
|
|
933
|
-
cursor: string
|
|
934
|
-
block_height: number
|
|
935
|
-
tx_id: string
|
|
936
|
-
tx_index: number
|
|
937
|
-
event_index: number
|
|
938
|
-
event_type: "stx_transfer"
|
|
939
|
-
decoded_payload: DecodedStxTransferPayload
|
|
940
|
-
source_cursor: string
|
|
1037
|
+
cursor: string;
|
|
1038
|
+
block_height: number;
|
|
1039
|
+
tx_id: string;
|
|
1040
|
+
tx_index: number;
|
|
1041
|
+
event_index: number;
|
|
1042
|
+
event_type: "stx_transfer";
|
|
1043
|
+
decoded_payload: DecodedStxTransferPayload;
|
|
1044
|
+
source_cursor: string;
|
|
941
1045
|
};
|
|
942
1046
|
type DecodedStxMintPayload = {
|
|
943
|
-
recipient: string
|
|
944
|
-
amount: string
|
|
1047
|
+
recipient: string;
|
|
1048
|
+
amount: string;
|
|
945
1049
|
};
|
|
946
1050
|
type DecodedStxMint = {
|
|
947
|
-
cursor: string
|
|
948
|
-
block_height: number
|
|
949
|
-
tx_id: string
|
|
950
|
-
tx_index: number
|
|
951
|
-
event_index: number
|
|
952
|
-
event_type: "stx_mint"
|
|
953
|
-
decoded_payload: DecodedStxMintPayload
|
|
954
|
-
source_cursor: string
|
|
1051
|
+
cursor: string;
|
|
1052
|
+
block_height: number;
|
|
1053
|
+
tx_id: string;
|
|
1054
|
+
tx_index: number;
|
|
1055
|
+
event_index: number;
|
|
1056
|
+
event_type: "stx_mint";
|
|
1057
|
+
decoded_payload: DecodedStxMintPayload;
|
|
1058
|
+
source_cursor: string;
|
|
955
1059
|
};
|
|
956
1060
|
type DecodedStxBurnPayload = {
|
|
957
|
-
sender: string
|
|
958
|
-
amount: string
|
|
1061
|
+
sender: string;
|
|
1062
|
+
amount: string;
|
|
959
1063
|
};
|
|
960
1064
|
type DecodedStxBurn = {
|
|
961
|
-
cursor: string
|
|
962
|
-
block_height: number
|
|
963
|
-
tx_id: string
|
|
964
|
-
tx_index: number
|
|
965
|
-
event_index: number
|
|
966
|
-
event_type: "stx_burn"
|
|
967
|
-
decoded_payload: DecodedStxBurnPayload
|
|
968
|
-
source_cursor: string
|
|
1065
|
+
cursor: string;
|
|
1066
|
+
block_height: number;
|
|
1067
|
+
tx_id: string;
|
|
1068
|
+
tx_index: number;
|
|
1069
|
+
event_index: number;
|
|
1070
|
+
event_type: "stx_burn";
|
|
1071
|
+
decoded_payload: DecodedStxBurnPayload;
|
|
1072
|
+
source_cursor: string;
|
|
969
1073
|
};
|
|
970
1074
|
declare function isStxTransfer(event: StreamsEvent): event is StreamsEvent & {
|
|
971
|
-
event_type: "stx_transfer"
|
|
1075
|
+
event_type: "stx_transfer";
|
|
972
1076
|
};
|
|
973
1077
|
declare function decodeStxTransfer(event: StreamsEvent): DecodedStxTransfer;
|
|
974
1078
|
declare function isStxMint(event: StreamsEvent): event is StreamsEvent & {
|
|
975
|
-
event_type: "stx_mint"
|
|
1079
|
+
event_type: "stx_mint";
|
|
976
1080
|
};
|
|
977
1081
|
declare function decodeStxMint(event: StreamsEvent): DecodedStxMint;
|
|
978
1082
|
declare function isStxBurn(event: StreamsEvent): event is StreamsEvent & {
|
|
979
|
-
event_type: "stx_burn"
|
|
1083
|
+
event_type: "stx_burn";
|
|
980
1084
|
};
|
|
981
1085
|
declare function decodeStxBurn(event: StreamsEvent): DecodedStxBurn;
|
|
982
1086
|
type DecodedStxLockPayload = {
|
|
983
|
-
sender: string
|
|
984
|
-
amount: string
|
|
1087
|
+
sender: string;
|
|
1088
|
+
amount: string;
|
|
985
1089
|
payload: {
|
|
986
|
-
unlock_height: string | null
|
|
987
|
-
}
|
|
1090
|
+
unlock_height: string | null;
|
|
1091
|
+
};
|
|
988
1092
|
};
|
|
989
1093
|
type DecodedStxLock = {
|
|
990
|
-
cursor: string
|
|
991
|
-
block_height: number
|
|
992
|
-
tx_id: string
|
|
993
|
-
tx_index: number
|
|
994
|
-
event_index: number
|
|
995
|
-
event_type: "stx_lock"
|
|
996
|
-
decoded_payload: DecodedStxLockPayload
|
|
997
|
-
source_cursor: string
|
|
1094
|
+
cursor: string;
|
|
1095
|
+
block_height: number;
|
|
1096
|
+
tx_id: string;
|
|
1097
|
+
tx_index: number;
|
|
1098
|
+
event_index: number;
|
|
1099
|
+
event_type: "stx_lock";
|
|
1100
|
+
decoded_payload: DecodedStxLockPayload;
|
|
1101
|
+
source_cursor: string;
|
|
998
1102
|
};
|
|
999
1103
|
declare function isStxLock(event: StreamsEvent): event is StreamsEvent & {
|
|
1000
|
-
event_type: "stx_lock"
|
|
1104
|
+
event_type: "stx_lock";
|
|
1001
1105
|
};
|
|
1002
1106
|
declare function decodeStxLock(event: StreamsEvent): DecodedStxLock;
|
|
1003
1107
|
type DecodedFtMintPayload = {
|
|
1004
|
-
asset_identifier: string
|
|
1005
|
-
contract_id: string
|
|
1006
|
-
token_name: string | null
|
|
1007
|
-
recipient: string
|
|
1008
|
-
amount: string
|
|
1108
|
+
asset_identifier: string;
|
|
1109
|
+
contract_id: string;
|
|
1110
|
+
token_name: string | null;
|
|
1111
|
+
recipient: string;
|
|
1112
|
+
amount: string;
|
|
1009
1113
|
};
|
|
1010
1114
|
type DecodedFtMint = {
|
|
1011
|
-
cursor: string
|
|
1012
|
-
block_height: number
|
|
1013
|
-
tx_id: string
|
|
1014
|
-
tx_index: number
|
|
1015
|
-
event_index: number
|
|
1016
|
-
event_type: "ft_mint"
|
|
1017
|
-
decoded_payload: DecodedFtMintPayload
|
|
1018
|
-
source_cursor: string
|
|
1115
|
+
cursor: string;
|
|
1116
|
+
block_height: number;
|
|
1117
|
+
tx_id: string;
|
|
1118
|
+
tx_index: number;
|
|
1119
|
+
event_index: number;
|
|
1120
|
+
event_type: "ft_mint";
|
|
1121
|
+
decoded_payload: DecodedFtMintPayload;
|
|
1122
|
+
source_cursor: string;
|
|
1019
1123
|
};
|
|
1020
1124
|
type DecodedFtBurnPayload = {
|
|
1021
|
-
asset_identifier: string
|
|
1022
|
-
contract_id: string
|
|
1023
|
-
token_name: string | null
|
|
1024
|
-
sender: string
|
|
1025
|
-
amount: string
|
|
1125
|
+
asset_identifier: string;
|
|
1126
|
+
contract_id: string;
|
|
1127
|
+
token_name: string | null;
|
|
1128
|
+
sender: string;
|
|
1129
|
+
amount: string;
|
|
1026
1130
|
};
|
|
1027
1131
|
type DecodedFtBurn = {
|
|
1028
|
-
cursor: string
|
|
1029
|
-
block_height: number
|
|
1030
|
-
tx_id: string
|
|
1031
|
-
tx_index: number
|
|
1032
|
-
event_index: number
|
|
1033
|
-
event_type: "ft_burn"
|
|
1034
|
-
decoded_payload: DecodedFtBurnPayload
|
|
1035
|
-
source_cursor: string
|
|
1132
|
+
cursor: string;
|
|
1133
|
+
block_height: number;
|
|
1134
|
+
tx_id: string;
|
|
1135
|
+
tx_index: number;
|
|
1136
|
+
event_index: number;
|
|
1137
|
+
event_type: "ft_burn";
|
|
1138
|
+
decoded_payload: DecodedFtBurnPayload;
|
|
1139
|
+
source_cursor: string;
|
|
1036
1140
|
};
|
|
1037
1141
|
type DecodedNftMintPayload = {
|
|
1038
|
-
asset_identifier: string
|
|
1039
|
-
contract_id: string
|
|
1040
|
-
token_name: string | null
|
|
1041
|
-
recipient: string
|
|
1042
|
-
value: string
|
|
1142
|
+
asset_identifier: string;
|
|
1143
|
+
contract_id: string;
|
|
1144
|
+
token_name: string | null;
|
|
1145
|
+
recipient: string;
|
|
1146
|
+
value: string;
|
|
1043
1147
|
};
|
|
1044
1148
|
type DecodedNftMint = {
|
|
1045
|
-
cursor: string
|
|
1046
|
-
block_height: number
|
|
1047
|
-
tx_id: string
|
|
1048
|
-
tx_index: number
|
|
1049
|
-
event_index: number
|
|
1050
|
-
event_type: "nft_mint"
|
|
1051
|
-
decoded_payload: DecodedNftMintPayload
|
|
1052
|
-
source_cursor: string
|
|
1149
|
+
cursor: string;
|
|
1150
|
+
block_height: number;
|
|
1151
|
+
tx_id: string;
|
|
1152
|
+
tx_index: number;
|
|
1153
|
+
event_index: number;
|
|
1154
|
+
event_type: "nft_mint";
|
|
1155
|
+
decoded_payload: DecodedNftMintPayload;
|
|
1156
|
+
source_cursor: string;
|
|
1053
1157
|
};
|
|
1054
1158
|
type DecodedNftBurnPayload = {
|
|
1055
|
-
asset_identifier: string
|
|
1056
|
-
contract_id: string
|
|
1057
|
-
token_name: string | null
|
|
1058
|
-
sender: string
|
|
1059
|
-
value: string
|
|
1159
|
+
asset_identifier: string;
|
|
1160
|
+
contract_id: string;
|
|
1161
|
+
token_name: string | null;
|
|
1162
|
+
sender: string;
|
|
1163
|
+
value: string;
|
|
1060
1164
|
};
|
|
1061
1165
|
type DecodedNftBurn = {
|
|
1062
|
-
cursor: string
|
|
1063
|
-
block_height: number
|
|
1064
|
-
tx_id: string
|
|
1065
|
-
tx_index: number
|
|
1066
|
-
event_index: number
|
|
1067
|
-
event_type: "nft_burn"
|
|
1068
|
-
decoded_payload: DecodedNftBurnPayload
|
|
1069
|
-
source_cursor: string
|
|
1166
|
+
cursor: string;
|
|
1167
|
+
block_height: number;
|
|
1168
|
+
tx_id: string;
|
|
1169
|
+
tx_index: number;
|
|
1170
|
+
event_index: number;
|
|
1171
|
+
event_type: "nft_burn";
|
|
1172
|
+
decoded_payload: DecodedNftBurnPayload;
|
|
1173
|
+
source_cursor: string;
|
|
1070
1174
|
};
|
|
1071
1175
|
declare function isFtMint(event: StreamsEvent): event is StreamsEvent & {
|
|
1072
|
-
event_type: "ft_mint"
|
|
1176
|
+
event_type: "ft_mint";
|
|
1073
1177
|
};
|
|
1074
1178
|
declare function decodeFtMint(event: StreamsEvent): DecodedFtMint;
|
|
1075
1179
|
declare function isFtBurn(event: StreamsEvent): event is StreamsEvent & {
|
|
1076
|
-
event_type: "ft_burn"
|
|
1180
|
+
event_type: "ft_burn";
|
|
1077
1181
|
};
|
|
1078
1182
|
declare function decodeFtBurn(event: StreamsEvent): DecodedFtBurn;
|
|
1079
1183
|
declare function isNftMint(event: StreamsEvent): event is StreamsEvent & {
|
|
1080
|
-
event_type: "nft_mint"
|
|
1184
|
+
event_type: "nft_mint";
|
|
1081
1185
|
};
|
|
1082
1186
|
declare function decodeNftMint(event: StreamsEvent): DecodedNftMint;
|
|
1083
1187
|
declare function isNftBurn(event: StreamsEvent): event is StreamsEvent & {
|
|
1084
|
-
event_type: "nft_burn"
|
|
1188
|
+
event_type: "nft_burn";
|
|
1085
1189
|
};
|
|
1086
1190
|
declare function decodeNftBurn(event: StreamsEvent): DecodedNftBurn;
|
|
1087
1191
|
/** Decoded form of a Clarity `print` event:
|
|
@@ -1090,41 +1194,41 @@ declare function decodeNftBurn(event: StreamsEvent): DecodedNftBurn;
|
|
|
1090
1194
|
* `0x…` hex, tuples as objects)
|
|
1091
1195
|
* - `raw_value`: the canonical serialized hex, for byte-exact consumers */
|
|
1092
1196
|
type DecodedPrintValue = {
|
|
1093
|
-
topic: string | null
|
|
1094
|
-
value: unknown
|
|
1095
|
-
raw_value: string | null
|
|
1197
|
+
topic: string | null;
|
|
1198
|
+
value: unknown;
|
|
1199
|
+
raw_value: string | null;
|
|
1096
1200
|
};
|
|
1097
1201
|
type DecodedPrintPayload = {
|
|
1098
|
-
contract_id: string | null
|
|
1099
|
-
payload: DecodedPrintValue
|
|
1202
|
+
contract_id: string | null;
|
|
1203
|
+
payload: DecodedPrintValue;
|
|
1100
1204
|
};
|
|
1101
1205
|
type DecodedPrint = {
|
|
1102
|
-
cursor: string
|
|
1103
|
-
block_height: number
|
|
1104
|
-
tx_id: string
|
|
1105
|
-
tx_index: number
|
|
1106
|
-
event_index: number
|
|
1107
|
-
event_type: "print"
|
|
1108
|
-
decoded_payload: DecodedPrintPayload
|
|
1109
|
-
source_cursor: string
|
|
1206
|
+
cursor: string;
|
|
1207
|
+
block_height: number;
|
|
1208
|
+
tx_id: string;
|
|
1209
|
+
tx_index: number;
|
|
1210
|
+
event_index: number;
|
|
1211
|
+
event_type: "print";
|
|
1212
|
+
decoded_payload: DecodedPrintPayload;
|
|
1213
|
+
source_cursor: string;
|
|
1110
1214
|
};
|
|
1111
1215
|
declare function isPrint(event: StreamsEvent): event is StreamsEvent & {
|
|
1112
|
-
event_type: "print"
|
|
1216
|
+
event_type: "print";
|
|
1113
1217
|
};
|
|
1114
1218
|
declare function decodePrint(event: StreamsEvent): DecodedPrint;
|
|
1115
1219
|
/** Superset of the columns the decoded_events table holds. Every decoded
|
|
1116
1220
|
* event's `decoded_payload` is assignable to this, so the indexer's writer
|
|
1117
1221
|
* can map columns generically instead of per-event-type. */
|
|
1118
1222
|
type DecodedEventColumns = {
|
|
1119
|
-
contract_id?: string | null
|
|
1120
|
-
asset_identifier?: string | null
|
|
1121
|
-
sender?: string | null
|
|
1122
|
-
recipient?: string | null
|
|
1123
|
-
amount?: string | null
|
|
1124
|
-
value?: string | null
|
|
1125
|
-
memo?: string | null
|
|
1223
|
+
contract_id?: string | null;
|
|
1224
|
+
asset_identifier?: string | null;
|
|
1225
|
+
sender?: string | null;
|
|
1226
|
+
recipient?: string | null;
|
|
1227
|
+
amount?: string | null;
|
|
1228
|
+
value?: string | null;
|
|
1229
|
+
memo?: string | null;
|
|
1126
1230
|
/** JSONB overflow for non-flat types (e.g. print's decoded value). */
|
|
1127
|
-
payload?: unknown
|
|
1231
|
+
payload?: unknown;
|
|
1128
1232
|
};
|
|
1129
1233
|
/**
|
|
1130
1234
|
* Helpers for Streams cursors. A cursor is the opaque `<block>:<index>` string
|
|
@@ -1149,12 +1253,12 @@ declare const Cursor: {
|
|
|
1149
1253
|
* type), larger than any real index, so nothing at `height - 1` survives the
|
|
1150
1254
|
* keyset and the next returned row is exactly `(height, 0)`.
|
|
1151
1255
|
*/
|
|
1152
|
-
atHeight(height: number): string
|
|
1256
|
+
atHeight(height: number): string;
|
|
1153
1257
|
/** Parse a `<block>:<index>` cursor. Throws `ValidationError` if malformed. */
|
|
1154
1258
|
parse(cursor: string): {
|
|
1155
|
-
blockHeight: number
|
|
1156
|
-
eventIndex: number
|
|
1157
|
-
}
|
|
1259
|
+
blockHeight: number;
|
|
1260
|
+
eventIndex: number;
|
|
1261
|
+
};
|
|
1158
1262
|
};
|
|
1159
1263
|
type DecodedEventRow = DecodedFtTransfer | DecodedNftTransfer | DecodedStxTransfer | DecodedStxMint | DecodedStxBurn | DecodedStxLock | DecodedFtMint | DecodedFtBurn | DecodedNftMint | DecodedNftBurn | DecodedPrint;
|
|
1160
1264
|
export { isStxTransfer, isStxMint, isStxLock, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, decodeStxTransfer, decodeStxMint, decodeStxLock, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, decode, createStreamsClient, ValidationError, StreamsUsage, StreamsTip, StreamsSignatureError, StreamsServerError, StreamsReorgsListParams, StreamsReorgsListEnvelope, StreamsReorgContext, StreamsReorg, StreamsEventsSubscribeParams, StreamsEventsStreamParams, StreamsEventsListParams, StreamsEventsListEnvelope, StreamsEventsEnvelope, StreamsEventsConsumeResult, StreamsEventsConsumeParams, StreamsEventType, StreamsEventPayload, StreamsEvent, StreamsDumpsManifest, StreamsDumps, StreamsDumpFile, StreamsConsumeParams, StreamsClient, StreamsCanonicalBlock, StreamsBatchContext, StreamsBatch, STREAMS_EVENT_TYPES, RateLimitError, NftTransferPayload, NftTransferEvent, FtTransferPayload, FtTransferEvent, FetchLike2 as FetchLike, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxLockPayload, DecodedStxLock, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns, Cursor, ConsumerBatchContext, AuthError };
|