@secondlayer/sdk 5.9.0 → 6.0.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.
@@ -1,7 +1,76 @@
1
1
  declare const STREAMS_EVENT_TYPES: readonly ["stx_transfer", "stx_mint", "stx_burn", "stx_lock", "ft_transfer", "ft_mint", "ft_burn", "nft_transfer", "nft_mint", "nft_burn", "print"];
2
2
  type StreamsEventType = (typeof STREAMS_EVENT_TYPES)[number];
3
- type StreamsEventPayload = Record<string, unknown>;
4
- type StreamsEvent = {
3
+ /** A Clarity value as Streams serves it: the canonical hex string, a typed
4
+ * object carrying that hex (`{ hex }`), or a decoded Clarity-JSON object.
5
+ * Decode helpers (`decodeNftTransfer`, etc.) resolve it to a concrete value. */
6
+ type StreamsClarityValue = string | {
7
+ hex: string
8
+ } | Record<string, unknown>;
9
+ type StxTransferPayload = {
10
+ sender: string
11
+ recipient: string
12
+ amount: string
13
+ memo?: string
14
+ };
15
+ type StxMintPayload = {
16
+ recipient: string
17
+ amount: string
18
+ };
19
+ type StxBurnPayload = {
20
+ sender: string
21
+ amount: string
22
+ };
23
+ type StxLockPayload = {
24
+ locked_address: string
25
+ locked_amount: string
26
+ unlock_height: string
27
+ };
28
+ type FtTransferPayload = {
29
+ asset_identifier: string
30
+ sender: string
31
+ recipient: string
32
+ amount: string
33
+ };
34
+ type FtMintPayload = {
35
+ asset_identifier: string
36
+ recipient: string
37
+ amount: string
38
+ };
39
+ type FtBurnPayload = {
40
+ asset_identifier: string
41
+ sender: string
42
+ amount: string
43
+ };
44
+ type NftTransferPayload = {
45
+ asset_identifier: string
46
+ sender: string
47
+ recipient: string
48
+ value: StreamsClarityValue
49
+ /** Canonical serialized hex of `value`, when the stream carries it. */
50
+ raw_value?: string
51
+ };
52
+ type NftMintPayload = {
53
+ asset_identifier: string
54
+ recipient: string
55
+ value: StreamsClarityValue
56
+ raw_value?: string
57
+ };
58
+ type NftBurnPayload = {
59
+ asset_identifier: string
60
+ sender: string
61
+ value: StreamsClarityValue
62
+ raw_value?: string
63
+ };
64
+ type PrintPayload = {
65
+ contract_id?: string | null
66
+ topic?: string
67
+ value?: unknown
68
+ raw_value?: string
69
+ };
70
+ /** Union of every Streams payload shape, discriminated by `event_type` on the
71
+ * parent `StreamsEvent`. */
72
+ type StreamsEventPayload = StxTransferPayload | StxMintPayload | StxBurnPayload | StxLockPayload | FtTransferPayload | FtMintPayload | FtBurnPayload | NftTransferPayload | NftMintPayload | NftBurnPayload | PrintPayload;
73
+ type StreamsEventBase = {
5
74
  cursor: string
6
75
  block_height: number
7
76
  block_hash: string
@@ -9,9 +78,7 @@ type StreamsEvent = {
9
78
  tx_id: string
10
79
  tx_index: number
11
80
  event_index: number
12
- event_type: StreamsEventType
13
81
  contract_id: string | null
14
- payload: StreamsEventPayload
15
82
  ts: string
16
83
  /**
17
84
  * True when this event's block is past the finality boundary (immutable).
@@ -19,6 +86,16 @@ type StreamsEvent = {
19
86
  */
20
87
  finalized?: boolean
21
88
  };
89
+ type StreamsEventOf<
90
+ T extends StreamsEventType,
91
+ P
92
+ > = StreamsEventBase & {
93
+ event_type: T
94
+ payload: P
95
+ };
96
+ /** A raw Streams event. Discriminated on `event_type`, so `event.payload`
97
+ * narrows to the matching payload shape once the type is checked. */
98
+ 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>;
22
99
  type StreamsTip = {
23
100
  block_height: number
24
101
  block_hash: string
@@ -61,23 +138,28 @@ type StreamsReorgsListEnvelope = {
61
138
  reorgs: StreamsReorg[]
62
139
  next_since: string | null
63
140
  };
141
+ /** A filter that matches a single value or any value in a list. */
142
+ type StreamsFilterValue = string | readonly string[];
64
143
  type StreamsEventsListParams = {
65
144
  cursor?: string | null
66
145
  fromHeight?: number
67
146
  toHeight?: number
68
147
  types?: readonly StreamsEventType[]
69
- contractId?: string
70
- sender?: string
71
- recipient?: string
148
+ /** Event types to exclude (applied after `types`). */
149
+ notTypes?: readonly StreamsEventType[]
150
+ contractId?: StreamsFilterValue
151
+ sender?: StreamsFilterValue
152
+ recipient?: StreamsFilterValue
72
153
  assetIdentifier?: string
73
154
  limit?: number
74
155
  };
75
156
  type StreamsEventsStreamParams = {
76
157
  fromCursor?: string | null
77
158
  types?: readonly StreamsEventType[]
78
- contractId?: string
79
- sender?: string
80
- recipient?: string
159
+ notTypes?: readonly StreamsEventType[]
160
+ contractId?: StreamsFilterValue
161
+ sender?: StreamsFilterValue
162
+ recipient?: StreamsFilterValue
81
163
  assetIdentifier?: string
82
164
  batchSize?: number
83
165
  emptyBackoffMs?: number
@@ -89,9 +171,10 @@ type StreamsEventsConsumeParams = {
89
171
  fromCursor?: string | null
90
172
  mode?: "tail" | "bounded"
91
173
  types?: readonly StreamsEventType[]
92
- contractId?: string
93
- sender?: string
94
- recipient?: string
174
+ notTypes?: readonly StreamsEventType[]
175
+ contractId?: StreamsFilterValue
176
+ sender?: StreamsFilterValue
177
+ recipient?: StreamsFilterValue
95
178
  assetIdentifier?: string
96
179
  batchSize?: number
97
180
  onBatch: (events: StreamsEvent[], envelope: StreamsEventsEnvelope) => Promise<string | null | undefined> | string | null | undefined
@@ -247,16 +330,9 @@ declare class StreamsServerError extends Error {
247
330
  declare class StreamsSignatureError extends Error {
248
331
  constructor(message?: string);
249
332
  }
250
- type FtTransferPayload = {
251
- asset_identifier: string
252
- sender: string
253
- recipient: string
254
- amount: string
255
- };
256
- type FtTransferEvent = StreamsEvent & {
333
+ type FtTransferEvent = Extract<StreamsEvent, {
257
334
  event_type: "ft_transfer"
258
- payload: FtTransferPayload
259
- };
335
+ }>;
260
336
  type DecodedFtTransferPayload = {
261
337
  asset_identifier: string
262
338
  contract_id: string
@@ -277,18 +353,9 @@ type DecodedFtTransfer = {
277
353
  };
278
354
  declare function isFtTransfer(event: StreamsEvent): event is FtTransferEvent;
279
355
  declare function decodeFtTransfer(event: StreamsEvent): DecodedFtTransfer;
280
- type NftTransferPayload = {
281
- asset_identifier: string
282
- sender: string
283
- recipient: string
284
- value: string | {
285
- hex: string
286
- }
287
- };
288
- type NftTransferEvent = StreamsEvent & {
356
+ type NftTransferEvent = Extract<StreamsEvent, {
289
357
  event_type: "nft_transfer"
290
- payload: NftTransferPayload
291
- };
358
+ }>;
292
359
  type DecodedNftTransferPayload = {
293
360
  asset_identifier: string
294
361
  contract_id: string
@@ -29,6 +29,7 @@ async function consumeStreamsEvents(opts) {
29
29
  cursor,
30
30
  limit: opts.batchSize,
31
31
  types: opts.types,
32
+ notTypes: opts.notTypes,
32
33
  contractId: opts.contractId,
33
34
  sender: opts.sender,
34
35
  recipient: opts.recipient,
@@ -67,6 +68,7 @@ async function* streamStreamsEvents(opts) {
67
68
  cursor,
68
69
  limit: opts.batchSize,
69
70
  types: opts.types,
71
+ notTypes: opts.notTypes,
70
72
  contractId: opts.contractId,
71
73
  sender: opts.sender,
72
74
  recipient: opts.recipient,
@@ -202,6 +204,13 @@ function appendSearchParam(params, name, value) {
202
204
  return;
203
205
  params.set(name, String(value));
204
206
  }
207
+ function appendListParam(params, name, value) {
208
+ if (value === undefined || value === null)
209
+ return;
210
+ const joined = Array.isArray(value) ? value.join(",") : value;
211
+ if (joined.length > 0)
212
+ params.set(name, joined);
213
+ }
205
214
  async function responseBody(response) {
206
215
  const text = await response.text();
207
216
  if (text.length === 0)
@@ -245,13 +254,16 @@ function createStreamsClient(options) {
245
254
  baseUrl: options.dumpsBaseUrl,
246
255
  fetchImpl
247
256
  });
248
- let publicKeyPromise = null;
249
- function getPublicKey() {
250
- if (publicKeyPromise)
251
- return publicKeyPromise;
252
- publicKeyPromise = (async () => {
257
+ let keyPromise = null;
258
+ function loadKey() {
259
+ if (keyPromise)
260
+ return keyPromise;
261
+ keyPromise = (async () => {
253
262
  if (typeof verify === "object") {
254
- return ed25519.loadEd25519PublicKey(verify.publicKey);
263
+ return {
264
+ keyId: ed25519.ed25519KeyId(verify.publicKey),
265
+ publicKey: ed25519.loadEd25519PublicKey(verify.publicKey)
266
+ };
255
267
  }
256
268
  const res = await fetchImpl(`${baseUrl}/public/streams/signing-key`);
257
269
  if (!res.ok) {
@@ -261,9 +273,12 @@ function createStreamsClient(options) {
261
273
  if (!body.public_key_pem) {
262
274
  throw new StreamsSignatureError("Signing key response missing key.");
263
275
  }
264
- return ed25519.loadEd25519PublicKey(body.public_key_pem);
276
+ return {
277
+ keyId: body.key_id ?? ed25519.ed25519KeyId(body.public_key_pem),
278
+ publicKey: ed25519.loadEd25519PublicKey(body.public_key_pem)
279
+ };
265
280
  })();
266
- return publicKeyPromise;
281
+ return keyPromise;
267
282
  }
268
283
  async function request(path) {
269
284
  const response = await fetchImpl(`${baseUrl}${path}`, {
@@ -277,8 +292,19 @@ function createStreamsClient(options) {
277
292
  if (!signature) {
278
293
  throw new StreamsSignatureError("Response is missing X-Signature.");
279
294
  }
280
- const publicKey = await getPublicKey();
281
- if (!ed25519.verifyEd25519(text, signature, publicKey)) {
295
+ const responseKeyId = response.headers.get("X-Signature-KeyId");
296
+ let key = await loadKey();
297
+ if (responseKeyId && responseKeyId !== key.keyId) {
298
+ if (typeof verify === "object") {
299
+ throw new StreamsSignatureError(`Response signed with key '${responseKeyId}', expected pinned key '${key.keyId}'.`);
300
+ }
301
+ keyPromise = null;
302
+ key = await loadKey();
303
+ if (responseKeyId !== key.keyId) {
304
+ throw new StreamsSignatureError(`Response signed with key '${responseKeyId}' not served by the signing-key endpoint.`);
305
+ }
306
+ }
307
+ if (!ed25519.verifyEd25519(text, signature, key.publicKey)) {
282
308
  throw new StreamsSignatureError;
283
309
  }
284
310
  }
@@ -288,6 +314,7 @@ function createStreamsClient(options) {
288
314
  cursor,
289
315
  limit,
290
316
  types,
317
+ notTypes,
291
318
  contractId,
292
319
  sender,
293
320
  recipient,
@@ -297,6 +324,7 @@ function createStreamsClient(options) {
297
324
  cursor,
298
325
  limit,
299
326
  types,
327
+ notTypes,
300
328
  contractId,
301
329
  sender,
302
330
  recipient,
@@ -309,13 +337,16 @@ function createStreamsClient(options) {
309
337
  appendSearchParam(searchParams, "from_height", params.fromHeight);
310
338
  appendSearchParam(searchParams, "to_height", params.toHeight);
311
339
  appendSearchParam(searchParams, "limit", params.limit);
312
- appendSearchParam(searchParams, "contract_id", params.contractId);
313
- appendSearchParam(searchParams, "sender", params.sender);
314
- appendSearchParam(searchParams, "recipient", params.recipient);
340
+ appendListParam(searchParams, "contract_id", params.contractId);
341
+ appendListParam(searchParams, "sender", params.sender);
342
+ appendListParam(searchParams, "recipient", params.recipient);
315
343
  appendSearchParam(searchParams, "asset_identifier", params.assetIdentifier);
316
344
  if (params.types?.length) {
317
345
  searchParams.set("types", params.types.join(","));
318
346
  }
347
+ if (params.notTypes?.length) {
348
+ searchParams.set("not_types", params.notTypes.join(","));
349
+ }
319
350
  const query = searchParams.toString();
320
351
  return request(`/v1/streams/events${query ? `?${query}` : ""}`);
321
352
  }
@@ -330,6 +361,7 @@ function createStreamsClient(options) {
330
361
  fromCursor: params.fromCursor,
331
362
  mode: params.mode,
332
363
  types: params.types,
364
+ notTypes: params.notTypes,
333
365
  contractId: params.contractId,
334
366
  sender: params.sender,
335
367
  recipient: params.recipient,
@@ -347,6 +379,7 @@ function createStreamsClient(options) {
347
379
  return streamStreamsEvents({
348
380
  fromCursor: params.fromCursor,
349
381
  types: params.types,
382
+ notTypes: params.notTypes,
350
383
  contractId: params.contractId,
351
384
  sender: params.sender,
352
385
  recipient: params.recipient,
@@ -804,5 +837,5 @@ export {
804
837
  AuthError
805
838
  };
806
839
 
807
- //# debugId=AC24B4EAD103932F64756E2164756E21
840
+ //# debugId=E556011474C772DE64756E2164756E21
808
841
  //# sourceMappingURL=index.js.map