@secondlayer/sdk 5.2.0 → 5.4.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 CHANGED
@@ -176,6 +176,138 @@ type NftTransfersWalkParams = Omit<NftTransfersListParams, "limit"> & {
176
176
  batchSize?: number
177
177
  signal?: AbortSignal
178
178
  };
179
+ type IndexEventBase = {
180
+ cursor: string
181
+ block_height: number
182
+ block_time?: string | null
183
+ tx_id: string
184
+ tx_index: number
185
+ event_index: number
186
+ contract_id: string | null
187
+ };
188
+ type IndexFtTransfer = IndexEventBase & {
189
+ event_type: "ft_transfer"
190
+ asset_identifier: string
191
+ sender: string
192
+ recipient: string
193
+ amount: string
194
+ };
195
+ type IndexNftTransfer = IndexEventBase & {
196
+ event_type: "nft_transfer"
197
+ asset_identifier: string
198
+ sender: string
199
+ recipient: string
200
+ value: string
201
+ };
202
+ type IndexStxTransfer = IndexEventBase & {
203
+ event_type: "stx_transfer"
204
+ sender: string
205
+ recipient: string
206
+ amount: string
207
+ memo: string | null
208
+ };
209
+ type IndexStxMint = IndexEventBase & {
210
+ event_type: "stx_mint"
211
+ recipient: string
212
+ amount: string
213
+ };
214
+ type IndexStxBurn = IndexEventBase & {
215
+ event_type: "stx_burn"
216
+ sender: string
217
+ amount: string
218
+ };
219
+ type IndexFtMint = IndexEventBase & {
220
+ event_type: "ft_mint"
221
+ asset_identifier: string
222
+ recipient: string
223
+ amount: string
224
+ };
225
+ type IndexFtBurn = IndexEventBase & {
226
+ event_type: "ft_burn"
227
+ asset_identifier: string
228
+ sender: string
229
+ amount: string
230
+ };
231
+ type IndexNftMint = IndexEventBase & {
232
+ event_type: "nft_mint"
233
+ asset_identifier: string
234
+ recipient: string
235
+ value: string
236
+ };
237
+ type IndexNftBurn = IndexEventBase & {
238
+ event_type: "nft_burn"
239
+ asset_identifier: string
240
+ sender: string
241
+ value: string
242
+ };
243
+ type IndexPrint = IndexEventBase & {
244
+ event_type: "print"
245
+ payload: {
246
+ topic: string | null
247
+ value: unknown
248
+ raw_value: string | null
249
+ }
250
+ };
251
+ /** Decoded chain event, discriminated by `event_type`. */
252
+ type IndexEvent = IndexFtTransfer | IndexNftTransfer | IndexStxTransfer | IndexStxMint | IndexStxBurn | IndexFtMint | IndexFtBurn | IndexNftMint | IndexNftBurn | IndexPrint;
253
+ type IndexEventType = IndexEvent["event_type"];
254
+ type EventsEnvelope = {
255
+ events: IndexEvent[]
256
+ next_cursor: string | null
257
+ tip: IndexTip
258
+ reorgs: never[]
259
+ };
260
+ type EventsListParams = {
261
+ /** Required. One of the decoded event types. */
262
+ eventType: IndexEventType
263
+ cursor?: string | null
264
+ fromCursor?: string | null
265
+ limit?: number
266
+ contractId?: string
267
+ assetIdentifier?: string
268
+ sender?: string
269
+ recipient?: string
270
+ fromHeight?: number
271
+ toHeight?: number
272
+ };
273
+ type EventsWalkParams = Omit<EventsListParams, "limit"> & {
274
+ batchSize?: number
275
+ signal?: AbortSignal
276
+ };
277
+ type IndexContractCall = {
278
+ cursor: string
279
+ block_height: number
280
+ block_time?: string | null
281
+ tx_id: string
282
+ tx_index: number
283
+ contract_id: string
284
+ function_name: string
285
+ sender: string
286
+ status: string
287
+ args: unknown[]
288
+ result: unknown
289
+ result_hex: string | null
290
+ };
291
+ type ContractCallsEnvelope = {
292
+ contract_calls: IndexContractCall[]
293
+ next_cursor: string | null
294
+ tip: IndexTip
295
+ reorgs: never[]
296
+ };
297
+ type ContractCallsListParams = {
298
+ cursor?: string | null
299
+ fromCursor?: string | null
300
+ limit?: number
301
+ contractId?: string
302
+ functionName?: string
303
+ sender?: string
304
+ fromHeight?: number
305
+ toHeight?: number
306
+ };
307
+ type ContractCallsWalkParams = Omit<ContractCallsListParams, "limit"> & {
308
+ batchSize?: number
309
+ signal?: AbortSignal
310
+ };
179
311
  declare class Index extends BaseClient {
180
312
  constructor(options?: Partial<SecondLayerOptions>);
181
313
  readonly ftTransfers: {
@@ -186,10 +318,23 @@ declare class Index extends BaseClient {
186
318
  list: (params?: NftTransfersListParams) => Promise<NftTransfersEnvelope>
187
319
  walk: (params?: NftTransfersWalkParams) => AsyncIterable<NftTransfer>
188
320
  };
321
+ /** Generic decoded events by `event_type` (the full /v1/index/events surface). */
322
+ readonly events: {
323
+ list: (params: EventsListParams) => Promise<EventsEnvelope>
324
+ walk: (params: EventsWalkParams) => AsyncIterable<IndexEvent>
325
+ };
326
+ readonly contractCalls: {
327
+ list: (params?: ContractCallsListParams) => Promise<ContractCallsEnvelope>
328
+ walk: (params?: ContractCallsWalkParams) => AsyncIterable<IndexContractCall>
329
+ };
189
330
  private listFtTransfers;
190
331
  private listNftTransfers;
191
332
  private walkFtTransfers;
192
333
  private walkNftTransfers;
334
+ private listEvents;
335
+ private walkEvents;
336
+ private listContractCalls;
337
+ private walkContractCalls;
193
338
  }
194
339
  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"];
195
340
  type StreamsEventType = (typeof STREAMS_EVENT_TYPES)[number];
@@ -748,4 +893,10 @@ type WebhookHeaderInput = HeaderLookup | StandardWebhooksHeaders | Record<string
748
893
  * ```
749
894
  */
750
895
  declare function verifyWebhookSignature(rawBody: string, headers: WebhookHeaderInput, secret: string, toleranceSeconds?: number): boolean;
751
- export { verifyWebhookSignature, isStxTransfer, isStxMint, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, getSubgraph, decodeStxTransfer, decodeStxMint, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, createStreamsClient, VersionConflictError, ValidationError, UpdateSubscriptionRequest2 as UpdateSubscriptionRequest, Subscriptions, SubscriptionSummary2 as SubscriptionSummary, SubscriptionStatus, SubscriptionRuntime, SubscriptionFormat, SubscriptionDetail2 as SubscriptionDetail, Subgraphs, SubgraphSpecOptions3 as SubgraphSpecOptions, SubgraphSpecFormat2 as SubgraphSpecFormat, SubgraphAgentSchema3 as SubgraphAgentSchema, StreamsTip, StreamsServerError, StreamsReorgsListParams, StreamsReorgsListEnvelope, StreamsReorg, StreamsEventsStreamParams, StreamsEventsListParams, StreamsEventsListEnvelope, StreamsEventsEnvelope, StreamsEventsConsumeResult, StreamsEventsConsumeParams, StreamsEventType, StreamsEventPayload, StreamsEvent, StreamsClient, StreamsCanonicalBlock, SecondLayerOptions, SecondLayer, RotateSecretResponse2 as RotateSecretResponse, ReplayResult2 as ReplayResult, RateLimitError, NftTransfersWalkParams, NftTransfersListParams, NftTransfersEnvelope, NftTransferPayload, NftTransferEvent, NftTransfer, IndexTip, Index, FtTransfersWalkParams, FtTransfersListParams, FtTransfersEnvelope, FtTransferPayload, FtTransferEvent, FtTransfer, FetchLike2 as FetchLike, DeliveryRow2 as DeliveryRow, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns, DeadRow2 as DeadRow, CreateSubscriptionResponse2 as CreateSubscriptionResponse, CreateSubscriptionRequest2 as CreateSubscriptionRequest, AuthError, ApiError };
896
+ /** Make a cvToValue result JSON-serializable: Clarity (u)ints decode to bigint,
897
+ * which JSON.stringify can't handle — convert recursively to strings. */
898
+ declare function toJsonSafe(value: unknown): unknown;
899
+ /** Decode a hex-encoded Clarity value to JSON-safe JS (uints as strings,
900
+ * buffers as `0x…` hex, tuples as objects). Returns the input hex on failure. */
901
+ declare function decodeClarityValue(hex: string): unknown;
902
+ export { verifyWebhookSignature, toJsonSafe, isStxTransfer, isStxMint, isStxBurn, isPrint, isNftTransfer, isNftMint, isNftBurn, isFtTransfer, isFtMint, isFtBurn, getSubgraph, decodeStxTransfer, decodeStxMint, decodeStxBurn, decodePrint, decodeNftTransfer, decodeNftMint, decodeNftBurn, decodeFtTransfer, decodeFtMint, decodeFtBurn, decodeClarityValue, createStreamsClient, VersionConflictError, ValidationError, UpdateSubscriptionRequest2 as UpdateSubscriptionRequest, Subscriptions, SubscriptionSummary2 as SubscriptionSummary, SubscriptionStatus, SubscriptionRuntime, SubscriptionFormat, SubscriptionDetail2 as SubscriptionDetail, Subgraphs, SubgraphSpecOptions3 as SubgraphSpecOptions, SubgraphSpecFormat2 as SubgraphSpecFormat, SubgraphAgentSchema3 as SubgraphAgentSchema, StreamsTip, StreamsServerError, StreamsReorgsListParams, StreamsReorgsListEnvelope, StreamsReorg, StreamsEventsStreamParams, StreamsEventsListParams, StreamsEventsListEnvelope, StreamsEventsEnvelope, StreamsEventsConsumeResult, StreamsEventsConsumeParams, StreamsEventType, StreamsEventPayload, StreamsEvent, StreamsClient, StreamsCanonicalBlock, SecondLayerOptions, SecondLayer, RotateSecretResponse2 as RotateSecretResponse, ReplayResult2 as ReplayResult, RateLimitError, NftTransfersWalkParams, NftTransfersListParams, NftTransfersEnvelope, NftTransferPayload, NftTransferEvent, NftTransfer, IndexTip, IndexEventType, IndexEvent, IndexContractCall, Index, FtTransfersWalkParams, FtTransfersListParams, FtTransfersEnvelope, FtTransferPayload, FtTransferEvent, FtTransfer, FetchLike2 as FetchLike, EventsWalkParams, EventsListParams, EventsEnvelope, DeliveryRow2 as DeliveryRow, DecodedStxTransferPayload, DecodedStxTransfer, DecodedStxMintPayload, DecodedStxMint, DecodedStxBurnPayload, DecodedStxBurn, DecodedPrintValue, DecodedPrintPayload, DecodedPrint, DecodedNftTransferPayload, DecodedNftTransfer, DecodedNftMintPayload, DecodedNftMint, DecodedNftBurnPayload, DecodedNftBurn, DecodedFtTransferPayload, DecodedFtTransfer, DecodedFtMintPayload, DecodedFtMint, DecodedFtBurnPayload, DecodedFtBurn, DecodedEventRow, DecodedEventColumns, DeadRow2 as DeadRow, CreateSubscriptionResponse2 as CreateSubscriptionResponse, CreateSubscriptionRequest2 as CreateSubscriptionRequest, ContractCallsWalkParams, ContractCallsListParams, ContractCallsEnvelope, AuthError, ApiError };
package/dist/index.js CHANGED
@@ -317,6 +317,14 @@ class Index extends BaseClient {
317
317
  list: (params = {}) => this.listNftTransfers(params),
318
318
  walk: (params = {}) => this.walkNftTransfers(params)
319
319
  };
320
+ events = {
321
+ list: (params) => this.listEvents(params),
322
+ walk: (params) => this.walkEvents(params)
323
+ };
324
+ contractCalls = {
325
+ list: (params = {}) => this.listContractCalls(params),
326
+ walk: (params = {}) => this.walkContractCalls(params)
327
+ };
320
328
  async listFtTransfers(params = {}) {
321
329
  const searchParams = new URLSearchParams;
322
330
  appendSearchParam(searchParams, "cursor", params.cursor);
@@ -394,6 +402,83 @@ class Index extends BaseClient {
394
402
  firstPage = false;
395
403
  }
396
404
  }
405
+ async listEvents(params) {
406
+ const searchParams = new URLSearchParams;
407
+ appendSearchParam(searchParams, "event_type", params.eventType);
408
+ appendSearchParam(searchParams, "cursor", params.cursor);
409
+ appendSearchParam(searchParams, "from_cursor", params.fromCursor);
410
+ appendSearchParam(searchParams, "limit", params.limit);
411
+ appendSearchParam(searchParams, "contract_id", params.contractId);
412
+ appendSearchParam(searchParams, "asset_identifier", params.assetIdentifier);
413
+ appendSearchParam(searchParams, "sender", params.sender);
414
+ appendSearchParam(searchParams, "recipient", params.recipient);
415
+ appendSearchParam(searchParams, "from_height", params.fromHeight);
416
+ appendSearchParam(searchParams, "to_height", params.toHeight);
417
+ return this.request("GET", `/v1/index/events?${searchParams.toString()}`);
418
+ }
419
+ async* walkEvents(params) {
420
+ const batchSize = params.batchSize ?? 200;
421
+ let cursor = params.cursor ?? params.fromCursor ?? null;
422
+ let firstPage = true;
423
+ while (!params.signal?.aborted) {
424
+ const envelope = await this.listEvents({
425
+ ...params,
426
+ limit: batchSize,
427
+ cursor: firstPage ? params.cursor : cursor,
428
+ fromCursor: firstPage ? params.fromCursor : undefined,
429
+ fromHeight: firstPage ? firstWalkFromHeight(params) : undefined
430
+ });
431
+ for (const event of envelope.events) {
432
+ if (params.signal?.aborted)
433
+ return;
434
+ yield event;
435
+ }
436
+ const nextCursor = envelope.next_cursor;
437
+ if (!nextCursor || nextCursor === cursor || envelope.events.length < batchSize) {
438
+ return;
439
+ }
440
+ cursor = nextCursor;
441
+ firstPage = false;
442
+ }
443
+ }
444
+ async listContractCalls(params = {}) {
445
+ const searchParams = new URLSearchParams;
446
+ appendSearchParam(searchParams, "cursor", params.cursor);
447
+ appendSearchParam(searchParams, "from_cursor", params.fromCursor);
448
+ appendSearchParam(searchParams, "limit", params.limit);
449
+ appendSearchParam(searchParams, "contract_id", params.contractId);
450
+ appendSearchParam(searchParams, "function_name", params.functionName);
451
+ appendSearchParam(searchParams, "sender", params.sender);
452
+ appendSearchParam(searchParams, "from_height", params.fromHeight);
453
+ appendSearchParam(searchParams, "to_height", params.toHeight);
454
+ const query = searchParams.toString();
455
+ return this.request("GET", `/v1/index/contract-calls${query ? `?${query}` : ""}`);
456
+ }
457
+ async* walkContractCalls(params = {}) {
458
+ const batchSize = params.batchSize ?? 200;
459
+ let cursor = params.cursor ?? params.fromCursor ?? null;
460
+ let firstPage = true;
461
+ while (!params.signal?.aborted) {
462
+ const envelope = await this.listContractCalls({
463
+ ...params,
464
+ limit: batchSize,
465
+ cursor: firstPage ? params.cursor : cursor,
466
+ fromCursor: firstPage ? params.fromCursor : undefined,
467
+ fromHeight: firstPage ? firstWalkFromHeight(params) : undefined
468
+ });
469
+ for (const call of envelope.contract_calls) {
470
+ if (params.signal?.aborted)
471
+ return;
472
+ yield call;
473
+ }
474
+ const nextCursor = envelope.next_cursor;
475
+ if (!nextCursor || nextCursor === cursor || envelope.contract_calls.length < batchSize) {
476
+ return;
477
+ }
478
+ cursor = nextCursor;
479
+ firstPage = false;
480
+ }
481
+ }
397
482
  }
398
483
 
399
484
  // src/streams/consumer.ts
@@ -1011,19 +1096,8 @@ function decodeNftBurn(event) {
1011
1096
  value: requireHexValue2(event.payload, "nft_burn")
1012
1097
  });
1013
1098
  }
1014
- // src/streams/print.ts
1099
+ // src/clarity.ts
1015
1100
  import { cvToValue, deserializeCV } from "@secondlayer/stacks/clarity";
1016
- function printValueHex(payload) {
1017
- if (typeof payload.raw_value === "string")
1018
- return payload.raw_value;
1019
- const value = payload.value;
1020
- if (typeof value === "string" && value.startsWith("0x"))
1021
- return value;
1022
- if (value && typeof value === "object" && typeof value.hex === "string") {
1023
- return value.hex;
1024
- }
1025
- return null;
1026
- }
1027
1101
  function toJsonSafe(value) {
1028
1102
  if (typeof value === "bigint")
1029
1103
  return value.toString();
@@ -1038,6 +1112,27 @@ function toJsonSafe(value) {
1038
1112
  }
1039
1113
  return value;
1040
1114
  }
1115
+ function decodeClarityValue(hex) {
1116
+ try {
1117
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
1118
+ return toJsonSafe(cvToValue(deserializeCV(clean)));
1119
+ } catch {
1120
+ return hex;
1121
+ }
1122
+ }
1123
+
1124
+ // src/streams/print.ts
1125
+ function printValueHex(payload) {
1126
+ if (typeof payload.raw_value === "string")
1127
+ return payload.raw_value;
1128
+ const value = payload.value;
1129
+ if (typeof value === "string" && value.startsWith("0x"))
1130
+ return value;
1131
+ if (value && typeof value === "object" && typeof value.hex === "string") {
1132
+ return value.hex;
1133
+ }
1134
+ return null;
1135
+ }
1041
1136
  function isPrint(event) {
1042
1137
  return event.event_type === "print";
1043
1138
  }
@@ -1048,17 +1143,7 @@ function decodePrint(event) {
1048
1143
  const payload = event.payload;
1049
1144
  const topic = optionalString(payload.topic);
1050
1145
  const rawValue = printValueHex(payload);
1051
- let value;
1052
- if (rawValue) {
1053
- try {
1054
- const hex = rawValue.startsWith("0x") ? rawValue.slice(2) : rawValue;
1055
- value = toJsonSafe(cvToValue(deserializeCV(hex)));
1056
- } catch {
1057
- value = toJsonSafe(payload.value ?? null);
1058
- }
1059
- } else {
1060
- value = toJsonSafe(payload.value ?? null);
1061
- }
1146
+ const value = rawValue ? decodeClarityValue(rawValue) : toJsonSafe(payload.value ?? null);
1062
1147
  return decodedRow(event, "print", {
1063
1148
  contract_id: event.contract_id ?? optionalString(payload.contract_id),
1064
1149
  payload: { topic, value, raw_value: rawValue }
@@ -1123,6 +1208,7 @@ function verifyWebhookSignature(rawBody, headers, secret, toleranceSeconds = 300
1123
1208
  }
1124
1209
  export {
1125
1210
  verifyWebhookSignature,
1211
+ toJsonSafe,
1126
1212
  isStxTransfer,
1127
1213
  isStxMint,
1128
1214
  isStxBurn,
@@ -1144,6 +1230,7 @@ export {
1144
1230
  decodeFtTransfer,
1145
1231
  decodeFtMint,
1146
1232
  decodeFtBurn,
1233
+ decodeClarityValue,
1147
1234
  createStreamsClient,
1148
1235
  VersionConflictError,
1149
1236
  ValidationError,
@@ -1157,5 +1244,5 @@ export {
1157
1244
  ApiError
1158
1245
  };
1159
1246
 
1160
- //# debugId=CA72339C973F500764756E2164756E21
1247
+ //# debugId=9D4DDE30AE2D8C2F64756E2164756E21
1161
1248
  //# sourceMappingURL=index.js.map