@secondlayer/sdk 6.37.1 → 6.39.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 +214 -20
- package/dist/index.js +267 -79
- 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 +155 -17
- package/dist/subgraphs/index.js +224 -17
- 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;
|
|
@@ -1079,7 +1113,8 @@ class Index extends BaseClient {
|
|
|
1079
1113
|
from_height: params.fromHeight,
|
|
1080
1114
|
to_height: params.toHeight,
|
|
1081
1115
|
trait: params.trait,
|
|
1082
|
-
tx_context: params.txContext ? "true" : undefined
|
|
1116
|
+
tx_context: params.txContext ? "true" : undefined,
|
|
1117
|
+
fields: params.fields?.join(",")
|
|
1083
1118
|
})}`);
|
|
1084
1119
|
}
|
|
1085
1120
|
walkEvents(params) {
|
|
@@ -1313,6 +1348,175 @@ class Projects extends BaseClient {
|
|
|
1313
1348
|
// src/streams/client.ts
|
|
1314
1349
|
import { ed25519 as ed255192 } from "@secondlayer/shared";
|
|
1315
1350
|
|
|
1351
|
+
// src/streams/_payload.ts
|
|
1352
|
+
function requireString(payload, field, eventType) {
|
|
1353
|
+
const value = payload[field];
|
|
1354
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
1355
|
+
throw new Error(`${eventType} payload missing ${field}`);
|
|
1356
|
+
}
|
|
1357
|
+
return value;
|
|
1358
|
+
}
|
|
1359
|
+
function optionalString(value) {
|
|
1360
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1361
|
+
}
|
|
1362
|
+
function requireAmountField(payload, field, eventType) {
|
|
1363
|
+
const amount = requireString(payload, field, eventType);
|
|
1364
|
+
if (!/^(0|[1-9]\d*)$/.test(amount)) {
|
|
1365
|
+
throw new Error(`${eventType} payload has malformed ${field}`);
|
|
1366
|
+
}
|
|
1367
|
+
return amount;
|
|
1368
|
+
}
|
|
1369
|
+
function requireAmount(payload, eventType) {
|
|
1370
|
+
return requireAmountField(payload, "amount", eventType);
|
|
1371
|
+
}
|
|
1372
|
+
function parseAssetIdentifier(assetIdentifier, eventType) {
|
|
1373
|
+
const [contractId, tokenName] = assetIdentifier.split("::");
|
|
1374
|
+
if (!contractId) {
|
|
1375
|
+
throw new Error(`${eventType} payload has malformed asset_identifier`);
|
|
1376
|
+
}
|
|
1377
|
+
return {
|
|
1378
|
+
contract_id: contractId,
|
|
1379
|
+
token_name: tokenName && tokenName.length > 0 ? tokenName : null
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
function requireHexValue(payload, eventType) {
|
|
1383
|
+
const rawValue = payload.raw_value;
|
|
1384
|
+
if (typeof rawValue === "string") {
|
|
1385
|
+
if (!/^0x[0-9a-fA-F]*$/.test(rawValue)) {
|
|
1386
|
+
throw new Error(`${eventType} payload has malformed value`);
|
|
1387
|
+
}
|
|
1388
|
+
return rawValue;
|
|
1389
|
+
}
|
|
1390
|
+
const value = payload.value;
|
|
1391
|
+
const hex = typeof value === "string" ? value : value && typeof value === "object" && typeof value.hex === "string" ? value.hex : null;
|
|
1392
|
+
if (!hex) {
|
|
1393
|
+
throw new Error(`${eventType} payload missing value`);
|
|
1394
|
+
}
|
|
1395
|
+
if (!/^0x[0-9a-fA-F]*$/.test(hex)) {
|
|
1396
|
+
throw new Error(`${eventType} payload has malformed value`);
|
|
1397
|
+
}
|
|
1398
|
+
return hex;
|
|
1399
|
+
}
|
|
1400
|
+
function decodedRow(event, eventType, decoded_payload) {
|
|
1401
|
+
return {
|
|
1402
|
+
cursor: event.cursor,
|
|
1403
|
+
block_height: event.block_height,
|
|
1404
|
+
tx_id: event.tx_id,
|
|
1405
|
+
tx_index: event.tx_index,
|
|
1406
|
+
event_index: event.event_index,
|
|
1407
|
+
event_type: eventType,
|
|
1408
|
+
decoded_payload,
|
|
1409
|
+
source_cursor: event.cursor
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
// src/streams/decode.ts
|
|
1414
|
+
function decode(event) {
|
|
1415
|
+
const base = {
|
|
1416
|
+
cursor: event.cursor,
|
|
1417
|
+
block_height: event.block_height,
|
|
1418
|
+
block_time: event.ts,
|
|
1419
|
+
tx_id: event.tx_id,
|
|
1420
|
+
tx_index: event.tx_index,
|
|
1421
|
+
event_index: event.event_index,
|
|
1422
|
+
contract_id: event.contract_id
|
|
1423
|
+
};
|
|
1424
|
+
const p = event.payload;
|
|
1425
|
+
switch (event.event_type) {
|
|
1426
|
+
case "stx_transfer":
|
|
1427
|
+
return {
|
|
1428
|
+
...base,
|
|
1429
|
+
event_type: "stx_transfer",
|
|
1430
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1431
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1432
|
+
amount: requireAmountField(p, "amount", event.event_type),
|
|
1433
|
+
memo: optionalString(p.memo)
|
|
1434
|
+
};
|
|
1435
|
+
case "stx_mint":
|
|
1436
|
+
return {
|
|
1437
|
+
...base,
|
|
1438
|
+
event_type: "stx_mint",
|
|
1439
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1440
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1441
|
+
};
|
|
1442
|
+
case "stx_burn":
|
|
1443
|
+
return {
|
|
1444
|
+
...base,
|
|
1445
|
+
event_type: "stx_burn",
|
|
1446
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1447
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1448
|
+
};
|
|
1449
|
+
case "stx_lock":
|
|
1450
|
+
return {
|
|
1451
|
+
...base,
|
|
1452
|
+
event_type: "stx_lock",
|
|
1453
|
+
sender: requireString(p, "locked_address", event.event_type),
|
|
1454
|
+
amount: requireAmountField(p, "locked_amount", event.event_type),
|
|
1455
|
+
payload: { unlock_height: optionalString(p.unlock_height) }
|
|
1456
|
+
};
|
|
1457
|
+
case "ft_transfer":
|
|
1458
|
+
return {
|
|
1459
|
+
...base,
|
|
1460
|
+
event_type: "ft_transfer",
|
|
1461
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1462
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1463
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1464
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1465
|
+
};
|
|
1466
|
+
case "ft_mint":
|
|
1467
|
+
return {
|
|
1468
|
+
...base,
|
|
1469
|
+
event_type: "ft_mint",
|
|
1470
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1471
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1472
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1473
|
+
};
|
|
1474
|
+
case "ft_burn":
|
|
1475
|
+
return {
|
|
1476
|
+
...base,
|
|
1477
|
+
event_type: "ft_burn",
|
|
1478
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1479
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1480
|
+
amount: requireAmountField(p, "amount", event.event_type)
|
|
1481
|
+
};
|
|
1482
|
+
case "nft_transfer":
|
|
1483
|
+
return {
|
|
1484
|
+
...base,
|
|
1485
|
+
event_type: "nft_transfer",
|
|
1486
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1487
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1488
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1489
|
+
value: requireHexValue(p, event.event_type)
|
|
1490
|
+
};
|
|
1491
|
+
case "nft_mint":
|
|
1492
|
+
return {
|
|
1493
|
+
...base,
|
|
1494
|
+
event_type: "nft_mint",
|
|
1495
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1496
|
+
recipient: requireString(p, "recipient", event.event_type),
|
|
1497
|
+
value: requireHexValue(p, event.event_type)
|
|
1498
|
+
};
|
|
1499
|
+
case "nft_burn":
|
|
1500
|
+
return {
|
|
1501
|
+
...base,
|
|
1502
|
+
event_type: "nft_burn",
|
|
1503
|
+
asset_identifier: requireString(p, "asset_identifier", event.event_type),
|
|
1504
|
+
sender: requireString(p, "sender", event.event_type),
|
|
1505
|
+
value: requireHexValue(p, event.event_type)
|
|
1506
|
+
};
|
|
1507
|
+
case "print":
|
|
1508
|
+
return {
|
|
1509
|
+
...base,
|
|
1510
|
+
event_type: "print",
|
|
1511
|
+
payload: {
|
|
1512
|
+
topic: optionalString(p.topic),
|
|
1513
|
+
value: p.value,
|
|
1514
|
+
raw_value: optionalString(p.raw_value)
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1316
1520
|
// src/streams/dumps.ts
|
|
1317
1521
|
import { createHash } from "node:crypto";
|
|
1318
1522
|
import { verifyStreamsBulkManifestSignature } from "@secondlayer/shared/streams-bulk-manifest";
|
|
@@ -1687,8 +1891,11 @@ function createStreamsClient(options) {
|
|
|
1687
1891
|
return request(`/v1/streams/events/${encodeURIComponent(txId)}`);
|
|
1688
1892
|
},
|
|
1689
1893
|
consume(params) {
|
|
1894
|
+
const onBatch = params.decoded ? (events, envelope, ctx) => params.onBatch(events.map(decode), envelope, ctx) : params.onBatch;
|
|
1690
1895
|
return consumeStreamsEvents({
|
|
1691
1896
|
fromCursor: params.fromCursor,
|
|
1897
|
+
sink: params.sink,
|
|
1898
|
+
onProgress: params.onProgress,
|
|
1692
1899
|
mode: params.mode,
|
|
1693
1900
|
finalizedOnly: params.finalizedOnly,
|
|
1694
1901
|
types: params.types,
|
|
@@ -1699,7 +1906,7 @@ function createStreamsClient(options) {
|
|
|
1699
1906
|
assetIdentifier: params.assetIdentifier,
|
|
1700
1907
|
batchSize: params.batchSize ?? 100,
|
|
1701
1908
|
fetchEvents,
|
|
1702
|
-
onBatch
|
|
1909
|
+
onBatch,
|
|
1703
1910
|
onReorg: params.onReorg,
|
|
1704
1911
|
emptyBackoffMs: params.emptyBackoffMs,
|
|
1705
1912
|
maxPages: params.maxPages,
|
|
@@ -1937,68 +2144,6 @@ function getSubgraph(def, options = {}) {
|
|
|
1937
2144
|
}
|
|
1938
2145
|
return new Subgraphs(options).typed(def);
|
|
1939
2146
|
}
|
|
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
2147
|
// src/streams/ft-transfer.ts
|
|
2003
2148
|
function isFtTransfer(event) {
|
|
2004
2149
|
return event.event_type === "ft_transfer";
|
|
@@ -2439,6 +2584,46 @@ async function payAndRetry(doFetch, opts) {
|
|
|
2439
2584
|
});
|
|
2440
2585
|
return doFetch({ "PAYMENT-SIGNATURE": header });
|
|
2441
2586
|
}
|
|
2587
|
+
// src/consumer-ops.ts
|
|
2588
|
+
function consumerHealth(options = {}) {
|
|
2589
|
+
const staleAfterMs = options.staleAfterMs ?? 120000;
|
|
2590
|
+
const startedAt = Date.now();
|
|
2591
|
+
let lastCtx = null;
|
|
2592
|
+
let lastBatchAt = 0;
|
|
2593
|
+
return {
|
|
2594
|
+
record(ctx) {
|
|
2595
|
+
lastCtx = ctx;
|
|
2596
|
+
lastBatchAt = Date.now();
|
|
2597
|
+
},
|
|
2598
|
+
handler(req) {
|
|
2599
|
+
if (new URL(req.url).pathname !== "/health") {
|
|
2600
|
+
return new Response("not found", { status: 404 });
|
|
2601
|
+
}
|
|
2602
|
+
const idleMs = lastBatchAt ? Date.now() - lastBatchAt : 0;
|
|
2603
|
+
const ok = idleMs < staleAfterMs;
|
|
2604
|
+
return Response.json({
|
|
2605
|
+
ok,
|
|
2606
|
+
checkpoint: lastCtx?.cursor ?? null,
|
|
2607
|
+
block_height: lastCtx?.height ?? null,
|
|
2608
|
+
tip_height: lastCtx?.tipHeight ?? null,
|
|
2609
|
+
blocks_behind: lastCtx?.blocksBehind ?? null,
|
|
2610
|
+
idle_s: Math.floor(idleMs / 1000),
|
|
2611
|
+
uptime_s: Math.floor((Date.now() - startedAt) / 1000)
|
|
2612
|
+
}, { status: ok ? 200 : 503 });
|
|
2613
|
+
}
|
|
2614
|
+
};
|
|
2615
|
+
}
|
|
2616
|
+
function shutdownSignal(options = {}) {
|
|
2617
|
+
const controller = new AbortController;
|
|
2618
|
+
if (typeof process !== "undefined" && typeof process.on === "function") {
|
|
2619
|
+
for (const signal of options.signals ?? ["SIGTERM", "SIGINT"]) {
|
|
2620
|
+
process.on(signal, () => {
|
|
2621
|
+
controller.abort(new Error(`${signal} — finishing the current batch`));
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
return controller.signal;
|
|
2626
|
+
}
|
|
2442
2627
|
// src/webhooks.ts
|
|
2443
2628
|
import { verifySecondlayerSignatureValues } from "@secondlayer/shared/crypto/secondlayer-webhook";
|
|
2444
2629
|
import {
|
|
@@ -2599,6 +2784,7 @@ export {
|
|
|
2599
2784
|
verifySecondlayerSignature,
|
|
2600
2785
|
trigger,
|
|
2601
2786
|
toJsonSafe,
|
|
2787
|
+
shutdownSignal,
|
|
2602
2788
|
selectOffer,
|
|
2603
2789
|
resolveApiKey,
|
|
2604
2790
|
resolveAccountNonce,
|
|
@@ -2632,8 +2818,10 @@ export {
|
|
|
2632
2818
|
decodeFtBurn,
|
|
2633
2819
|
decodeClarityValue,
|
|
2634
2820
|
decodeChainWebhook,
|
|
2821
|
+
decode,
|
|
2635
2822
|
createX402Client,
|
|
2636
2823
|
createStreamsClient,
|
|
2824
|
+
consumerHealth,
|
|
2637
2825
|
consumeIndexFeed,
|
|
2638
2826
|
buildSignedX402Payment,
|
|
2639
2827
|
X402SpendGuardError,
|
|
@@ -2657,5 +2845,5 @@ export {
|
|
|
2657
2845
|
ApiError
|
|
2658
2846
|
};
|
|
2659
2847
|
|
|
2660
|
-
//# debugId=
|
|
2848
|
+
//# debugId=8D2C49296338C5CF64756E2164756E21
|
|
2661
2849
|
//# sourceMappingURL=index.js.map
|