@secondlayer/subgraphs 7.1.0 → 7.3.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 +16 -2
- package/dist/index.js +198 -128
- package/dist/index.js.map +7 -7
- package/dist/runtime/replay.js +279 -26
- package/dist/runtime/replay.js.map +10 -8
- package/dist/schema/index.d.ts +6 -0
- package/dist/schema/index.js +6 -4
- package/dist/schema/index.js.map +3 -3
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/index.js +1738 -1631
- package/dist/testing/index.js.map +9 -9
- package/dist/types.d.ts +6 -0
- package/dist/validate.d.ts +6 -0
- package/dist/validate.js +3 -1
- package/dist/validate.js.map +3 -3
- package/dist/verification.d.ts +6 -0
- package/dist/verification.js +4 -4
- package/dist/verification.js.map +1 -1
- package/dist/verify/index.d.ts +6 -0
- package/dist/verify/index.js +138 -41
- package/dist/verify/index.js.map +6 -6
- package/package.json +3 -3
package/dist/runtime/replay.js
CHANGED
|
@@ -17,7 +17,7 @@ import { createHash } from "node:crypto";
|
|
|
17
17
|
// package.json
|
|
18
18
|
var package_default = {
|
|
19
19
|
name: "@secondlayer/subgraphs",
|
|
20
|
-
version: "7.
|
|
20
|
+
version: "7.3.0",
|
|
21
21
|
description: "Describe the Stacks data you want as one TypeScript file; it fills itself and survives reorgs.",
|
|
22
22
|
license: "MIT",
|
|
23
23
|
repository: {
|
|
@@ -77,8 +77,8 @@ var package_default = {
|
|
|
77
77
|
prepublishOnly: "bun run build"
|
|
78
78
|
},
|
|
79
79
|
dependencies: {
|
|
80
|
-
"@secondlayer/shared": "^13.
|
|
81
|
-
"@secondlayer/stacks": "^6.
|
|
80
|
+
"@secondlayer/shared": "^13.2.0",
|
|
81
|
+
"@secondlayer/stacks": "^6.4.0",
|
|
82
82
|
"@secondlayer/verify": "^0.6.0",
|
|
83
83
|
esbuild: "^0.28.2",
|
|
84
84
|
kysely: "0.28.17",
|
|
@@ -1134,13 +1134,199 @@ function buildHttpClient() {
|
|
|
1134
1134
|
return createInternalIndexHttpClient();
|
|
1135
1135
|
}
|
|
1136
1136
|
|
|
1137
|
-
// src/runtime/
|
|
1138
|
-
import { getSourceDb as
|
|
1137
|
+
// src/runtime/chain-data-reader.ts
|
|
1138
|
+
import { getSourceDb as getSourceDb2 } from "@secondlayer/shared/db";
|
|
1139
1139
|
import { resolveTraitContractIds } from "@secondlayer/shared/db/queries/contracts";
|
|
1140
|
+
import { hasNoLocalChain } from "@secondlayer/shared/db/queries/instance";
|
|
1141
|
+
function databaseChainDataReader(db) {
|
|
1142
|
+
return {
|
|
1143
|
+
async sbtcEvents(fromHeight, toHeight, topics) {
|
|
1144
|
+
if (topics.length === 0)
|
|
1145
|
+
return [];
|
|
1146
|
+
return db.selectFrom("sbtc_events").selectAll().where("block_height", ">=", fromHeight).where("block_height", "<=", toHeight).where("canonical", "=", true).where("topic", "in", [...topics]).orderBy("block_height").orderBy("event_index").execute();
|
|
1147
|
+
},
|
|
1148
|
+
traitContractIds(trait, asOfBlock) {
|
|
1149
|
+
return resolveTraitContractIds(db, trait, asOfBlock);
|
|
1150
|
+
},
|
|
1151
|
+
settlementsConfirmedAfter(after) {
|
|
1152
|
+
return db.selectFrom("sbtc_settlements as s").innerJoin("sbtc_events as e", (join) => join.onRef("e.sweep_txid", "=", "s.sweep_txid").on("e.topic", "=", "withdrawal-accept").on("e.canonical", "=", true)).innerJoin("blocks as b", (join) => join.onRef("b.height", "=", "e.block_height").on("b.canonical", "=", true)).where("s.settlement_confirmed", "=", true).where("s.confirmed_at", ">", after).select([
|
|
1153
|
+
"s.sweep_txid",
|
|
1154
|
+
"s.request_id",
|
|
1155
|
+
"s.btc_confirmations",
|
|
1156
|
+
"s.block_height as btc_block_height",
|
|
1157
|
+
"s.confirmed_at",
|
|
1158
|
+
"e.tx_id",
|
|
1159
|
+
"e.block_height as stacks_block_height",
|
|
1160
|
+
"e.amount",
|
|
1161
|
+
"e.sender",
|
|
1162
|
+
"b.hash as block_hash",
|
|
1163
|
+
"b.timestamp as block_timestamp"
|
|
1164
|
+
]).execute();
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
var THROUGH_TIP = Number.MAX_SAFE_INTEGER;
|
|
1169
|
+
var TRAIT_REFRESH_MS = 5000;
|
|
1170
|
+
var TRAIT_OVERLAP_MS = 5 * 60000;
|
|
1171
|
+
var traitCaches = new WeakMap;
|
|
1172
|
+
function traitCacheFor(client) {
|
|
1173
|
+
let cache = traitCaches.get(client);
|
|
1174
|
+
if (!cache) {
|
|
1175
|
+
cache = new Map;
|
|
1176
|
+
traitCaches.set(client, cache);
|
|
1177
|
+
}
|
|
1178
|
+
return cache;
|
|
1179
|
+
}
|
|
1180
|
+
function toSbtcEventRow(e) {
|
|
1181
|
+
return {
|
|
1182
|
+
topic: e.topic,
|
|
1183
|
+
sender: e.sender,
|
|
1184
|
+
bitcoin_txid: e.bitcoin_txid,
|
|
1185
|
+
request_id: e.request_id === null ? null : String(e.request_id),
|
|
1186
|
+
amount: e.amount,
|
|
1187
|
+
sweep_txid: e.sweep_txid,
|
|
1188
|
+
block_height: String(e.block_height),
|
|
1189
|
+
tx_id: e.tx_id,
|
|
1190
|
+
event_index: e.event_index
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
function oneWithdrawalPerSweep(rows) {
|
|
1194
|
+
const bySweep = new Map;
|
|
1195
|
+
for (const row of rows) {
|
|
1196
|
+
if (!row.sweep_txid || !row.confirmed_at)
|
|
1197
|
+
continue;
|
|
1198
|
+
const seen = bySweep.get(row.sweep_txid);
|
|
1199
|
+
if (!seen || row.request_id < seen.request_id) {
|
|
1200
|
+
bySweep.set(row.sweep_txid, row);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return [...bySweep.values()];
|
|
1204
|
+
}
|
|
1205
|
+
function hostedChainDataReader(client, opts = {}) {
|
|
1206
|
+
const now = opts.now ?? Date.now;
|
|
1207
|
+
return {
|
|
1208
|
+
async sbtcEvents(fromHeight, toHeight, topics) {
|
|
1209
|
+
if (topics.length === 0)
|
|
1210
|
+
return [];
|
|
1211
|
+
const rows = await client.fetchSbtcEvents(fromHeight, toHeight, topics);
|
|
1212
|
+
return rows.map(toSbtcEventRow);
|
|
1213
|
+
},
|
|
1214
|
+
async traitContractIds(trait, asOfBlock) {
|
|
1215
|
+
const cache = traitCacheFor(client);
|
|
1216
|
+
let entry = cache.get(trait);
|
|
1217
|
+
const due = !entry || asOfBlock > entry.checkedThrough && now() - entry.fetchedAt >= TRAIT_REFRESH_MS;
|
|
1218
|
+
if (due) {
|
|
1219
|
+
const since = entry?.classifiedThrough == null ? undefined : new Date(entry.classifiedThrough - TRAIT_OVERLAP_MS);
|
|
1220
|
+
const rows = await client.listContractsByTrait(trait, since ? { classifiedAfter: since } : undefined);
|
|
1221
|
+
const members = entry?.members ?? new Map;
|
|
1222
|
+
let classifiedThrough = entry?.classifiedThrough ?? null;
|
|
1223
|
+
for (const r of rows) {
|
|
1224
|
+
members.set(r.contract_id, Number(r.block_height));
|
|
1225
|
+
if (r.classified_at) {
|
|
1226
|
+
classifiedThrough = Math.max(classifiedThrough ?? 0, new Date(r.classified_at).getTime());
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
entry = {
|
|
1230
|
+
members,
|
|
1231
|
+
classifiedThrough,
|
|
1232
|
+
checkedThrough: asOfBlock,
|
|
1233
|
+
fetchedAt: now()
|
|
1234
|
+
};
|
|
1235
|
+
cache.set(trait, entry);
|
|
1236
|
+
}
|
|
1237
|
+
if (!entry)
|
|
1238
|
+
return [];
|
|
1239
|
+
const ids = [];
|
|
1240
|
+
for (const [contractId, height] of entry.members) {
|
|
1241
|
+
if (height <= asOfBlock)
|
|
1242
|
+
ids.push(contractId);
|
|
1243
|
+
}
|
|
1244
|
+
return ids;
|
|
1245
|
+
},
|
|
1246
|
+
async settlementsConfirmedAfter(after) {
|
|
1247
|
+
const withdrawals = oneWithdrawalPerSweep(await client.fetchSettledWithdrawals(after));
|
|
1248
|
+
const out = [];
|
|
1249
|
+
for (const w of withdrawals) {
|
|
1250
|
+
const accepts = await client.fetchSbtcEvents(0, THROUGH_TIP, ["withdrawal-accept"], { requestId: w.request_id });
|
|
1251
|
+
const accept = accepts.filter((e) => e.sweep_txid === w.sweep_txid).at(-1);
|
|
1252
|
+
if (!accept)
|
|
1253
|
+
continue;
|
|
1254
|
+
const [block] = await client.walkBlocks(accept.block_height, accept.block_height);
|
|
1255
|
+
if (!block)
|
|
1256
|
+
continue;
|
|
1257
|
+
out.push({
|
|
1258
|
+
sweep_txid: w.sweep_txid,
|
|
1259
|
+
request_id: w.request_id,
|
|
1260
|
+
btc_confirmations: w.btc_confirmations ?? 0,
|
|
1261
|
+
btc_block_height: w.btc_block_height,
|
|
1262
|
+
confirmed_at: new Date(w.confirmed_at),
|
|
1263
|
+
tx_id: accept.tx_id,
|
|
1264
|
+
stacks_block_height: accept.block_height,
|
|
1265
|
+
amount: accept.amount,
|
|
1266
|
+
sender: accept.sender,
|
|
1267
|
+
block_hash: block.block_hash,
|
|
1268
|
+
block_timestamp: isoToUnixSeconds(block.block_time)
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
return out;
|
|
1272
|
+
}
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
function chainDataReader(opts) {
|
|
1276
|
+
let resolved;
|
|
1277
|
+
const reader = () => {
|
|
1278
|
+
resolved ??= (async () => {
|
|
1279
|
+
const localDb = opts?.localDb ?? getSourceDb2();
|
|
1280
|
+
if (await hasNoLocalChain(getSourceDb2())) {
|
|
1281
|
+
return hostedChainDataReader(opts?.httpClient ?? sharedHttpClient());
|
|
1282
|
+
}
|
|
1283
|
+
return databaseChainDataReader(localDb);
|
|
1284
|
+
})();
|
|
1285
|
+
return resolved;
|
|
1286
|
+
};
|
|
1287
|
+
return {
|
|
1288
|
+
sbtcEvents: async (...args) => (await reader()).sbtcEvents(...args),
|
|
1289
|
+
traitContractIds: async (...args) => (await reader()).traitContractIds(...args),
|
|
1290
|
+
settlementsConfirmedAfter: async (...args) => (await reader()).settlementsConfirmedAfter(...args)
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
var processHttpClient;
|
|
1294
|
+
function sharedHttpClient() {
|
|
1295
|
+
processHttpClient ??= buildHttpClient();
|
|
1296
|
+
return processHttpClient;
|
|
1297
|
+
}
|
|
1140
1298
|
|
|
1141
1299
|
// src/runtime/decoder-bound.ts
|
|
1142
1300
|
import { committedHeight } from "@secondlayer/shared";
|
|
1143
|
-
import { getSourceDb as
|
|
1301
|
+
import { getSourceDb as getSourceDb3 } from "@secondlayer/shared/db";
|
|
1302
|
+
|
|
1303
|
+
// src/runtime/clarity.ts
|
|
1304
|
+
import { cvToValue, deserializeCV } from "@secondlayer/stacks/clarity";
|
|
1305
|
+
function decodeClarityValue(hex) {
|
|
1306
|
+
try {
|
|
1307
|
+
const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
1308
|
+
const cv = deserializeCV(cleanHex);
|
|
1309
|
+
return cvToValue(cv);
|
|
1310
|
+
} catch {
|
|
1311
|
+
return hex;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
function decodeEventData(data) {
|
|
1315
|
+
if (typeof data === "string" && data.startsWith("0x") && data.length > 10) {
|
|
1316
|
+
return decodeClarityValue(data);
|
|
1317
|
+
}
|
|
1318
|
+
if (Array.isArray(data)) {
|
|
1319
|
+
return data.map(decodeEventData);
|
|
1320
|
+
}
|
|
1321
|
+
if (typeof data === "object" && data !== null) {
|
|
1322
|
+
const decoded = {};
|
|
1323
|
+
for (const [key, value] of Object.entries(data)) {
|
|
1324
|
+
decoded[key] = decodeEventData(value);
|
|
1325
|
+
}
|
|
1326
|
+
return decoded;
|
|
1327
|
+
}
|
|
1328
|
+
return data;
|
|
1329
|
+
}
|
|
1144
1330
|
|
|
1145
1331
|
// src/runtime/source-matcher.ts
|
|
1146
1332
|
var patternCache = new Map;
|
|
@@ -1183,6 +1369,41 @@ function printContractId(data) {
|
|
|
1183
1369
|
const id = (typeof data.contract_identifier === "string" ? data.contract_identifier : undefined) ?? (typeof data.contract_id === "string" ? data.contract_id : undefined);
|
|
1184
1370
|
return id || undefined;
|
|
1185
1371
|
}
|
|
1372
|
+
var decodedPrints = new WeakMap;
|
|
1373
|
+
function decodedPrintTuple(event, data) {
|
|
1374
|
+
if (decodedPrints.has(event))
|
|
1375
|
+
return decodedPrints.get(event) ?? null;
|
|
1376
|
+
const raw = data.raw_value;
|
|
1377
|
+
const value = typeof raw === "string" && raw.startsWith("0x") ? decodeClarityValue(raw) : null;
|
|
1378
|
+
const tuple = value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
1379
|
+
decodedPrints.set(event, tuple);
|
|
1380
|
+
return tuple;
|
|
1381
|
+
}
|
|
1382
|
+
function printFieldEquals(decoded, key, expected) {
|
|
1383
|
+
const value = decoded[key];
|
|
1384
|
+
let actual;
|
|
1385
|
+
if (typeof value === "string")
|
|
1386
|
+
actual = value;
|
|
1387
|
+
else if (typeof value === "bigint" || typeof value === "boolean")
|
|
1388
|
+
actual = String(value);
|
|
1389
|
+
else
|
|
1390
|
+
return false;
|
|
1391
|
+
return typeof expected === "string" ? actual === expected : expected.includes(actual);
|
|
1392
|
+
}
|
|
1393
|
+
function printFieldsAllow(filter, event, data) {
|
|
1394
|
+
if (!filter.topic && !filter.where)
|
|
1395
|
+
return true;
|
|
1396
|
+
const decoded = decodedPrintTuple(event, data);
|
|
1397
|
+
if (!decoded)
|
|
1398
|
+
return false;
|
|
1399
|
+
if (filter.topic && !printFieldEquals(decoded, "topic", filter.topic))
|
|
1400
|
+
return false;
|
|
1401
|
+
for (const [key, expected] of Object.entries(filter.where ?? {})) {
|
|
1402
|
+
if (!printFieldEquals(decoded, key, expected))
|
|
1403
|
+
return false;
|
|
1404
|
+
}
|
|
1405
|
+
return true;
|
|
1406
|
+
}
|
|
1186
1407
|
function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryContracts = new Map, vmEventsByTx = new Map) {
|
|
1187
1408
|
const results = [];
|
|
1188
1409
|
switch (filter.type) {
|
|
@@ -1419,7 +1640,7 @@ function matchFilter(filter, transactions, eventsByTx, traitContracts, factoryCo
|
|
|
1419
1640
|
return false;
|
|
1420
1641
|
if (!factoryAllows(filter, contractId, factoryContracts))
|
|
1421
1642
|
return false;
|
|
1422
|
-
return
|
|
1643
|
+
return printFieldsAllow(filter, e, data);
|
|
1423
1644
|
});
|
|
1424
1645
|
if (matched.length > 0) {
|
|
1425
1646
|
results.push({ tx, events: matched });
|
|
@@ -1539,11 +1760,21 @@ function referencedTraits(chainSubs) {
|
|
|
1539
1760
|
}
|
|
1540
1761
|
return [...traits];
|
|
1541
1762
|
}
|
|
1763
|
+
function readerFor(opts) {
|
|
1764
|
+
if (opts?.reader)
|
|
1765
|
+
return opts.reader;
|
|
1766
|
+
if (opts?.sourceDb)
|
|
1767
|
+
return databaseChainDataReader(opts.sourceDb);
|
|
1768
|
+
return chainDataReader();
|
|
1769
|
+
}
|
|
1542
1770
|
async function buildTraitContracts(chainSubs, asOfBlock, opts) {
|
|
1543
|
-
const
|
|
1771
|
+
const traits = referencedTraits(chainSubs);
|
|
1772
|
+
if (traits.length === 0)
|
|
1773
|
+
return new Map;
|
|
1774
|
+
const reader = readerFor(opts);
|
|
1544
1775
|
const resolved = new Map;
|
|
1545
|
-
for (const trait of
|
|
1546
|
-
const ids = await
|
|
1776
|
+
for (const trait of traits) {
|
|
1777
|
+
const ids = await reader.traitContractIds(trait, asOfBlock);
|
|
1547
1778
|
resolved.set(trait, new Set(ids));
|
|
1548
1779
|
}
|
|
1549
1780
|
return resolved;
|
|
@@ -1626,10 +1857,35 @@ async function emitChainOutbox(db, matches, keyMeta, blockHeight, blockHash, blo
|
|
|
1626
1857
|
const result = await db.insertInto("webhook_outbox").values(rows).onConflict((oc) => oc.columns(["webhook_id", "dedup_key"]).doNothing()).executeTakeFirst();
|
|
1627
1858
|
return Number(result.numInsertedOrUpdatedRows ?? 0);
|
|
1628
1859
|
}
|
|
1629
|
-
|
|
1860
|
+
function sbtcSubsOf(chainSubs) {
|
|
1861
|
+
return chainSubs.filter((sub) => triggersOf(sub).some((t) => isSbtcTriggerType(t.type)));
|
|
1862
|
+
}
|
|
1863
|
+
function sbtcTopicsOf(sbtcSubs) {
|
|
1864
|
+
const topics = new Set;
|
|
1865
|
+
for (const sub of sbtcSubs) {
|
|
1866
|
+
for (const trigger of triggersOf(sub)) {
|
|
1867
|
+
const topic = SBTC_TRIGGER_TO_TOPIC[trigger.type];
|
|
1868
|
+
if (topic)
|
|
1869
|
+
topics.add(topic);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
return [...topics];
|
|
1873
|
+
}
|
|
1874
|
+
async function loadSbtcEventsForRange(chainSubs, fromHeight, toHeight, opts) {
|
|
1875
|
+
const byHeight = new Map;
|
|
1876
|
+
const topics = sbtcTopicsOf(sbtcSubsOf(chainSubs));
|
|
1630
1877
|
if (topics.length === 0)
|
|
1631
|
-
return
|
|
1632
|
-
|
|
1878
|
+
return byHeight;
|
|
1879
|
+
const rows = await readerFor(opts).sbtcEvents(fromHeight, toHeight, topics);
|
|
1880
|
+
for (const row of rows) {
|
|
1881
|
+
const height = Number(row.block_height);
|
|
1882
|
+
const list = byHeight.get(height);
|
|
1883
|
+
if (list)
|
|
1884
|
+
list.push(row);
|
|
1885
|
+
else
|
|
1886
|
+
byHeight.set(height, [row]);
|
|
1887
|
+
}
|
|
1888
|
+
return byHeight;
|
|
1633
1889
|
}
|
|
1634
1890
|
function toAmountBigInt(v) {
|
|
1635
1891
|
return v === undefined ? undefined : BigInt(v);
|
|
@@ -1714,18 +1970,10 @@ function buildSbtcEventPayload(triggerType, row) {
|
|
|
1714
1970
|
};
|
|
1715
1971
|
}
|
|
1716
1972
|
async function emitSbtcOutbox(db, chainSubs, blockHeight, blockHash, blockTime, opts) {
|
|
1717
|
-
const sbtcSubs = chainSubs
|
|
1973
|
+
const sbtcSubs = sbtcSubsOf(chainSubs);
|
|
1718
1974
|
if (sbtcSubs.length === 0)
|
|
1719
1975
|
return 0;
|
|
1720
|
-
const
|
|
1721
|
-
for (const sub of sbtcSubs) {
|
|
1722
|
-
for (const trigger of triggersOf(sub)) {
|
|
1723
|
-
const topic = SBTC_TRIGGER_TO_TOPIC[trigger.type];
|
|
1724
|
-
if (topic)
|
|
1725
|
-
neededTopics.add(topic);
|
|
1726
|
-
}
|
|
1727
|
-
}
|
|
1728
|
-
const sbtcRows = await loadSbtcEventsForBlock(opts?.sourceDb ?? getSourceDb3(), blockHeight, [...neededTopics]);
|
|
1976
|
+
const sbtcRows = opts?.rows ?? (await loadSbtcEventsForRange(sbtcSubs, blockHeight, blockHeight, opts)).get(blockHeight) ?? [];
|
|
1729
1977
|
if (sbtcRows.length === 0)
|
|
1730
1978
|
return 0;
|
|
1731
1979
|
const replayId = opts?.replayId;
|
|
@@ -1810,12 +2058,16 @@ async function replayChainWebhook(db, sub, input, opts) {
|
|
|
1810
2058
|
const replayId = deterministicReplayId(sub.id, input.fromBlock, input.toBlock, input.replayIdSuffix);
|
|
1811
2059
|
const { sources, keyMeta } = buildSourcesMap([sub]);
|
|
1812
2060
|
const source = opts?.source ?? new PublicApiBlockSource(buildHttpClient(), referencedEventTypes([sub]));
|
|
2061
|
+
const reader = chainDataReader();
|
|
1813
2062
|
let scanned = 0;
|
|
1814
2063
|
let enqueued = 0;
|
|
1815
2064
|
for (let from = input.fromBlock;from <= input.toBlock; from += CHAIN_REPLAY_BATCH) {
|
|
1816
2065
|
const to = Math.min(from + CHAIN_REPLAY_BATCH - 1, input.toBlock);
|
|
1817
2066
|
const blocks = await source.loadBlockRange(from, to);
|
|
1818
|
-
const traitContracts = await buildTraitContracts([sub], to);
|
|
2067
|
+
const traitContracts = await buildTraitContracts([sub], to, { reader });
|
|
2068
|
+
const sbtcByHeight = await loadSbtcEventsForRange([sub], from, to, {
|
|
2069
|
+
reader
|
|
2070
|
+
});
|
|
1819
2071
|
for (let h = from;h <= to; h++) {
|
|
1820
2072
|
const bd = blocks.get(h);
|
|
1821
2073
|
if (!bd)
|
|
@@ -1829,7 +2081,8 @@ async function replayChainWebhook(db, sub, input, opts) {
|
|
|
1829
2081
|
});
|
|
1830
2082
|
}
|
|
1831
2083
|
enqueued += await emitSbtcOutbox(db, [sub], h, bd.block.hash, blockTime, {
|
|
1832
|
-
replayId
|
|
2084
|
+
replayId,
|
|
2085
|
+
rows: sbtcByHeight.get(h) ?? []
|
|
1833
2086
|
});
|
|
1834
2087
|
}
|
|
1835
2088
|
}
|
|
@@ -1850,5 +2103,5 @@ export {
|
|
|
1850
2103
|
replayWebhook
|
|
1851
2104
|
};
|
|
1852
2105
|
|
|
1853
|
-
//# debugId=
|
|
2106
|
+
//# debugId=E8EBA7C326C2348864756E2164756E21
|
|
1854
2107
|
//# sourceMappingURL=replay.js.map
|