@secondlayer/subgraphs 4.0.4 → 4.1.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/src/index.js +174 -8
- package/dist/src/index.js.map +5 -4
- package/dist/src/runtime/block-processor.js +174 -8
- package/dist/src/runtime/block-processor.js.map +5 -4
- package/dist/src/runtime/catchup.js +174 -8
- package/dist/src/runtime/catchup.js.map +5 -4
- package/dist/src/runtime/processor.js +178 -15
- package/dist/src/runtime/processor.js.map +6 -5
- package/dist/src/runtime/reindex.js +174 -8
- package/dist/src/runtime/reindex.js.map +5 -4
- package/dist/src/runtime/reorg.js +174 -8
- package/dist/src/runtime/reorg.js.map +5 -4
- package/dist/src/runtime/replay.js +174 -8
- package/dist/src/runtime/replay.js.map +5 -4
- package/dist/src/service.js +178 -15
- package/dist/src/service.js.map +6 -5
- package/package.json +2 -2
|
@@ -1668,7 +1668,7 @@ import { sql as sql3 } from "kysely";
|
|
|
1668
1668
|
// src/runtime/block-source.ts
|
|
1669
1669
|
import { getSourceDb as getSourceDb2 } from "@secondlayer/shared/db";
|
|
1670
1670
|
import {
|
|
1671
|
-
|
|
1671
|
+
createInternalIndexHttpClient
|
|
1672
1672
|
} from "@secondlayer/shared/index-http";
|
|
1673
1673
|
import { logger as logger4 } from "@secondlayer/shared/logger";
|
|
1674
1674
|
|
|
@@ -1714,6 +1714,167 @@ function avgEventsPerBlock(batch) {
|
|
|
1714
1714
|
return totalEvents / batch.size;
|
|
1715
1715
|
}
|
|
1716
1716
|
|
|
1717
|
+
// src/runtime/observer-http-source.ts
|
|
1718
|
+
var OBSERVER_HTTP_EXPORT_PATH = "/internal/observer-events";
|
|
1719
|
+
function stripTrailingSlash(url) {
|
|
1720
|
+
return url.replace(/\/+$/, "");
|
|
1721
|
+
}
|
|
1722
|
+
function blockTimestamp(payload) {
|
|
1723
|
+
for (const value of [
|
|
1724
|
+
payload.timestamp,
|
|
1725
|
+
payload.block_time,
|
|
1726
|
+
payload.burn_block_time,
|
|
1727
|
+
payload.burn_block_timestamp
|
|
1728
|
+
]) {
|
|
1729
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
1730
|
+
return value;
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
return 0;
|
|
1734
|
+
}
|
|
1735
|
+
function eventData(event) {
|
|
1736
|
+
if (typeof event.type === "string" && event.type in event) {
|
|
1737
|
+
return event[event.type] ?? {};
|
|
1738
|
+
}
|
|
1739
|
+
return {};
|
|
1740
|
+
}
|
|
1741
|
+
function mapNewBlockPayloadToBlockData(payload) {
|
|
1742
|
+
const p = payload;
|
|
1743
|
+
if (typeof p.block_height !== "number" || !Number.isFinite(p.block_height) || typeof p.index_block_hash !== "string" || p.index_block_hash.length === 0) {
|
|
1744
|
+
throw new Error("observer /new_block payload missing block_height or index_block_hash");
|
|
1745
|
+
}
|
|
1746
|
+
const height = p.block_height;
|
|
1747
|
+
const block = {
|
|
1748
|
+
height,
|
|
1749
|
+
hash: p.block_hash ?? "",
|
|
1750
|
+
parent_hash: p.parent_block_hash ?? "",
|
|
1751
|
+
burn_block_height: p.burn_block_height ?? 0,
|
|
1752
|
+
burn_block_hash: p.burn_block_hash ?? null,
|
|
1753
|
+
index_block_hash: p.index_block_hash,
|
|
1754
|
+
timestamp: blockTimestamp(p),
|
|
1755
|
+
canonical: true,
|
|
1756
|
+
created_at: new Date(0)
|
|
1757
|
+
};
|
|
1758
|
+
const txs = (p.transactions ?? []).map((tx) => {
|
|
1759
|
+
let contractId = null;
|
|
1760
|
+
let functionName = null;
|
|
1761
|
+
if (tx.tx_type === "contract_call" && tx.contract_call) {
|
|
1762
|
+
contractId = tx.contract_call.contract_id ?? null;
|
|
1763
|
+
functionName = tx.contract_call.function_name ?? null;
|
|
1764
|
+
} else if (tx.tx_type === "smart_contract" && tx.smart_contract) {
|
|
1765
|
+
contractId = tx.smart_contract.contract_id ?? null;
|
|
1766
|
+
}
|
|
1767
|
+
return {
|
|
1768
|
+
tx_id: tx.txid ?? "",
|
|
1769
|
+
block_height: height,
|
|
1770
|
+
tx_index: tx.tx_index ?? 0,
|
|
1771
|
+
type: tx.tx_type ?? "",
|
|
1772
|
+
sender: tx.sender_address ?? "",
|
|
1773
|
+
status: tx.status ?? "success",
|
|
1774
|
+
contract_id: contractId,
|
|
1775
|
+
function_name: functionName,
|
|
1776
|
+
function_args: [],
|
|
1777
|
+
raw_result: tx.raw_result ?? null,
|
|
1778
|
+
raw_tx: tx.raw_tx ?? "",
|
|
1779
|
+
created_at: new Date(0)
|
|
1780
|
+
};
|
|
1781
|
+
});
|
|
1782
|
+
const events = (p.events ?? []).map((event) => {
|
|
1783
|
+
const txId = event.txid ?? "";
|
|
1784
|
+
const eventIndex = event.event_index ?? 0;
|
|
1785
|
+
return {
|
|
1786
|
+
id: `${txId}#${eventIndex}`,
|
|
1787
|
+
tx_id: txId,
|
|
1788
|
+
block_height: height,
|
|
1789
|
+
event_index: eventIndex,
|
|
1790
|
+
type: event.type ?? "",
|
|
1791
|
+
data: eventData(event),
|
|
1792
|
+
created_at: new Date(0)
|
|
1793
|
+
};
|
|
1794
|
+
});
|
|
1795
|
+
return { block, txs, events };
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
class ObserverHttpBlockSource {
|
|
1799
|
+
baseUrl;
|
|
1800
|
+
token;
|
|
1801
|
+
fetchFn;
|
|
1802
|
+
constructor(opts) {
|
|
1803
|
+
this.baseUrl = stripTrailingSlash(opts.baseUrl);
|
|
1804
|
+
this.token = opts.token ?? null;
|
|
1805
|
+
this.fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
1806
|
+
}
|
|
1807
|
+
headers() {
|
|
1808
|
+
if (!this.token)
|
|
1809
|
+
return {};
|
|
1810
|
+
return { Authorization: `Bearer ${this.token}` };
|
|
1811
|
+
}
|
|
1812
|
+
async getTip() {
|
|
1813
|
+
const res = await this.fetchFn(`${this.baseUrl}${OBSERVER_HTTP_EXPORT_PATH}/tip`, { headers: this.headers() });
|
|
1814
|
+
if (!res.ok) {
|
|
1815
|
+
throw new Error(`observer tip HTTP ${res.status}: ${await res.text().catch(() => "")}`);
|
|
1816
|
+
}
|
|
1817
|
+
let body;
|
|
1818
|
+
try {
|
|
1819
|
+
body = await res.json();
|
|
1820
|
+
} catch (err) {
|
|
1821
|
+
throw new Error(`observer tip invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
1822
|
+
}
|
|
1823
|
+
if (typeof body.block_height !== "number" || !Number.isFinite(body.block_height)) {
|
|
1824
|
+
throw new Error("observer tip missing block_height");
|
|
1825
|
+
}
|
|
1826
|
+
return body.block_height;
|
|
1827
|
+
}
|
|
1828
|
+
async loadBlockRange(fromHeight, toHeight) {
|
|
1829
|
+
const result = new Map;
|
|
1830
|
+
let afterHeight = fromHeight > 0 ? fromHeight - 1 : undefined;
|
|
1831
|
+
let afterIndexBlockHash;
|
|
1832
|
+
for (;; ) {
|
|
1833
|
+
const url = new URL(`${this.baseUrl}${OBSERVER_HTTP_EXPORT_PATH}`);
|
|
1834
|
+
url.searchParams.set("path", "/new_block");
|
|
1835
|
+
url.searchParams.set("limit", "100");
|
|
1836
|
+
if (afterHeight != null) {
|
|
1837
|
+
url.searchParams.set("after_height", String(afterHeight));
|
|
1838
|
+
}
|
|
1839
|
+
if (afterIndexBlockHash) {
|
|
1840
|
+
url.searchParams.set("after_index_block_hash", afterIndexBlockHash);
|
|
1841
|
+
}
|
|
1842
|
+
const res = await this.fetchFn(url.toString(), {
|
|
1843
|
+
headers: this.headers()
|
|
1844
|
+
});
|
|
1845
|
+
if (!res.ok) {
|
|
1846
|
+
throw new Error(`observer events HTTP ${res.status}: ${await res.text().catch(() => "")}`);
|
|
1847
|
+
}
|
|
1848
|
+
let body;
|
|
1849
|
+
try {
|
|
1850
|
+
body = await res.json();
|
|
1851
|
+
} catch (err) {
|
|
1852
|
+
throw new Error(`observer events invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
1853
|
+
}
|
|
1854
|
+
let pastTo = false;
|
|
1855
|
+
for (const message of body.events ?? []) {
|
|
1856
|
+
if (message.path === "/new_burn_block")
|
|
1857
|
+
continue;
|
|
1858
|
+
const height = message.payload?.block_height;
|
|
1859
|
+
if (typeof height === "number" && height > toHeight) {
|
|
1860
|
+
pastTo = true;
|
|
1861
|
+
break;
|
|
1862
|
+
}
|
|
1863
|
+
const data = mapNewBlockPayloadToBlockData(message.payload);
|
|
1864
|
+
const h = data.block.height;
|
|
1865
|
+
if (h >= fromHeight && h <= toHeight) {
|
|
1866
|
+
result.set(h, data);
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
if (pastTo || body.next == null)
|
|
1870
|
+
break;
|
|
1871
|
+
afterHeight = body.next.after_height;
|
|
1872
|
+
afterIndexBlockHash = body.next.after_index_block_hash;
|
|
1873
|
+
}
|
|
1874
|
+
return result;
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1717
1878
|
// src/runtime/reconstruct.ts
|
|
1718
1879
|
function isoToUnixSeconds(iso) {
|
|
1719
1880
|
if (!iso)
|
|
@@ -2024,14 +2185,19 @@ class FallbackBlockSource {
|
|
|
2024
2185
|
}
|
|
2025
2186
|
var postgresBlockSource = new PostgresBlockSource;
|
|
2026
2187
|
function buildHttpClient() {
|
|
2027
|
-
|
|
2028
|
-
return new IndexHttpClient({
|
|
2029
|
-
indexBaseUrl: baseUrl,
|
|
2030
|
-
streamsBaseUrl: baseUrl,
|
|
2031
|
-
streamsApiKey: process.env.STREAMS_INTERNAL_API_KEY ?? "sk-sl_streams_decode_internal"
|
|
2032
|
-
});
|
|
2188
|
+
return createInternalIndexHttpClient();
|
|
2033
2189
|
}
|
|
2034
2190
|
function resolveBlockSource(subgraph) {
|
|
2191
|
+
if (process.env.SUBGRAPH_SOURCE === "observer-http") {
|
|
2192
|
+
const baseUrl = process.env.OBSERVER_HTTP_URL;
|
|
2193
|
+
if (!baseUrl) {
|
|
2194
|
+
throw new Error("SUBGRAPH_SOURCE=observer-http requires OBSERVER_HTTP_URL");
|
|
2195
|
+
}
|
|
2196
|
+
return new ObserverHttpBlockSource({
|
|
2197
|
+
baseUrl,
|
|
2198
|
+
token: process.env.OBSERVER_HTTP_EXPORT_TOKEN || null
|
|
2199
|
+
});
|
|
2200
|
+
}
|
|
2035
2201
|
if (process.env.SUBGRAPH_SOURCE === "streams-index" && subgraph && isStreamsIndexEligible(subgraph)) {
|
|
2036
2202
|
return new FallbackBlockSource(new PublicApiBlockSource(buildHttpClient(), referencedIndexEventTypes(subgraph), canSparseScan(subgraph) ? sparseProbeTargets(subgraph) : undefined, needsTransactionData(subgraph)), postgresBlockSource);
|
|
2037
2203
|
}
|
|
@@ -3980,7 +4146,9 @@ import {
|
|
|
3980
4146
|
|
|
3981
4147
|
// src/runtime/streams-reorg-poll.ts
|
|
3982
4148
|
import { getErrorMessage as getErrorMessage5 } from "@secondlayer/shared";
|
|
3983
|
-
import {
|
|
4149
|
+
import {
|
|
4150
|
+
createInternalIndexHttpClient as createInternalIndexHttpClient2
|
|
4151
|
+
} from "@secondlayer/shared/index-http";
|
|
3984
4152
|
import { logger as logger12 } from "@secondlayer/shared/logger";
|
|
3985
4153
|
var POLL_MS = Number(process.env.SUBGRAPH_REORG_POLL_MS) || 15000;
|
|
3986
4154
|
var STARTUP_MARGIN_MS = 60 * 60 * 1000;
|
|
@@ -4005,12 +4173,7 @@ async function pollReorgsOnce(http2, cursor, onReorg, handled) {
|
|
|
4005
4173
|
return next_since ?? cursor;
|
|
4006
4174
|
}
|
|
4007
4175
|
function startStreamsReorgPoll(onReorg) {
|
|
4008
|
-
const
|
|
4009
|
-
const http2 = new IndexHttpClient2({
|
|
4010
|
-
indexBaseUrl: baseUrl,
|
|
4011
|
-
streamsBaseUrl: baseUrl,
|
|
4012
|
-
streamsApiKey: process.env.STREAMS_INTERNAL_API_KEY ?? "sk-sl_streams_decode_internal"
|
|
4013
|
-
});
|
|
4176
|
+
const http2 = createInternalIndexHttpClient2();
|
|
4014
4177
|
let since = new Date(Date.now() - STARTUP_MARGIN_MS).toISOString();
|
|
4015
4178
|
let running = true;
|
|
4016
4179
|
let timer;
|
|
@@ -4392,5 +4555,5 @@ export {
|
|
|
4392
4555
|
startSubgraphOperationRunner
|
|
4393
4556
|
};
|
|
4394
4557
|
|
|
4395
|
-
//# debugId=
|
|
4558
|
+
//# debugId=DC53F813C2D7B5F564756E2164756E21
|
|
4396
4559
|
//# sourceMappingURL=processor.js.map
|