@notuslabs/yail 0.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/LICENSE +21 -0
- package/README.md +226 -0
- package/bin/yail.js +7 -0
- package/dist/addresses/registry.d.ts +57 -0
- package/dist/addresses/registry.d.ts.map +1 -0
- package/dist/addresses/registry.js +131 -0
- package/dist/addresses/registry.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +204 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/address.d.ts +32 -0
- package/dist/config/address.d.ts.map +1 -0
- package/dist/config/address.js +31 -0
- package/dist/config/address.js.map +1 -0
- package/dist/config/chain-ref.d.ts +5 -0
- package/dist/config/chain-ref.d.ts.map +1 -0
- package/dist/config/chain-ref.js +13 -0
- package/dist/config/chain-ref.js.map +1 -0
- package/dist/config/create-config.d.ts +9 -0
- package/dist/config/create-config.d.ts.map +1 -0
- package/dist/config/create-config.js +86 -0
- package/dist/config/create-config.js.map +1 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +3 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +113 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/db/batch.d.ts +33 -0
- package/dist/db/batch.d.ts.map +1 -0
- package/dist/db/batch.js +71 -0
- package/dist/db/batch.js.map +1 -0
- package/dist/db/client.d.ts +50 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +104 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/index.d.ts +11 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +7 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/internal.d.ts +2332 -0
- package/dist/db/internal.d.ts.map +1 -0
- package/dist/db/internal.js +75 -0
- package/dist/db/internal.js.map +1 -0
- package/dist/db/migrate.d.ts +22 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +72 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/serialize.d.ts +14 -0
- package/dist/db/serialize.d.ts.map +1 -0
- package/dist/db/serialize.js +133 -0
- package/dist/db/serialize.js.map +1 -0
- package/dist/db/sql.d.ts +44 -0
- package/dist/db/sql.d.ts.map +1 -0
- package/dist/db/sql.js +122 -0
- package/dist/db/sql.js.map +1 -0
- package/dist/http/client.d.ts +40 -0
- package/dist/http/client.d.ts.map +1 -0
- package/dist/http/client.js +128 -0
- package/dist/http/client.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/context.d.ts +84 -0
- package/dist/indexer/context.d.ts.map +1 -0
- package/dist/indexer/context.js +45 -0
- package/dist/indexer/context.js.map +1 -0
- package/dist/indexer/events.d.ts +87 -0
- package/dist/indexer/events.d.ts.map +1 -0
- package/dist/indexer/events.js +88 -0
- package/dist/indexer/events.js.map +1 -0
- package/dist/indexer/indexer.d.ts +114 -0
- package/dist/indexer/indexer.d.ts.map +1 -0
- package/dist/indexer/indexer.js +237 -0
- package/dist/indexer/indexer.js.map +1 -0
- package/dist/indexer/jobs.d.ts +61 -0
- package/dist/indexer/jobs.d.ts.map +1 -0
- package/dist/indexer/jobs.js +170 -0
- package/dist/indexer/jobs.js.map +1 -0
- package/dist/indexer/plan.d.ts +73 -0
- package/dist/indexer/plan.d.ts.map +1 -0
- package/dist/indexer/plan.js +238 -0
- package/dist/indexer/plan.js.map +1 -0
- package/dist/indexer/runtime.d.ts +100 -0
- package/dist/indexer/runtime.d.ts.map +1 -0
- package/dist/indexer/runtime.js +572 -0
- package/dist/indexer/runtime.js.map +1 -0
- package/dist/observability/logger.d.ts +23 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +72 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/metrics.d.ts +61 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +131 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/otel.d.ts +28 -0
- package/dist/observability/otel.d.ts.map +1 -0
- package/dist/observability/otel.js +49 -0
- package/dist/observability/otel.js.map +1 -0
- package/dist/rpc/cached-client.d.ts +33 -0
- package/dist/rpc/cached-client.d.ts.map +1 -0
- package/dist/rpc/cached-client.js +50 -0
- package/dist/rpc/cached-client.js.map +1 -0
- package/dist/schema/column.d.ts +61 -0
- package/dist/schema/column.d.ts.map +1 -0
- package/dist/schema/column.js +76 -0
- package/dist/schema/column.js.map +1 -0
- package/dist/schema/ddl.d.ts +9 -0
- package/dist/schema/ddl.d.ts.map +1 -0
- package/dist/schema/ddl.js +58 -0
- package/dist/schema/ddl.js.map +1 -0
- package/dist/schema/index.d.ts +8 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +5 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/table.d.ts +69 -0
- package/dist/schema/table.d.ts.map +1 -0
- package/dist/schema/table.js +35 -0
- package/dist/schema/table.js.map +1 -0
- package/dist/schema/view.d.ts +19 -0
- package/dist/schema/view.d.ts.map +1 -0
- package/dist/schema/view.js +16 -0
- package/dist/schema/view.js.map +1 -0
- package/dist/server/api.d.ts +11 -0
- package/dist/server/api.d.ts.map +1 -0
- package/dist/server/api.js +71 -0
- package/dist/server/api.js.map +1 -0
- package/dist/sources/cached.d.ts +27 -0
- package/dist/sources/cached.d.ts.map +1 -0
- package/dist/sources/cached.js +111 -0
- package/dist/sources/cached.js.map +1 -0
- package/dist/sources/esplora.d.ts +22 -0
- package/dist/sources/esplora.d.ts.map +1 -0
- package/dist/sources/esplora.js +138 -0
- package/dist/sources/esplora.js.map +1 -0
- package/dist/sources/fixture.d.ts +51 -0
- package/dist/sources/fixture.d.ts.map +1 -0
- package/dist/sources/fixture.js +102 -0
- package/dist/sources/fixture.js.map +1 -0
- package/dist/sources/hypersync.d.ts +19 -0
- package/dist/sources/hypersync.d.ts.map +1 -0
- package/dist/sources/hypersync.js +169 -0
- package/dist/sources/hypersync.js.map +1 -0
- package/dist/sources/index.d.ts +13 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +7 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/rpc.d.ts +21 -0
- package/dist/sources/rpc.d.ts.map +1 -0
- package/dist/sources/rpc.js +187 -0
- package/dist/sources/rpc.js.map +1 -0
- package/dist/sources/types.d.ts +137 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +17 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/testing/index.d.ts +20 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +44 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/util.d.ts +9 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +25 -0
- package/dist/util.js.map +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Table } from "./table.js";
|
|
2
|
+
import type { MaterializedView } from "./view.js";
|
|
3
|
+
import { qualify } from "../db/sql.js";
|
|
4
|
+
export { qualify };
|
|
5
|
+
export declare function tableDdl(table: Table<any>, database?: string): string;
|
|
6
|
+
export declare function materializedViewDdl(view: MaterializedView, database?: string): string;
|
|
7
|
+
/** One-off backfill of a materialized view's target from existing source data. */
|
|
8
|
+
export declare function materializedViewPopulateSql(view: MaterializedView, database?: string): string;
|
|
9
|
+
//# sourceMappingURL=ddl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ddl.d.ts","sourceRoot":"","sources":["../../src/schema/ddl.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,OAAO,EAAa,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,OAAO,EAAE,CAAC;AAEnB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAoCrE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAGrF;AAED,kFAAkF;AAClF,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7F"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { columnTypeSql } from "./column.js";
|
|
2
|
+
import { INDEX_META_COLUMNS } from "./table.js";
|
|
3
|
+
import { qualify, renderSql } from "../db/sql.js";
|
|
4
|
+
export { qualify };
|
|
5
|
+
export function tableDdl(table, database) {
|
|
6
|
+
const cols = [];
|
|
7
|
+
for (const key of table.columnKeys) {
|
|
8
|
+
const col = table.columns[key];
|
|
9
|
+
let line = `\`${table.columnName(key)}\` ${columnTypeSql(col)}`;
|
|
10
|
+
if (col.hasDefault && col.defaultSql)
|
|
11
|
+
line += ` DEFAULT ${col.defaultSql}`;
|
|
12
|
+
if (col.codecSql)
|
|
13
|
+
line += ` CODEC(${col.codecSql})`;
|
|
14
|
+
cols.push(line);
|
|
15
|
+
}
|
|
16
|
+
const meta = table.options.indexMeta !== false;
|
|
17
|
+
if (meta) {
|
|
18
|
+
cols.push(`\`${INDEX_META_COLUMNS.chain}\` LowCardinality(String) DEFAULT ''`);
|
|
19
|
+
cols.push(`\`${INDEX_META_COLUMNS.block}\` UInt64 DEFAULT 0`);
|
|
20
|
+
cols.push(`\`${INDEX_META_COLUMNS.version}\` UInt64 DEFAULT 0`);
|
|
21
|
+
}
|
|
22
|
+
const engine = table.options.engine ?? "ReplacingMergeTree";
|
|
23
|
+
let engineArgs = table.options.engineArgs ?? [];
|
|
24
|
+
if ((engine === "ReplacingMergeTree" || engine === "ReplicatedReplacingMergeTree") && engineArgs.length === 0 && meta) {
|
|
25
|
+
engineArgs = [INDEX_META_COLUMNS.version];
|
|
26
|
+
}
|
|
27
|
+
const orderBy = table.options.orderBy.map((k) => `\`${table.columnName(k)}\``).join(", ");
|
|
28
|
+
const parts = [
|
|
29
|
+
`CREATE TABLE IF NOT EXISTS ${qualify(table.name, database)} (\n ${cols.join(",\n ")}\n)`,
|
|
30
|
+
`ENGINE = ${engine}(${engineArgs.join(", ")})`,
|
|
31
|
+
];
|
|
32
|
+
if (table.options.partitionBy)
|
|
33
|
+
parts.push(`PARTITION BY ${table.options.partitionBy}`);
|
|
34
|
+
parts.push(`ORDER BY (${orderBy})`);
|
|
35
|
+
if (table.options.ttl)
|
|
36
|
+
parts.push(`TTL ${table.options.ttl}`);
|
|
37
|
+
if (table.options.settings && Object.keys(table.options.settings).length > 0) {
|
|
38
|
+
parts.push(`SETTINGS ${Object.entries(table.options.settings)
|
|
39
|
+
.map(([k, v]) => `${k} = ${settingValue(v)}`)
|
|
40
|
+
.join(", ")}`);
|
|
41
|
+
}
|
|
42
|
+
return parts.join("\n");
|
|
43
|
+
}
|
|
44
|
+
export function materializedViewDdl(view, database) {
|
|
45
|
+
const { text } = renderSql(view.query, { inline: true, database });
|
|
46
|
+
return `CREATE MATERIALIZED VIEW IF NOT EXISTS ${qualify(view.name, database)} TO ${qualify(view.to.name, database)} AS\n${text}`;
|
|
47
|
+
}
|
|
48
|
+
/** One-off backfill of a materialized view's target from existing source data. */
|
|
49
|
+
export function materializedViewPopulateSql(view, database) {
|
|
50
|
+
const { text } = renderSql(view.query, { inline: true, database });
|
|
51
|
+
return `INSERT INTO ${qualify(view.to.name, database)}\n${text}`;
|
|
52
|
+
}
|
|
53
|
+
function settingValue(v) {
|
|
54
|
+
if (typeof v === "number")
|
|
55
|
+
return String(v);
|
|
56
|
+
return `'${v}'`;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=ddl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ddl.js","sourceRoot":"","sources":["../../src/schema/ddl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { t, columnTypeSql } from "./column.js";
|
|
2
|
+
export type { Column, ColumnKind } from "./column.js";
|
|
3
|
+
export { table, isTable, snakeCase, INDEX_META_COLUMNS } from "./table.js";
|
|
4
|
+
export type { Table, TableOptions, TableEngine, InsertRow, InferRow, Columns } from "./table.js";
|
|
5
|
+
export { materializedView, isMaterializedView } from "./view.js";
|
|
6
|
+
export type { MaterializedView } from "./view.js";
|
|
7
|
+
export { tableDdl, materializedViewDdl, materializedViewPopulateSql } from "./ddl.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC3E,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACjE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { t, columnTypeSql } from "./column.js";
|
|
2
|
+
export { table, isTable, snakeCase, INDEX_META_COLUMNS } from "./table.js";
|
|
3
|
+
export { materializedView, isMaterializedView } from "./view.js";
|
|
4
|
+
export { tableDdl, materializedViewDdl, materializedViewPopulateSql } from "./ddl.js";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE3E,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEjE,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Column } from "./column.js";
|
|
2
|
+
export type Columns = Record<string, Column<any, boolean, boolean>>;
|
|
3
|
+
export type TableEngine = "MergeTree" | "ReplacingMergeTree" | "SummingMergeTree" | "AggregatingMergeTree" | "CollapsingMergeTree" | "ReplicatedMergeTree" | "ReplicatedReplacingMergeTree";
|
|
4
|
+
export interface TableOptions<C extends Columns> {
|
|
5
|
+
/**
|
|
6
|
+
* Sorting key / primary key. Rows with the same key are deduplicated on
|
|
7
|
+
* ReplacingMergeTree (the default engine), which is what makes re-indexing
|
|
8
|
+
* idempotent. Choose the natural identity of a row (e.g. chain + tx + logIndex).
|
|
9
|
+
*/
|
|
10
|
+
orderBy: ReadonlyArray<keyof C & string>;
|
|
11
|
+
/** Raw ClickHouse PARTITION BY expression, e.g. `toYYYYMM(block_time)`. */
|
|
12
|
+
partitionBy?: string;
|
|
13
|
+
/** Defaults to ReplacingMergeTree versioned by the internal `_yail_version` column. */
|
|
14
|
+
engine?: TableEngine;
|
|
15
|
+
/** Extra engine args (e.g. summed columns for SummingMergeTree). Not needed for Replacing. */
|
|
16
|
+
engineArgs?: string[];
|
|
17
|
+
/** Raw TTL expression. */
|
|
18
|
+
ttl?: string;
|
|
19
|
+
/** Extra SETTINGS for the table. */
|
|
20
|
+
settings?: Record<string, string | number>;
|
|
21
|
+
/**
|
|
22
|
+
* Entity scopes for targeted re-indexing. Keys are scope names (e.g. `wallet`,
|
|
23
|
+
* `pool`) and values are the column holding the entity id. `yail reindex
|
|
24
|
+
* --scope wallet=0xabc` deletes matching rows in every table declaring that scope.
|
|
25
|
+
*/
|
|
26
|
+
scopes?: Record<string, keyof C & string>;
|
|
27
|
+
/**
|
|
28
|
+
* Whether to add the hidden bookkeeping columns `_yail_chain`, `_yail_block`,
|
|
29
|
+
* `_yail_version`. Required for range re-indexing and versioned dedup. Default true.
|
|
30
|
+
*/
|
|
31
|
+
indexMeta?: boolean;
|
|
32
|
+
/** Optional column name overrides: TS key -> ClickHouse column name. Defaults to snake_case. */
|
|
33
|
+
columnNames?: Partial<Record<keyof C & string, string>>;
|
|
34
|
+
}
|
|
35
|
+
export interface Table<C extends Columns = Columns> {
|
|
36
|
+
readonly __brand: "yail.table";
|
|
37
|
+
readonly name: string;
|
|
38
|
+
readonly columns: C;
|
|
39
|
+
readonly options: TableOptions<C>;
|
|
40
|
+
/** TS key -> ClickHouse column name. */
|
|
41
|
+
readonly columnName: (key: keyof C & string) => string;
|
|
42
|
+
readonly columnKeys: ReadonlyArray<keyof C & string>;
|
|
43
|
+
toString(): string;
|
|
44
|
+
}
|
|
45
|
+
type OptionalKeys<C extends Columns> = {
|
|
46
|
+
[K in keyof C]: C[K]["isNullable"] extends true ? K : C[K]["hasDefault"] extends true ? K : never;
|
|
47
|
+
}[keyof C];
|
|
48
|
+
type RequiredKeys<C extends Columns> = Exclude<keyof C, OptionalKeys<C>>;
|
|
49
|
+
type ColType<Col> = Col extends Column<infer T, infer N, boolean> ? (N extends true ? T | null : T) : never;
|
|
50
|
+
/** Row type accepted by `db.insert(table).values(row)`. */
|
|
51
|
+
export type InsertRow<T extends Table<any>> = T extends Table<infer C> ? {
|
|
52
|
+
[K in RequiredKeys<C>]: ColType<C[K]>;
|
|
53
|
+
} & {
|
|
54
|
+
[K in OptionalKeys<C>]?: ColType<C[K]> | undefined;
|
|
55
|
+
} : never;
|
|
56
|
+
/** Row type returned by `db.rows(table, ...)`. */
|
|
57
|
+
export type InferRow<T extends Table<any>> = T extends Table<infer C> ? {
|
|
58
|
+
[K in keyof C]: ColType<C[K]>;
|
|
59
|
+
} : never;
|
|
60
|
+
export declare const INDEX_META_COLUMNS: {
|
|
61
|
+
readonly chain: "_yail_chain";
|
|
62
|
+
readonly block: "_yail_block";
|
|
63
|
+
readonly version: "_yail_version";
|
|
64
|
+
};
|
|
65
|
+
export declare function snakeCase(s: string): string;
|
|
66
|
+
export declare function table<C extends Columns>(name: string, columns: C, options: TableOptions<C>): Table<C>;
|
|
67
|
+
export declare function isTable(v: unknown): v is Table;
|
|
68
|
+
export {};
|
|
69
|
+
//# sourceMappingURL=table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/schema/table.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const INDEX_META_COLUMNS = {
|
|
2
|
+
chain: "_yail_chain",
|
|
3
|
+
block: "_yail_block",
|
|
4
|
+
version: "_yail_version",
|
|
5
|
+
};
|
|
6
|
+
export function snakeCase(s) {
|
|
7
|
+
return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase();
|
|
8
|
+
}
|
|
9
|
+
export function table(name, columns, options) {
|
|
10
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name))
|
|
11
|
+
throw new Error(`Invalid table name "${name}"`);
|
|
12
|
+
for (const key of options.orderBy) {
|
|
13
|
+
if (!(key in columns))
|
|
14
|
+
throw new Error(`Table "${name}": orderBy column "${key}" does not exist`);
|
|
15
|
+
}
|
|
16
|
+
for (const [scope, col] of Object.entries(options.scopes ?? {})) {
|
|
17
|
+
if (!(col in columns))
|
|
18
|
+
throw new Error(`Table "${name}": scope "${scope}" points to unknown column "${col}"`);
|
|
19
|
+
}
|
|
20
|
+
const overrides = options.columnNames ?? {};
|
|
21
|
+
const columnName = (key) => overrides[key] ?? snakeCase(key);
|
|
22
|
+
return {
|
|
23
|
+
__brand: "yail.table",
|
|
24
|
+
name,
|
|
25
|
+
columns,
|
|
26
|
+
options: { indexMeta: true, engine: "ReplacingMergeTree", ...options },
|
|
27
|
+
columnName,
|
|
28
|
+
columnKeys: Object.keys(columns),
|
|
29
|
+
toString: () => name,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function isTable(v) {
|
|
33
|
+
return typeof v === "object" && v !== null && v.__brand === "yail.table";
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/schema/table.ts"],"names":[],"mappings":"AAuEA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,KAAK,EAAE,aAAa;IACpB,KAAK,EAAE,aAAa;IACpB,OAAO,EAAE,eAAe;CAChB,CAAC;AAEX,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,OAAO,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACzG,CAAC;AAED,MAAM,UAAU,KAAK,CAAoB,IAAY,EAAE,OAAU,EAAE,OAAwB;IACzF,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,GAAG,CAAC,CAAC;IAC5F,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAClC,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,sBAAsB,GAAG,kBAAkB,CAAC,CAAC;IACpG,CAAC;IACD,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,IAAI,aAAa,KAAK,+BAA+B,GAAG,GAAG,CAAC,CAAC;IAChH,CAAC;IACD,MAAM,SAAS,GAA8C,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;IACvF,MAAM,UAAU,GAAG,CAAC,GAAqB,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/E,OAAO;QACL,OAAO,EAAE,YAAY;QACrB,IAAI;QACJ,OAAO;QACP,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,oBAAoB,EAAE,GAAG,OAAO,EAAE;QACtE,UAAU;QACV,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAA4B;QAC3D,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,CAAU;IAChC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAK,CAAW,CAAC,OAAO,KAAK,YAAY,CAAC;AACtF,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Table } from "./table.js";
|
|
2
|
+
import type { SqlFragment } from "../db/sql.js";
|
|
3
|
+
export interface MaterializedView {
|
|
4
|
+
readonly __brand: "yail.materializedView";
|
|
5
|
+
readonly name: string;
|
|
6
|
+
/** Target table the view writes into (must be created, use `table()`). */
|
|
7
|
+
readonly to: Table<any>;
|
|
8
|
+
/** The SELECT that transforms inserts into rows of `to`. */
|
|
9
|
+
readonly query: SqlFragment;
|
|
10
|
+
/** Source table(s), used for `yail migrate --populate` ordering and docs. */
|
|
11
|
+
readonly from: ReadonlyArray<Table<any>>;
|
|
12
|
+
}
|
|
13
|
+
export declare function materializedView(name: string, def: {
|
|
14
|
+
to: Table<any>;
|
|
15
|
+
from: Table<any> | ReadonlyArray<Table<any>>;
|
|
16
|
+
query: SqlFragment;
|
|
17
|
+
}): MaterializedView;
|
|
18
|
+
export declare function isMaterializedView(v: unknown): v is MaterializedView;
|
|
19
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/schema/view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1C;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE;IAAE,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GACxF,gBAAgB,CASlB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,gBAAgB,CAEpE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { toArray } from "../util.js";
|
|
2
|
+
export function materializedView(name, def) {
|
|
3
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name))
|
|
4
|
+
throw new Error(`Invalid view name "${name}"`);
|
|
5
|
+
return {
|
|
6
|
+
__brand: "yail.materializedView",
|
|
7
|
+
name,
|
|
8
|
+
to: def.to,
|
|
9
|
+
query: def.query,
|
|
10
|
+
from: toArray(def.from),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function isMaterializedView(v) {
|
|
14
|
+
return typeof v === "object" && v !== null && v.__brand === "yail.materializedView";
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/schema/view.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAarC,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,GAAyF;IAEzF,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,GAAG,CAAC,CAAC;IAC3F,OAAO;QACL,OAAO,EAAE,uBAAuB;QAChC,IAAI;QACJ,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,IAAI,EAAE,OAAO,CAAa,GAAG,CAAC,IAAI,CAAC;KACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,CAAU;IAC3C,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAK,CAAsB,CAAC,OAAO,KAAK,uBAAuB,CAAC;AAC5G,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import type { Indexer } from "../indexer/indexer.js";
|
|
3
|
+
export declare function createApp(indexer: Indexer<any>): Hono;
|
|
4
|
+
export declare function startServer(indexer: Indexer<any>, options: {
|
|
5
|
+
port: number;
|
|
6
|
+
hostname?: string;
|
|
7
|
+
}): Promise<{
|
|
8
|
+
close(): Promise<void>;
|
|
9
|
+
port: number;
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/server/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAKrD,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAqDrD;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC;IAAE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CASxJ"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { serve } from "@hono/node-server";
|
|
3
|
+
import { jobs as jobsTable } from "../db/internal.js";
|
|
4
|
+
import { sql } from "../db/sql.js";
|
|
5
|
+
import { bigintReplacer, toArray } from "../util.js";
|
|
6
|
+
export function createApp(indexer) {
|
|
7
|
+
const app = new Hono();
|
|
8
|
+
app.get("/health", async (c) => {
|
|
9
|
+
const status = await indexer.status();
|
|
10
|
+
const failed = Object.values(status.chains).filter((ch) => ch.error);
|
|
11
|
+
return c.json({ ok: failed.length === 0, failed: failed.length }, statusCode(failed.length === 0));
|
|
12
|
+
});
|
|
13
|
+
app.get("/ready", async (c) => {
|
|
14
|
+
const status = await indexer.status();
|
|
15
|
+
const ready = Object.values(status.chains).every((ch) => ch.caughtUp && !ch.error);
|
|
16
|
+
return c.json({ ready, chains: Object.fromEntries(Object.entries(status.chains).map(([k, v]) => [k, { caughtUp: v.caughtUp, lagBlocks: v.lagBlocks }])) }, statusCode(ready));
|
|
17
|
+
});
|
|
18
|
+
app.get("/status", async (c) => c.json(await indexer.status()));
|
|
19
|
+
app.get("/addresses", (c) => {
|
|
20
|
+
const set = c.req.query("set");
|
|
21
|
+
const chain = c.req.query("chain");
|
|
22
|
+
const status = c.req.query("status");
|
|
23
|
+
return c.json(indexer.addresses.list({ set, chain, status }).map(serializable));
|
|
24
|
+
});
|
|
25
|
+
app.post("/addresses", async (c) => {
|
|
26
|
+
const body = await c.req.json();
|
|
27
|
+
if (!body.set || !body.address)
|
|
28
|
+
return c.json({ error: "set and address are required" }, 400);
|
|
29
|
+
const list = toArray(body.address).map((address) => ({ set: body.set, address, chain: body.chain, fromBlock: body.fromBlock, meta: body.meta }));
|
|
30
|
+
const rows = await indexer.addresses.register(list);
|
|
31
|
+
return c.json(rows.map(serializable), 201);
|
|
32
|
+
});
|
|
33
|
+
app.post("/reindex", async (c) => {
|
|
34
|
+
const body = await c.req.json();
|
|
35
|
+
try {
|
|
36
|
+
const rows = await indexer.reindex(body);
|
|
37
|
+
return c.json(rows.map(serializable), 202);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
return c.json({ error: err.message }, 400);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
app.get("/jobs", async (c) => {
|
|
44
|
+
const rows = await indexer.db.rows(jobsTable, sql `ORDER BY created_at DESC LIMIT 200`);
|
|
45
|
+
return c.json(rows.map(serializable));
|
|
46
|
+
});
|
|
47
|
+
app.get("/_evlog/logs", (c) => {
|
|
48
|
+
const limit = Number(c.req.query("limit") ?? 100);
|
|
49
|
+
return c.json(indexer.observability.recentEvents(limit));
|
|
50
|
+
});
|
|
51
|
+
return app;
|
|
52
|
+
}
|
|
53
|
+
export async function startServer(indexer, options) {
|
|
54
|
+
const app = createApp(indexer);
|
|
55
|
+
const server = serve({ fetch: app.fetch, port: options.port, hostname: options.hostname ?? "0.0.0.0" });
|
|
56
|
+
const port = server.address()?.port ?? options.port;
|
|
57
|
+
indexer.observability.log.info("yail", `status API listening on http://${options.hostname ?? "0.0.0.0"}:${port} (/status, /health, /addresses, /reindex, /jobs)`);
|
|
58
|
+
return {
|
|
59
|
+
port,
|
|
60
|
+
close: () => new Promise((resolve) => server.close(() => resolve())),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function statusCode(ok) {
|
|
64
|
+
if (ok)
|
|
65
|
+
return 200;
|
|
66
|
+
return 503;
|
|
67
|
+
}
|
|
68
|
+
function serializable(v) {
|
|
69
|
+
return JSON.parse(JSON.stringify(v, bigintReplacer));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/server/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Db } from "../db/client.js";
|
|
2
|
+
import type { BitcoinSource, EvmSource, RangeQuery, Source } from "./types.js";
|
|
3
|
+
export interface CachedSourceOptions {
|
|
4
|
+
db: Db;
|
|
5
|
+
/** Chain name used as cache namespace. */
|
|
6
|
+
chain: string;
|
|
7
|
+
/** Only cache batches whose range ends at or below this height (avoid caching reorgable data). */
|
|
8
|
+
finalizedHeight?: () => number | undefined;
|
|
9
|
+
onEvent?: (event: {
|
|
10
|
+
type: "hit" | "miss" | "store";
|
|
11
|
+
fromBlock: number;
|
|
12
|
+
nextBlock: number;
|
|
13
|
+
}) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Wrap any source with a ClickHouse-backed page cache. The wrapped source has
|
|
17
|
+
* the same interface; ranges already cached are served from the database and
|
|
18
|
+
* gaps are fetched from the inner source and stored. Cache keys hash the query
|
|
19
|
+
* shape (filters) so different filter sets never mix.
|
|
20
|
+
*/
|
|
21
|
+
export declare function cached<S extends Source>(inner: S, options: CachedSourceOptions): S;
|
|
22
|
+
/** Hash of the query minus its block range. */
|
|
23
|
+
export declare function hashQuery(query: RangeQuery): string;
|
|
24
|
+
export declare function serializeBatch(batch: unknown): string;
|
|
25
|
+
export declare function reviveBatch(payload: string): unknown;
|
|
26
|
+
export type { EvmSource, BitcoinSource };
|
|
27
|
+
//# sourceMappingURL=cached.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cached.d.ts","sourceRoot":"","sources":["../../src/sources/cached.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAA4B,UAAU,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzG,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,EAAE,CAAC;IACP,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,kGAAkG;IAClG,eAAe,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACrG;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,mBAAmB,GAAG,CAAC,CA8DlF;AAED,+CAA+C;AAC/C,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAQnD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAErD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEpD;AAqBD,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { sql } from "../db/sql.js";
|
|
3
|
+
import { sourceCache } from "../db/internal.js";
|
|
4
|
+
/**
|
|
5
|
+
* Wrap any source with a ClickHouse-backed page cache. The wrapped source has
|
|
6
|
+
* the same interface; ranges already cached are served from the database and
|
|
7
|
+
* gaps are fetched from the inner source and stored. Cache keys hash the query
|
|
8
|
+
* shape (filters) so different filter sets never mix.
|
|
9
|
+
*/
|
|
10
|
+
export function cached(inner, options) {
|
|
11
|
+
const evmInner = inner;
|
|
12
|
+
const wrapped = {
|
|
13
|
+
kind: inner.kind,
|
|
14
|
+
name: `cached(${inner.name})`,
|
|
15
|
+
getHeight: () => inner.getHeight(),
|
|
16
|
+
async *fetch(query, fetchOptions) {
|
|
17
|
+
const queryHash = hashQuery(query);
|
|
18
|
+
const cachedRanges = await options.db.query(sql `SELECT from_block, next_block FROM ${sourceCache} FINAL
|
|
19
|
+
WHERE chain = ${options.chain} AND query_hash = ${queryHash}
|
|
20
|
+
AND from_block >= ${query.fromBlock} AND from_block < ${query.toBlock}
|
|
21
|
+
ORDER BY from_block`);
|
|
22
|
+
const ranges = cachedRanges.map((r) => ({ from: Number(r.from_block), next: Number(r.next_block) }));
|
|
23
|
+
let cursor = query.fromBlock;
|
|
24
|
+
let ri = 0;
|
|
25
|
+
while (cursor < query.toBlock) {
|
|
26
|
+
fetchOptions?.signal?.throwIfAborted();
|
|
27
|
+
while (ri < ranges.length && ranges[ri].next <= cursor)
|
|
28
|
+
ri++;
|
|
29
|
+
const hit = ranges[ri];
|
|
30
|
+
if (hit && hit.from === cursor) {
|
|
31
|
+
const rows = await options.db.query(sql `SELECT payload FROM ${sourceCache} FINAL WHERE chain = ${options.chain} AND query_hash = ${queryHash} AND from_block = ${cursor} LIMIT 1`);
|
|
32
|
+
const payload = rows[0]?.payload;
|
|
33
|
+
if (payload) {
|
|
34
|
+
const batch = reviveBatch(payload);
|
|
35
|
+
const next = Math.min(batch.nextBlock, query.toBlock);
|
|
36
|
+
options.onEvent?.({ type: "hit", fromBlock: cursor, nextBlock: next });
|
|
37
|
+
yield clampBatch(batch, next);
|
|
38
|
+
cursor = next;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Miss: fetch from inner up to the next cached range start (or the end).
|
|
43
|
+
let missEnd = query.toBlock;
|
|
44
|
+
if (hit)
|
|
45
|
+
missEnd = Math.min(hit.from, missEnd);
|
|
46
|
+
options.onEvent?.({ type: "miss", fromBlock: cursor, nextBlock: missEnd });
|
|
47
|
+
const finalized = options.finalizedHeight?.();
|
|
48
|
+
for await (const batch of inner.fetch({ ...query, fromBlock: cursor, toBlock: missEnd }, fetchOptions)) {
|
|
49
|
+
const b = batch;
|
|
50
|
+
if (finalized === undefined || b.nextBlock - 1 <= finalized) {
|
|
51
|
+
await options.db.insert(sourceCache).values({
|
|
52
|
+
chain: options.chain,
|
|
53
|
+
queryHash,
|
|
54
|
+
fromBlock: BigInt(b.fromBlock),
|
|
55
|
+
nextBlock: BigInt(b.nextBlock),
|
|
56
|
+
payload: serializeBatch(b),
|
|
57
|
+
createdAt: new Date(),
|
|
58
|
+
});
|
|
59
|
+
options.onEvent?.({ type: "store", fromBlock: b.fromBlock, nextBlock: b.nextBlock });
|
|
60
|
+
}
|
|
61
|
+
yield b;
|
|
62
|
+
cursor = b.nextBlock;
|
|
63
|
+
}
|
|
64
|
+
if (cursor < missEnd)
|
|
65
|
+
throw new Error(`cached(${inner.name}): inner source stopped at ${cursor} before ${missEnd}`);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
if (evmInner.getBlock)
|
|
70
|
+
wrapped.getBlock = (n) => evmInner.getBlock(n);
|
|
71
|
+
return wrapped;
|
|
72
|
+
}
|
|
73
|
+
/** Hash of the query minus its block range. */
|
|
74
|
+
export function hashQuery(query) {
|
|
75
|
+
const { fromBlock: _f, toBlock: _t, ...shape } = query;
|
|
76
|
+
const json = JSON.stringify(shape, (_k, v) => {
|
|
77
|
+
if (typeof v === "string")
|
|
78
|
+
return v.toLowerCase();
|
|
79
|
+
if (Array.isArray(v) && v.every((x) => typeof x === "string"))
|
|
80
|
+
return [...v].map((x) => x.toLowerCase()).sort();
|
|
81
|
+
return v;
|
|
82
|
+
});
|
|
83
|
+
return createHash("sha256").update(json).digest("hex").slice(0, 32);
|
|
84
|
+
}
|
|
85
|
+
export function serializeBatch(batch) {
|
|
86
|
+
return JSON.stringify(batch, tagBigint);
|
|
87
|
+
}
|
|
88
|
+
export function reviveBatch(payload) {
|
|
89
|
+
return JSON.parse(payload, untagBigint);
|
|
90
|
+
}
|
|
91
|
+
function tagBigint(_key, value) {
|
|
92
|
+
if (typeof value === "bigint")
|
|
93
|
+
return { $big: value.toString() };
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
function untagBigint(_key, value) {
|
|
97
|
+
if (value && typeof value === "object" && typeof value.$big === "string")
|
|
98
|
+
return BigInt(value.$big);
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
function clampBatch(batch, next) {
|
|
102
|
+
if (batch.nextBlock === next)
|
|
103
|
+
return batch;
|
|
104
|
+
const b = { ...batch, nextBlock: next };
|
|
105
|
+
for (const key of ["blocks", "transactions", "logs"]) {
|
|
106
|
+
if (Array.isArray(b[key]))
|
|
107
|
+
b[key] = b[key].filter((x) => (x.number ?? x.blockNumber) < next);
|
|
108
|
+
}
|
|
109
|
+
return b;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=cached.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cached.js","sourceRoot":"","sources":["../../src/sources/cached.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BitcoinSource } from "./types.js";
|
|
2
|
+
export interface EsploraOptions {
|
|
3
|
+
/** Esplora-compatible base URL: https://mempool.space/api or https://blockstream.info/api (or your own electrs). */
|
|
4
|
+
url: string;
|
|
5
|
+
/** Max parallel address scans. Public instances rate-limit aggressively; default 2. */
|
|
6
|
+
concurrency?: number;
|
|
7
|
+
/** Extra headers (e.g. API key for a hosted instance). */
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
/** Override fetch (testing). */
|
|
10
|
+
fetch?: typeof fetch;
|
|
11
|
+
/** Max transactions per yielded batch. Default 500. */
|
|
12
|
+
batchSize?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Bitcoin source backed by an Esplora HTTP API (mempool.space, blockstream.info,
|
|
16
|
+
* or self-hosted electrs). HyperSync has no Bitcoin support and Bitcoin Core's
|
|
17
|
+
* RPC has no address index, so address history is scanned through Esplora.
|
|
18
|
+
* Each query scans the requested addresses newest-first and keeps confirmed
|
|
19
|
+
* transactions inside [fromBlock, toBlock).
|
|
20
|
+
*/
|
|
21
|
+
export declare function esplora(options: EsploraOptions): BitcoinSource;
|
|
22
|
+
//# sourceMappingURL=esplora.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esplora.d.ts","sourceRoot":"","sources":["../../src/sources/esplora.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA8B,aAAa,EAAoC,MAAM,YAAY,CAAC;AAE9G,MAAM,WAAW,cAAc;IAC7B,oHAAoH;IACpH,GAAG,EAAE,MAAM,CAAC;IACZ,uFAAuF;IACvF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,gCAAgC;IAChC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CA4F9D"}
|