@secondlayer/shared 11.10.1 → 11.11.1
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/coverage/index.js +3 -1
- package/dist/src/coverage/index.js.map +3 -3
- package/dist/src/db/index.d.ts +18 -1
- package/dist/src/db/index.js +4 -1
- package/dist/src/db/index.js.map +3 -3
- package/dist/src/db/queries/chain-reorgs.js.map +2 -2
- package/dist/src/index-http.d.ts +42 -4
- package/dist/src/index-http.js +45 -10
- package/dist/src/index-http.js.map +3 -3
- package/dist/src/index.d.ts +18 -1
- package/dist/src/index.js +4 -1
- package/dist/src/index.js.map +3 -3
- package/dist/src/queue/listener.d.ts +33 -7
- package/dist/src/queue/listener.js +984 -5
- package/dist/src/queue/listener.js.map +12 -4
- package/package.json +1 -1
package/dist/src/index-http.js
CHANGED
|
@@ -40,17 +40,28 @@ function defaultInternalIndexBaseUrl() {
|
|
|
40
40
|
|
|
41
41
|
// src/index-http.ts
|
|
42
42
|
var PAGE_LIMIT = 1000;
|
|
43
|
+
var MAX_INDEX_WAIT_SECONDS = 25;
|
|
43
44
|
var MAX_ATTEMPTS = 4;
|
|
44
45
|
var RETRY_BASE_MS = 150;
|
|
45
46
|
var RETRYABLE_STATUS = new Set([502, 503, 504]);
|
|
46
47
|
var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
47
48
|
|
|
49
|
+
class IndexHttpStatusError extends Error {
|
|
50
|
+
status;
|
|
51
|
+
constructor(status, message) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.status = status;
|
|
54
|
+
this.name = "IndexHttpStatusError";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
48
58
|
class IndexHttpClient {
|
|
49
59
|
indexBaseUrl;
|
|
50
60
|
indexApiKey;
|
|
51
61
|
streamsBaseUrl;
|
|
52
62
|
streamsApiKey;
|
|
53
63
|
lastTipEnvelope;
|
|
64
|
+
waitSupported = true;
|
|
54
65
|
constructor(opts) {
|
|
55
66
|
this.indexBaseUrl = opts.indexBaseUrl.replace(/\/+$/, "");
|
|
56
67
|
this.indexApiKey = opts.indexApiKey ?? defaultInternalIndexApiKey();
|
|
@@ -79,7 +90,7 @@ class IndexHttpClient {
|
|
|
79
90
|
await delay(RETRY_BASE_MS * 2 ** (attempt - 1));
|
|
80
91
|
continue;
|
|
81
92
|
}
|
|
82
|
-
throw new
|
|
93
|
+
throw new IndexHttpStatusError(res.status, `GET ${url} → ${res.status} ${await res.text()}`);
|
|
83
94
|
}
|
|
84
95
|
return await res.json();
|
|
85
96
|
}
|
|
@@ -148,21 +159,43 @@ class IndexHttpClient {
|
|
|
148
159
|
const tip = await this.get(`${this.streamsBaseUrl}/v1/streams/tip`, this.streamsApiKey);
|
|
149
160
|
return Number(tip.block_height) || 0;
|
|
150
161
|
}
|
|
151
|
-
async getIndexTip() {
|
|
152
|
-
const env = await this.getIndexTipEnvelope();
|
|
162
|
+
async getIndexTip(opts) {
|
|
163
|
+
const env = await this.getIndexTipEnvelope({ ...opts, tipOnly: true });
|
|
153
164
|
return Number(env.tip?.block_height) || 0;
|
|
154
165
|
}
|
|
155
|
-
async getIndexSourceTip() {
|
|
156
|
-
const env = await this.getIndexTipEnvelope();
|
|
166
|
+
async getIndexSourceTip(opts) {
|
|
167
|
+
const env = await this.getIndexTipEnvelope(opts);
|
|
157
168
|
return Number(env.tip?.source_block_height ?? env.tip?.block_height) || 0;
|
|
158
169
|
}
|
|
159
170
|
getDecodedHeights() {
|
|
160
171
|
return this.lastTipEnvelope?.tip.decoded_heights;
|
|
161
172
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
173
|
+
waitIsSupported() {
|
|
174
|
+
return this.waitSupported;
|
|
175
|
+
}
|
|
176
|
+
async getIndexTipEnvelope(opts) {
|
|
177
|
+
const wantsWait = this.waitSupported && (opts?.wait ?? 0) > 0;
|
|
178
|
+
const wantsTipOnly = this.waitSupported && Boolean(opts?.tipOnly);
|
|
179
|
+
const params = new URLSearchParams({ limit: "1" });
|
|
180
|
+
if (wantsTipOnly)
|
|
181
|
+
params.set("tip_only", "true");
|
|
182
|
+
if (wantsWait) {
|
|
183
|
+
params.set("wait", String(Math.min(MAX_INDEX_WAIT_SECONDS, Math.max(0, opts?.wait ?? 0))));
|
|
184
|
+
if (opts?.knownHeight !== undefined) {
|
|
185
|
+
params.set("from_height", String(opts.knownHeight + 1));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
const env = await this.get(`${this.indexBaseUrl}/v1/index/blocks?${params}`, this.indexApiKey);
|
|
190
|
+
this.lastTipEnvelope = env;
|
|
191
|
+
return env;
|
|
192
|
+
} catch (err) {
|
|
193
|
+
if ((wantsWait || wantsTipOnly) && err instanceof IndexHttpStatusError && err.status === 400) {
|
|
194
|
+
this.waitSupported = false;
|
|
195
|
+
return this.getIndexTipEnvelope(opts);
|
|
196
|
+
}
|
|
197
|
+
throw err;
|
|
198
|
+
}
|
|
166
199
|
}
|
|
167
200
|
async listReorgs(since) {
|
|
168
201
|
const params = new URLSearchParams({ since });
|
|
@@ -180,8 +213,10 @@ function createInternalIndexHttpClient() {
|
|
|
180
213
|
}
|
|
181
214
|
export {
|
|
182
215
|
IndexHttpClient,
|
|
216
|
+
IndexHttpStatusError,
|
|
217
|
+
MAX_INDEX_WAIT_SECONDS,
|
|
183
218
|
createInternalIndexHttpClient
|
|
184
219
|
};
|
|
185
220
|
|
|
186
|
-
//# debugId=
|
|
221
|
+
//# debugId=86DE9405EBDF6BE664756E2164756E21
|
|
187
222
|
//# sourceMappingURL=index-http.js.map
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"sources": ["../src/index-internal-auth.ts", "../src/index-http.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"// Internal service credentials for first-party consumers of /v1/index and\n// /v1/streams over HTTP (decoder, subgraph processor PublicApiBlockSource).\n// Seeded as internal tenants with NO account_id, so these reads are\n// unmetered (metering gates on account_id). Lives in shared so the API (seed)\n// and the consumers import it without a cycle.\n//\n// Resolution: STREAMS_INTERNAL_API_KEY / INDEX_INTERNAL_API_KEY, then\n// INSTANCE_TOKEN (OSS). No committed fallback. Empty-string env values fall\n// through (`trim()`, then empty): compose interpolates\n// `${STREAMS_INTERNAL_API_KEY:-}` which is \"\" when unset.\n//\n// Archive keys must not use the `sk-sl_` prefix; generate with `sl-int_`.\n// OSS compose should omit the internal env and send INSTANCE_TOKEN.\nexport const INDEX_INTERNAL_TENANT_ID = \"tenant_index_internal\";\nexport const INTERNAL_STREAMS_TENANT_ID = \"tenant_streams_decode_internal\";\n\nconst DEFAULT_INTERNAL_INDEX_BASE_URL = \"http://api:3800\";\n\nconst MISSING_INTERNAL_STREAMS_API_KEY =\n\t\"Set STREAMS_INTERNAL_API_KEY (archive; prefix sl-int_) or INSTANCE_TOKEN (OSS). Empty env no longer falls back to a committed secret.\";\n\nconst MISSING_INTERNAL_INDEX_API_KEY =\n\t\"Set INDEX_INTERNAL_API_KEY (archive; prefix sl-int_) or INSTANCE_TOKEN (OSS). Without one, Index reads carry no credential and platform mode 401s every one of them.\";\n\nexport function defaultInternalIndexApiKey(\n\tenv: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n\tconst internal = env.INDEX_INTERNAL_API_KEY?.trim();\n\tif (internal) return internal;\n\tconst instance = env.INSTANCE_TOKEN?.trim();\n\tif (instance) return instance;\n\treturn undefined;\n}\n\nexport function defaultInternalStreamsApiKey(\n\tenv: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n\tconst internal = env.STREAMS_INTERNAL_API_KEY?.trim();\n\tif (internal) return internal;\n\tconst instance = env.INSTANCE_TOKEN?.trim();\n\tif (instance) return instance;\n\treturn undefined;\n}\n\n/**\n * Platform-mode Index consumer: refuse to run with neither credential.\n *\n * Platform mode requires a credential on every Index read (a keyless read\n * 401s, `api/src/index/auth.ts`) — a first-party consumer with no internal\n * key would fail every request at call time. Fail here at startup instead.\n *\n * Self-hosted (oss/dedicated) instances are not gated, so they must NOT call\n * this — `defaultInternalIndexApiKey()` returning undefined is correct there.\n */\nexport function requireInternalIndexApiKey(\n\tenv: NodeJS.ProcessEnv = process.env,\n): string {\n\tconst key = defaultInternalIndexApiKey(env);\n\tif (!key) throw new Error(MISSING_INTERNAL_INDEX_API_KEY);\n\treturn key;\n}\n\n/** Decoder startup: refuse to run with neither credential. */\nexport function requireInternalStreamsApiKey(\n\tenv: NodeJS.ProcessEnv = process.env,\n): string {\n\tconst key = defaultInternalStreamsApiKey(env);\n\tif (!key) throw new Error(MISSING_INTERNAL_STREAMS_API_KEY);\n\treturn key;\n}\n\n/** Shared env contract for decoder + subgraph HTTP dogfood. */\nexport function defaultInternalIndexBaseUrl(): string {\n\treturn (\n\t\tprocess.env.SUBGRAPH_INDEX_API_URL ||\n\t\tprocess.env.STREAMS_API_URL ||\n\t\tDEFAULT_INTERNAL_INDEX_BASE_URL\n\t);\n}\n",
|
|
6
|
-
"import {\n\tdefaultInternalIndexApiKey,\n\tdefaultInternalIndexBaseUrl,\n\tdefaultInternalStreamsApiKey,\n} from \"./index-internal-auth.ts\";\n\n/**\n * Low-level transport for the public Index (`/v1/index`) + Streams clock\n * (`/v1/streams`) HTTP APIs: cursor-paginated reads, tip, reorgs. Lives in\n * `shared` (a leaf both the SDK and the subgraph runtime depend on) so the wire\n * format has one home and no package cycle. The SDK's ergonomic client should\n * eventually consume these row types too (see the plan's convergence task).\n *\n * This is intentionally minimal — just the GETs the subgraph runtime's\n * PublicApiBlockSource needs. It is NOT the SDK's full client (walk/consume/\n * retries/auth resolution).\n */\n\nconst PAGE_LIMIT = 1000;\n\n// Transport resilience for the streams-index data plane. The api runs N>1\n// replicas behind Caddy; during a rolling deploy one replica is briefly\n// unreachable, surfacing as a thrown fetch (connection refused/reset) or a\n// Caddy 502/503/504 while it fails over. Retrying a few times with backoff\n// makes a single-replica recreate transparent to the subgraph-processor /\n// decoder — closing the processors-depend-on-api coupling.\nconst MAX_ATTEMPTS = 4;\nconst RETRY_BASE_MS = 150;\nconst RETRYABLE_STATUS = new Set([502, 503, 504]);\n\nconst delay = (ms: number): Promise<void> =>\n\tnew Promise((resolve) => setTimeout(resolve, ms));\n\ntype Envelope<K extends string, T> = {\n\t[P in K]: T[];\n} & { next_cursor: string | null };\n\n// ── Index API wire shapes (single source of truth) ─────────────────────────\nexport type IndexBlockRow = {\n\tblock_height: number;\n\tblock_hash: string;\n\tparent_hash: string;\n\tburn_block_height: number;\n\tburn_block_hash: string | null;\n\t/** Nakamoto StacksBlockId. Absent from pre-2026-07 API deployments. */\n\tindex_block_hash?: string | null;\n\tblock_time: string | null;\n};\n\ntype IndexEventCommon = {\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index?: number;\n\tevent_index: number;\n\tcontract_id: string | null;\n\t/** Submitting-tx context — present only when the read passed `tx_context=true`.\n\t * Lets a consumer build the tx for `ctx.tx` without a separate\n\t * walkTransactions (the ~37x reindex over-fetch; see indexing-speed plan). */\n\ttx_sender?: string | null;\n\ttx_type?: string | null;\n\ttx_status?: string | null;\n\ttx_contract_id?: string | null;\n\ttx_function_name?: string | null;\n};\n\nexport type IndexEventRow = IndexEventCommon &\n\t(\n\t\t| {\n\t\t\t\tevent_type: \"ft_transfer\" | \"ft_mint\" | \"ft_burn\";\n\t\t\t\tasset_identifier: string;\n\t\t\t\tsender?: string;\n\t\t\t\trecipient?: string;\n\t\t\t\tamount: string;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"nft_transfer\" | \"nft_mint\" | \"nft_burn\";\n\t\t\t\tasset_identifier: string;\n\t\t\t\tsender?: string;\n\t\t\t\trecipient?: string;\n\t\t\t\tvalue: string;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"stx_transfer\" | \"stx_mint\" | \"stx_burn\";\n\t\t\t\tsender?: string;\n\t\t\t\trecipient?: string;\n\t\t\t\tamount: string;\n\t\t\t\tmemo?: string | null;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"stx_lock\";\n\t\t\t\tsender: string;\n\t\t\t\tamount: string;\n\t\t\t\tpayload: { unlock_height: string | null };\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"print\";\n\t\t\t\tpayload: {\n\t\t\t\t\ttopic: string | null;\n\t\t\t\t\tvalue: unknown;\n\t\t\t\t\traw_value: string | null;\n\t\t\t\t};\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"nested_contract_call\";\n\t\t\t\tsender?: string | null;\n\t\t\t\tcaller: string;\n\t\t\t\tfunction_name: string;\n\t\t\t\tfunction_args?: unknown;\n\t\t\t\traw_result?: string | null;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"var_set\";\n\t\t\t\tvar_name: string;\n\t\t\t\traw_value?: string | null;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"map_set\" | \"map_insert\";\n\t\t\t\tmap: string;\n\t\t\t\traw_key?: string | null;\n\t\t\t\traw_value?: string | null;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"map_delete\";\n\t\t\t\tmap: string;\n\t\t\t\traw_key?: string | null;\n\t\t }\n\t);\n\nexport type IndexTransactionRow = {\n\ttx_id: string;\n\tblock_height: number;\n\tblock_time?: string | null;\n\tburn_block_height?: number | null;\n\ttx_index: number;\n\ttx_type: string;\n\tsender: string;\n\tstatus: string;\n\tcontract_call?: {\n\t\tcontract_id: string;\n\t\tfunction_name: string;\n\t\tfunction_args_hex?: string[] | null;\n\t\tresult_hex?: string | null;\n\t} | null;\n\tsmart_contract?: { contract_id: string | null } | null;\n};\n\nexport type StreamsReorgRow = {\n\tid: string;\n\tdetected_at: string;\n\tfork_point_height: number;\n\torphaned_range: { from: string; to: string };\n\tnew_canonical_tip: string;\n};\n\nexport type IndexHttpOptions = {\n\t/** Base URL for /v1/index (the decoded data plane). */\n\tindexBaseUrl: string;\n\t/** Bearer for /v1/index. Empty/unset omits the header. */\n\tindexApiKey?: string;\n\t/** Base URL for /v1/streams (the canonical clock). */\n\tstreamsBaseUrl: string;\n\t/** Bearer for /v1/streams. Empty/unset omits the header. */\n\tstreamsApiKey?: string;\n};\n\n/** `/v1/index/blocks?limit=1`'s envelope — read for its `tip`, not its rows. */\nexport type IndexTipEnvelope = {\n\ttip: {\n\t\tblock_height: number;\n\t\tsource_block_height?: number;\n\t\t/**\n\t\t * Committed height per classic decoded event_type (plan-063), e.g.\n\t\t * `{ ft_transfer: 950, stx_transfer: 940 }`. `null` means that decoder\n\t\t * has no checkpoint yet (fail-closed for a caller that references it,\n\t\t * not \"committed to height 0\"); a missing key means an older server\n\t\t * that doesn't send this field at all. Absent on an instance built\n\t\t * before plan-063 shipped it.\n\t\t */\n\t\tdecoded_heights?: Record<string, number | null>;\n\t};\n};\n\nexport class IndexHttpClient {\n\tprivate readonly indexBaseUrl: string;\n\tprivate readonly indexApiKey: string | undefined;\n\tprivate readonly streamsBaseUrl: string;\n\tprivate readonly streamsApiKey: string | undefined;\n\t/** Populated by the last `getIndexTipEnvelope()` call (via `getIndexTip`/\n\t * `getIndexSourceTip`) so `getDecodedHeights()` can read the SAME response\n\t * synchronously instead of making a second request. */\n\tprivate lastTipEnvelope: IndexTipEnvelope | undefined;\n\n\tconstructor(opts: IndexHttpOptions) {\n\t\tthis.indexBaseUrl = opts.indexBaseUrl.replace(/\\/+$/, \"\");\n\t\tthis.indexApiKey = opts.indexApiKey ?? defaultInternalIndexApiKey();\n\t\tthis.streamsBaseUrl = opts.streamsBaseUrl.replace(/\\/+$/, \"\");\n\t\tthis.streamsApiKey = opts.streamsApiKey;\n\t}\n\n\tprivate async get<T>(url: string, apiKey: string | undefined): Promise<T> {\n\t\t// Index reads are anon — omit the header entirely when no key is set, so\n\t\t// an empty key reads anonymously rather than 401-ing as an invalid bearer.\n\t\tconst headers: Record<string, string> = apiKey\n\t\t\t? { authorization: `Bearer ${apiKey}` }\n\t\t\t: {};\n\t\tlet lastErr: unknown;\n\t\tfor (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n\t\t\tlet res: Response;\n\t\t\ttry {\n\t\t\t\tres = await fetch(url, { headers });\n\t\t\t} catch (err) {\n\t\t\t\t// An explicit abort/cancel is intentional — surface it immediately\n\t\t\t\t// rather than burning the retry budget masking it as transient.\n\t\t\t\tif (err instanceof Error && err.name === \"AbortError\") throw err;\n\t\t\t\t// Otherwise a transport-level failure (connection refused/reset) —\n\t\t\t\t// e.g. an api replica mid-recreate. Retry; the next attempt\n\t\t\t\t// round-robins to a healthy replica.\n\t\t\t\tlastErr = err;\n\t\t\t\tif (attempt >= MAX_ATTEMPTS) break;\n\t\t\t\tawait delay(RETRY_BASE_MS * 2 ** (attempt - 1));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!res.ok) {\n\t\t\t\tif (RETRYABLE_STATUS.has(res.status) && attempt < MAX_ATTEMPTS) {\n\t\t\t\t\t// Drain the body so the connection can be reused, then back off.\n\t\t\t\t\tawait res.text().catch(() => {});\n\t\t\t\t\tawait delay(RETRY_BASE_MS * 2 ** (attempt - 1));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`GET ${url} → ${res.status} ${await res.text()}`);\n\t\t\t}\n\t\t\treturn (await res.json()) as T;\n\t\t}\n\t\tthrow (\n\t\t\tlastErr ?? new Error(`GET ${url} failed after ${MAX_ATTEMPTS} attempts`)\n\t\t);\n\t}\n\n\t/** Fetch a single cursor page of an Index collection. */\n\tprivate async getPage<K extends string, T>(\n\t\tpath: string,\n\t\tkey: K,\n\t\tparams: URLSearchParams,\n\t): Promise<{ items: T[]; next_cursor: string | null }> {\n\t\tconst env: Envelope<K, T> = await this.get(\n\t\t\t`${this.indexBaseUrl}${path}?${params}`,\n\t\t\tthis.indexApiKey,\n\t\t);\n\t\treturn { items: env[key], next_cursor: env.next_cursor };\n\t}\n\n\t/** Drain a cursor-paginated Index collection over [fromHeight, toHeight]. */\n\tprivate async walk<K extends string, T>(\n\t\tpath: string,\n\t\tkey: K,\n\t\tfromHeight: number,\n\t\ttoHeight: number,\n\t\textraParams: Record<string, string> = {},\n\t): Promise<T[]> {\n\t\tconst out: T[] = [];\n\t\tlet cursor: string | null = null;\n\t\tdo {\n\t\t\tconst params = new URLSearchParams({\n\t\t\t\tto_height: String(toHeight),\n\t\t\t\tlimit: String(PAGE_LIMIT),\n\t\t\t\t...extraParams,\n\t\t\t});\n\t\t\t// from_height and cursor are mutually exclusive — anchor the first page\n\t\t\t// by height, then page forward by cursor only.\n\t\t\tif (cursor) params.set(\"cursor\", cursor);\n\t\t\telse params.set(\"from_height\", String(fromHeight));\n\t\t\tconst { items, next_cursor } = await this.getPage<K, T>(\n\t\t\t\tpath,\n\t\t\t\tkey,\n\t\t\t\tparams,\n\t\t\t);\n\t\t\tout.push(...items);\n\t\t\tcursor = next_cursor;\n\t\t} while (cursor);\n\t\treturn out;\n\t}\n\n\t/**\n\t * Fetch ONE page of contract-call transactions filtered to `contractId`.\n\t * Unlike walk(), this does NOT drain — the caller pages by feeding back\n\t * next_cursor — so a sparse high-volume filter (e.g. a single contract over\n\t * all history) costs one request per batch, not O(all-history) per tick.\n\t * `cursor` is exclusive (rows strictly after it); on the first call pass\n\t * `fromHeight` to anchor the backfill start instead.\n\t */\n\tasync fetchContractCalls(\n\t\tcontractId: string,\n\t\topts: {\n\t\t\ttoHeight: number;\n\t\t\tcursor?: string | null;\n\t\t\tfromHeight?: number;\n\t\t\tlimit?: number;\n\t\t},\n\t): Promise<{\n\t\ttransactions: IndexTransactionRow[];\n\t\tnext_cursor: string | null;\n\t}> {\n\t\tconst params = new URLSearchParams({\n\t\t\tto_height: String(opts.toHeight),\n\t\t\tlimit: String(opts.limit ?? PAGE_LIMIT),\n\t\t\tcontract_id: contractId,\n\t\t});\n\t\tif (opts.cursor) params.set(\"cursor\", opts.cursor);\n\t\telse params.set(\"from_height\", String(opts.fromHeight ?? 0));\n\t\tconst { items, next_cursor } = await this.getPage<\n\t\t\t\"transactions\",\n\t\t\tIndexTransactionRow\n\t\t>(\"/v1/index/transactions\", \"transactions\", params);\n\t\treturn { transactions: items, next_cursor };\n\t}\n\n\twalkBlocks(fromHeight: number, toHeight: number): Promise<IndexBlockRow[]> {\n\t\treturn this.walk<\"blocks\", IndexBlockRow>(\n\t\t\t\"/v1/index/blocks\",\n\t\t\t\"blocks\",\n\t\t\tfromHeight,\n\t\t\ttoHeight,\n\t\t);\n\t}\n\n\t/** Lowest block height in [fromHeight, toHeight] with a matching event, or\n\t * null. One page, limit 1 — built for sparse-scan probes. */\n\tasync firstEventHeight(\n\t\teventType: string,\n\t\tfromHeight: number,\n\t\ttoHeight: number,\n\t\tcontractId?: string,\n\t): Promise<number | null> {\n\t\tconst params = new URLSearchParams({\n\t\t\tevent_type: eventType,\n\t\t\tfrom_height: String(fromHeight),\n\t\t\tto_height: String(toHeight),\n\t\t\tlimit: \"1\",\n\t\t\t...(contractId ? { contract_id: contractId } : {}),\n\t\t});\n\t\tconst { items } = await this.getPage<\"events\", IndexEventRow>(\n\t\t\t\"/v1/index/events\",\n\t\t\t\"events\",\n\t\t\tparams,\n\t\t);\n\t\treturn items[0]?.block_height ?? null;\n\t}\n\n\twalkEvents(\n\t\teventType: string,\n\t\tfromHeight: number,\n\t\ttoHeight: number,\n\t\t/** Join the submitting tx so each row carries `tx_*` — lets an event-only\n\t\t * subgraph skip walkTransactions and build `ctx.tx` from the event. */\n\t\twithTx = false,\n\t): Promise<IndexEventRow[]> {\n\t\treturn this.walk<\"events\", IndexEventRow>(\n\t\t\t\"/v1/index/events\",\n\t\t\t\"events\",\n\t\t\tfromHeight,\n\t\t\ttoHeight,\n\t\t\t{\n\t\t\t\tevent_type: eventType,\n\t\t\t\t...(withTx ? { tx_context: \"true\" } : {}),\n\t\t\t},\n\t\t);\n\t}\n\n\twalkTransactions(\n\t\tfromHeight: number,\n\t\ttoHeight: number,\n\t): Promise<IndexTransactionRow[]> {\n\t\treturn this.walk<\"transactions\", IndexTransactionRow>(\n\t\t\t\"/v1/index/transactions\",\n\t\t\t\"transactions\",\n\t\t\tfromHeight,\n\t\t\ttoHeight,\n\t\t);\n\t}\n\n\t/** Canonical tip height from the Streams clock. */\n\tasync getStreamsTip(): Promise<number> {\n\t\tconst tip = await this.get<{ block_height: number }>(\n\t\t\t`${this.streamsBaseUrl}/v1/streams/tip`,\n\t\t\tthis.streamsApiKey,\n\t\t);\n\t\treturn Number(tip.block_height) || 0;\n\t}\n\n\t/**\n\t * Highest block height the Index data plane can serve (tip is inline in every\n\t * envelope). This is the data-availability bound — a consumer must not\n\t * process past it, even if the Streams clock is ahead.\n\t */\n\tasync getIndexTip(): Promise<number> {\n\t\tconst env = await this.getIndexTipEnvelope();\n\t\treturn Number(env.tip?.block_height) || 0;\n\t}\n\n\t/** Ingest tip. VM rows land with the block; decoded `block_height` can lag. */\n\tasync getIndexSourceTip(): Promise<number> {\n\t\tconst env = await this.getIndexTipEnvelope();\n\t\treturn Number(env.tip?.source_block_height ?? env.tip?.block_height) || 0;\n\t}\n\n\t/**\n\t * Per-decoder committed heights from the last tip envelope fetched by\n\t * `getIndexTip()`/`getIndexSourceTip()` — reads the cached response, no\n\t * extra request. `undefined` before either has been called, or against an\n\t * older server that doesn't send the field. A caller (the chain evaluator)\n\t * uses this to bound itself by the decoders it actually reads instead of\n\t * the conservative cross-decoder floor `block_height` itself carries.\n\t */\n\tgetDecodedHeights(): Record<string, number | null> | undefined {\n\t\treturn this.lastTipEnvelope?.tip.decoded_heights;\n\t}\n\n\tprivate async getIndexTipEnvelope(): Promise<IndexTipEnvelope> {\n\t\tconst env = await this.get<IndexTipEnvelope>(\n\t\t\t`${this.indexBaseUrl}/v1/index/blocks?limit=1`,\n\t\t\tthis.indexApiKey,\n\t\t);\n\t\tthis.lastTipEnvelope = env;\n\t\treturn env;\n\t}\n\n\t/** Reorgs since a resume token (wall-clock `detected_at`-keyed). */\n\tasync listReorgs(\n\t\tsince: string,\n\t): Promise<{ reorgs: StreamsReorgRow[]; next_since: string | null }> {\n\t\tconst params = new URLSearchParams({ since });\n\t\treturn this.get(\n\t\t\t`${this.streamsBaseUrl}/v1/streams/reorgs?${params}`,\n\t\t\tthis.streamsApiKey,\n\t\t);\n\t}\n}\n\n/** Decoder + subgraph processor client. One env contract; omits bearer when no key. */\nexport function createInternalIndexHttpClient(): IndexHttpClient {\n\tconst baseUrl = defaultInternalIndexBaseUrl();\n\treturn new IndexHttpClient({\n\t\tindexBaseUrl: baseUrl,\n\t\tstreamsBaseUrl: baseUrl,\n\t\tindexApiKey: defaultInternalIndexApiKey(),\n\t\tstreamsApiKey: defaultInternalStreamsApiKey(),\n\t});\n}\n"
|
|
6
|
+
"import {\n\tdefaultInternalIndexApiKey,\n\tdefaultInternalIndexBaseUrl,\n\tdefaultInternalStreamsApiKey,\n} from \"./index-internal-auth.ts\";\n\n/**\n * Low-level transport for the public Index (`/v1/index`) + Streams clock\n * (`/v1/streams`) HTTP APIs: cursor-paginated reads, tip, reorgs. Lives in\n * `shared` (a leaf both the SDK and the subgraph runtime depend on) so the wire\n * format has one home and no package cycle. The SDK's ergonomic client should\n * eventually consume these row types too (see the plan's convergence task).\n *\n * This is intentionally minimal — just the GETs the subgraph runtime's\n * PublicApiBlockSource needs. It is NOT the SDK's full client (walk/consume/\n * retries/auth resolution).\n */\n\nconst PAGE_LIMIT = 1000;\n\n/** Ceiling on the Index long-poll `wait` param (seconds), shared by client and\n * server so neither drifts from the other. Kept comfortably under app-server\n * Caddy's `reverse_proxy` (no read/write timeout override, so this is a\n * self-imposed ceiling, not one it's protecting against) and Bun's own\n * 90s idleTimeout on the api listener. */\nexport const MAX_INDEX_WAIT_SECONDS = 25;\n\n// Transport resilience for the streams-index data plane. The api runs N>1\n// replicas behind Caddy; during a rolling deploy one replica is briefly\n// unreachable, surfacing as a thrown fetch (connection refused/reset) or a\n// Caddy 502/503/504 while it fails over. Retrying a few times with backoff\n// makes a single-replica recreate transparent to the subgraph-processor /\n// decoder — closing the processors-depend-on-api coupling.\nconst MAX_ATTEMPTS = 4;\nconst RETRY_BASE_MS = 150;\nconst RETRYABLE_STATUS = new Set([502, 503, 504]);\n\nconst delay = (ms: number): Promise<void> =>\n\tnew Promise((resolve) => setTimeout(resolve, ms));\n\n/** A non-2xx Index/Streams response, carrying the status so a caller can\n * distinguish \"the server rejected this request\" (e.g. a `wait`/`from_height`\n * param an older server's `validateQueryParams` doesn't recognize, HTTP 400)\n * from a transient outage — see `getIndexTipEnvelope`'s wait fallback. */\nexport class IndexHttpStatusError extends Error {\n\tconstructor(\n\t\treadonly status: number,\n\t\tmessage: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"IndexHttpStatusError\";\n\t}\n}\n\ntype Envelope<K extends string, T> = {\n\t[P in K]: T[];\n} & { next_cursor: string | null };\n\n// ── Index API wire shapes (single source of truth) ─────────────────────────\nexport type IndexBlockRow = {\n\tblock_height: number;\n\tblock_hash: string;\n\tparent_hash: string;\n\tburn_block_height: number;\n\tburn_block_hash: string | null;\n\t/** Nakamoto StacksBlockId. Absent from pre-2026-07 API deployments. */\n\tindex_block_hash?: string | null;\n\tblock_time: string | null;\n};\n\ntype IndexEventCommon = {\n\tblock_height: number;\n\ttx_id: string;\n\ttx_index?: number;\n\tevent_index: number;\n\tcontract_id: string | null;\n\t/** Submitting-tx context — present only when the read passed `tx_context=true`.\n\t * Lets a consumer build the tx for `ctx.tx` without a separate\n\t * walkTransactions (the ~37x reindex over-fetch; see indexing-speed plan). */\n\ttx_sender?: string | null;\n\ttx_type?: string | null;\n\ttx_status?: string | null;\n\ttx_contract_id?: string | null;\n\ttx_function_name?: string | null;\n};\n\nexport type IndexEventRow = IndexEventCommon &\n\t(\n\t\t| {\n\t\t\t\tevent_type: \"ft_transfer\" | \"ft_mint\" | \"ft_burn\";\n\t\t\t\tasset_identifier: string;\n\t\t\t\tsender?: string;\n\t\t\t\trecipient?: string;\n\t\t\t\tamount: string;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"nft_transfer\" | \"nft_mint\" | \"nft_burn\";\n\t\t\t\tasset_identifier: string;\n\t\t\t\tsender?: string;\n\t\t\t\trecipient?: string;\n\t\t\t\tvalue: string;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"stx_transfer\" | \"stx_mint\" | \"stx_burn\";\n\t\t\t\tsender?: string;\n\t\t\t\trecipient?: string;\n\t\t\t\tamount: string;\n\t\t\t\tmemo?: string | null;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"stx_lock\";\n\t\t\t\tsender: string;\n\t\t\t\tamount: string;\n\t\t\t\tpayload: { unlock_height: string | null };\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"print\";\n\t\t\t\tpayload: {\n\t\t\t\t\ttopic: string | null;\n\t\t\t\t\tvalue: unknown;\n\t\t\t\t\traw_value: string | null;\n\t\t\t\t};\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"nested_contract_call\";\n\t\t\t\tsender?: string | null;\n\t\t\t\tcaller: string;\n\t\t\t\tfunction_name: string;\n\t\t\t\tfunction_args?: unknown;\n\t\t\t\traw_result?: string | null;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"var_set\";\n\t\t\t\tvar_name: string;\n\t\t\t\traw_value?: string | null;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"map_set\" | \"map_insert\";\n\t\t\t\tmap: string;\n\t\t\t\traw_key?: string | null;\n\t\t\t\traw_value?: string | null;\n\t\t }\n\t\t| {\n\t\t\t\tevent_type: \"map_delete\";\n\t\t\t\tmap: string;\n\t\t\t\traw_key?: string | null;\n\t\t }\n\t);\n\nexport type IndexTransactionRow = {\n\ttx_id: string;\n\tblock_height: number;\n\tblock_time?: string | null;\n\tburn_block_height?: number | null;\n\ttx_index: number;\n\ttx_type: string;\n\tsender: string;\n\tstatus: string;\n\tcontract_call?: {\n\t\tcontract_id: string;\n\t\tfunction_name: string;\n\t\tfunction_args_hex?: string[] | null;\n\t\tresult_hex?: string | null;\n\t} | null;\n\tsmart_contract?: { contract_id: string | null } | null;\n};\n\nexport type StreamsReorgRow = {\n\tid: string;\n\tdetected_at: string;\n\tfork_point_height: number;\n\torphaned_range: { from: string; to: string };\n\tnew_canonical_tip: string;\n};\n\nexport type IndexHttpOptions = {\n\t/** Base URL for /v1/index (the decoded data plane). */\n\tindexBaseUrl: string;\n\t/** Bearer for /v1/index. Empty/unset omits the header. */\n\tindexApiKey?: string;\n\t/** Base URL for /v1/streams (the canonical clock). */\n\tstreamsBaseUrl: string;\n\t/** Bearer for /v1/streams. Empty/unset omits the header. */\n\tstreamsApiKey?: string;\n};\n\n/** `/v1/index/blocks?limit=1`'s envelope — read for its `tip`, not its rows. */\nexport type IndexTipEnvelope = {\n\ttip: {\n\t\tblock_height: number;\n\t\tsource_block_height?: number;\n\t\t/**\n\t\t * Committed height per classic decoded event_type (plan-063), e.g.\n\t\t * `{ ft_transfer: 950, stx_transfer: 940 }`. `null` means that decoder\n\t\t * has no checkpoint yet (fail-closed for a caller that references it,\n\t\t * not \"committed to height 0\"); a missing key means an older server\n\t\t * that doesn't send this field at all. Absent on an instance built\n\t\t * before plan-063 shipped it.\n\t\t */\n\t\tdecoded_heights?: Record<string, number | null>;\n\t};\n};\n\nexport class IndexHttpClient {\n\tprivate readonly indexBaseUrl: string;\n\tprivate readonly indexApiKey: string | undefined;\n\tprivate readonly streamsBaseUrl: string;\n\tprivate readonly streamsApiKey: string | undefined;\n\t/** Populated by the last `getIndexTipEnvelope()` call (via `getIndexTip`/\n\t * `getIndexSourceTip`) so `getDecodedHeights()` can read the SAME response\n\t * synchronously instead of making a second request. */\n\tprivate lastTipEnvelope: IndexTipEnvelope | undefined;\n\t/** Flips false the first time a `wait` request 400s — see\n\t * `getIndexTipEnvelope`'s catch. Per-instance, not global: a fresh client\n\t * (e.g. against a different/upgraded server) always tries wait again. */\n\tprivate waitSupported = true;\n\n\tconstructor(opts: IndexHttpOptions) {\n\t\tthis.indexBaseUrl = opts.indexBaseUrl.replace(/\\/+$/, \"\");\n\t\tthis.indexApiKey = opts.indexApiKey ?? defaultInternalIndexApiKey();\n\t\tthis.streamsBaseUrl = opts.streamsBaseUrl.replace(/\\/+$/, \"\");\n\t\tthis.streamsApiKey = opts.streamsApiKey;\n\t}\n\n\tprivate async get<T>(url: string, apiKey: string | undefined): Promise<T> {\n\t\t// Index reads are anon — omit the header entirely when no key is set, so\n\t\t// an empty key reads anonymously rather than 401-ing as an invalid bearer.\n\t\tconst headers: Record<string, string> = apiKey\n\t\t\t? { authorization: `Bearer ${apiKey}` }\n\t\t\t: {};\n\t\tlet lastErr: unknown;\n\t\tfor (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n\t\t\tlet res: Response;\n\t\t\ttry {\n\t\t\t\tres = await fetch(url, { headers });\n\t\t\t} catch (err) {\n\t\t\t\t// An explicit abort/cancel is intentional — surface it immediately\n\t\t\t\t// rather than burning the retry budget masking it as transient.\n\t\t\t\tif (err instanceof Error && err.name === \"AbortError\") throw err;\n\t\t\t\t// Otherwise a transport-level failure (connection refused/reset) —\n\t\t\t\t// e.g. an api replica mid-recreate. Retry; the next attempt\n\t\t\t\t// round-robins to a healthy replica.\n\t\t\t\tlastErr = err;\n\t\t\t\tif (attempt >= MAX_ATTEMPTS) break;\n\t\t\t\tawait delay(RETRY_BASE_MS * 2 ** (attempt - 1));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!res.ok) {\n\t\t\t\tif (RETRYABLE_STATUS.has(res.status) && attempt < MAX_ATTEMPTS) {\n\t\t\t\t\t// Drain the body so the connection can be reused, then back off.\n\t\t\t\t\tawait res.text().catch(() => {});\n\t\t\t\t\tawait delay(RETRY_BASE_MS * 2 ** (attempt - 1));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new IndexHttpStatusError(\n\t\t\t\t\tres.status,\n\t\t\t\t\t`GET ${url} → ${res.status} ${await res.text()}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn (await res.json()) as T;\n\t\t}\n\t\tthrow (\n\t\t\tlastErr ?? new Error(`GET ${url} failed after ${MAX_ATTEMPTS} attempts`)\n\t\t);\n\t}\n\n\t/** Fetch a single cursor page of an Index collection. */\n\tprivate async getPage<K extends string, T>(\n\t\tpath: string,\n\t\tkey: K,\n\t\tparams: URLSearchParams,\n\t): Promise<{ items: T[]; next_cursor: string | null }> {\n\t\tconst env: Envelope<K, T> = await this.get(\n\t\t\t`${this.indexBaseUrl}${path}?${params}`,\n\t\t\tthis.indexApiKey,\n\t\t);\n\t\treturn { items: env[key], next_cursor: env.next_cursor };\n\t}\n\n\t/** Drain a cursor-paginated Index collection over [fromHeight, toHeight]. */\n\tprivate async walk<K extends string, T>(\n\t\tpath: string,\n\t\tkey: K,\n\t\tfromHeight: number,\n\t\ttoHeight: number,\n\t\textraParams: Record<string, string> = {},\n\t): Promise<T[]> {\n\t\tconst out: T[] = [];\n\t\tlet cursor: string | null = null;\n\t\tdo {\n\t\t\tconst params = new URLSearchParams({\n\t\t\t\tto_height: String(toHeight),\n\t\t\t\tlimit: String(PAGE_LIMIT),\n\t\t\t\t...extraParams,\n\t\t\t});\n\t\t\t// from_height and cursor are mutually exclusive — anchor the first page\n\t\t\t// by height, then page forward by cursor only.\n\t\t\tif (cursor) params.set(\"cursor\", cursor);\n\t\t\telse params.set(\"from_height\", String(fromHeight));\n\t\t\tconst { items, next_cursor } = await this.getPage<K, T>(\n\t\t\t\tpath,\n\t\t\t\tkey,\n\t\t\t\tparams,\n\t\t\t);\n\t\t\tout.push(...items);\n\t\t\tcursor = next_cursor;\n\t\t} while (cursor);\n\t\treturn out;\n\t}\n\n\t/**\n\t * Fetch ONE page of contract-call transactions filtered to `contractId`.\n\t * Unlike walk(), this does NOT drain — the caller pages by feeding back\n\t * next_cursor — so a sparse high-volume filter (e.g. a single contract over\n\t * all history) costs one request per batch, not O(all-history) per tick.\n\t * `cursor` is exclusive (rows strictly after it); on the first call pass\n\t * `fromHeight` to anchor the backfill start instead.\n\t */\n\tasync fetchContractCalls(\n\t\tcontractId: string,\n\t\topts: {\n\t\t\ttoHeight: number;\n\t\t\tcursor?: string | null;\n\t\t\tfromHeight?: number;\n\t\t\tlimit?: number;\n\t\t},\n\t): Promise<{\n\t\ttransactions: IndexTransactionRow[];\n\t\tnext_cursor: string | null;\n\t}> {\n\t\tconst params = new URLSearchParams({\n\t\t\tto_height: String(opts.toHeight),\n\t\t\tlimit: String(opts.limit ?? PAGE_LIMIT),\n\t\t\tcontract_id: contractId,\n\t\t});\n\t\tif (opts.cursor) params.set(\"cursor\", opts.cursor);\n\t\telse params.set(\"from_height\", String(opts.fromHeight ?? 0));\n\t\tconst { items, next_cursor } = await this.getPage<\n\t\t\t\"transactions\",\n\t\t\tIndexTransactionRow\n\t\t>(\"/v1/index/transactions\", \"transactions\", params);\n\t\treturn { transactions: items, next_cursor };\n\t}\n\n\twalkBlocks(fromHeight: number, toHeight: number): Promise<IndexBlockRow[]> {\n\t\treturn this.walk<\"blocks\", IndexBlockRow>(\n\t\t\t\"/v1/index/blocks\",\n\t\t\t\"blocks\",\n\t\t\tfromHeight,\n\t\t\ttoHeight,\n\t\t);\n\t}\n\n\t/** Lowest block height in [fromHeight, toHeight] with a matching event, or\n\t * null. One page, limit 1 — built for sparse-scan probes. */\n\tasync firstEventHeight(\n\t\teventType: string,\n\t\tfromHeight: number,\n\t\ttoHeight: number,\n\t\tcontractId?: string,\n\t): Promise<number | null> {\n\t\tconst params = new URLSearchParams({\n\t\t\tevent_type: eventType,\n\t\t\tfrom_height: String(fromHeight),\n\t\t\tto_height: String(toHeight),\n\t\t\tlimit: \"1\",\n\t\t\t...(contractId ? { contract_id: contractId } : {}),\n\t\t});\n\t\tconst { items } = await this.getPage<\"events\", IndexEventRow>(\n\t\t\t\"/v1/index/events\",\n\t\t\t\"events\",\n\t\t\tparams,\n\t\t);\n\t\treturn items[0]?.block_height ?? null;\n\t}\n\n\twalkEvents(\n\t\teventType: string,\n\t\tfromHeight: number,\n\t\ttoHeight: number,\n\t\t/** Join the submitting tx so each row carries `tx_*` — lets an event-only\n\t\t * subgraph skip walkTransactions and build `ctx.tx` from the event. */\n\t\twithTx = false,\n\t): Promise<IndexEventRow[]> {\n\t\treturn this.walk<\"events\", IndexEventRow>(\n\t\t\t\"/v1/index/events\",\n\t\t\t\"events\",\n\t\t\tfromHeight,\n\t\t\ttoHeight,\n\t\t\t{\n\t\t\t\tevent_type: eventType,\n\t\t\t\t...(withTx ? { tx_context: \"true\" } : {}),\n\t\t\t},\n\t\t);\n\t}\n\n\twalkTransactions(\n\t\tfromHeight: number,\n\t\ttoHeight: number,\n\t): Promise<IndexTransactionRow[]> {\n\t\treturn this.walk<\"transactions\", IndexTransactionRow>(\n\t\t\t\"/v1/index/transactions\",\n\t\t\t\"transactions\",\n\t\t\tfromHeight,\n\t\t\ttoHeight,\n\t\t);\n\t}\n\n\t/** Canonical tip height from the Streams clock. */\n\tasync getStreamsTip(): Promise<number> {\n\t\tconst tip = await this.get<{ block_height: number }>(\n\t\t\t`${this.streamsBaseUrl}/v1/streams/tip`,\n\t\t\tthis.streamsApiKey,\n\t\t);\n\t\treturn Number(tip.block_height) || 0;\n\t}\n\n\t/**\n\t * Highest block height the Index data plane can serve (tip is inline in every\n\t * envelope). This is the data-availability bound — a consumer must not\n\t * process past it, even if the Streams clock is ahead.\n\t *\n\t * `opts.wait` (seconds, clamped to `MAX_INDEX_WAIT_SECONDS`) long-polls:\n\t * the server holds the request until a fresher tip than `opts.knownHeight`\n\t * is available or `wait` elapses (plan-063 3.4/3.5). Pass `knownHeight` —\n\t * the last tip THIS caller observed — or `wait` is a no-op (nothing to\n\t * compare against). A caller that only wants the plain tip omits both.\n\t */\n\tasync getIndexTip(opts?: {\n\t\twait?: number;\n\t\tknownHeight?: number;\n\t}): Promise<number> {\n\t\t// `tip_only`: this method never reads `blocks[]`, only `tip`, so the\n\t\t// server can skip the row query. It ALSO fixes what `tip_only` exists\n\t\t// for: `blocks.length` is governed by the SOURCE tip (`/blocks` windows\n\t\t// to it), but `knownHeight` here is the DECODED tip this method itself\n\t\t// returns — comparing against raw rows made an idle `wait` return\n\t\t// almost instantly whenever ingest ran even slightly ahead of decode\n\t\t// (routes/index.ts's /blocks handler judges emptiness against\n\t\t// `tip.block_height` directly when `tip_only` is set, sidestepping the\n\t\t// mismatch). Do NOT set this on `getIndexSourceTip` below — its\n\t\t// `knownHeight` baseline is the source tip already, so the row-based\n\t\t// check is the CORRECT one there, not a bug to route around.\n\t\tconst env = await this.getIndexTipEnvelope({ ...opts, tipOnly: true });\n\t\treturn Number(env.tip?.block_height) || 0;\n\t}\n\n\t/** Ingest tip. VM rows land with the block; decoded `block_height` can lag.\n\t * Same `wait`/`knownHeight` long-poll contract as {@link getIndexTip}. */\n\tasync getIndexSourceTip(opts?: {\n\t\twait?: number;\n\t\tknownHeight?: number;\n\t}): Promise<number> {\n\t\tconst env = await this.getIndexTipEnvelope(opts);\n\t\treturn Number(env.tip?.source_block_height ?? env.tip?.block_height) || 0;\n\t}\n\n\t/**\n\t * Per-decoder committed heights from the last tip envelope fetched by\n\t * `getIndexTip()`/`getIndexSourceTip()` — reads the cached response, no\n\t * extra request. `undefined` before either has been called, or against an\n\t * older server that doesn't send the field. A caller (the chain evaluator)\n\t * uses this to bound itself by the decoders it actually reads instead of\n\t * the conservative cross-decoder floor `block_height` itself carries.\n\t */\n\tgetDecodedHeights(): Record<string, number | null> | undefined {\n\t\treturn this.lastTipEnvelope?.tip.decoded_heights;\n\t}\n\n\t/** False once a `wait`/`tip_only` request has 400'd on THIS client instance\n\t * (see the catch in `getIndexTipEnvelope`) — an older server that doesn't\n\t * recognize these params. A caller that reuses one client across many\n\t * calls (the chain evaluator, plan-063 3.5) uses this to stop scheduling\n\t * itself as if `wait` actually blocked, instead of re-discovering the 400\n\t * on every single call. */\n\twaitIsSupported(): boolean {\n\t\treturn this.waitSupported;\n\t}\n\n\tprivate async getIndexTipEnvelope(opts?: {\n\t\twait?: number;\n\t\tknownHeight?: number;\n\t\ttipOnly?: boolean;\n\t}): Promise<IndexTipEnvelope> {\n\t\tconst wantsWait = this.waitSupported && (opts?.wait ?? 0) > 0;\n\t\tconst wantsTipOnly = this.waitSupported && Boolean(opts?.tipOnly);\n\t\tconst params = new URLSearchParams({ limit: \"1\" });\n\t\tif (wantsTipOnly) params.set(\"tip_only\", \"true\");\n\t\tif (wantsWait) {\n\t\t\tparams.set(\n\t\t\t\t\"wait\",\n\t\t\t\tString(Math.min(MAX_INDEX_WAIT_SECONDS, Math.max(0, opts?.wait ?? 0))),\n\t\t\t);\n\t\t\t// `from_height` is what makes the wait meaningful here: with no cursor,\n\t\t\t// `/v1/index/blocks?limit=1` always returns a row (the default window's\n\t\t\t// oldest block), so the server would never see \"nothing new\" to wait\n\t\t\t// on. Anchoring one past the last height THIS caller saw makes the page\n\t\t\t// empty until a fresher block lands — the same signal the endpoint\n\t\t\t// already uses for a normal forward walk.\n\t\t\tif (opts?.knownHeight !== undefined) {\n\t\t\t\tparams.set(\"from_height\", String(opts.knownHeight + 1));\n\t\t\t}\n\t\t}\n\t\ttry {\n\t\t\tconst env = await this.get<IndexTipEnvelope>(\n\t\t\t\t`${this.indexBaseUrl}/v1/index/blocks?${params}`,\n\t\t\t\tthis.indexApiKey,\n\t\t\t);\n\t\t\tthis.lastTipEnvelope = env;\n\t\t\treturn env;\n\t\t} catch (err) {\n\t\t\t// An older server's `validateQueryParams` 400s on `wait`/`from_height`/\n\t\t\t// `tip_only` it doesn't recognize. Treat that ONE status as \"this\n\t\t\t// server predates long-poll\", not an outage: disable BOTH extensions\n\t\t\t// for the rest of this client's life and retry plainly, so\n\t\t\t// `FallbackBlockSource` never mistakes a version-skew 400 for the api\n\t\t\t// being down and routes to the DB tap. Gating retry on `wantsWait ||\n\t\t\t// wantsTipOnly` (not `wantsWait` alone) matters mid-rollout: a server\n\t\t\t// already upgraded for `wait` but not yet for `tip_only` (or vice\n\t\t\t// versa) still 400s on the one it doesn't know, even on a plain,\n\t\t\t// non-waiting `getIndexTip()` call.\n\t\t\tif (\n\t\t\t\t(wantsWait || wantsTipOnly) &&\n\t\t\t\terr instanceof IndexHttpStatusError &&\n\t\t\t\terr.status === 400\n\t\t\t) {\n\t\t\t\tthis.waitSupported = false;\n\t\t\t\treturn this.getIndexTipEnvelope(opts);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/** Reorgs since a resume token (wall-clock `detected_at`-keyed). */\n\tasync listReorgs(\n\t\tsince: string,\n\t): Promise<{ reorgs: StreamsReorgRow[]; next_since: string | null }> {\n\t\tconst params = new URLSearchParams({ since });\n\t\treturn this.get(\n\t\t\t`${this.streamsBaseUrl}/v1/streams/reorgs?${params}`,\n\t\t\tthis.streamsApiKey,\n\t\t);\n\t}\n}\n\n/** Decoder + subgraph processor client. One env contract; omits bearer when no key. */\nexport function createInternalIndexHttpClient(): IndexHttpClient {\n\tconst baseUrl = defaultInternalIndexBaseUrl();\n\treturn new IndexHttpClient({\n\t\tindexBaseUrl: baseUrl,\n\t\tstreamsBaseUrl: baseUrl,\n\t\tindexApiKey: defaultInternalIndexApiKey(),\n\t\tstreamsApiKey: defaultInternalStreamsApiKey(),\n\t});\n}\n"
|
|
7
7
|
],
|
|
8
|
-
"mappings": ";AAaO,IAAM,2BAA2B;AACjC,IAAM,6BAA6B;AAE1C,IAAM,kCAAkC;AAExC,IAAM,mCACL;AAED,IAAM,iCACL;AAEM,SAAS,0BAA0B,CACzC,MAAyB,QAAQ,KACZ;AAAA,EACrB,MAAM,WAAW,IAAI,wBAAwB,KAAK;AAAA,EAClD,IAAI;AAAA,IAAU,OAAO;AAAA,EACrB,MAAM,WAAW,IAAI,gBAAgB,KAAK;AAAA,EAC1C,IAAI;AAAA,IAAU,OAAO;AAAA,EACrB;AAAA;AAGM,SAAS,4BAA4B,CAC3C,MAAyB,QAAQ,KACZ;AAAA,EACrB,MAAM,WAAW,IAAI,0BAA0B,KAAK;AAAA,EACpD,IAAI;AAAA,IAAU,OAAO;AAAA,EACrB,MAAM,WAAW,IAAI,gBAAgB,KAAK;AAAA,EAC1C,IAAI;AAAA,IAAU,OAAO;AAAA,EACrB;AAAA;AAaM,SAAS,0BAA0B,CACzC,MAAyB,QAAQ,KACxB;AAAA,EACT,MAAM,MAAM,2BAA2B,GAAG;AAAA,EAC1C,IAAI,CAAC;AAAA,IAAK,MAAM,IAAI,MAAM,8BAA8B;AAAA,EACxD,OAAO;AAAA;AAID,SAAS,4BAA4B,CAC3C,MAAyB,QAAQ,KACxB;AAAA,EACT,MAAM,MAAM,6BAA6B,GAAG;AAAA,EAC5C,IAAI,CAAC;AAAA,IAAK,MAAM,IAAI,MAAM,gCAAgC;AAAA,EAC1D,OAAO;AAAA;AAID,SAAS,2BAA2B,GAAW;AAAA,EACrD,OACC,QAAQ,IAAI,0BACZ,QAAQ,IAAI,mBACZ;AAAA;;;AC1DF,IAAM,aAAa;
|
|
9
|
-
"debugId": "
|
|
8
|
+
"mappings": "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",
|
|
9
|
+
"debugId": "86DE9405EBDF6BE664756E2164756E21",
|
|
10
10
|
"names": []
|
|
11
11
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2046,6 +2046,23 @@ declare const TABLE_TO_DB: {
|
|
|
2046
2046
|
};
|
|
2047
2047
|
/** OSS: one application URL. SOURCE_/TARGET_ are hosted split only. */
|
|
2048
2048
|
declare function applicationDatabaseUrl(): string;
|
|
2049
|
+
/**
|
|
2050
|
+
* Canonical source-DB URL — the ONE place that decides it. Exported so a
|
|
2051
|
+
* LISTEN connection (`queue/listener.ts`) resolves the same database a write
|
|
2052
|
+
* through `getSourceDb()` commits to; a second, hand-duplicated resolution
|
|
2053
|
+
* that skips the `isPlatformMode()` gate silently listens on the wrong
|
|
2054
|
+
* database whenever a process isn't in platform mode but `SOURCE_DATABASE_URL`
|
|
2055
|
+
* happens to be set anyway (a shared env template, a staging box) — a NOTIFY
|
|
2056
|
+
* on the real (gated) URL then never reaches it.
|
|
2057
|
+
*/
|
|
2058
|
+
declare function resolveSourceUrl(): string;
|
|
2059
|
+
/** Canonical target-DB URL — see {@link resolveSourceUrl}. */
|
|
2060
|
+
declare function resolveTargetUrl(): string;
|
|
2061
|
+
/** Host[:port]/dbname for a connection URL — credentials stripped. Exported
|
|
2062
|
+
* so anything logging which database it connected to (a LISTEN channel's
|
|
2063
|
+
* startup log, an ops health check) can describe it without ever printing a
|
|
2064
|
+
* password. */
|
|
2065
|
+
declare function describeDbUrl(url: string): string;
|
|
2049
2066
|
interface DbSplitStatus {
|
|
2050
2067
|
/** "split" when source/target resolve to different DBs, else "single". */
|
|
2051
2068
|
mode: "split" | "single";
|
|
@@ -3101,4 +3118,4 @@ declare function publicKeyPemFromPrivate(privateKeyPem: string): string;
|
|
|
3101
3118
|
declare function ed25519KeyId(publicKeyPem: string): string;
|
|
3102
3119
|
declare function signEd25519(payload: string, privateKey: KeyObject): string;
|
|
3103
3120
|
declare function verifyEd25519(payload: string, signatureBase64: string, publicKey: KeyObject): boolean;
|
|
3104
|
-
export { Account, AccountCredits, AccountCreditsTable, AccountSpendCap, AccountSpendCapsTable, AccountsTable, ApiKey, ApiKeysTable, ArchiveFetch, ArchiveFetchesTable, AuthenticationError, AuthorizationError, Block, BlocksTable, BnsMarketplaceAction, BnsMarketplaceEventsTable, BnsNameEventTopic, BnsNameEventsTable, BnsNamesTable, BnsNamespaceEventStatus, BnsNamespaceEventsTable, BnsNamespacesTable, BurnBlockRewardSlotsTable, BurnBlockRewardsTable, CHAIN_TRIGGER_FIELDS, CHAIN_TRIGGER_TYPES, CODE_TO_STATUS, ChainApplyDeliveryOf, ChainApplyEnvelope, ChainApplyEnvelopeOf, ChainEventEnvelope, ChainFtBurnData, ChainFtMintData, ChainFtTransferData, ChainNftBurnData, ChainNftMintData, ChainNftTransferData, ChainPrintEventData, ChainReadCacheTable, ChainReorgOrphanedEntry, ChainReorgRollbackDelivery, ChainReorgRollbackEnvelope, ChainReorgsTable, ChainStxBurnData, ChainStxLockData, ChainStxMintData, ChainStxTransferData, ChainTestDelivery, ChainTxLevelEvent, ChainWebhookDelivery, ChainWebhookEnvelope, Contract, ContractsTable, CoverageSegmentsTable, CreateWebhookRequest, CreateWebhookRequestSchema, CreateWebhookResponse, DB_TO_STREAMS_EVENT_TYPE, DECODED_EVENT_TYPES2 as DECODED_EVENT_TYPES, DEFAULT_BTC_CONFIRMATIONS, Database, DatabaseError, DbPlane, DbReadRow, DbSplitStatus, DeadLetterEventsTable, DeadRow, DecodedEventType2 as DecodedEventType, DecodedEventsTable, DecoderCheckpointsTable, DeliveryRow, DeploySubgraphRequest, DeploySubgraphRequestSchema, DeploySubgraphResponse, EMPTY_RANGE_EVENT_INDEX_SENTINEL, Env, ErrorCode, ErrorCodes, Event, EventsArchiveTable, EventsTable, FailureClass, FailureUnit, ForbiddenError, IndexColumn, IndexColumnType, IndexPrimaryKey, IndexProgress, IndexProgressTable, InsertAccount, InsertAccountCredits, InsertAccountSpendCap, InsertApiKey, InsertArchiveFetch, InsertBlock, InsertContract, InsertEvent, InsertIndexProgress, InsertMagicLink, InsertMempoolTransaction, InsertSession, InsertSubgraph, InsertSubgraphGap, InsertSubgraphHealthSnapshot, InsertSubgraphOperation, InsertTransaction, InsertUsageLedgerRow, InsertVmEvent, InsertWaitlistSignup, InsertWebhook, InsertWebhookDelivery, InsertWebhookOutbox, InstancesTable, KeyRotatedError, MagicLink, MagicLinksTable, MempoolTransaction, MempoolTransactionsTable, MigrationRole, NativeClock, NotFoundError, NumericAsText, ObserverJournalStatus, ObserverJournalTable, OutboxStatus, ParsedCreateWebhookRequest, ParsedReplayWebhookRequest, ParsedUpdateWebhookRequest, PaymentRequiredError, PendingForkBlocksTable, Pox4CallsTable, Pox4FunctionName, Pox5EventTopic, Pox5EventsTable, ProcessedStripeEventsTable, RateLimitError, ReindexResponse, RepairMode, ReplayResult, ReplayWebhookRequest, ReplayWebhookRequestSchema, RetryState, RotateSecretResponse, RunStatus, SOURCE_READ_COLUMNS, SOURCE_READ_PKS, SOURCE_READ_TYPES, STREAMS_DB_EVENT_TYPES, STREAMS_EVENT_TYPES, STREAMS_TO_DB_EVENT_TYPES, SbtcDepositEvent, SbtcEventTopic, SbtcEventsTable, SbtcSettlementsTable, SbtcTokenEventType, SbtcTokenEventsTable, SbtcWithdrawalEvent, SbtcWithdrawalSweptConfirmedEvent, SecondLayerError, ServiceHeartbeatsTable, Session, SessionsTable, StageBlockReceiptsTable, StageFailuresTable, StageKind, StageRegistryTable, StageRunsTable, StreamsCursor, StreamsDbEventType, StreamsEventType, Subgraph, SubgraphAgentSchema, SubgraphAggregateParams, SubgraphAggregateResponse, SubgraphDetail, SubgraphGap, SubgraphGapEntry, SubgraphGapRange, SubgraphGapsResponse, SubgraphGapsTable, SubgraphHealthSnapshot, SubgraphHealthSnapshotsTable, SubgraphOperation, SubgraphOperationKind, SubgraphOperationStatus, SubgraphOperationsTable, SubgraphProcessingStatsTable, SubgraphQueryParams, SubgraphSpecFormat, SubgraphSpecOptions, SubgraphSummary, SubgraphSyncInfo, SubgraphViolationsTable, SubgraphsTable, SyncScopesTable, TABLE_TO_DB, TenantSuspendedError, Transaction, TransactionsArchiveTable, TransactionsTable, TriggerEvaluatorState, TriggerEvaluatorStateTable, UpdateAccountCredits, UpdateAccountSpendCap, UpdateApiKey, UpdateArchiveFetch, UpdateBlock, UpdateContract, UpdateEvent, UpdateIndexProgress, UpdateSubgraph, UpdateSubgraphOperation, UpdateTransaction, UpdateUsageLedgerRow, UpdateVmEvent, UpdateWebhook, UpdateWebhookOutbox, UpdateWebhookRequest, UpdateWebhookRequestSchema, UsageLedgerRow, UsageLedgerTable, VM_EVENT_TYPES, VM_NODE_TO_STORED_TYPE2 as VM_NODE_TO_STORED_TYPE, VM_STORED_TO_NODE_TYPE, ValidationError, VersionConflictError, VmEvent, VmEventType, VmEventsArchiveTable, VmEventsTable, VmNodeEventType, WEBHOOK_FILTER_OPERATORS, WEBHOOK_FORMATS, WEBHOOK_RUNTIMES, WEBHOOK_STATUSES, Waitlist, WaitlistSignup, WaitlistSignupsTable, WaitlistsTable, Webhook, WebhookDeliveriesTable, WebhookDelivery, WebhookDetail, WebhookFilter, WebhookFilterClause, WebhookFilterClauseSchema, WebhookFilterOperator, WebhookFilterOperatorSchema, WebhookFilterPrimitive, WebhookFilterPrimitiveSchema, WebhookFilterSchema, WebhookFormat, WebhookFormatSchema, WebhookKind, WebhookOutbox, WebhookOutboxTable, WebhookRuntime, WebhookRuntimeSchema, WebhookSchemaColumn, WebhookSchemaTable, WebhookSchemaTables, WebhookStatus, WebhookStatusSchema, WebhookSummary, WebhooksTable, applicationDatabaseUrl, assertDbSplit, blockEndCursor, closeDb, committedHeight, compareStreamsCursor, exports_hmac as crypto, decodeStreamsCursor, exports_ed25519 as ed25519, encodeStreamsCursor, finalizedBurnHeight, formatWebhookSchemaErrors, generateSubgraphAgentSchema, generateSubgraphMarkdown, generateSubgraphOpenApi, generateSubgraphSpec, getDb, getDbSplitStatus, getEnv, getErrorMessage, getMigrationRole, getRawClient, getRawClientFor, getSourceDb, getTargetDb, isBnsDecoderEnabled, isEmptyRangeCursor, isPox4DecoderEnabled, isPox5DecoderEnabled, isSbtcDecoderEnabled, jsonb, logger, onChainPlane, onControlPlane, parseJsonb, setMigrationRole, sql, validateWebhookFilterForTable };
|
|
3121
|
+
export { Account, AccountCredits, AccountCreditsTable, AccountSpendCap, AccountSpendCapsTable, AccountsTable, ApiKey, ApiKeysTable, ArchiveFetch, ArchiveFetchesTable, AuthenticationError, AuthorizationError, Block, BlocksTable, BnsMarketplaceAction, BnsMarketplaceEventsTable, BnsNameEventTopic, BnsNameEventsTable, BnsNamesTable, BnsNamespaceEventStatus, BnsNamespaceEventsTable, BnsNamespacesTable, BurnBlockRewardSlotsTable, BurnBlockRewardsTable, CHAIN_TRIGGER_FIELDS, CHAIN_TRIGGER_TYPES, CODE_TO_STATUS, ChainApplyDeliveryOf, ChainApplyEnvelope, ChainApplyEnvelopeOf, ChainEventEnvelope, ChainFtBurnData, ChainFtMintData, ChainFtTransferData, ChainNftBurnData, ChainNftMintData, ChainNftTransferData, ChainPrintEventData, ChainReadCacheTable, ChainReorgOrphanedEntry, ChainReorgRollbackDelivery, ChainReorgRollbackEnvelope, ChainReorgsTable, ChainStxBurnData, ChainStxLockData, ChainStxMintData, ChainStxTransferData, ChainTestDelivery, ChainTxLevelEvent, ChainWebhookDelivery, ChainWebhookEnvelope, Contract, ContractsTable, CoverageSegmentsTable, CreateWebhookRequest, CreateWebhookRequestSchema, CreateWebhookResponse, DB_TO_STREAMS_EVENT_TYPE, DECODED_EVENT_TYPES2 as DECODED_EVENT_TYPES, DEFAULT_BTC_CONFIRMATIONS, Database, DatabaseError, DbPlane, DbReadRow, DbSplitStatus, DeadLetterEventsTable, DeadRow, DecodedEventType2 as DecodedEventType, DecodedEventsTable, DecoderCheckpointsTable, DeliveryRow, DeploySubgraphRequest, DeploySubgraphRequestSchema, DeploySubgraphResponse, EMPTY_RANGE_EVENT_INDEX_SENTINEL, Env, ErrorCode, ErrorCodes, Event, EventsArchiveTable, EventsTable, FailureClass, FailureUnit, ForbiddenError, IndexColumn, IndexColumnType, IndexPrimaryKey, IndexProgress, IndexProgressTable, InsertAccount, InsertAccountCredits, InsertAccountSpendCap, InsertApiKey, InsertArchiveFetch, InsertBlock, InsertContract, InsertEvent, InsertIndexProgress, InsertMagicLink, InsertMempoolTransaction, InsertSession, InsertSubgraph, InsertSubgraphGap, InsertSubgraphHealthSnapshot, InsertSubgraphOperation, InsertTransaction, InsertUsageLedgerRow, InsertVmEvent, InsertWaitlistSignup, InsertWebhook, InsertWebhookDelivery, InsertWebhookOutbox, InstancesTable, KeyRotatedError, MagicLink, MagicLinksTable, MempoolTransaction, MempoolTransactionsTable, MigrationRole, NativeClock, NotFoundError, NumericAsText, ObserverJournalStatus, ObserverJournalTable, OutboxStatus, ParsedCreateWebhookRequest, ParsedReplayWebhookRequest, ParsedUpdateWebhookRequest, PaymentRequiredError, PendingForkBlocksTable, Pox4CallsTable, Pox4FunctionName, Pox5EventTopic, Pox5EventsTable, ProcessedStripeEventsTable, RateLimitError, ReindexResponse, RepairMode, ReplayResult, ReplayWebhookRequest, ReplayWebhookRequestSchema, RetryState, RotateSecretResponse, RunStatus, SOURCE_READ_COLUMNS, SOURCE_READ_PKS, SOURCE_READ_TYPES, STREAMS_DB_EVENT_TYPES, STREAMS_EVENT_TYPES, STREAMS_TO_DB_EVENT_TYPES, SbtcDepositEvent, SbtcEventTopic, SbtcEventsTable, SbtcSettlementsTable, SbtcTokenEventType, SbtcTokenEventsTable, SbtcWithdrawalEvent, SbtcWithdrawalSweptConfirmedEvent, SecondLayerError, ServiceHeartbeatsTable, Session, SessionsTable, StageBlockReceiptsTable, StageFailuresTable, StageKind, StageRegistryTable, StageRunsTable, StreamsCursor, StreamsDbEventType, StreamsEventType, Subgraph, SubgraphAgentSchema, SubgraphAggregateParams, SubgraphAggregateResponse, SubgraphDetail, SubgraphGap, SubgraphGapEntry, SubgraphGapRange, SubgraphGapsResponse, SubgraphGapsTable, SubgraphHealthSnapshot, SubgraphHealthSnapshotsTable, SubgraphOperation, SubgraphOperationKind, SubgraphOperationStatus, SubgraphOperationsTable, SubgraphProcessingStatsTable, SubgraphQueryParams, SubgraphSpecFormat, SubgraphSpecOptions, SubgraphSummary, SubgraphSyncInfo, SubgraphViolationsTable, SubgraphsTable, SyncScopesTable, TABLE_TO_DB, TenantSuspendedError, Transaction, TransactionsArchiveTable, TransactionsTable, TriggerEvaluatorState, TriggerEvaluatorStateTable, UpdateAccountCredits, UpdateAccountSpendCap, UpdateApiKey, UpdateArchiveFetch, UpdateBlock, UpdateContract, UpdateEvent, UpdateIndexProgress, UpdateSubgraph, UpdateSubgraphOperation, UpdateTransaction, UpdateUsageLedgerRow, UpdateVmEvent, UpdateWebhook, UpdateWebhookOutbox, UpdateWebhookRequest, UpdateWebhookRequestSchema, UsageLedgerRow, UsageLedgerTable, VM_EVENT_TYPES, VM_NODE_TO_STORED_TYPE2 as VM_NODE_TO_STORED_TYPE, VM_STORED_TO_NODE_TYPE, ValidationError, VersionConflictError, VmEvent, VmEventType, VmEventsArchiveTable, VmEventsTable, VmNodeEventType, WEBHOOK_FILTER_OPERATORS, WEBHOOK_FORMATS, WEBHOOK_RUNTIMES, WEBHOOK_STATUSES, Waitlist, WaitlistSignup, WaitlistSignupsTable, WaitlistsTable, Webhook, WebhookDeliveriesTable, WebhookDelivery, WebhookDetail, WebhookFilter, WebhookFilterClause, WebhookFilterClauseSchema, WebhookFilterOperator, WebhookFilterOperatorSchema, WebhookFilterPrimitive, WebhookFilterPrimitiveSchema, WebhookFilterSchema, WebhookFormat, WebhookFormatSchema, WebhookKind, WebhookOutbox, WebhookOutboxTable, WebhookRuntime, WebhookRuntimeSchema, WebhookSchemaColumn, WebhookSchemaTable, WebhookSchemaTables, WebhookStatus, WebhookStatusSchema, WebhookSummary, WebhooksTable, applicationDatabaseUrl, assertDbSplit, blockEndCursor, closeDb, committedHeight, compareStreamsCursor, exports_hmac as crypto, decodeStreamsCursor, describeDbUrl, exports_ed25519 as ed25519, encodeStreamsCursor, finalizedBurnHeight, formatWebhookSchemaErrors, generateSubgraphAgentSchema, generateSubgraphMarkdown, generateSubgraphOpenApi, generateSubgraphSpec, getDb, getDbSplitStatus, getEnv, getErrorMessage, getMigrationRole, getRawClient, getRawClientFor, getSourceDb, getTargetDb, isBnsDecoderEnabled, isEmptyRangeCursor, isPox4DecoderEnabled, isPox5DecoderEnabled, isSbtcDecoderEnabled, jsonb, logger, onChainPlane, onControlPlane, parseJsonb, resolveSourceUrl, resolveTargetUrl, setMigrationRole, sql, validateWebhookFilterForTable };
|
package/dist/src/index.js
CHANGED
|
@@ -2171,6 +2171,7 @@ export {
|
|
|
2171
2171
|
compareStreamsCursor,
|
|
2172
2172
|
exports_hmac as crypto,
|
|
2173
2173
|
decodeStreamsCursor,
|
|
2174
|
+
describeDbUrl,
|
|
2174
2175
|
exports_ed25519 as ed25519,
|
|
2175
2176
|
encodeStreamsCursor,
|
|
2176
2177
|
finalizedBurnHeight,
|
|
@@ -2198,10 +2199,12 @@ export {
|
|
|
2198
2199
|
onChainPlane,
|
|
2199
2200
|
onControlPlane,
|
|
2200
2201
|
parseJsonb,
|
|
2202
|
+
resolveSourceUrl,
|
|
2203
|
+
resolveTargetUrl,
|
|
2201
2204
|
setMigrationRole,
|
|
2202
2205
|
sql2 as sql,
|
|
2203
2206
|
validateWebhookFilterForTable
|
|
2204
2207
|
};
|
|
2205
2208
|
|
|
2206
|
-
//# debugId=
|
|
2209
|
+
//# debugId=B12885A371ED0F4264756E2164756E21
|
|
2207
2210
|
//# sourceMappingURL=index.js.map
|