@secondlayer/sdk 6.37.1 → 6.38.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 +177 -18
- package/dist/index.js +265 -78
- package/dist/index.js.map +11 -9
- package/dist/sinks/kysely.d.ts +108 -0
- package/dist/sinks/kysely.js +236 -0
- package/dist/sinks/kysely.js.map +11 -0
- package/dist/streams/index.d.ts +188 -6
- package/dist/streams/index.js +199 -71
- package/dist/streams/index.js.map +8 -7
- package/dist/subgraphs/index.d.ts +118 -15
- package/dist/subgraphs/index.js +222 -16
- package/dist/subgraphs/index.js.map +9 -7
- package/package.json +18 -3
package/dist/index.js
CHANGED
|
@@ -655,7 +655,7 @@ async function consumeStreamsEvents(opts) {
|
|
|
655
655
|
const emptyBackoffMs = opts.emptyBackoffMs ?? 500;
|
|
656
656
|
const maxPages = opts.maxPages ?? Number.POSITIVE_INFINITY;
|
|
657
657
|
const maxEmptyPolls = opts.maxEmptyPolls ?? Number.POSITIVE_INFINITY;
|
|
658
|
-
let cursor = opts.fromCursor ?? null;
|
|
658
|
+
let cursor = opts.fromCursor ?? await opts.sink?.loadCursor() ?? null;
|
|
659
659
|
const handledReorgs = new Set;
|
|
660
660
|
let pages = 0;
|
|
661
661
|
let emptyPolls = 0;
|
|
@@ -678,13 +678,14 @@ async function consumeStreamsEvents(opts) {
|
|
|
678
678
|
signal: opts.signal
|
|
679
679
|
});
|
|
680
680
|
pages++;
|
|
681
|
-
if (!finalizedOnly && opts.onReorg) {
|
|
681
|
+
if (!finalizedOnly && (opts.onReorg || opts.sink)) {
|
|
682
682
|
const fresh = envelope.reorgs.filter((reorg) => !handledReorgs.has(reorgKey(reorg))).sort((a, b) => a.fork_point_height - b.fork_point_height);
|
|
683
683
|
if (fresh.length > 0) {
|
|
684
684
|
const forkPoint = Math.min(...fresh.map((reorg) => reorg.fork_point_height));
|
|
685
685
|
const rewind = Cursor.atHeight(forkPoint);
|
|
686
686
|
for (const reorg of fresh) {
|
|
687
|
-
await opts.
|
|
687
|
+
await opts.sink?.rollback(reorg.fork_point_height, rewind);
|
|
688
|
+
await opts.onReorg?.(reorg, { cursor: rewind });
|
|
688
689
|
handledReorgs.add(reorgKey(reorg));
|
|
689
690
|
}
|
|
690
691
|
cursor = rewind;
|
|
@@ -696,10 +697,26 @@ async function consumeStreamsEvents(opts) {
|
|
|
696
697
|
const emitted = finalizedOnly ? envelope.events.filter((event) => event.finalized) : envelope.events;
|
|
697
698
|
const checkpoint = finalizedOnly ? emitted.at(-1)?.cursor ?? cursor : envelope.next_cursor;
|
|
698
699
|
height = emitted.at(-1)?.block_height ?? height;
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
700
|
+
const ctx = batchContext(checkpoint, height, envelope.tip.block_height);
|
|
701
|
+
opts.onProgress?.(ctx);
|
|
702
|
+
let nextCursor;
|
|
703
|
+
if (opts.sink) {
|
|
704
|
+
const sink = opts.sink;
|
|
705
|
+
if (checkpoint !== null && (checkpoint !== cursor || emitted.length > 0)) {
|
|
706
|
+
await sink.commitBatch(checkpoint, async (tx) => {
|
|
707
|
+
await opts.onBatch(emitted, envelope, {
|
|
708
|
+
...ctx,
|
|
709
|
+
tx
|
|
710
|
+
});
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
nextCursor = checkpoint;
|
|
714
|
+
} else {
|
|
715
|
+
const returnedCursor = await opts.onBatch(emitted, envelope, ctx);
|
|
716
|
+
if (finalizedOnly)
|
|
717
|
+
assertFinalizedCheckpoint(returnedCursor, checkpoint);
|
|
718
|
+
nextCursor = returnedCursor ?? checkpoint;
|
|
719
|
+
}
|
|
703
720
|
if (nextCursor && nextCursor !== cursor) {
|
|
704
721
|
cursor = nextCursor;
|
|
705
722
|
emptyPolls = 0;
|
|
@@ -800,7 +817,7 @@ async function consumeIndexFeed(opts) {
|
|
|
800
817
|
const emptyBackoffMs = opts.emptyBackoffMs ?? 500;
|
|
801
818
|
const maxPages = opts.maxPages ?? Number.POSITIVE_INFINITY;
|
|
802
819
|
const maxEmptyPolls = opts.maxEmptyPolls ?? Number.POSITIVE_INFINITY;
|
|
803
|
-
let cursor = opts.fromCursor ?? null;
|
|
820
|
+
let cursor = opts.fromCursor ?? await opts.sink?.loadCursor() ?? null;
|
|
804
821
|
const handledReorgs = new Set;
|
|
805
822
|
let pages = 0;
|
|
806
823
|
let emptyPolls = 0;
|
|
@@ -818,13 +835,14 @@ async function consumeIndexFeed(opts) {
|
|
|
818
835
|
signal: opts.signal
|
|
819
836
|
});
|
|
820
837
|
pages++;
|
|
821
|
-
if (!finalizedOnly && opts.onReorg) {
|
|
838
|
+
if (!finalizedOnly && (opts.onReorg || opts.sink)) {
|
|
822
839
|
const fresh = envelope.reorgs.filter((reorg) => !handledReorgs.has(reorg.id)).sort((a, b) => a.fork_point_height - b.fork_point_height);
|
|
823
840
|
if (fresh.length > 0) {
|
|
824
841
|
const forkPoint = Math.min(...fresh.map((reorg) => reorg.fork_point_height));
|
|
825
842
|
const rewind = Cursor.atHeight(forkPoint);
|
|
826
843
|
for (const reorg of fresh) {
|
|
827
|
-
await opts.
|
|
844
|
+
await opts.sink?.rollback(reorg.fork_point_height, rewind);
|
|
845
|
+
await opts.onReorg?.(reorg, { cursor: rewind });
|
|
828
846
|
handledReorgs.add(reorg.id);
|
|
829
847
|
}
|
|
830
848
|
cursor = rewind;
|
|
@@ -837,10 +855,26 @@ async function consumeIndexFeed(opts) {
|
|
|
837
855
|
const emitted = finalizedOnly ? items.filter((item) => item.block_height <= envelope.tip.finalized_height) : items;
|
|
838
856
|
const checkpoint = finalizedOnly ? emitted.at(-1)?.cursor ?? cursor : envelope.next_cursor;
|
|
839
857
|
height = emitted.at(-1)?.block_height ?? height;
|
|
840
|
-
const
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
858
|
+
const ctx = batchContext(checkpoint, height, envelope.tip.block_height);
|
|
859
|
+
opts.onProgress?.(ctx);
|
|
860
|
+
let nextCursor;
|
|
861
|
+
if (opts.sink) {
|
|
862
|
+
const sink = opts.sink;
|
|
863
|
+
if (checkpoint !== null && (checkpoint !== cursor || emitted.length > 0)) {
|
|
864
|
+
await sink.commitBatch(checkpoint, async (tx) => {
|
|
865
|
+
await opts.onBatch(emitted, envelope, {
|
|
866
|
+
...ctx,
|
|
867
|
+
tx
|
|
868
|
+
});
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
nextCursor = checkpoint;
|
|
872
|
+
} else {
|
|
873
|
+
const returnedCursor = await opts.onBatch(emitted, envelope, ctx);
|
|
874
|
+
if (finalizedOnly)
|
|
875
|
+
assertFinalizedCheckpoint(returnedCursor, checkpoint);
|
|
876
|
+
nextCursor = returnedCursor ?? checkpoint;
|
|
877
|
+
}
|
|
844
878
|
if (nextCursor && nextCursor !== cursor) {
|
|
845
879
|
cursor = nextCursor;
|
|
846
880
|
emptyPolls = 0;
|
|
@@ -1313,6 +1347,175 @@ class Projects extends BaseClient {
|
|
|
1313
1347
|
// src/streams/client.ts
|
|
1314
1348
|
import { ed25519 as ed255192 } from "@secondlayer/shared";
|
|
1315
1349
|
|
|
1350
|
+
// src/streams/_payload.ts
|
|
1351
|
+
function requireString(payload, field, eventType) {
|
|
1352
|
+
const value = payload[field];
|
|
1353
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
1354
|
+
throw new Error(`${eventType} payload missing ${field}`);
|
|
1355
|
+
}
|
|
1356
|
+
return value;
|
|
1357
|
+
}
|
|
1358
|
+
function optionalString(value) {
|
|
1359
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1360
|
+
}
|
|
1361
|
+
function requireAmountField(payload, field, eventType) {
|
|
1362
|
+
const amount = requireString(payload, field, eventType);
|
|
1363
|
+
if (!/^(0|[1-9]\d*)$/.test(amount)) {
|
|
1364
|
+
throw new Error(`${eventType} payload has malformed ${field}`);
|
|
1365
|
+
}
|
|
1366
|
+
return amount;
|
|
1367
|
+
}
|
|
1368
|
+
function requireAmount(payload, eventType) {
|
|
1369
|
+
return requireAmountField(payload, "amount", eventType);
|
|
1370
|
+
}
|
|
1371
|
+
function parseAssetIdentifier(assetIdentifier, eventType) {
|
|
1372
|
+
const [contractId, tokenName] = assetIdentifier.split("::");
|
|
1373
|
+
if (!contractId) {
|
|
1374
|
+
throw new Error(`${eventType} payload has malformed asset_identifier`);
|
|
1375
|
+
}
|
|
1376
|
+
return {
|
|
1377
|
+
contract_id: contractId,
|
|
1378
|
+
token_name: tokenName && tokenName.length > 0 ? tokenName : null
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
function requireHexValue(payload, eventType) {
|
|
1382
|
+
const rawValue = payload.raw_value;
|
|
1383
|
+
if (typeof rawValue === "string") {
|
|
1384
|
+
if (!/^0x[0-9a-fA-F]*$/.test(rawValue)) {
|
|
1385
|
+
throw new Error(`${eventType} payload has malformed value`);
|
|
1386
|
+
}
|
|
1387
|
+
return rawValue;
|
|
1388
|
+
}
|
|
1389
|
+
const value = payload.value;
|
|
1390
|
+
const hex = typeof value === "string" ? value : value && typeof value === "object" && typeof value.hex === "string" ? value.hex : null;
|
|
1391
|
+
if (!hex) {
|
|
1392
|
+
throw new Error(`${eventType} payload missing value`);
|
|
1393
|
+
}
|
|
1394
|
+
if (!/^0x[0-9a-fA-F]*$/.test(hex)) {
|
|
1395
|
+
throw new Error(`${eventType} payload has malformed value`);
|
|
1396
|
+
}
|
|
1397
|
+
return hex;
|
|
1398
|
+
}
|
|
1399
|
+
function decodedRow(event, eventType, decoded_payload) {
|
|
1400
|
+
return {
|
|
1401
|
+
cursor: event.cursor,
|
|
1402
|
+
block_height: event.block_height,
|
|
1403
|
+
tx_id: event.tx_id,
|
|
1404
|
+
tx_index: event.tx_index,
|
|
1405
|
+
event_index: event.event_index,
|
|
1406
|
+
event_type: eventType,
|
|
1407
|
+
decoded_payload,
|
|
1408
|
+
source_cursor: event.cursor
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
// src/streams/decode.ts
|
|
1413
|
+
function decode(event) {
|
|
1414
|
+
const base = {
|
|
1415
|
+
cursor: event.cursor,
|
|
1416
|
+
block_height: event.block_height,
|
|
1417
|
+
block_time: event.ts,
|
|
1418
|
+
tx_id: event.tx_id,
|
|
1419
|
+
tx_index: event.tx_index,
|
|
1420
|
+
event_index: event.event_index,
|
|
1421
|
+
contract_id: event.contract_id
|
|
1422
|
+
};
|
|
1423
|
+
const p = event.payload;
|
|
1424
|
+
switch (event.event_type) {
|
|
1425
|
+
case "stx_transfer":
|
|
1426
|
+
return {
|
|
1427
|
+
...base,
|
|
1428
|
+
event_type: "stx_transfer",
|
|
1429
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1430
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1431
|
+
amount: requireAmountField(p, "amount", event.event_type),
|
|
1432
|
+
memo: optionalString(p.memo)
|
|
1433
|
+
};
|
|
1434
|
+
case "stx_mint":
|
|
1435
|
+
return {
|
|
1436
|
+
...base,
|
|
1437
|
+
event_type: "stx_mint",
|
|
1438
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1439
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1440
|
+
};
|
|
1441
|
+
case "stx_burn":
|
|
1442
|
+
return {
|
|
1443
|
+
...base,
|
|
1444
|
+
event_type: "stx_burn",
|
|
1445
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1446
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1447
|
+
};
|
|
1448
|
+
case "stx_lock":
|
|
1449
|
+
return {
|
|
1450
|
+
...base,
|
|
1451
|
+
event_type: "stx_lock",
|
|
1452
|
+
sender: requireString(p, "locked_address", event.event_type),
|
|
1453
|
+
amount: requireAmountField(p, "locked_amount", event.event_type),
|
|
1454
|
+
payload: { unlock_height: optionalString(p.unlock_height) }
|
|
1455
|
+
};
|
|
1456
|
+
case "ft_transfer":
|
|
1457
|
+
return {
|
|
1458
|
+
...base,
|
|
1459
|
+
event_type: "ft_transfer",
|
|
1460
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1461
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1462
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1463
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1464
|
+
};
|
|
1465
|
+
case "ft_mint":
|
|
1466
|
+
return {
|
|
1467
|
+
...base,
|
|
1468
|
+
event_type: "ft_mint",
|
|
1469
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1470
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1471
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1472
|
+
};
|
|
1473
|
+
case "ft_burn":
|
|
1474
|
+
return {
|
|
1475
|
+
...base,
|
|
1476
|
+
event_type: "ft_burn",
|
|
1477
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1478
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1479
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1480
|
+
};
|
|
1481
|
+
case "nft_transfer":
|
|
1482
|
+
return {
|
|
1483
|
+
...base,
|
|
1484
|
+
event_type: "nft_transfer",
|
|
1485
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1486
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1487
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1488
|
+
value: requireHexValue(p, event.event_type)
|
|
1489
|
+
};
|
|
1490
|
+
case "nft_mint":
|
|
1491
|
+
return {
|
|
1492
|
+
...base,
|
|
1493
|
+
event_type: "nft_mint",
|
|
1494
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1495
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1496
|
+
value: requireHexValue(p, event.event_type)
|
|
1497
|
+
};
|
|
1498
|
+
case "nft_burn":
|
|
1499
|
+
return {
|
|
1500
|
+
...base,
|
|
1501
|
+
event_type: "nft_burn",
|
|
1502
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1503
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1504
|
+
value: requireHexValue(p, event.event_type)
|
|
1505
|
+
};
|
|
1506
|
+
case "print":
|
|
1507
|
+
return {
|
|
1508
|
+
...base,
|
|
1509
|
+
event_type: "print",
|
|
1510
|
+
payload: {
|
|
1511
|
+
topic: optionalString(p.topic),
|
|
1512
|
+
value: p.value,
|
|
1513
|
+
raw_value: optionalString(p.raw_value)
|
|
1514
|
+
}
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1316
1519
|
// src/streams/dumps.ts
|
|
1317
1520
|
import { createHash } from "node:crypto";
|
|
1318
1521
|
import { verifyStreamsBulkManifestSignature } from "@secondlayer/shared/streams-bulk-manifest";
|
|
@@ -1687,8 +1890,11 @@ function createStreamsClient(options) {
|
|
|
1687
1890
|
return request(`/v1/streams/events/${encodeURIComponent(txId)}`);
|
|
1688
1891
|
},
|
|
1689
1892
|
consume(params) {
|
|
1893
|
+
const onBatch = params.decoded ? (events, envelope, ctx) => params.onBatch(events.map(decode), envelope, ctx) : params.onBatch;
|
|
1690
1894
|
return consumeStreamsEvents({
|
|
1691
1895
|
fromCursor: params.fromCursor,
|
|
1896
|
+
sink: params.sink,
|
|
1897
|
+
onProgress: params.onProgress,
|
|
1692
1898
|
mode: params.mode,
|
|
1693
1899
|
finalizedOnly: params.finalizedOnly,
|
|
1694
1900
|
types: params.types,
|
|
@@ -1699,7 +1905,7 @@ function createStreamsClient(options) {
|
|
|
1699
1905
|
assetIdentifier: params.assetIdentifier,
|
|
1700
1906
|
batchSize: params.batchSize ?? 100,
|
|
1701
1907
|
fetchEvents,
|
|
1702
|
-
onBatch
|
|
1908
|
+
onBatch,
|
|
1703
1909
|
onReorg: params.onReorg,
|
|
1704
1910
|
emptyBackoffMs: params.emptyBackoffMs,
|
|
1705
1911
|
maxPages: params.maxPages,
|
|
@@ -1937,68 +2143,6 @@ function getSubgraph(def, options = {}) {
|
|
|
1937
2143
|
}
|
|
1938
2144
|
return new Subgraphs(options).typed(def);
|
|
1939
2145
|
}
|
|
1940
|
-
// src/streams/_payload.ts
|
|
1941
|
-
function requireString(payload, field, eventType) {
|
|
1942
|
-
const value = payload[field];
|
|
1943
|
-
if (typeof value !== "string" || value.length === 0) {
|
|
1944
|
-
throw new Error(`${eventType} payload missing ${field}`);
|
|
1945
|
-
}
|
|
1946
|
-
return value;
|
|
1947
|
-
}
|
|
1948
|
-
function optionalString(value) {
|
|
1949
|
-
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1950
|
-
}
|
|
1951
|
-
function requireAmountField(payload, field, eventType) {
|
|
1952
|
-
const amount = requireString(payload, field, eventType);
|
|
1953
|
-
if (!/^(0|[1-9]\d*)$/.test(amount)) {
|
|
1954
|
-
throw new Error(`${eventType} payload has malformed ${field}`);
|
|
1955
|
-
}
|
|
1956
|
-
return amount;
|
|
1957
|
-
}
|
|
1958
|
-
function requireAmount(payload, eventType) {
|
|
1959
|
-
return requireAmountField(payload, "amount", eventType);
|
|
1960
|
-
}
|
|
1961
|
-
function parseAssetIdentifier(assetIdentifier, eventType) {
|
|
1962
|
-
const [contractId, tokenName] = assetIdentifier.split("::");
|
|
1963
|
-
if (!contractId) {
|
|
1964
|
-
throw new Error(`${eventType} payload has malformed asset_identifier`);
|
|
1965
|
-
}
|
|
1966
|
-
return {
|
|
1967
|
-
contract_id: contractId,
|
|
1968
|
-
token_name: tokenName && tokenName.length > 0 ? tokenName : null
|
|
1969
|
-
};
|
|
1970
|
-
}
|
|
1971
|
-
function requireHexValue(payload, eventType) {
|
|
1972
|
-
const rawValue = payload.raw_value;
|
|
1973
|
-
if (typeof rawValue === "string") {
|
|
1974
|
-
if (!/^0x[0-9a-fA-F]*$/.test(rawValue)) {
|
|
1975
|
-
throw new Error(`${eventType} payload has malformed value`);
|
|
1976
|
-
}
|
|
1977
|
-
return rawValue;
|
|
1978
|
-
}
|
|
1979
|
-
const value = payload.value;
|
|
1980
|
-
const hex = typeof value === "string" ? value : value && typeof value === "object" && typeof value.hex === "string" ? value.hex : null;
|
|
1981
|
-
if (!hex) {
|
|
1982
|
-
throw new Error(`${eventType} payload missing value`);
|
|
1983
|
-
}
|
|
1984
|
-
if (!/^0x[0-9a-fA-F]*$/.test(hex)) {
|
|
1985
|
-
throw new Error(`${eventType} payload has malformed value`);
|
|
1986
|
-
}
|
|
1987
|
-
return hex;
|
|
1988
|
-
}
|
|
1989
|
-
function decodedRow(event, eventType, decoded_payload) {
|
|
1990
|
-
return {
|
|
1991
|
-
cursor: event.cursor,
|
|
1992
|
-
block_height: event.block_height,
|
|
1993
|
-
tx_id: event.tx_id,
|
|
1994
|
-
tx_index: event.tx_index,
|
|
1995
|
-
event_index: event.event_index,
|
|
1996
|
-
event_type: eventType,
|
|
1997
|
-
decoded_payload,
|
|
1998
|
-
source_cursor: event.cursor
|
|
1999
|
-
};
|
|
2000
|
-
}
|
|
2001
|
-
|
|
2002
2146
|
// src/streams/ft-transfer.ts
|
|
2003
2147
|
function isFtTransfer(event) {
|
|
2004
2148
|
return event.event_type === "ft_transfer";
|
|
@@ -2439,6 +2583,46 @@ async function payAndRetry(doFetch, opts) {
|
|
|
2439
2583
|
});
|
|
2440
2584
|
return doFetch({ "PAYMENT-SIGNATURE": header });
|
|
2441
2585
|
}
|
|
2586
|
+
// src/consumer-ops.ts
|
|
2587
|
+
function consumerHealth(options = {}) {
|
|
2588
|
+
const staleAfterMs = options.staleAfterMs ?? 120000;
|
|
2589
|
+
const startedAt = Date.now();
|
|
2590
|
+
let lastCtx = null;
|
|
2591
|
+
let lastBatchAt = 0;
|
|
2592
|
+
return {
|
|
2593
|
+
record(ctx) {
|
|
2594
|
+
lastCtx = ctx;
|
|
2595
|
+
lastBatchAt = Date.now();
|
|
2596
|
+
},
|
|
2597
|
+
handler(req) {
|
|
2598
|
+
if (new URL(req.url).pathname !== "/health") {
|
|
2599
|
+
return new Response("not found", { status: 404 });
|
|
2600
|
+
}
|
|
2601
|
+
const idleMs = lastBatchAt ? Date.now() - lastBatchAt : 0;
|
|
2602
|
+
const ok = idleMs < staleAfterMs;
|
|
2603
|
+
return Response.json({
|
|
2604
|
+
ok,
|
|
2605
|
+
checkpoint: lastCtx?.cursor ?? null,
|
|
2606
|
+
block_height: lastCtx?.height ?? null,
|
|
2607
|
+
tip_height: lastCtx?.tipHeight ?? null,
|
|
2608
|
+
blocks_behind: lastCtx?.blocksBehind ?? null,
|
|
2609
|
+
idle_s: Math.floor(idleMs / 1000),
|
|
2610
|
+
uptime_s: Math.floor((Date.now() - startedAt) / 1000)
|
|
2611
|
+
}, { status: ok ? 200 : 503 });
|
|
2612
|
+
}
|
|
2613
|
+
};
|
|
2614
|
+
}
|
|
2615
|
+
function shutdownSignal(options = {}) {
|
|
2616
|
+
const controller = new AbortController;
|
|
2617
|
+
if (typeof process !== "undefined" && typeof process.on === "function") {
|
|
2618
|
+
for (const signal of options.signals ?? ["SIGTERM", "SIGINT"]) {
|
|
2619
|
+
process.on(signal, () => {
|
|
2620
|
+
controller.abort(new Error(`${signal} — finishing the current batch`));
|
|
2621
|
+
});
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
return controller.signal;
|
|
2625
|
+
}
|
|
2442
2626
|
// src/webhooks.ts
|
|
2443
2627
|
import { verifySecondlayerSignatureValues } from "@secondlayer/shared/crypto/secondlayer-webhook";
|
|
2444
2628
|
import {
|
|
@@ -2599,6 +2783,7 @@ export {
|
|
|
2599
2783
|
verifySecondlayerSignature,
|
|
2600
2784
|
trigger,
|
|
2601
2785
|
toJsonSafe,
|
|
2786
|
+
shutdownSignal,
|
|
2602
2787
|
selectOffer,
|
|
2603
2788
|
resolveApiKey,
|
|
2604
2789
|
resolveAccountNonce,
|
|
@@ -2632,8 +2817,10 @@ export {
|
|
|
2632
2817
|
decodeFtBurn,
|
|
2633
2818
|
decodeClarityValue,
|
|
2634
2819
|
decodeChainWebhook,
|
|
2820
|
+
decode,
|
|
2635
2821
|
createX402Client,
|
|
2636
2822
|
createStreamsClient,
|
|
2823
|
+
consumerHealth,
|
|
2637
2824
|
consumeIndexFeed,
|
|
2638
2825
|
buildSignedX402Payment,
|
|
2639
2826
|
X402SpendGuardError,
|
|
@@ -2657,5 +2844,5 @@ export {
|
|
|
2657
2844
|
ApiError
|
|
2658
2845
|
};
|
|
2659
2846
|
|
|
2660
|
-
//# debugId=
|
|
2847
|
+
//# debugId=1D3B2F9E333F939964756E2164756E21
|
|
2661
2848
|
//# sourceMappingURL=index.js.map
|