envio 3.10.0-subgraph → 3.11.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.
Files changed (76) hide show
  1. package/evm.schema.json +21 -4
  2. package/fuel.schema.json +21 -4
  3. package/index.d.ts +1 -1
  4. package/package.json +6 -6
  5. package/src/ChainState.res +9 -73
  6. package/src/ChainState.res.mjs +6 -58
  7. package/src/Config.res +73 -27
  8. package/src/Config.res.mjs +71 -21
  9. package/src/Core.res +0 -15
  10. package/src/Core.res.mjs +0 -11
  11. package/src/EventConfigBuilder.res +14 -10
  12. package/src/EventConfigBuilder.res.mjs +6 -4
  13. package/src/EventProcessing.res +6 -6
  14. package/src/EventProcessing.res.mjs +6 -8
  15. package/src/HandlerLoader.res +8 -20
  16. package/src/HandlerLoader.res.mjs +2 -11
  17. package/src/HandlerRegister.res +12 -11
  18. package/src/HandlerRegister.res.mjs +6 -5
  19. package/src/Internal.res +20 -4
  20. package/src/Internal.res.mjs +9 -0
  21. package/src/Main.res +8 -1
  22. package/src/Main.res.mjs +3 -3
  23. package/src/Persistence.res +11 -1
  24. package/src/Persistence.res.mjs +6 -2
  25. package/src/PgStorage.res +1 -1
  26. package/src/PgStorage.res.mjs +1 -1
  27. package/src/SimulateItems.res +13 -6
  28. package/src/SimulateItems.res.mjs +7 -6
  29. package/src/TestIndexer.res +6 -5
  30. package/src/TestIndexer.res.mjs +5 -4
  31. package/src/UserContext.res +51 -358
  32. package/src/UserContext.res.mjs +35 -271
  33. package/src/db/InternalTable.res +1 -1
  34. package/src/db/InternalTable.res.mjs +2 -1
  35. package/src/sources/ChainSources.res +72 -0
  36. package/src/sources/ChainSources.res.mjs +55 -0
  37. package/src/sources/EvmHyperSyncSource.res +10 -22
  38. package/src/sources/EvmHyperSyncSource.res.mjs +9 -41
  39. package/src/sources/FuelHyperSyncSource.res +10 -18
  40. package/src/sources/FuelHyperSyncSource.res.mjs +8 -38
  41. package/src/sources/HyperSync.res +31 -0
  42. package/src/sources/HyperSync.res.mjs +31 -0
  43. package/src/sources/HyperSync.resi +16 -0
  44. package/src/sources/StartBlockResolver.res +173 -0
  45. package/src/sources/StartBlockResolver.res.mjs +134 -0
  46. package/src/sources/Svm.res +0 -51
  47. package/src/sources/Svm.res.mjs +0 -46
  48. package/src/sources/SvmHyperSyncSource.res +20 -9
  49. package/src/sources/SvmHyperSyncSource.res.mjs +34 -12
  50. package/svm.schema.json +78 -63
  51. package/src/subgraph/blocks.ts +0 -176
  52. package/src/subgraph/calls.ts +0 -217
  53. package/src/subgraph/conformance.ts +0 -102
  54. package/src/subgraph/division.ts +0 -133
  55. package/src/subgraph/errors.ts +0 -90
  56. package/src/subgraph/graph-ts-types/VERSION +0 -2
  57. package/src/subgraph/graph-ts-types/chain/arweave.d.ts +0 -70
  58. package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +0 -327
  59. package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +0 -233
  60. package/src/subgraph/graph-ts-types/chain/near.d.ts +0 -253
  61. package/src/subgraph/graph-ts-types/chain/starknet.d.ts +0 -32
  62. package/src/subgraph/graph-ts-types/common/collections.d.ts +0 -136
  63. package/src/subgraph/graph-ts-types/common/conversion.d.ts +0 -11
  64. package/src/subgraph/graph-ts-types/common/datasource.d.ts +0 -30
  65. package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
  66. package/src/subgraph/graph-ts-types/common/json.d.ts +0 -17
  67. package/src/subgraph/graph-ts-types/common/numbers.d.ts +0 -120
  68. package/src/subgraph/graph-ts-types/common/value.d.ts +0 -120
  69. package/src/subgraph/graph-ts-types/common/yaml.d.ts +0 -90
  70. package/src/subgraph/graph-ts-types/global/global.d.ts +0 -194
  71. package/src/subgraph/graph-ts-types/helper-functions.d.ts +0 -22
  72. package/src/subgraph/graph-ts-types/index.d.ts +0 -102
  73. package/src/subgraph/graph-ts.ts +0 -1948
  74. package/src/subgraph/hosts.ts +0 -148
  75. package/src/subgraph/runtime.ts +0 -863
  76. package/src/subgraph/scope.ts +0 -66
package/src/Main.res CHANGED
@@ -126,7 +126,9 @@ let buildChainsObject = (~config: Config.t) => {
126
126
  get: () => {
127
127
  switch getInitialChainState(~chainId=chainConfig.id) {
128
128
  | Some(chainState) => chainState.startBlock
129
- | None => chainConfig.startBlock
129
+ // Only before persistence is ready, which in a real run is before any
130
+ // handler module has loaded. The test indexer sits here for good.
131
+ | None => chainConfig->Config.startBlockOrZero
130
132
  }
131
133
  },
132
134
  },
@@ -589,6 +591,10 @@ let migrate = async (~reset) => {
589
591
  ~envioInfo=getEnvioInfo(),
590
592
  ~resetCommand="envio local db-migrate setup",
591
593
  ~runCommand=None,
594
+ ~lowercaseAddresses=config.lowercaseAddresses,
595
+ // A migration command runs once and exits, with nobody watching it recover:
596
+ // an unreachable chain should say so now rather than hold the command open.
597
+ ~startBlockRetry=StartBlockResolver.Once,
592
598
  )
593
599
  await persistence.storage.close()
594
600
  }
@@ -641,6 +647,7 @@ let start = async (
641
647
  ~envioInfo=getEnvioInfo(),
642
648
  ~resetCommand=isDevelopmentMode ? "envio dev -r" : "envio start -r",
643
649
  ~runCommand=Some(isDevelopmentMode ? "envio dev" : "envio start"),
650
+ ~lowercaseAddresses=config.lowercaseAddresses,
644
651
  )
645
652
 
646
653
  // Loads user handler files, which register handler/contractRegister/where
package/src/Main.res.mjs CHANGED
@@ -130,7 +130,7 @@ function buildChainsObject(config) {
130
130
  if (chainState !== undefined) {
131
131
  return chainState.startBlock;
132
132
  } else {
133
- return chainConfig.startBlock;
133
+ return Config.startBlockOrZero(chainConfig);
134
134
  }
135
135
  }
136
136
  }), "endBlock", {
@@ -467,7 +467,7 @@ function getEnvioInfo() {
467
467
  async function migrate(reset) {
468
468
  let config = Config.load();
469
469
  let persistence = PgStorage.makePersistenceFromConfig(config, undefined);
470
- await Persistence.init(persistence, ChainMap.values(config.chainMap), config.contractMapping, Config.stripSensitiveData(Config.getPublicConfigJson()), "envio local db-migrate setup", undefined, reset);
470
+ await Persistence.init(persistence, ChainMap.values(config.chainMap), config.contractMapping, Config.stripSensitiveData(Config.getPublicConfigJson()), "envio local db-migrate setup", undefined, reset, config.lowercaseAddresses, "Once");
471
471
  return await persistence.storage.close();
472
472
  }
473
473
 
@@ -494,7 +494,7 @@ async function start(persistence, resetOpt, isTestOpt, exitAfterFirstEventBlockO
494
494
  let isDevelopmentMode = !isTest && config.isDev;
495
495
  let persistence$1 = persistence !== undefined ? persistence : PgStorage.makePersistenceFromConfig(config, undefined);
496
496
  EnvioGlobal.value.persistence = Primitive_option.some(persistence$1);
497
- await Persistence.init(persistence$1, ChainMap.values(config.chainMap), config.contractMapping, Config.stripSensitiveData(Config.getPublicConfigJson()), isDevelopmentMode ? "envio dev -r" : "envio start -r", isDevelopmentMode ? "envio dev" : "envio start", reset);
497
+ await Persistence.init(persistence$1, ChainMap.values(config.chainMap), config.contractMapping, Config.stripSensitiveData(Config.getPublicConfigJson()), isDevelopmentMode ? "envio dev -r" : "envio start -r", isDevelopmentMode ? "envio dev" : "envio start", reset, config.lowercaseAddresses, undefined);
498
498
  let registrationsByChainId = await HandlerLoader.registerAllHandlers(config);
499
499
  let config$1;
500
500
  if (isTest) {
@@ -235,12 +235,14 @@ let make = (
235
235
  let init = {
236
236
  async (
237
237
  persistence,
238
- ~chainConfigs,
238
+ ~chainConfigs: array<Config.chain>,
239
239
  ~contractMapping,
240
240
  ~envioInfo,
241
241
  ~resetCommand,
242
242
  ~runCommand,
243
243
  ~reset=false,
244
+ ~lowercaseAddresses=false,
245
+ ~startBlockRetry=StartBlockResolver.UntilItAnswers,
244
246
  ) => {
245
247
  try {
246
248
  let shouldRun = switch persistence.storageStatus {
@@ -259,6 +261,14 @@ let init = {
259
261
  persistence.storageStatus = Initializing(promise)
260
262
  if reset || !(await persistence.storage.isInitialized()) {
261
263
  Logging.info(`Initializing the indexer storage...`)
264
+ // Only runs once per schema (this branch is the "first deploy or
265
+ // reset" gate), which is exactly when a `latest` start block must be
266
+ // resolved: every later resume reads `envio_chains.start_block` back
267
+ // verbatim instead of re-running this.
268
+ let chainConfigs = await chainConfigs->StartBlockResolver.resolveAllOrThrow(
269
+ ~lowercaseAddresses,
270
+ ~retry=startBlockRetry,
271
+ )
262
272
  let initialState = await persistence.storage.initialize(
263
273
  ~entities=persistence.allEntities,
264
274
  ~enums=persistence.allEnums,
@@ -5,6 +5,7 @@ import * as Logging from "./Logging.res.mjs";
5
5
  import * as EntityHistory from "./db/EntityHistory.res.mjs";
6
6
  import * as ErrorHandling from "./ErrorHandling.res.mjs";
7
7
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
8
+ import * as StartBlockResolver from "./sources/StartBlockResolver.res.mjs";
8
9
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
9
10
 
10
11
  let StorageError = /* @__PURE__ */Primitive_exceptions.create("Persistence.StorageError");
@@ -20,8 +21,10 @@ function make(userEntities, allEnums, storage) {
20
21
  };
21
22
  }
22
23
 
23
- async function init(persistence, chainConfigs, contractMapping, envioInfo, resetCommand, runCommand, resetOpt) {
24
+ async function init(persistence, chainConfigs, contractMapping, envioInfo, resetCommand, runCommand, resetOpt, lowercaseAddressesOpt, startBlockRetryOpt) {
24
25
  let reset = resetOpt !== undefined ? resetOpt : false;
26
+ let lowercaseAddresses = lowercaseAddressesOpt !== undefined ? lowercaseAddressesOpt : false;
27
+ let startBlockRetry = startBlockRetryOpt !== undefined ? startBlockRetryOpt : "UntilItAnswers";
25
28
  try {
26
29
  let promise = persistence.storageStatus;
27
30
  let shouldRun;
@@ -48,7 +51,8 @@ async function init(persistence, chainConfigs, contractMapping, envioInfo, reset
48
51
  };
49
52
  if (reset || !await persistence.storage.isInitialized()) {
50
53
  Logging.info(`Initializing the indexer storage...`);
51
- let initialState = await persistence.storage.initialize(chainConfigs, persistence.allEntities, persistence.allEnums, contractMapping, envioInfo);
54
+ let chainConfigs$1 = await StartBlockResolver.resolveAllOrThrow(chainConfigs, lowercaseAddresses, startBlockRetry, undefined, undefined);
55
+ let initialState = await persistence.storage.initialize(chainConfigs$1, persistence.allEntities, persistence.allEnums, contractMapping, envioInfo);
52
56
  Logging.info(`The indexer storage is ready. Starting indexing!`);
53
57
  persistence.storageStatus = {
54
58
  TAG: "Ready",
package/src/PgStorage.res CHANGED
@@ -1917,7 +1917,7 @@ let make = (
1917
1917
  idx,
1918
1918
  ): Persistence.initialChainState => {
1919
1919
  id: chainConfig.id,
1920
- startBlock: chainConfig.startBlock,
1920
+ startBlock: chainConfig->Config.startBlockOrThrow,
1921
1921
  endBlock: chainConfig.endBlock,
1922
1922
  maxReorgDepth: chainConfig.maxReorgDepth,
1923
1923
  progressBlockNumber: -1,
@@ -1161,7 +1161,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1161
1161
  cache: cache,
1162
1162
  chains: chainConfigs.map((chainConfig, idx) => ({
1163
1163
  id: chainConfig.id,
1164
- startBlock: chainConfig.startBlock,
1164
+ startBlock: Config.startBlockOrThrow(chainConfig),
1165
1165
  endBlock: chainConfig.endBlock,
1166
1166
  maxReorgDepth: chainConfig.maxReorgDepth,
1167
1167
  progressBlockNumber: -1,
@@ -299,7 +299,7 @@ let parse = (
299
299
  ~onEventRegistrations: array<Internal.onEventRegistration>,
300
300
  ): parseResult => {
301
301
  let chainId = chainConfig.id
302
- let startBlock = chainConfig.startBlock
302
+ let startBlock = chainConfig->Config.startBlockOrZero
303
303
  let currentBlock = ref(startBlock)
304
304
  let currentLogIndex = ref(0)
305
305
 
@@ -358,15 +358,22 @@ let parse = (
358
358
  let path = item.path->Option.getOr([0])
359
359
  let programId =
360
360
  item.programId->Option.getOr(svmEventConfig.programId->SvmTypes.Pubkey.toString)
361
+ // `accountArguments` is the list the call carries, so it stands as
362
+ // written: a short one leaves the later slots absent, the way a
363
+ // truncated instruction reads from chain. Named accounts speak about
364
+ // some slots instead, so they go back onto their declared positions and
365
+ // a slot the item leaves out carries the program id — chain's own
366
+ // stand-in for an absent account, which reads back as absent for an
367
+ // optional slot and as the program for a required one.
361
368
  let accountArguments = switch item.accountArguments {
362
369
  | Some(args) => args
363
370
  | None =>
364
371
  switch item.accounts {
365
372
  | Some(named) =>
366
- svmEventConfig.accounts->Array.map(name =>
367
- switch named->Dict.get(name) {
368
- | Some({address}) => address
369
- | None => ""
373
+ svmEventConfig.accounts->Array.map(slot =>
374
+ switch slot->Internal.svmAccountSlotName {
375
+ | None => programId
376
+ | Some(name) => named->Dict.get(name)->Option.mapOr(programId, ({address}) => address)
370
377
  }
371
378
  )
372
379
  | None => []
@@ -695,7 +702,7 @@ let patchConfig = (
695
702
  let endBlock: int = raw["endBlock"]->(Utils.magic: 'a => int)
696
703
  // Parse with the process's startBlock so items default into the range
697
704
  // the source will be queried over; the source now filters by range.
698
- let chainConfig = {...chainConfig, startBlock, endBlock}
705
+ let chainConfig = {...chainConfig, startBlock: Config.Block(startBlock), endBlock}
699
706
  let {items, transactionStore, blockStore} = parse(
700
707
  ~simulateItems,
701
708
  ~config,
@@ -5,6 +5,7 @@ import * as Config from "./Config.res.mjs";
5
5
  import * as Address from "./Address.res.mjs";
6
6
  import * as ChainId from "./ChainId.res.mjs";
7
7
  import * as ChainMap from "./ChainMap.res.mjs";
8
+ import * as Internal from "./Internal.res.mjs";
8
9
  import * as BlockStore from "./sources/BlockStore.res.mjs";
9
10
  import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
10
11
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
@@ -184,7 +185,7 @@ function liveRegistrationsFor(config, chainId, eventConfig) {
184
185
 
185
186
  function parse(simulateItems, config, chainConfig, onEventRegistrations) {
186
187
  let chainId = chainConfig.id;
187
- let startBlock = chainConfig.startBlock;
188
+ let startBlock = Config.startBlockOrZero(chainConfig);
188
189
  let currentBlock = {
189
190
  contents: startBlock
190
191
  };
@@ -236,12 +237,12 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
236
237
  accountArguments = args;
237
238
  } else {
238
239
  let named = rawJson.accounts;
239
- accountArguments = named !== undefined ? eventConfig.accounts.map(name => {
240
- let match = named[name];
241
- if (match !== undefined) {
242
- return match.address;
240
+ accountArguments = named !== undefined ? eventConfig.accounts.map(slot => {
241
+ let name = Internal.svmAccountSlotName(slot);
242
+ if (name !== undefined) {
243
+ return Stdlib_Option.mapOr(named[name], programId, param => param.address);
243
244
  } else {
244
- return "";
245
+ return programId;
245
246
  }
246
247
  }) : [];
247
248
  }
@@ -355,13 +355,14 @@ let parseBlockRange = (
355
355
  JsError.throwWithMessage(`Chain ${chainIdStr} is not configured in config.yaml`)
356
356
  }
357
357
  let configChain = config.chainMap->ChainMap.get(chain)
358
+ let configStartBlock = configChain->Config.startBlockOrZero
358
359
 
359
360
  let startBlock = switch rawChainConfig.startBlock {
360
361
  | Some(sb) => sb
361
362
  | None =>
362
363
  switch progressBlock {
363
364
  | Some(prevEndBlock) => prevEndBlock + 1
364
- | None => configChain.startBlock
365
+ | None => configStartBlock
365
366
  }
366
367
  }
367
368
 
@@ -378,10 +379,10 @@ let parseBlockRange = (
378
379
  | None => None // auto-exit mode: will fetch first block with events and exit
379
380
  }
380
381
 
381
- if startBlock < configChain.startBlock {
382
+ if startBlock < configStartBlock {
382
383
  JsError.throwWithMessage(
383
- `Invalid block range for chain ${chainIdStr}: startBlock (${startBlock->Int.toString}) is less than config.startBlock (${configChain.startBlock->Int.toString}). ` ++
384
- `Either use startBlock >= ${configChain.startBlock->Int.toString} or create a new test indexer with createTestIndexer().`,
384
+ `Invalid block range for chain ${chainIdStr}: startBlock (${startBlock->Int.toString}) is less than config.startBlock (${configStartBlock->Int.toString}). ` ++
385
+ `Either use startBlock >= ${configStartBlock->Int.toString} or create a new test indexer with createTestIndexer().`,
385
386
  )
386
387
  }
387
388
 
@@ -754,7 +755,7 @@ let createTestIndexer = (): t<'processConfig> => {
754
755
  ->Utils.Object.definePropertyWithValue("id", {enumerable: true, value: chainConfig.id})
755
756
  ->Utils.Object.definePropertyWithValue(
756
757
  "startBlock",
757
- {enumerable: true, value: chainConfig.startBlock},
758
+ {enumerable: true, value: chainConfig->Config.startBlockOrZero},
758
759
  )
759
760
  ->Utils.Object.definePropertyWithValue(
760
761
  "endBlock",
@@ -268,16 +268,17 @@ function parseBlockRange(chainIdStr, config, rawChainConfig, progressBlock) {
268
268
  Stdlib_JsError.throwWithMessage(`Chain ` + chainIdStr + ` is not configured in config.yaml`);
269
269
  }
270
270
  let configChain = ChainMap.get(config.chainMap, chain);
271
+ let configStartBlock = Config.startBlockOrZero(configChain);
271
272
  let sb = rawChainConfig.startBlock;
272
273
  let startBlock = sb !== undefined ? sb : (
273
- progressBlock !== undefined ? progressBlock + 1 | 0 : configChain.startBlock
274
+ progressBlock !== undefined ? progressBlock + 1 | 0 : configStartBlock
274
275
  );
275
276
  let eb = rawChainConfig.endBlock;
276
277
  let endBlock = eb !== undefined ? eb : (
277
278
  Stdlib_Option.isSome(rawChainConfig.simulate) ? getSimulateEndBlock(Stdlib_Option.getOrThrow(rawChainConfig.simulate, undefined), config, startBlock) : undefined
278
279
  );
279
- if (startBlock < configChain.startBlock) {
280
- Stdlib_JsError.throwWithMessage(`Invalid block range for chain ` + chainIdStr + `: startBlock (` + startBlock.toString() + `) is less than config.startBlock (` + configChain.startBlock.toString() + `). ` + (`Either use startBlock >= ` + configChain.startBlock.toString() + ` or create a new test indexer with createTestIndexer().`));
280
+ if (startBlock < configStartBlock) {
281
+ Stdlib_JsError.throwWithMessage(`Invalid block range for chain ` + chainIdStr + `: startBlock (` + startBlock.toString() + `) is less than config.startBlock (` + configStartBlock.toString() + `). ` + (`Either use startBlock >= ` + configStartBlock.toString() + ` or create a new test indexer with createTestIndexer().`));
281
282
  }
282
283
  let match = configChain.endBlock;
283
284
  if (endBlock !== undefined && match !== undefined && endBlock > match) {
@@ -480,7 +481,7 @@ function createTestIndexer() {
480
481
  value: chainConfig.id
481
482
  }), "startBlock", {
482
483
  enumerable: true,
483
- value: chainConfig.startBlock
484
+ value: Config.startBlockOrZero(chainConfig)
484
485
  }), "endBlock", {
485
486
  enumerable: true,
486
487
  value: chainConfig.endBlock