@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
package/dist/src/index.js
CHANGED
|
@@ -1883,7 +1883,7 @@ import { sql as sql3 } from "kysely";
|
|
|
1883
1883
|
// src/runtime/block-source.ts
|
|
1884
1884
|
import { getSourceDb as getSourceDb2 } from "@secondlayer/shared/db";
|
|
1885
1885
|
import {
|
|
1886
|
-
|
|
1886
|
+
createInternalIndexHttpClient
|
|
1887
1887
|
} from "@secondlayer/shared/index-http";
|
|
1888
1888
|
import { logger as logger4 } from "@secondlayer/shared/logger";
|
|
1889
1889
|
|
|
@@ -1929,6 +1929,167 @@ function avgEventsPerBlock(batch) {
|
|
|
1929
1929
|
return totalEvents / batch.size;
|
|
1930
1930
|
}
|
|
1931
1931
|
|
|
1932
|
+
// src/runtime/observer-http-source.ts
|
|
1933
|
+
var OBSERVER_HTTP_EXPORT_PATH = "/internal/observer-events";
|
|
1934
|
+
function stripTrailingSlash(url) {
|
|
1935
|
+
return url.replace(/\/+$/, "");
|
|
1936
|
+
}
|
|
1937
|
+
function blockTimestamp(payload) {
|
|
1938
|
+
for (const value of [
|
|
1939
|
+
payload.timestamp,
|
|
1940
|
+
payload.block_time,
|
|
1941
|
+
payload.burn_block_time,
|
|
1942
|
+
payload.burn_block_timestamp
|
|
1943
|
+
]) {
|
|
1944
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
1945
|
+
return value;
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
return 0;
|
|
1949
|
+
}
|
|
1950
|
+
function eventData(event) {
|
|
1951
|
+
if (typeof event.type === "string" && event.type in event) {
|
|
1952
|
+
return event[event.type] ?? {};
|
|
1953
|
+
}
|
|
1954
|
+
return {};
|
|
1955
|
+
}
|
|
1956
|
+
function mapNewBlockPayloadToBlockData(payload) {
|
|
1957
|
+
const p = payload;
|
|
1958
|
+
if (typeof p.block_height !== "number" || !Number.isFinite(p.block_height) || typeof p.index_block_hash !== "string" || p.index_block_hash.length === 0) {
|
|
1959
|
+
throw new Error("observer /new_block payload missing block_height or index_block_hash");
|
|
1960
|
+
}
|
|
1961
|
+
const height = p.block_height;
|
|
1962
|
+
const block = {
|
|
1963
|
+
height,
|
|
1964
|
+
hash: p.block_hash ?? "",
|
|
1965
|
+
parent_hash: p.parent_block_hash ?? "",
|
|
1966
|
+
burn_block_height: p.burn_block_height ?? 0,
|
|
1967
|
+
burn_block_hash: p.burn_block_hash ?? null,
|
|
1968
|
+
index_block_hash: p.index_block_hash,
|
|
1969
|
+
timestamp: blockTimestamp(p),
|
|
1970
|
+
canonical: true,
|
|
1971
|
+
created_at: new Date(0)
|
|
1972
|
+
};
|
|
1973
|
+
const txs = (p.transactions ?? []).map((tx) => {
|
|
1974
|
+
let contractId = null;
|
|
1975
|
+
let functionName = null;
|
|
1976
|
+
if (tx.tx_type === "contract_call" && tx.contract_call) {
|
|
1977
|
+
contractId = tx.contract_call.contract_id ?? null;
|
|
1978
|
+
functionName = tx.contract_call.function_name ?? null;
|
|
1979
|
+
} else if (tx.tx_type === "smart_contract" && tx.smart_contract) {
|
|
1980
|
+
contractId = tx.smart_contract.contract_id ?? null;
|
|
1981
|
+
}
|
|
1982
|
+
return {
|
|
1983
|
+
tx_id: tx.txid ?? "",
|
|
1984
|
+
block_height: height,
|
|
1985
|
+
tx_index: tx.tx_index ?? 0,
|
|
1986
|
+
type: tx.tx_type ?? "",
|
|
1987
|
+
sender: tx.sender_address ?? "",
|
|
1988
|
+
status: tx.status ?? "success",
|
|
1989
|
+
contract_id: contractId,
|
|
1990
|
+
function_name: functionName,
|
|
1991
|
+
function_args: [],
|
|
1992
|
+
raw_result: tx.raw_result ?? null,
|
|
1993
|
+
raw_tx: tx.raw_tx ?? "",
|
|
1994
|
+
created_at: new Date(0)
|
|
1995
|
+
};
|
|
1996
|
+
});
|
|
1997
|
+
const events = (p.events ?? []).map((event) => {
|
|
1998
|
+
const txId = event.txid ?? "";
|
|
1999
|
+
const eventIndex = event.event_index ?? 0;
|
|
2000
|
+
return {
|
|
2001
|
+
id: `${txId}#${eventIndex}`,
|
|
2002
|
+
tx_id: txId,
|
|
2003
|
+
block_height: height,
|
|
2004
|
+
event_index: eventIndex,
|
|
2005
|
+
type: event.type ?? "",
|
|
2006
|
+
data: eventData(event),
|
|
2007
|
+
created_at: new Date(0)
|
|
2008
|
+
};
|
|
2009
|
+
});
|
|
2010
|
+
return { block, txs, events };
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
class ObserverHttpBlockSource {
|
|
2014
|
+
baseUrl;
|
|
2015
|
+
token;
|
|
2016
|
+
fetchFn;
|
|
2017
|
+
constructor(opts) {
|
|
2018
|
+
this.baseUrl = stripTrailingSlash(opts.baseUrl);
|
|
2019
|
+
this.token = opts.token ?? null;
|
|
2020
|
+
this.fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
2021
|
+
}
|
|
2022
|
+
headers() {
|
|
2023
|
+
if (!this.token)
|
|
2024
|
+
return {};
|
|
2025
|
+
return { Authorization: `Bearer ${this.token}` };
|
|
2026
|
+
}
|
|
2027
|
+
async getTip() {
|
|
2028
|
+
const res = await this.fetchFn(`${this.baseUrl}${OBSERVER_HTTP_EXPORT_PATH}/tip`, { headers: this.headers() });
|
|
2029
|
+
if (!res.ok) {
|
|
2030
|
+
throw new Error(`observer tip HTTP ${res.status}: ${await res.text().catch(() => "")}`);
|
|
2031
|
+
}
|
|
2032
|
+
let body;
|
|
2033
|
+
try {
|
|
2034
|
+
body = await res.json();
|
|
2035
|
+
} catch (err) {
|
|
2036
|
+
throw new Error(`observer tip invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
2037
|
+
}
|
|
2038
|
+
if (typeof body.block_height !== "number" || !Number.isFinite(body.block_height)) {
|
|
2039
|
+
throw new Error("observer tip missing block_height");
|
|
2040
|
+
}
|
|
2041
|
+
return body.block_height;
|
|
2042
|
+
}
|
|
2043
|
+
async loadBlockRange(fromHeight, toHeight) {
|
|
2044
|
+
const result = new Map;
|
|
2045
|
+
let afterHeight = fromHeight > 0 ? fromHeight - 1 : undefined;
|
|
2046
|
+
let afterIndexBlockHash;
|
|
2047
|
+
for (;; ) {
|
|
2048
|
+
const url = new URL(`${this.baseUrl}${OBSERVER_HTTP_EXPORT_PATH}`);
|
|
2049
|
+
url.searchParams.set("path", "/new_block");
|
|
2050
|
+
url.searchParams.set("limit", "100");
|
|
2051
|
+
if (afterHeight != null) {
|
|
2052
|
+
url.searchParams.set("after_height", String(afterHeight));
|
|
2053
|
+
}
|
|
2054
|
+
if (afterIndexBlockHash) {
|
|
2055
|
+
url.searchParams.set("after_index_block_hash", afterIndexBlockHash);
|
|
2056
|
+
}
|
|
2057
|
+
const res = await this.fetchFn(url.toString(), {
|
|
2058
|
+
headers: this.headers()
|
|
2059
|
+
});
|
|
2060
|
+
if (!res.ok) {
|
|
2061
|
+
throw new Error(`observer events HTTP ${res.status}: ${await res.text().catch(() => "")}`);
|
|
2062
|
+
}
|
|
2063
|
+
let body;
|
|
2064
|
+
try {
|
|
2065
|
+
body = await res.json();
|
|
2066
|
+
} catch (err) {
|
|
2067
|
+
throw new Error(`observer events invalid JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
2068
|
+
}
|
|
2069
|
+
let pastTo = false;
|
|
2070
|
+
for (const message of body.events ?? []) {
|
|
2071
|
+
if (message.path === "/new_burn_block")
|
|
2072
|
+
continue;
|
|
2073
|
+
const height = message.payload?.block_height;
|
|
2074
|
+
if (typeof height === "number" && height > toHeight) {
|
|
2075
|
+
pastTo = true;
|
|
2076
|
+
break;
|
|
2077
|
+
}
|
|
2078
|
+
const data = mapNewBlockPayloadToBlockData(message.payload);
|
|
2079
|
+
const h = data.block.height;
|
|
2080
|
+
if (h >= fromHeight && h <= toHeight) {
|
|
2081
|
+
result.set(h, data);
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
if (pastTo || body.next == null)
|
|
2085
|
+
break;
|
|
2086
|
+
afterHeight = body.next.after_height;
|
|
2087
|
+
afterIndexBlockHash = body.next.after_index_block_hash;
|
|
2088
|
+
}
|
|
2089
|
+
return result;
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
|
|
1932
2093
|
// src/runtime/reconstruct.ts
|
|
1933
2094
|
function isoToUnixSeconds(iso) {
|
|
1934
2095
|
if (!iso)
|
|
@@ -2239,14 +2400,19 @@ class FallbackBlockSource {
|
|
|
2239
2400
|
}
|
|
2240
2401
|
var postgresBlockSource = new PostgresBlockSource;
|
|
2241
2402
|
function buildHttpClient() {
|
|
2242
|
-
|
|
2243
|
-
return new IndexHttpClient({
|
|
2244
|
-
indexBaseUrl: baseUrl,
|
|
2245
|
-
streamsBaseUrl: baseUrl,
|
|
2246
|
-
streamsApiKey: process.env.STREAMS_INTERNAL_API_KEY ?? "sk-sl_streams_decode_internal"
|
|
2247
|
-
});
|
|
2403
|
+
return createInternalIndexHttpClient();
|
|
2248
2404
|
}
|
|
2249
2405
|
function resolveBlockSource(subgraph) {
|
|
2406
|
+
if (process.env.SUBGRAPH_SOURCE === "observer-http") {
|
|
2407
|
+
const baseUrl = process.env.OBSERVER_HTTP_URL;
|
|
2408
|
+
if (!baseUrl) {
|
|
2409
|
+
throw new Error("SUBGRAPH_SOURCE=observer-http requires OBSERVER_HTTP_URL");
|
|
2410
|
+
}
|
|
2411
|
+
return new ObserverHttpBlockSource({
|
|
2412
|
+
baseUrl,
|
|
2413
|
+
token: process.env.OBSERVER_HTTP_EXPORT_TOKEN || null
|
|
2414
|
+
});
|
|
2415
|
+
}
|
|
2250
2416
|
if (process.env.SUBGRAPH_SOURCE === "streams-index" && subgraph && isStreamsIndexEligible(subgraph)) {
|
|
2251
2417
|
return new FallbackBlockSource(new PublicApiBlockSource(buildHttpClient(), referencedIndexEventTypes(subgraph), canSparseScan(subgraph) ? sparseProbeTargets(subgraph) : undefined, needsTransactionData(subgraph)), postgresBlockSource);
|
|
2252
2418
|
}
|
|
@@ -5272,5 +5438,5 @@ export {
|
|
|
5272
5438
|
ChainReadError
|
|
5273
5439
|
};
|
|
5274
5440
|
|
|
5275
|
-
//# debugId=
|
|
5441
|
+
//# debugId=E71414D5C2925EDA64756E2164756E21
|
|
5276
5442
|
//# sourceMappingURL=index.js.map
|