ponder 0.14.13 → 0.15.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/CHANGELOG.md +16 -0
- package/dist/esm/bin/commands/createViews.js +28 -11
- package/dist/esm/bin/commands/createViews.js.map +1 -1
- package/dist/esm/bin/commands/dev.js +42 -22
- package/dist/esm/bin/commands/dev.js.map +1 -1
- package/dist/esm/bin/commands/prune.js +3 -0
- package/dist/esm/bin/commands/prune.js.map +1 -1
- package/dist/esm/bin/commands/serve.js +4 -1
- package/dist/esm/bin/commands/serve.js.map +1 -1
- package/dist/esm/bin/commands/start.js +18 -6
- package/dist/esm/bin/commands/start.js.map +1 -1
- package/dist/esm/bin/isolatedController.js +200 -0
- package/dist/esm/bin/isolatedController.js.map +1 -0
- package/dist/esm/bin/isolatedWorker.js +146 -0
- package/dist/esm/bin/isolatedWorker.js.map +1 -0
- package/dist/esm/build/config.js +322 -402
- package/dist/esm/build/config.js.map +1 -1
- package/dist/esm/build/index.js +8 -11
- package/dist/esm/build/index.js.map +1 -1
- package/dist/esm/build/pre.js +1 -4
- package/dist/esm/build/pre.js.map +1 -1
- package/dist/esm/build/schema.js +25 -3
- package/dist/esm/build/schema.js.map +1 -1
- package/dist/esm/client/index.js +306 -42
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/database/actions.js +264 -104
- package/dist/esm/database/actions.js.map +1 -1
- package/dist/esm/database/index.js +39 -33
- package/dist/esm/database/index.js.map +1 -1
- package/dist/esm/database/queryBuilder.js +1 -0
- package/dist/esm/database/queryBuilder.js.map +1 -1
- package/dist/esm/drizzle/index.js +11 -7
- package/dist/esm/drizzle/index.js.map +1 -1
- package/dist/esm/drizzle/onchain.js +18 -0
- package/dist/esm/drizzle/onchain.js.map +1 -1
- package/dist/esm/indexing/client.js +32 -25
- package/dist/esm/indexing/client.js.map +1 -1
- package/dist/esm/indexing/index.js +110 -178
- package/dist/esm/indexing/index.js.map +1 -1
- package/dist/esm/indexing/profile.js +1 -1
- package/dist/esm/indexing/profile.js.map +1 -1
- package/dist/esm/indexing-store/cache.js +196 -274
- package/dist/esm/indexing-store/cache.js.map +1 -1
- package/dist/esm/indexing-store/historical.js +17 -13
- package/dist/esm/indexing-store/historical.js.map +1 -1
- package/dist/esm/indexing-store/index.js +10 -1
- package/dist/esm/indexing-store/index.js.map +1 -1
- package/dist/esm/indexing-store/profile.js +3 -3
- package/dist/esm/indexing-store/profile.js.map +1 -1
- package/dist/esm/indexing-store/realtime.js +27 -2
- package/dist/esm/indexing-store/realtime.js.map +1 -1
- package/dist/esm/internal/errors.js +28 -0
- package/dist/esm/internal/errors.js.map +1 -1
- package/dist/esm/internal/metrics.js +279 -82
- package/dist/esm/internal/metrics.js.map +1 -1
- package/dist/esm/internal/options.js +1 -0
- package/dist/esm/internal/options.js.map +1 -1
- package/dist/esm/internal/telemetry.js +1 -1
- package/dist/esm/internal/telemetry.js.map +1 -1
- package/dist/esm/rpc/http.js +130 -0
- package/dist/esm/rpc/http.js.map +1 -0
- package/dist/esm/rpc/index.js +38 -7
- package/dist/esm/rpc/index.js.map +1 -1
- package/dist/esm/runtime/events.js +179 -212
- package/dist/esm/runtime/events.js.map +1 -1
- package/dist/esm/runtime/filter.js +71 -0
- package/dist/esm/runtime/filter.js.map +1 -1
- package/dist/esm/runtime/fragments.js +78 -73
- package/dist/esm/runtime/fragments.js.map +1 -1
- package/dist/esm/runtime/historical.js +306 -130
- package/dist/esm/runtime/historical.js.map +1 -1
- package/dist/esm/runtime/index.js +183 -58
- package/dist/esm/runtime/index.js.map +1 -1
- package/dist/esm/runtime/isolated.js +462 -0
- package/dist/esm/runtime/isolated.js.map +1 -0
- package/dist/esm/runtime/multichain.js +80 -73
- package/dist/esm/runtime/multichain.js.map +1 -1
- package/dist/esm/runtime/omnichain.js +82 -75
- package/dist/esm/runtime/omnichain.js.map +1 -1
- package/dist/esm/runtime/realtime.js +198 -66
- package/dist/esm/runtime/realtime.js.map +1 -1
- package/dist/esm/sync-historical/index.js +416 -457
- package/dist/esm/sync-historical/index.js.map +1 -1
- package/dist/esm/sync-realtime/bloom.js +3 -3
- package/dist/esm/sync-realtime/bloom.js.map +1 -1
- package/dist/esm/sync-realtime/index.js +27 -46
- package/dist/esm/sync-realtime/index.js.map +1 -1
- package/dist/esm/sync-store/index.js +112 -63
- package/dist/esm/sync-store/index.js.map +1 -1
- package/dist/esm/utils/abi.js +20 -32
- package/dist/esm/utils/abi.js.map +1 -1
- package/dist/esm/utils/chunk.js +8 -0
- package/dist/esm/utils/chunk.js.map +1 -0
- package/dist/esm/utils/promiseAllSettledWithThrow.js +19 -0
- package/dist/esm/utils/promiseAllSettledWithThrow.js.map +1 -0
- package/dist/esm/{client/parse.js → utils/sql-parse.js} +94 -80
- package/dist/esm/utils/sql-parse.js.map +1 -0
- package/dist/types/bin/commands/createViews.d.ts.map +1 -1
- package/dist/types/bin/commands/dev.d.ts.map +1 -1
- package/dist/types/bin/commands/prune.d.ts.map +1 -1
- package/dist/types/bin/commands/serve.d.ts.map +1 -1
- package/dist/types/bin/commands/start.d.ts.map +1 -1
- package/dist/types/bin/isolatedController.d.ts +13 -0
- package/dist/types/bin/isolatedController.d.ts.map +1 -0
- package/dist/types/bin/isolatedWorker.d.ts +9 -0
- package/dist/types/bin/isolatedWorker.d.ts.map +1 -0
- package/dist/types/build/config.d.ts +29 -11
- package/dist/types/build/config.d.ts.map +1 -1
- package/dist/types/build/index.d.ts +3 -2
- package/dist/types/build/index.d.ts.map +1 -1
- package/dist/types/build/pre.d.ts +1 -1
- package/dist/types/build/pre.d.ts.map +1 -1
- package/dist/types/build/schema.d.ts +5 -3
- package/dist/types/build/schema.d.ts.map +1 -1
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/config/index.d.ts +3 -3
- package/dist/types/config/index.d.ts.map +1 -1
- package/dist/types/database/actions.d.ts +53 -7
- package/dist/types/database/actions.d.ts.map +1 -1
- package/dist/types/database/index.d.ts +21 -21
- package/dist/types/database/index.d.ts.map +1 -1
- package/dist/types/database/queryBuilder.d.ts.map +1 -1
- package/dist/types/drizzle/index.d.ts +4 -5
- package/dist/types/drizzle/index.d.ts.map +1 -1
- package/dist/types/drizzle/onchain.d.ts +6 -0
- package/dist/types/drizzle/onchain.d.ts.map +1 -1
- package/dist/types/indexing/client.d.ts.map +1 -1
- package/dist/types/indexing/index.d.ts +2 -5
- package/dist/types/indexing/index.d.ts.map +1 -1
- package/dist/types/indexing-store/cache.d.ts +3 -2
- package/dist/types/indexing-store/cache.d.ts.map +1 -1
- package/dist/types/indexing-store/historical.d.ts +2 -1
- package/dist/types/indexing-store/historical.d.ts.map +1 -1
- package/dist/types/indexing-store/index.d.ts +1 -0
- package/dist/types/indexing-store/index.d.ts.map +1 -1
- package/dist/types/indexing-store/realtime.d.ts +2 -1
- package/dist/types/indexing-store/realtime.d.ts.map +1 -1
- package/dist/types/internal/errors.d.ts +5 -0
- package/dist/types/internal/errors.d.ts.map +1 -1
- package/dist/types/internal/metrics.d.ts +21 -0
- package/dist/types/internal/metrics.d.ts.map +1 -1
- package/dist/types/internal/options.d.ts +2 -0
- package/dist/types/internal/options.d.ts.map +1 -1
- package/dist/types/internal/types.d.ts +66 -58
- package/dist/types/internal/types.d.ts.map +1 -1
- package/dist/types/rpc/http.d.ts +17 -0
- package/dist/types/rpc/http.d.ts.map +1 -0
- package/dist/types/rpc/index.d.ts.map +1 -1
- package/dist/types/runtime/events.d.ts +4 -4
- package/dist/types/runtime/events.d.ts.map +1 -1
- package/dist/types/runtime/filter.d.ts +5 -1
- package/dist/types/runtime/filter.d.ts.map +1 -1
- package/dist/types/runtime/fragments.d.ts +4 -3
- package/dist/types/runtime/fragments.d.ts.map +1 -1
- package/dist/types/runtime/historical.d.ts +29 -13
- package/dist/types/runtime/historical.d.ts.map +1 -1
- package/dist/types/runtime/index.d.ts +49 -6
- package/dist/types/runtime/index.d.ts.map +1 -1
- package/dist/types/runtime/init.d.ts +5 -5
- package/dist/types/runtime/init.d.ts.map +1 -1
- package/dist/types/runtime/isolated.d.ts +14 -0
- package/dist/types/runtime/isolated.d.ts.map +1 -0
- package/dist/types/runtime/multichain.d.ts.map +1 -1
- package/dist/types/runtime/omnichain.d.ts.map +1 -1
- package/dist/types/runtime/realtime.d.ts +21 -10
- package/dist/types/runtime/realtime.d.ts.map +1 -1
- package/dist/types/sync-historical/index.d.ts +18 -8
- package/dist/types/sync-historical/index.d.ts.map +1 -1
- package/dist/types/sync-realtime/bloom.d.ts.map +1 -1
- package/dist/types/sync-realtime/index.d.ts +2 -2
- package/dist/types/sync-realtime/index.d.ts.map +1 -1
- package/dist/types/sync-store/index.d.ts +9 -9
- package/dist/types/sync-store/index.d.ts.map +1 -1
- package/dist/types/utils/abi.d.ts +3 -34
- package/dist/types/utils/abi.d.ts.map +1 -1
- package/dist/types/utils/chunk.d.ts +2 -0
- package/dist/types/utils/chunk.d.ts.map +1 -0
- package/dist/types/utils/promiseAllSettledWithThrow.d.ts +8 -0
- package/dist/types/utils/promiseAllSettledWithThrow.d.ts.map +1 -0
- package/dist/types/utils/sql-parse.d.ts +21 -0
- package/dist/types/utils/sql-parse.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/bin/commands/createViews.ts +35 -15
- package/src/bin/commands/dev.ts +43 -21
- package/src/bin/commands/prune.ts +6 -0
- package/src/bin/commands/serve.ts +4 -1
- package/src/bin/commands/start.ts +20 -5
- package/src/bin/isolatedController.ts +300 -0
- package/src/bin/isolatedWorker.ts +192 -0
- package/src/build/config.ts +570 -632
- package/src/build/index.ts +14 -14
- package/src/build/pre.ts +1 -4
- package/src/build/schema.ts +49 -4
- package/src/client/index.ts +386 -48
- package/src/config/index.ts +3 -3
- package/src/database/actions.ts +469 -120
- package/src/database/index.ts +85 -58
- package/src/database/queryBuilder.ts +1 -0
- package/src/drizzle/index.ts +15 -7
- package/src/drizzle/onchain.ts +19 -0
- package/src/indexing/client.ts +38 -25
- package/src/indexing/index.ts +137 -230
- package/src/indexing/profile.ts +1 -1
- package/src/indexing-store/cache.ts +285 -414
- package/src/indexing-store/historical.ts +20 -10
- package/src/indexing-store/index.ts +16 -0
- package/src/indexing-store/profile.ts +3 -3
- package/src/indexing-store/realtime.ts +28 -0
- package/src/internal/errors.ts +26 -0
- package/src/internal/metrics.ts +341 -111
- package/src/internal/options.ts +4 -0
- package/src/internal/telemetry.ts +1 -1
- package/src/internal/types.ts +70 -87
- package/src/rpc/http.ts +164 -0
- package/src/rpc/index.ts +39 -7
- package/src/runtime/events.ts +195 -240
- package/src/runtime/filter.ts +85 -1
- package/src/runtime/fragments.ts +109 -113
- package/src/runtime/historical.ts +467 -189
- package/src/runtime/index.ts +337 -69
- package/src/runtime/init.ts +5 -5
- package/src/runtime/isolated.ts +768 -0
- package/src/runtime/multichain.ts +137 -102
- package/src/runtime/omnichain.ts +138 -106
- package/src/runtime/realtime.ts +322 -123
- package/src/sync-historical/index.ts +556 -692
- package/src/sync-realtime/bloom.ts +7 -3
- package/src/sync-realtime/index.ts +31 -46
- package/src/sync-store/index.ts +189 -95
- package/src/utils/abi.ts +33 -90
- package/src/utils/chunk.ts +7 -0
- package/src/utils/promiseAllSettledWithThrow.ts +27 -0
- package/src/{client/parse.ts → utils/sql-parse.ts} +100 -90
- package/dist/esm/client/parse.js.map +0 -1
- package/dist/types/client/parse.d.ts +0 -14
- package/dist/types/client/parse.d.ts.map +0 -1
package/src/internal/options.ts
CHANGED
|
@@ -31,6 +31,8 @@ export type Options = {
|
|
|
31
31
|
databaseHeartbeatTimeout: number;
|
|
32
32
|
databaseMaxQueryParameters: number;
|
|
33
33
|
|
|
34
|
+
maxThreads: number;
|
|
35
|
+
|
|
34
36
|
factoryAddressCountThreshold: number;
|
|
35
37
|
|
|
36
38
|
indexingCacheMaxBytes: number;
|
|
@@ -103,6 +105,8 @@ export const buildOptions = ({ cliOptions }: { cliOptions: CliOptions }) => {
|
|
|
103
105
|
// Half of the max query parameters for PGlite
|
|
104
106
|
databaseMaxQueryParameters: 16_000,
|
|
105
107
|
|
|
108
|
+
maxThreads: 4,
|
|
109
|
+
|
|
106
110
|
factoryAddressCountThreshold: 1_000,
|
|
107
111
|
|
|
108
112
|
rpcMaxConcurrency: 256,
|
|
@@ -295,7 +295,7 @@ export function buildPayload({
|
|
|
295
295
|
|
|
296
296
|
return {
|
|
297
297
|
database_kind: preBuild?.databaseConfig.kind,
|
|
298
|
-
contract_count:
|
|
298
|
+
contract_count: 0,
|
|
299
299
|
network_count: indexingBuild?.chains.length ?? 0,
|
|
300
300
|
table_count,
|
|
301
301
|
indexing_function_count,
|
package/src/internal/types.ts
CHANGED
|
@@ -9,7 +9,6 @@ import type {
|
|
|
9
9
|
Transfer,
|
|
10
10
|
} from "@/types/eth.js";
|
|
11
11
|
import type { PartialExcept, Prettify } from "@/types/utils.js";
|
|
12
|
-
import type { AbiEvents, AbiFunctions } from "@/utils/abi.js";
|
|
13
12
|
import type { Trace as DebugTrace } from "@/utils/debug.js";
|
|
14
13
|
import type { PGliteOptions } from "@/utils/pglite.js";
|
|
15
14
|
import type { PGlite } from "@electric-sql/pglite";
|
|
@@ -17,6 +16,8 @@ import type { Hono } from "hono";
|
|
|
17
16
|
import type { PoolConfig } from "pg";
|
|
18
17
|
import type {
|
|
19
18
|
Abi,
|
|
19
|
+
AbiEvent,
|
|
20
|
+
AbiFunction,
|
|
20
21
|
Address,
|
|
21
22
|
BlockTag,
|
|
22
23
|
Hex,
|
|
@@ -40,18 +41,13 @@ export type DatabaseConfig =
|
|
|
40
41
|
// Indexing
|
|
41
42
|
|
|
42
43
|
/** Indexing functions as defined in `ponder.on()` */
|
|
43
|
-
export type
|
|
44
|
+
export type IndexingFunctions = {
|
|
44
45
|
/** Name of the event */
|
|
45
46
|
name: string;
|
|
46
47
|
/** Callback function */
|
|
47
48
|
fn: (...args: any) => any;
|
|
48
49
|
}[];
|
|
49
50
|
|
|
50
|
-
/** Indexing functions for event callbacks */
|
|
51
|
-
export type IndexingFunctions = {
|
|
52
|
-
[eventName: string]: (...args: any) => any;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
51
|
// Filters
|
|
56
52
|
|
|
57
53
|
/** Filter definition based on the fundamental data model of the Ethereum blockchain. */
|
|
@@ -61,12 +57,6 @@ export type Filter =
|
|
|
61
57
|
| TransferFilter
|
|
62
58
|
| TransactionFilter
|
|
63
59
|
| TraceFilter;
|
|
64
|
-
export type FilterWithoutBlocks =
|
|
65
|
-
| Omit<BlockFilter, "fromBlock" | "toBlock">
|
|
66
|
-
| Omit<TransactionFilter, "fromBlock" | "toBlock">
|
|
67
|
-
| Omit<TraceFilter, "fromBlock" | "toBlock">
|
|
68
|
-
| Omit<LogFilter, "fromBlock" | "toBlock">
|
|
69
|
-
| Omit<TransferFilter, "fromBlock" | "toBlock">;
|
|
70
60
|
|
|
71
61
|
/** Filter that matches addresses. */
|
|
72
62
|
export type Factory = LogFactory;
|
|
@@ -77,6 +67,7 @@ export type FilterAddress<
|
|
|
77
67
|
export type BlockFilter = {
|
|
78
68
|
type: "block";
|
|
79
69
|
chainId: number;
|
|
70
|
+
sourceId: string;
|
|
80
71
|
interval: number;
|
|
81
72
|
offset: number;
|
|
82
73
|
fromBlock: number | undefined;
|
|
@@ -91,6 +82,7 @@ export type TransactionFilter<
|
|
|
91
82
|
> = {
|
|
92
83
|
type: "transaction";
|
|
93
84
|
chainId: number;
|
|
85
|
+
sourceId: string;
|
|
94
86
|
fromAddress: FilterAddress<fromFactory>;
|
|
95
87
|
toAddress: FilterAddress<toFactory>;
|
|
96
88
|
includeReverted: boolean;
|
|
@@ -110,9 +102,10 @@ export type TraceFilter<
|
|
|
110
102
|
> = {
|
|
111
103
|
type: "trace";
|
|
112
104
|
chainId: number;
|
|
105
|
+
sourceId: string;
|
|
113
106
|
fromAddress: FilterAddress<fromFactory>;
|
|
114
107
|
toAddress: FilterAddress<toFactory>;
|
|
115
|
-
functionSelector: Hex
|
|
108
|
+
functionSelector: Hex;
|
|
116
109
|
callType: Trace["type"] | undefined;
|
|
117
110
|
includeReverted: boolean;
|
|
118
111
|
fromBlock: number | undefined;
|
|
@@ -131,8 +124,9 @@ export type LogFilter<
|
|
|
131
124
|
> = {
|
|
132
125
|
type: "log";
|
|
133
126
|
chainId: number;
|
|
127
|
+
sourceId: string;
|
|
134
128
|
address: FilterAddress<factory>;
|
|
135
|
-
topic0:
|
|
129
|
+
topic0: Hex;
|
|
136
130
|
topic1: LogTopic;
|
|
137
131
|
topic2: LogTopic;
|
|
138
132
|
topic3: LogTopic;
|
|
@@ -153,6 +147,7 @@ export type TransferFilter<
|
|
|
153
147
|
> = {
|
|
154
148
|
type: "transfer";
|
|
155
149
|
chainId: number;
|
|
150
|
+
sourceId: string;
|
|
156
151
|
fromAddress: FilterAddress<fromFactory>;
|
|
157
152
|
toAddress: FilterAddress<toFactory>;
|
|
158
153
|
includeReverted: boolean;
|
|
@@ -215,14 +210,14 @@ export type Fragment =
|
|
|
215
210
|
chainId: number;
|
|
216
211
|
fromAddress: FragmentAddress;
|
|
217
212
|
toAddress: FragmentAddress;
|
|
218
|
-
functionSelector: Hex
|
|
213
|
+
functionSelector: Hex;
|
|
219
214
|
includeTransactionReceipts: boolean;
|
|
220
215
|
}
|
|
221
216
|
| {
|
|
222
217
|
type: "log";
|
|
223
218
|
chainId: number;
|
|
224
219
|
address: FragmentAddress;
|
|
225
|
-
topic0:
|
|
220
|
+
topic0: Hex;
|
|
226
221
|
topic1: FragmentTopic;
|
|
227
222
|
topic2: FragmentTopic;
|
|
228
223
|
topic3: FragmentTopic;
|
|
@@ -234,6 +229,13 @@ export type Fragment =
|
|
|
234
229
|
fromAddress: FragmentAddress;
|
|
235
230
|
toAddress: FragmentAddress;
|
|
236
231
|
includeTransactionReceipts: boolean;
|
|
232
|
+
}
|
|
233
|
+
| {
|
|
234
|
+
type: "factory_log";
|
|
235
|
+
chainId: number;
|
|
236
|
+
address: Address;
|
|
237
|
+
eventSelector: Factory["eventSelector"];
|
|
238
|
+
childAddressLocation: Factory["childAddressLocation"];
|
|
237
239
|
};
|
|
238
240
|
|
|
239
241
|
/** Minimum slice of a {@link Filter} */
|
|
@@ -247,53 +249,40 @@ export type FragmentId =
|
|
|
247
249
|
/** log_{chainId}_{address}_{topic0}_{topic1}_{topic2}_{topic3}_{includeReceipts} */
|
|
248
250
|
| `log_${number}_${FragmentAddressId}_${FragmentTopic}_${FragmentTopic}_${FragmentTopic}_${FragmentTopic}_${0 | 1}`
|
|
249
251
|
/** transfer_{chainId}_{fromAddress}_{toAddress}_{includeReceipts} */
|
|
250
|
-
| `transfer_${number}_${FragmentAddressId}_${FragmentAddressId}_${0 | 1}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
/** Event source that matches {@link Event}s containing an underlying filter and metadata. */
|
|
255
|
-
export type Source = ContractSource | AccountSource | BlockSource;
|
|
256
|
-
|
|
257
|
-
export type ContractSource<
|
|
258
|
-
filter extends "log" | "trace" = "log" | "trace",
|
|
259
|
-
factory extends Factory | undefined = Factory | undefined,
|
|
260
|
-
fromFactory extends Factory | undefined = Factory | undefined,
|
|
261
|
-
toFactory extends Factory | undefined = Factory | undefined,
|
|
262
|
-
> = {
|
|
263
|
-
filter: filter extends "log"
|
|
264
|
-
? LogFilter<factory>
|
|
265
|
-
: TraceFilter<fromFactory, toFactory>;
|
|
266
|
-
} & ContractMetadata;
|
|
267
|
-
|
|
268
|
-
export type AccountSource<
|
|
269
|
-
filter extends "transaction" | "transfer" = "transaction" | "transfer",
|
|
270
|
-
fromFactory extends Factory | undefined = Factory | undefined,
|
|
271
|
-
toFactory extends Factory | undefined = Factory | undefined,
|
|
272
|
-
> = {
|
|
273
|
-
filter: filter extends "transaction"
|
|
274
|
-
? TransactionFilter<fromFactory, toFactory>
|
|
275
|
-
: TransferFilter<fromFactory, toFactory>;
|
|
276
|
-
} & AccountMetadata;
|
|
252
|
+
| `transfer_${number}_${FragmentAddressId}_${FragmentAddressId}_${0 | 1}`
|
|
253
|
+
/** factory_log_{chainId}_{address}_{eventSelector}_{childAddressLocation} */
|
|
254
|
+
| `factory_log_${number}_${Address}_${Factory["eventSelector"]}_${Factory["childAddressLocation"]}`;
|
|
277
255
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
export type ContractMetadata = {
|
|
281
|
-
type: "contract";
|
|
256
|
+
// Contract
|
|
257
|
+
export type Contract = {
|
|
282
258
|
abi: Abi;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
chain: Chain;
|
|
259
|
+
address?: Address | readonly Address[];
|
|
260
|
+
startBlock?: number;
|
|
261
|
+
endBlock?: number;
|
|
287
262
|
};
|
|
288
|
-
|
|
289
|
-
|
|
263
|
+
|
|
264
|
+
// Event Callback
|
|
265
|
+
|
|
266
|
+
export type EventCallback = {
|
|
267
|
+
filter: Filter;
|
|
290
268
|
name: string;
|
|
269
|
+
fn: (...args: any) => any;
|
|
291
270
|
chain: Chain;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
|
|
271
|
+
} & (
|
|
272
|
+
| {
|
|
273
|
+
type: "contract";
|
|
274
|
+
abiItem: AbiEvent | AbiFunction;
|
|
275
|
+
metadata: { safeName: string; abi: Abi };
|
|
276
|
+
}
|
|
277
|
+
| { type: "account"; direction: "from" | "to" }
|
|
278
|
+
| { type: "block" }
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
export type SetupCallback = {
|
|
295
282
|
name: string;
|
|
283
|
+
fn: (...args: any) => any;
|
|
296
284
|
chain: Chain;
|
|
285
|
+
block: number | undefined;
|
|
297
286
|
};
|
|
298
287
|
|
|
299
288
|
// Chain
|
|
@@ -327,7 +316,7 @@ export type PreBuild = {
|
|
|
327
316
|
/** Database type and configuration */
|
|
328
317
|
databaseConfig: DatabaseConfig;
|
|
329
318
|
/** Ordering of events */
|
|
330
|
-
ordering: "omnichain" | "multichain";
|
|
319
|
+
ordering: "omnichain" | "multichain" | "experimental_isolated";
|
|
331
320
|
};
|
|
332
321
|
|
|
333
322
|
export type SchemaBuild = {
|
|
@@ -339,16 +328,22 @@ export type SchemaBuild = {
|
|
|
339
328
|
export type IndexingBuild = {
|
|
340
329
|
/** Ten character hex string identifier. */
|
|
341
330
|
buildId: string;
|
|
342
|
-
/** Sources to index. */
|
|
343
|
-
sources: Source[];
|
|
344
331
|
/** Chains to index. */
|
|
345
332
|
chains: Chain[];
|
|
346
333
|
/** RPCs for all `chains`. */
|
|
347
334
|
rpcs: Rpc[];
|
|
348
335
|
/** Finalized blocks for all `chains`. */
|
|
349
336
|
finalizedBlocks: LightBlock[];
|
|
350
|
-
/** Event callbacks for all `
|
|
337
|
+
/** Event callbacks for all `chains`. */
|
|
338
|
+
eventCallbacks: EventCallback[][];
|
|
339
|
+
/** Setup callbacks for all `chains`. */
|
|
340
|
+
setupCallbacks: SetupCallback[][];
|
|
341
|
+
/** Indexing functions registered with `ponder.on()`. */
|
|
351
342
|
indexingFunctions: IndexingFunctions;
|
|
343
|
+
/** Contracts for all `chains`. */
|
|
344
|
+
contracts: {
|
|
345
|
+
[name: string]: Contract;
|
|
346
|
+
}[];
|
|
352
347
|
};
|
|
353
348
|
|
|
354
349
|
export type ApiBuild = {
|
|
@@ -489,9 +484,9 @@ export type UserLog = Log;
|
|
|
489
484
|
// Events
|
|
490
485
|
|
|
491
486
|
export type RawEvent = {
|
|
492
|
-
chainId: number;
|
|
493
|
-
sourceIndex: number;
|
|
494
487
|
checkpoint: string;
|
|
488
|
+
chainId: number;
|
|
489
|
+
eventCallbackIndex: number;
|
|
495
490
|
log?: UserLog;
|
|
496
491
|
block: UserBlock;
|
|
497
492
|
transaction?: UserTransaction;
|
|
@@ -508,22 +503,18 @@ export type Event =
|
|
|
508
503
|
|
|
509
504
|
export type SetupEvent = {
|
|
510
505
|
type: "setup";
|
|
511
|
-
chainId: number;
|
|
512
506
|
checkpoint: string;
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
name: string;
|
|
507
|
+
chain: Chain;
|
|
508
|
+
setupCallback: SetupCallback;
|
|
516
509
|
|
|
517
510
|
block: bigint;
|
|
518
511
|
};
|
|
519
512
|
|
|
520
513
|
export type BlockEvent = {
|
|
521
514
|
type: "block";
|
|
522
|
-
chainId: number;
|
|
523
515
|
checkpoint: string;
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
name: string;
|
|
516
|
+
chain: Chain;
|
|
517
|
+
eventCallback: EventCallback;
|
|
527
518
|
|
|
528
519
|
event: {
|
|
529
520
|
id: string;
|
|
@@ -533,11 +524,9 @@ export type BlockEvent = {
|
|
|
533
524
|
|
|
534
525
|
export type TransactionEvent = {
|
|
535
526
|
type: "transaction";
|
|
536
|
-
chainId: number;
|
|
537
527
|
checkpoint: string;
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
name: string;
|
|
528
|
+
chain: Chain;
|
|
529
|
+
eventCallback: EventCallback;
|
|
541
530
|
|
|
542
531
|
event: {
|
|
543
532
|
id: string;
|
|
@@ -549,11 +538,9 @@ export type TransactionEvent = {
|
|
|
549
538
|
|
|
550
539
|
export type TraceEvent = {
|
|
551
540
|
type: "trace";
|
|
552
|
-
chainId: number;
|
|
553
541
|
checkpoint: string;
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
name: string;
|
|
542
|
+
chain: Chain;
|
|
543
|
+
eventCallback: EventCallback;
|
|
557
544
|
|
|
558
545
|
event: {
|
|
559
546
|
id: string;
|
|
@@ -568,11 +555,9 @@ export type TraceEvent = {
|
|
|
568
555
|
|
|
569
556
|
export type LogEvent = {
|
|
570
557
|
type: "log";
|
|
571
|
-
chainId: number;
|
|
572
558
|
checkpoint: string;
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
name: string;
|
|
559
|
+
chain: Chain;
|
|
560
|
+
eventCallback: EventCallback;
|
|
576
561
|
|
|
577
562
|
event: {
|
|
578
563
|
id: string;
|
|
@@ -586,11 +571,9 @@ export type LogEvent = {
|
|
|
586
571
|
|
|
587
572
|
export type TransferEvent = {
|
|
588
573
|
type: "transfer";
|
|
589
|
-
chainId: number;
|
|
590
574
|
checkpoint: string;
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
name: string;
|
|
575
|
+
chain: Chain;
|
|
576
|
+
eventCallback: EventCallback;
|
|
594
577
|
|
|
595
578
|
event: {
|
|
596
579
|
id: string;
|
package/src/rpc/http.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { URL } from "node:url";
|
|
2
|
+
import type { Common } from "@/internal/common.js";
|
|
3
|
+
import type { Chain } from "@/internal/types.js";
|
|
4
|
+
import { HttpRequestError, RpcRequestError, TimeoutError } from "viem";
|
|
5
|
+
import {
|
|
6
|
+
type HttpRequestParameters,
|
|
7
|
+
type HttpRequestReturnType,
|
|
8
|
+
type HttpRpcClientOptions,
|
|
9
|
+
stringify,
|
|
10
|
+
} from "viem/utils";
|
|
11
|
+
|
|
12
|
+
export type RpcRequest = {
|
|
13
|
+
jsonrpc?: "2.0" | undefined;
|
|
14
|
+
method: string;
|
|
15
|
+
params?: any | undefined;
|
|
16
|
+
id?: number | undefined;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type HttpRpcClient = {
|
|
20
|
+
request<body extends RpcRequest>(
|
|
21
|
+
params: HttpRequestParameters<body>,
|
|
22
|
+
): Promise<HttpRequestReturnType<body>>;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function getHttpRpcClient(
|
|
26
|
+
url: string,
|
|
27
|
+
options: HttpRpcClientOptions & { common: Common; chain: Chain },
|
|
28
|
+
): HttpRpcClient {
|
|
29
|
+
const { common, chain } = options;
|
|
30
|
+
const timeoutMs = options?.timeout ?? 10_000;
|
|
31
|
+
let id = 1;
|
|
32
|
+
return {
|
|
33
|
+
async request(params) {
|
|
34
|
+
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: <explanation>
|
|
35
|
+
return new Promise(async (resolve, reject) => {
|
|
36
|
+
let isTimeoutRejected = false;
|
|
37
|
+
const { body } = params;
|
|
38
|
+
|
|
39
|
+
const fetchOptions = {
|
|
40
|
+
...(params.fetchOptions ?? {}),
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const { headers, method } = fetchOptions;
|
|
44
|
+
|
|
45
|
+
let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;
|
|
46
|
+
const controller = new AbortController();
|
|
47
|
+
const timeoutId = setTimeout(async () => {
|
|
48
|
+
isTimeoutRejected = true;
|
|
49
|
+
controller.abort();
|
|
50
|
+
|
|
51
|
+
reject(new TimeoutError({ body, url }));
|
|
52
|
+
|
|
53
|
+
if (reader) {
|
|
54
|
+
common.logger.warn({
|
|
55
|
+
msg: "JSON-RPC request timed out reading response body",
|
|
56
|
+
chain: chain.name,
|
|
57
|
+
chain_id: chain.id,
|
|
58
|
+
hostname: new URL(url).hostname,
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
request_id: headers ? headers["X-Request-ID"] : undefined,
|
|
61
|
+
method: body.method,
|
|
62
|
+
request: JSON.stringify(body),
|
|
63
|
+
duration: timeoutMs,
|
|
64
|
+
});
|
|
65
|
+
try {
|
|
66
|
+
await reader.cancel("Timeout");
|
|
67
|
+
} catch {}
|
|
68
|
+
}
|
|
69
|
+
}, timeoutMs);
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
const init: RequestInit = {
|
|
73
|
+
body: stringify({
|
|
74
|
+
jsonrpc: "2.0",
|
|
75
|
+
id: body.id ?? id++,
|
|
76
|
+
...body,
|
|
77
|
+
}),
|
|
78
|
+
headers: {
|
|
79
|
+
"Content-Type": "application/json",
|
|
80
|
+
...headers,
|
|
81
|
+
},
|
|
82
|
+
method: method || "POST",
|
|
83
|
+
signal: controller.signal,
|
|
84
|
+
};
|
|
85
|
+
const request = new Request(url, init);
|
|
86
|
+
const response = await fetch(request);
|
|
87
|
+
|
|
88
|
+
reader = response.body?.getReader()!;
|
|
89
|
+
const chunks: Uint8Array[] = [];
|
|
90
|
+
let totalLength = 0;
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
while (true) {
|
|
94
|
+
const { done, value } = await reader.read();
|
|
95
|
+
if (done) break;
|
|
96
|
+
chunks.push(value);
|
|
97
|
+
totalLength += value.length;
|
|
98
|
+
}
|
|
99
|
+
} finally {
|
|
100
|
+
reader.releaseLock();
|
|
101
|
+
reader = undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (isTimeoutRejected) return;
|
|
105
|
+
|
|
106
|
+
let offset = 0;
|
|
107
|
+
const fullData = new Uint8Array(totalLength);
|
|
108
|
+
for (const chunk of chunks) {
|
|
109
|
+
fullData.set(chunk, offset);
|
|
110
|
+
offset += chunk.length;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const text = new TextDecoder().decode(fullData);
|
|
114
|
+
|
|
115
|
+
let data: any = text;
|
|
116
|
+
try {
|
|
117
|
+
data = JSON.parse(data || "{}");
|
|
118
|
+
} catch (err) {
|
|
119
|
+
if (response.ok) throw err;
|
|
120
|
+
data = { error: data };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
clearTimeout(timeoutId);
|
|
124
|
+
|
|
125
|
+
if (!response.ok) {
|
|
126
|
+
reject(
|
|
127
|
+
new HttpRequestError({
|
|
128
|
+
body,
|
|
129
|
+
details: stringify(data.error) || response.statusText,
|
|
130
|
+
headers: response.headers,
|
|
131
|
+
status: response.status,
|
|
132
|
+
url,
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (data.error) {
|
|
139
|
+
reject(
|
|
140
|
+
new RpcRequestError({
|
|
141
|
+
body,
|
|
142
|
+
error: data.error,
|
|
143
|
+
url: url,
|
|
144
|
+
}),
|
|
145
|
+
);
|
|
146
|
+
} else {
|
|
147
|
+
resolve(data.result);
|
|
148
|
+
}
|
|
149
|
+
} catch (_error) {
|
|
150
|
+
const error = _error as Error;
|
|
151
|
+
clearTimeout(timeoutId);
|
|
152
|
+
|
|
153
|
+
if (isTimeoutRejected) return;
|
|
154
|
+
|
|
155
|
+
if (error.name === "AbortError") {
|
|
156
|
+
reject(new TimeoutError({ body, url }));
|
|
157
|
+
}
|
|
158
|
+
if (error instanceof HttpRequestError) reject(error);
|
|
159
|
+
reject(new HttpRequestError({ body, cause: error, url }));
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
package/src/rpc/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
1
|
+
import crypto, { type UUID } from "node:crypto";
|
|
2
2
|
import url from "node:url";
|
|
3
3
|
import type { Common } from "@/internal/common.js";
|
|
4
4
|
import type { Logger } from "@/internal/logger.js";
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
getLogsRetryHelper,
|
|
17
17
|
} from "@ponder/utils";
|
|
18
18
|
import {
|
|
19
|
-
http,
|
|
20
19
|
BlockNotFoundError,
|
|
21
20
|
type EIP1193Parameters,
|
|
22
21
|
type EIP1193RequestFn,
|
|
@@ -30,12 +29,14 @@ import {
|
|
|
30
29
|
type RpcError,
|
|
31
30
|
type RpcTransactionReceipt,
|
|
32
31
|
TimeoutError,
|
|
32
|
+
custom,
|
|
33
33
|
hexToNumber,
|
|
34
34
|
isHex,
|
|
35
35
|
webSocket,
|
|
36
36
|
} from "viem";
|
|
37
37
|
import { WebSocket } from "ws";
|
|
38
38
|
import type { DebugRpcSchema } from "../utils/debug.js";
|
|
39
|
+
import { getHttpRpcClient } from "./http.js";
|
|
39
40
|
|
|
40
41
|
export type RpcSchema = [
|
|
41
42
|
...PublicRpcSchema,
|
|
@@ -176,16 +177,32 @@ export const createRpc = ({
|
|
|
176
177
|
}: { common: Common; chain: Chain; concurrency?: number }): Rpc => {
|
|
177
178
|
let backends: { request: EIP1193RequestFn<RpcSchema>; hostname: string }[];
|
|
178
179
|
|
|
180
|
+
let requestId: UUID | undefined;
|
|
181
|
+
|
|
179
182
|
if (typeof chain.rpc === "string") {
|
|
180
183
|
const protocol = new url.URL(chain.rpc).protocol;
|
|
181
184
|
const hostname = new url.URL(chain.rpc).hostname;
|
|
182
185
|
if (protocol === "https:" || protocol === "http:") {
|
|
186
|
+
const httpRpcClient = getHttpRpcClient(chain.rpc, {
|
|
187
|
+
common,
|
|
188
|
+
chain,
|
|
189
|
+
timeout: 10_000,
|
|
190
|
+
});
|
|
183
191
|
backends = [
|
|
184
192
|
{
|
|
185
|
-
request:
|
|
193
|
+
request: custom({
|
|
194
|
+
request(body) {
|
|
195
|
+
if (requestId) {
|
|
196
|
+
return httpRpcClient.request({
|
|
197
|
+
body,
|
|
198
|
+
fetchOptions: { headers: { "X-Request-ID": requestId } },
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
return httpRpcClient.request({ body });
|
|
202
|
+
},
|
|
203
|
+
})({
|
|
186
204
|
chain: chain.viemChain,
|
|
187
205
|
retryCount: 0,
|
|
188
|
-
timeout: 10_000,
|
|
189
206
|
}).request,
|
|
190
207
|
hostname,
|
|
191
208
|
},
|
|
@@ -210,11 +227,25 @@ export const createRpc = ({
|
|
|
210
227
|
const hostname = new url.URL(chain.rpc).hostname;
|
|
211
228
|
|
|
212
229
|
if (protocol === "https:" || protocol === "http:") {
|
|
230
|
+
const httpRpcClient = getHttpRpcClient(rpc, {
|
|
231
|
+
common,
|
|
232
|
+
chain,
|
|
233
|
+
timeout: 10_000,
|
|
234
|
+
});
|
|
213
235
|
return {
|
|
214
|
-
request:
|
|
236
|
+
request: custom({
|
|
237
|
+
request(body) {
|
|
238
|
+
if (requestId) {
|
|
239
|
+
return httpRpcClient.request({
|
|
240
|
+
body,
|
|
241
|
+
fetchOptions: { headers: { "X-Request-ID": requestId } },
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return httpRpcClient.request({ body });
|
|
245
|
+
},
|
|
246
|
+
})({
|
|
215
247
|
chain: chain.viemChain,
|
|
216
248
|
retryCount: 0,
|
|
217
|
-
timeout: 10_000,
|
|
218
249
|
}).request,
|
|
219
250
|
hostname,
|
|
220
251
|
};
|
|
@@ -433,7 +464,7 @@ export const createRpc = ({
|
|
|
433
464
|
clearTimeout(t);
|
|
434
465
|
const getBucketDuration = endClock();
|
|
435
466
|
endClock = startClock();
|
|
436
|
-
const id = crypto.randomUUID()
|
|
467
|
+
const id = crypto.randomUUID();
|
|
437
468
|
|
|
438
469
|
const surpassTimeout = setTimeout(() => {
|
|
439
470
|
logger.warn({
|
|
@@ -469,6 +500,7 @@ export const createRpc = ({
|
|
|
469
500
|
bucket.rps[bucket.rps.length - 1]!.count++;
|
|
470
501
|
}
|
|
471
502
|
|
|
503
|
+
requestId = id;
|
|
472
504
|
const response = await bucket.request(body);
|
|
473
505
|
|
|
474
506
|
if (response === undefined) {
|