envio 3.7.0 → 3.9.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/README.md +2 -2
- package/index.d.ts +399 -156
- package/package.json +6 -6
- package/src/AddressRows.res +121 -0
- package/src/AddressRows.res.mjs +143 -0
- package/src/Batch.res +2 -0
- package/src/Batch.res.mjs +2 -1
- package/src/ChainState.res +82 -68
- package/src/ChainState.res.mjs +81 -65
- package/src/ChainState.resi +14 -9
- package/src/Config.res +41 -91
- package/src/Config.res.mjs +34 -68
- package/src/ContractMapping.res +66 -0
- package/src/ContractMapping.res.mjs +73 -0
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +4 -0
- package/src/Envio.res +54 -76
- package/src/EventConfigBuilder.res +157 -30
- package/src/EventConfigBuilder.res.mjs +118 -24
- package/src/FetchState.res +59 -67
- package/src/FetchState.res.mjs +34 -44
- package/src/HandlerRegister.res +20 -11
- package/src/HandlerRegister.res.mjs +22 -5
- package/src/Hasura.res +30 -22
- package/src/Hasura.res.mjs +11 -5
- package/src/InMemoryStore.res +18 -36
- package/src/InMemoryStore.res.mjs +12 -26
- package/src/IndexerState.res +21 -1
- package/src/IndexerState.res.mjs +9 -3
- package/src/IndexerState.resi +1 -0
- package/src/Internal.res +33 -13
- package/src/Internal.res.mjs +12 -16
- package/src/Main.res +27 -20
- package/src/Main.res.mjs +19 -14
- package/src/MemoryStorage.res +78 -73
- package/src/MemoryStorage.res.mjs +66 -81
- package/src/Metrics.res +15 -1
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +34 -18
- package/src/Persistence.res.mjs +8 -5
- package/src/PgStorage.res +189 -66
- package/src/PgStorage.res.mjs +93 -59
- package/src/Rollback.res +14 -10
- package/src/Rollback.res.mjs +4 -2
- package/src/SimulateItems.res +254 -9
- package/src/SimulateItems.res.mjs +214 -47
- package/src/TestIndexer.res +119 -121
- package/src/TestIndexer.res.mjs +95 -100
- package/src/Utils.res +7 -0
- package/src/Utils.res.mjs +9 -2
- package/src/Writing.res +2 -0
- package/src/Writing.res.mjs +2 -1
- package/src/bindings/ClickHouse.res +39 -6
- package/src/bindings/ClickHouse.res.mjs +29 -4
- package/src/bindings/NodeJs.res +9 -0
- package/src/bindings/NodeJs.res.mjs +8 -1
- package/src/bindings/Postgres.res +9 -0
- package/src/bindings/Postgres.res.mjs +3 -0
- package/src/db/EntityHistory.res +12 -18
- package/src/db/EntityHistory.res.mjs +3 -14
- package/src/db/InternalTable.res +182 -65
- package/src/db/InternalTable.res.mjs +183 -73
- package/src/db/Table.res +24 -0
- package/src/db/Table.res.mjs +20 -1
- package/src/sources/AddressSet.res +0 -22
- package/src/sources/AddressStore.res +48 -88
- package/src/sources/AddressStore.res.mjs +11 -22
- package/src/sources/EvmHyperSyncSource.res +3 -2
- package/src/sources/SimulateSource.res +8 -4
- package/src/sources/SimulateSource.res.mjs +7 -3
- package/src/sources/Svm.res +34 -7
- package/src/sources/Svm.res.mjs +32 -4
- package/src/sources/SvmHyperSyncClient.res +24 -30
- package/src/sources/SvmHyperSyncClient.res.mjs +3 -2
- package/src/sources/SvmHyperSyncSource.res +88 -36
- package/src/sources/SvmHyperSyncSource.res.mjs +71 -39
- package/src/sources/TransactionStore.res +38 -0
- package/src/sources/TransactionStore.res.mjs +5 -0
- package/svm.schema.json +37 -82
package/src/TestIndexer.res
CHANGED
|
@@ -10,6 +10,12 @@ type fuelChainConfig = {
|
|
|
10
10
|
simulate?: array<Envio.fuelSimulateItem>,
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
type svmChainConfig = {
|
|
14
|
+
startBlock?: int,
|
|
15
|
+
endBlock?: int,
|
|
16
|
+
simulate?: array<Envio.svmSimulateItem>,
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
// Internal type used for block range validation and state management
|
|
14
20
|
type chainConfig = {
|
|
15
21
|
startBlock: int,
|
|
@@ -31,44 +37,19 @@ type testIndexerState = {
|
|
|
31
37
|
// Store decoded entities (not JSON) for proper comparison operations
|
|
32
38
|
entities: dict<dict<Internal.entity>>,
|
|
33
39
|
entityConfigs: dict<Internal.entityConfig>,
|
|
40
|
+
addresses: AddressRows.Table.t,
|
|
41
|
+
contractMapping: ContractMapping.t,
|
|
34
42
|
mutable processChanges: array<unknown>,
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
|
|
45
|
+
let addressRowsByChain = (state: testIndexerState) =>
|
|
46
|
+
state.addresses->AddressRows.Table.groupByChain
|
|
39
47
|
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// All indexing addresses (config-seeded + dynamically registered) grouped by
|
|
47
|
-
// chain id string, derived from the envio_addresses entities.
|
|
48
|
-
let getIndexingAddressesByChain = (state: testIndexerState): dict<
|
|
49
|
-
array<Internal.indexingAddress>,
|
|
50
|
-
> => {
|
|
51
|
-
let byChain = Dict.make()
|
|
52
|
-
switch state.entities->Dict.get(InternalTable.EnvioAddresses.name) {
|
|
53
|
-
| Some(dcDict) =>
|
|
54
|
-
dcDict
|
|
55
|
-
->Dict.valuesToArray
|
|
56
|
-
->Array.forEach(entity => {
|
|
57
|
-
let dc = entity->castToEnvioAddresses
|
|
58
|
-
let chainIdStr = dc.chainId->ChainId.toString
|
|
59
|
-
let contracts = switch byChain->Dict.get(chainIdStr) {
|
|
60
|
-
| Some(arr) => arr
|
|
61
|
-
| None =>
|
|
62
|
-
let arr = []
|
|
63
|
-
byChain->Dict.set(chainIdStr, arr)
|
|
64
|
-
arr
|
|
65
|
-
}
|
|
66
|
-
contracts->Array.push(dc->toIndexingAddress)->ignore
|
|
67
|
-
})
|
|
68
|
-
| None => ()
|
|
69
|
-
}
|
|
70
|
-
byChain
|
|
71
|
-
}
|
|
48
|
+
let renderRows = (rows: array<AddressRows.row>, ~config: Config.t) =>
|
|
49
|
+
rows->AddressRows.render(
|
|
50
|
+
~ecosystem=(config.ecosystem.name :> string),
|
|
51
|
+
~shouldChecksum=!config.lowercaseAddresses,
|
|
52
|
+
)
|
|
72
53
|
|
|
73
54
|
// Rows of a per-chain entity are keyed per (chain, id): the same id exists
|
|
74
55
|
// independently on every chain.
|
|
@@ -119,7 +100,9 @@ let handleLoad = (state: testIndexerState, ~tableName: string, ~filter: EntityFi
|
|
|
119
100
|
|
|
120
101
|
let handleWriteBatch = (
|
|
121
102
|
state: testIndexerState,
|
|
103
|
+
~config: Config.t,
|
|
122
104
|
~updatedEntities: array<Persistence.updatedEntity>,
|
|
105
|
+
~registeredAddresses: array<AddressRows.staged>,
|
|
123
106
|
~checkpointIds: array<bigint>,
|
|
124
107
|
~checkpointChainIds: array<ChainId.t>,
|
|
125
108
|
~checkpointBlockNumbers: array<int>,
|
|
@@ -129,6 +112,22 @@ let handleWriteBatch = (
|
|
|
129
112
|
// checkpointId -> entityName -> entityChange
|
|
130
113
|
let changesByCheckpoint: dict<dict<entityChange>> = Dict.make()
|
|
131
114
|
|
|
115
|
+
// checkpointId -> the addresses that checkpoint registered, rendered for the
|
|
116
|
+
// change log. Rendering is the Rust codec's job, so the rows keep their keys
|
|
117
|
+
// right up to here.
|
|
118
|
+
let addressesByCheckpoint: dict<array<{"address": Address.t, "contract": string}>> = Dict.make()
|
|
119
|
+
let rendered = registeredAddresses->Array.map(({row}) => row)->renderRows(~config)
|
|
120
|
+
registeredAddresses->Array.forEachWithIndex(({row, checkpointId}, idx) => {
|
|
121
|
+
state.addresses->AddressRows.Table.insert(row)
|
|
122
|
+
addressesByCheckpoint->Utils.Dict.push(
|
|
123
|
+
checkpointId->BigInt.toString,
|
|
124
|
+
{
|
|
125
|
+
"address": rendered->Array.getUnsafe(idx),
|
|
126
|
+
"contract": state.contractMapping->ContractMapping.nameOfOrThrow(row.contractId),
|
|
127
|
+
},
|
|
128
|
+
)
|
|
129
|
+
})
|
|
130
|
+
|
|
132
131
|
updatedEntities->Array.forEach(({entityConfig, scope, changes}: Persistence.updatedEntity) => {
|
|
133
132
|
let entityName = entityConfig.name
|
|
134
133
|
// The scope is what makes a per-chain row identifiable, so it's stamped
|
|
@@ -204,43 +203,33 @@ let handleWriteBatch = (
|
|
|
204
203
|
|
|
205
204
|
// Add entity changes for this checkpoint
|
|
206
205
|
let checkpointKey = checkpointId->BigInt.toString
|
|
206
|
+
switch addressesByCheckpoint->Utils.Dict.dangerouslyGetNonOption(checkpointKey) {
|
|
207
|
+
| Some(rendered) =>
|
|
208
|
+
let addressesObj: dict<unknown> = Dict.make()
|
|
209
|
+
addressesObj->Dict.set(
|
|
210
|
+
"sets",
|
|
211
|
+
rendered->(Utils.magic: array<{"address": Address.t, "contract": string}> => unknown),
|
|
212
|
+
)
|
|
213
|
+
change->Dict.set("addresses", addressesObj->(Utils.magic: dict<unknown> => unknown))
|
|
214
|
+
| None => ()
|
|
215
|
+
}
|
|
207
216
|
switch changesByCheckpoint->Dict.get(checkpointKey) {
|
|
208
217
|
| Some(entityChanges) =>
|
|
209
218
|
entityChanges
|
|
210
219
|
->Dict.toArray
|
|
211
220
|
->Array.forEach(((entityName, {sets, deleted})) => {
|
|
212
|
-
|
|
213
|
-
if
|
|
214
|
-
|
|
215
|
-
if sets->Array.length > 0 {
|
|
216
|
-
// Transform sets to simplified {address, contract} objects
|
|
217
|
-
let simplifiedSets = sets->Array.map(entity => {
|
|
218
|
-
let dc = entity->Utils.magic->castToEnvioAddresses
|
|
219
|
-
{"address": dc->Config.EnvioAddresses.getAddress, "contract": dc.contractName}
|
|
220
|
-
})
|
|
221
|
-
entityObj->Dict.set(
|
|
222
|
-
"sets",
|
|
223
|
-
simplifiedSets->(
|
|
224
|
-
Utils.magic: array<{"address": Address.t, "contract": string}> => unknown
|
|
225
|
-
),
|
|
226
|
-
)
|
|
227
|
-
}
|
|
228
|
-
// Note: deleted is not relevant for addresses since we use address string directly
|
|
229
|
-
change->Dict.set("addresses", entityObj->(Utils.magic: dict<unknown> => unknown))
|
|
230
|
-
} else {
|
|
231
|
-
let entityObj: dict<unknown> = Dict.make()
|
|
232
|
-
if sets->Array.length > 0 {
|
|
233
|
-
entityObj->Dict.set("sets", sets->(Utils.magic: array<unknown> => unknown))
|
|
234
|
-
}
|
|
235
|
-
if deleted->Array.length > 0 {
|
|
236
|
-
entityObj->Dict.set("deleted", deleted->(Utils.magic: array<EntityId.t> => unknown))
|
|
237
|
-
}
|
|
238
|
-
// Match the capitalized entity accessor the generated change types expose.
|
|
239
|
-
change->Dict.set(
|
|
240
|
-
entityName->Utils.String.capitalize,
|
|
241
|
-
entityObj->(Utils.magic: dict<unknown> => unknown),
|
|
242
|
-
)
|
|
221
|
+
let entityObj: dict<unknown> = Dict.make()
|
|
222
|
+
if sets->Array.length > 0 {
|
|
223
|
+
entityObj->Dict.set("sets", sets->(Utils.magic: array<unknown> => unknown))
|
|
243
224
|
}
|
|
225
|
+
if deleted->Array.length > 0 {
|
|
226
|
+
entityObj->Dict.set("deleted", deleted->(Utils.magic: array<EntityId.t> => unknown))
|
|
227
|
+
}
|
|
228
|
+
// Match the capitalized entity accessor the generated change types expose.
|
|
229
|
+
change->Dict.set(
|
|
230
|
+
entityName->Utils.String.capitalize,
|
|
231
|
+
entityObj->(Utils.magic: dict<unknown> => unknown),
|
|
232
|
+
)
|
|
244
233
|
})
|
|
245
234
|
| None => ()
|
|
246
235
|
}
|
|
@@ -254,7 +243,8 @@ let handleWriteBatch = (
|
|
|
254
243
|
let makeInitialState = (
|
|
255
244
|
~config: Config.t,
|
|
256
245
|
~processConfigChains: dict<chainConfig>,
|
|
257
|
-
~
|
|
246
|
+
~addressRowsByChain: dict<AddressRows.seedRows>,
|
|
247
|
+
~contractMapping: ContractMapping.t,
|
|
258
248
|
): Persistence.initialState => {
|
|
259
249
|
let chainKeys = processConfigChains->Dict.keysToArray
|
|
260
250
|
let chains = chainKeys->Array.map(chainIdStr => {
|
|
@@ -265,7 +255,10 @@ let makeInitialState = (
|
|
|
265
255
|
}
|
|
266
256
|
|
|
267
257
|
let processChainConfig = processConfigChains->Dict.getUnsafe(chainIdStr)
|
|
268
|
-
let
|
|
258
|
+
let addressRows =
|
|
259
|
+
addressRowsByChain
|
|
260
|
+
->Utils.Dict.dangerouslyGetNonOption(chainIdStr)
|
|
261
|
+
->Option.getOr(AddressRows.emptySeedRows())
|
|
269
262
|
{
|
|
270
263
|
Persistence.id: chain,
|
|
271
264
|
startBlock: processChainConfig.startBlock,
|
|
@@ -276,17 +269,18 @@ let makeInitialState = (
|
|
|
276
269
|
numEventsProcessed: 0.,
|
|
277
270
|
firstEventBlockNumber: None,
|
|
278
271
|
timestampCaughtUpToHeadOrEndblock: None,
|
|
279
|
-
|
|
272
|
+
addressRows,
|
|
280
273
|
}
|
|
281
274
|
})
|
|
282
275
|
|
|
283
276
|
{
|
|
284
277
|
cleanRun: true,
|
|
278
|
+
contractMapping,
|
|
279
|
+
envioInfo: Some(JSON.Encode.object(Dict.make())),
|
|
285
280
|
cache: Dict.make(),
|
|
286
281
|
chains,
|
|
287
282
|
checkpointId: InternalTable.Checkpoints.initialCheckpointId,
|
|
288
283
|
reorgCheckpoints: [],
|
|
289
|
-
envioInfo: Some(Config.getPublicConfigJson()->Config.stripSensitiveData),
|
|
290
284
|
}
|
|
291
285
|
}
|
|
292
286
|
|
|
@@ -314,22 +308,32 @@ let getSimulateEndBlock = (
|
|
|
314
308
|
~startBlock: int,
|
|
315
309
|
): int => {
|
|
316
310
|
let maxBlock = ref(startBlock)
|
|
311
|
+
let blockNumberKey = switch config.ecosystem.name {
|
|
312
|
+
| Svm => "slot"
|
|
313
|
+
| _ => config.ecosystem.blockNumberName
|
|
314
|
+
}
|
|
315
|
+
let bump = (n: option<int>) =>
|
|
316
|
+
switch n {
|
|
317
|
+
| Some(v) if v > maxBlock.contents => maxBlock := v
|
|
318
|
+
| _ => ()
|
|
319
|
+
}
|
|
320
|
+
let getInt = (d: dict<JSON.t>, key) =>
|
|
321
|
+
d
|
|
322
|
+
->Dict.get(key)
|
|
323
|
+
->Option.flatMap(v => v->(Utils.magic: JSON.t => Nullable.t<int>)->Nullable.toOption)
|
|
317
324
|
simulateItems->Array.forEach(rawJson => {
|
|
325
|
+
let itemDict = rawJson->(Utils.magic: JSON.t => dict<JSON.t>)
|
|
326
|
+
// SVM items carry the slot at the top level (`block.slot` is the override).
|
|
327
|
+
switch config.ecosystem.name {
|
|
328
|
+
| Svm => itemDict->getInt("slot")->bump
|
|
329
|
+
| _ => ()
|
|
330
|
+
}
|
|
318
331
|
let blockJson: option<JSON.t> =
|
|
319
332
|
(rawJson->(Utils.magic: JSON.t => {..}))["block"]
|
|
320
333
|
->(Utils.magic: 'a => Nullable.t<JSON.t>)
|
|
321
334
|
->Nullable.toOption
|
|
322
335
|
switch blockJson {
|
|
323
|
-
| Some(bj) =>
|
|
324
|
-
let blockDict = bj->(Utils.magic: JSON.t => dict<JSON.t>)
|
|
325
|
-
let n: option<int> =
|
|
326
|
-
blockDict
|
|
327
|
-
->Dict.get(config.ecosystem.blockNumberName)
|
|
328
|
-
->Option.flatMap(v => v->(Utils.magic: JSON.t => Nullable.t<int>)->Nullable.toOption)
|
|
329
|
-
switch n {
|
|
330
|
-
| Some(v) if v > maxBlock.contents => maxBlock := v
|
|
331
|
-
| _ => ()
|
|
332
|
-
}
|
|
336
|
+
| Some(bj) => bj->(Utils.magic: JSON.t => dict<JSON.t>)->getInt(blockNumberKey)->bump
|
|
333
337
|
| None => ()
|
|
334
338
|
}
|
|
335
339
|
})
|
|
@@ -575,7 +579,13 @@ let makeInMemoryStorage = (~state: testIndexerState): Persistence.storage => {
|
|
|
575
579
|
// The runner injects the config-derived initial state by setting
|
|
576
580
|
// `persistence.storageStatus = Ready(...)` directly, bypassing `Persistence.init`,
|
|
577
581
|
// so neither of these is reached.
|
|
578
|
-
initialize: async (
|
|
582
|
+
initialize: async (
|
|
583
|
+
~chainConfigs as _=?,
|
|
584
|
+
~entities as _=?,
|
|
585
|
+
~enums as _=?,
|
|
586
|
+
~contractMapping as _,
|
|
587
|
+
~envioInfo as _,
|
|
588
|
+
) =>
|
|
579
589
|
JsError.throwWithMessage(
|
|
580
590
|
"TestIndexer: initialize should not be called; the initial state is derived from config.",
|
|
581
591
|
),
|
|
@@ -595,15 +605,18 @@ let makeInMemoryStorage = (~state: testIndexerState): Persistence.storage => {
|
|
|
595
605
|
~batch,
|
|
596
606
|
~rollback as _,
|
|
597
607
|
~isInReorgThreshold as _,
|
|
598
|
-
~config
|
|
608
|
+
~config,
|
|
599
609
|
~allEntities as _,
|
|
600
610
|
~updatedEffectsCache as _,
|
|
601
611
|
~updatedEntities,
|
|
612
|
+
~registeredAddresses,
|
|
602
613
|
~chainMetaData as _,
|
|
603
614
|
~onWrite as _,
|
|
604
615
|
) =>
|
|
605
616
|
state->handleWriteBatch(
|
|
617
|
+
~config,
|
|
606
618
|
~updatedEntities,
|
|
619
|
+
~registeredAddresses,
|
|
607
620
|
~checkpointIds=batch.checkpointIds,
|
|
608
621
|
~checkpointChainIds=batch.checkpointChainIds,
|
|
609
622
|
~checkpointBlockNumbers=batch.checkpointBlockNumbers,
|
|
@@ -672,7 +685,7 @@ let getRegistrations = (~config) =>
|
|
|
672
685
|
|
|
673
686
|
let createTestIndexer = (): t<'processConfig> => {
|
|
674
687
|
let config = Config.load()
|
|
675
|
-
let allEntities = config.
|
|
688
|
+
let allEntities = config.userEntities
|
|
676
689
|
let entities = Dict.make()
|
|
677
690
|
let entityConfigs = Dict.make()
|
|
678
691
|
allEntities->Array.forEach(entityConfig => {
|
|
@@ -680,32 +693,19 @@ let createTestIndexer = (): t<'processConfig> => {
|
|
|
680
693
|
entityConfigs->Dict.set(entityConfig.name, entityConfig)
|
|
681
694
|
})
|
|
682
695
|
|
|
683
|
-
|
|
684
|
-
let
|
|
685
|
-
config.
|
|
686
|
-
|
|
687
|
-
->
|
|
688
|
-
chainConfig.contracts->Array.forEach(contract => {
|
|
689
|
-
contract.addresses->Array.forEach(
|
|
690
|
-
address => {
|
|
691
|
-
let entity: InternalTable.EnvioAddresses.t = {
|
|
692
|
-
id: Config.EnvioAddresses.makeId(~chainId=chainConfig.id, ~address),
|
|
693
|
-
chainId: chainConfig.id,
|
|
694
|
-
contractName: contract.name,
|
|
695
|
-
registrationBlock: -1,
|
|
696
|
-
registrationLogIndex: -1,
|
|
697
|
-
}
|
|
698
|
-
envioAddressesDict->Dict.set(entity.id, entity->Config.EnvioAddresses.castToInternal)
|
|
699
|
-
},
|
|
700
|
-
)
|
|
701
|
-
})
|
|
702
|
-
})
|
|
696
|
+
let chainConfigs = config.chainMap->ChainMap.values
|
|
697
|
+
let contractMapping = config.contractMapping
|
|
698
|
+
let ecosystem = config.ecosystem.name
|
|
699
|
+
let addresses = AddressRows.Table.make()
|
|
700
|
+
addresses->ChainState.seedConfigAddresses(~chainConfigs, ~ecosystem, ~contractMapping)
|
|
703
701
|
|
|
704
702
|
let state = {
|
|
705
703
|
processInProgress: false,
|
|
706
704
|
progressBlockByChain: Dict.make(),
|
|
707
705
|
entities,
|
|
708
706
|
entityConfigs,
|
|
707
|
+
addresses,
|
|
708
|
+
contractMapping,
|
|
709
709
|
processChanges: [],
|
|
710
710
|
}
|
|
711
711
|
|
|
@@ -728,19 +728,16 @@ let createTestIndexer = (): t<'processConfig> => {
|
|
|
728
728
|
// Build entity operations for each user entity
|
|
729
729
|
let entityOpsDict: dict<entityOperations> = Dict.make()
|
|
730
730
|
allEntities->Array.forEach(entityConfig => {
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
entityConfig
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
},
|
|
742
|
-
)
|
|
743
|
-
}
|
|
731
|
+
entityOpsDict->Dict.set(
|
|
732
|
+
entityConfig.name,
|
|
733
|
+
{
|
|
734
|
+
get: makeEntityGet(~state, ~entityConfig),
|
|
735
|
+
getAll: makeEntityGetAll(~state, ~entityConfig),
|
|
736
|
+
getWhere: makeEntityGetWhere(~state, ~entityConfig),
|
|
737
|
+
getOrThrow: makeEntityGetOrThrow(~state, ~entityConfig),
|
|
738
|
+
set: makeEntitySet(~state, ~entityConfig),
|
|
739
|
+
},
|
|
740
|
+
)
|
|
744
741
|
})
|
|
745
742
|
|
|
746
743
|
// Build chain info from config (similar to Main.getGlobalIndexer but static)
|
|
@@ -783,10 +780,11 @@ let createTestIndexer = (): t<'processConfig> => {
|
|
|
783
780
|
`Cannot access ${contract.name}.addresses while indexer.process() is running. ` ++ "Wait for process() to complete before reading contract addresses.",
|
|
784
781
|
)
|
|
785
782
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
->
|
|
789
|
-
->Array.
|
|
783
|
+
let contractId = state.contractMapping->ContractMapping.idOfOrThrow(contract.name)
|
|
784
|
+
state.addresses
|
|
785
|
+
->AddressRows.Table.rows
|
|
786
|
+
->Array.filter(row => row.chainId === chainConfig.id && row.contractId === contractId)
|
|
787
|
+
->renderRows(~config)
|
|
790
788
|
},
|
|
791
789
|
},
|
|
792
790
|
)
|
|
@@ -883,11 +881,11 @@ let createTestIndexer = (): t<'processConfig> => {
|
|
|
883
881
|
// by earlier ones.
|
|
884
882
|
let chains: dict<chainConfig> = Dict.make()
|
|
885
883
|
chains->Dict.set(chainIdStr, processChainConfig)
|
|
886
|
-
let indexingAddressesByChain = getIndexingAddressesByChain(state)
|
|
887
884
|
let initialState = makeInitialState(
|
|
888
885
|
~config,
|
|
889
886
|
~processConfigChains=chains,
|
|
890
|
-
~
|
|
887
|
+
~addressRowsByChain=addressRowsByChain(state),
|
|
888
|
+
~contractMapping=state.contractMapping,
|
|
891
889
|
)
|
|
892
890
|
|
|
893
891
|
// No endBlock means auto-exit mode: process one block checkpoint at a
|