envio 3.0.2 → 3.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +0 -1
  2. package/evm.schema.json +15 -8
  3. package/fuel.schema.json +19 -12
  4. package/index.d.ts +0 -2
  5. package/package.json +6 -7
  6. package/rescript.json +1 -1
  7. package/src/Batch.res +4 -214
  8. package/src/Batch.res.mjs +6 -165
  9. package/src/ChainFetcher.res +12 -28
  10. package/src/ChainFetcher.res.mjs +8 -17
  11. package/src/ChainManager.res +10 -9
  12. package/src/ChainManager.res.mjs +6 -10
  13. package/src/Config.res +9 -25
  14. package/src/Config.res.mjs +17 -27
  15. package/src/Core.res +7 -0
  16. package/src/Ctx.res +1 -0
  17. package/src/Env.res +0 -8
  18. package/src/Env.res.mjs +0 -6
  19. package/src/EventConfigBuilder.res +13 -123
  20. package/src/EventConfigBuilder.res.mjs +6 -73
  21. package/src/EventProcessing.res +5 -29
  22. package/src/EventProcessing.res.mjs +11 -20
  23. package/src/EventUtils.res +0 -27
  24. package/src/EventUtils.res.mjs +0 -24
  25. package/src/FetchState.res +2 -15
  26. package/src/FetchState.res.mjs +3 -18
  27. package/src/GlobalState.res +26 -39
  28. package/src/GlobalState.res.mjs +12 -40
  29. package/src/HandlerLoader.res +6 -5
  30. package/src/HandlerLoader.res.mjs +27 -9
  31. package/src/HandlerRegister.res +1 -12
  32. package/src/HandlerRegister.res.mjs +1 -6
  33. package/src/HandlerRegister.resi +1 -1
  34. package/src/Hasura.res +96 -32
  35. package/src/Hasura.res.mjs +93 -38
  36. package/src/InMemoryStore.res +205 -45
  37. package/src/InMemoryStore.res.mjs +157 -40
  38. package/src/InMemoryTable.res +165 -249
  39. package/src/InMemoryTable.res.mjs +156 -227
  40. package/src/Internal.res +10 -34
  41. package/src/Internal.res.mjs +9 -3
  42. package/src/LoadLayer.res +5 -5
  43. package/src/LoadLayer.res.mjs +5 -5
  44. package/src/LogSelection.res +15 -19
  45. package/src/LogSelection.res.mjs +5 -6
  46. package/src/Main.res +4 -6
  47. package/src/Main.res.mjs +26 -15
  48. package/src/Persistence.res +7 -132
  49. package/src/Persistence.res.mjs +1 -102
  50. package/src/PgStorage.res +57 -40
  51. package/src/PgStorage.res.mjs +60 -34
  52. package/src/ReorgDetection.res +35 -58
  53. package/src/ReorgDetection.res.mjs +21 -29
  54. package/src/SimulateItems.res.mjs +21 -3
  55. package/src/Sink.res +2 -2
  56. package/src/Sink.res.mjs +1 -1
  57. package/src/TableIndices.res +9 -2
  58. package/src/TableIndices.res.mjs +7 -1
  59. package/src/TestIndexer.res +53 -60
  60. package/src/TestIndexer.res.mjs +77 -63
  61. package/src/TestIndexerProxyStorage.res +4 -14
  62. package/src/TestIndexerProxyStorage.res.mjs +1 -5
  63. package/src/UserContext.res +2 -4
  64. package/src/UserContext.res.mjs +4 -5
  65. package/src/Utils.res +0 -2
  66. package/src/Utils.res.mjs +0 -3
  67. package/src/bindings/ClickHouse.res +45 -38
  68. package/src/bindings/ClickHouse.res.mjs +16 -17
  69. package/src/bindings/Vitest.res +3 -0
  70. package/src/db/InternalTable.res +59 -18
  71. package/src/db/InternalTable.res.mjs +82 -51
  72. package/src/db/Table.res +9 -2
  73. package/src/db/Table.res.mjs +10 -7
  74. package/src/sources/EnvioApiClient.res +15 -0
  75. package/src/sources/EnvioApiClient.res.mjs +24 -0
  76. package/src/sources/EvmChain.res +32 -10
  77. package/src/sources/EvmChain.res.mjs +31 -5
  78. package/src/sources/HyperFuelSource.res +15 -58
  79. package/src/sources/HyperFuelSource.res.mjs +20 -39
  80. package/src/sources/HyperSync.res +54 -100
  81. package/src/sources/HyperSync.res.mjs +67 -96
  82. package/src/sources/HyperSync.resi +4 -22
  83. package/src/sources/HyperSyncClient.res +70 -247
  84. package/src/sources/HyperSyncClient.res.mjs +47 -46
  85. package/src/sources/HyperSyncSource.res +94 -166
  86. package/src/sources/HyperSyncSource.res.mjs +100 -127
  87. package/src/sources/RpcSource.res +43 -22
  88. package/src/sources/RpcSource.res.mjs +50 -35
  89. package/src/sources/SimulateSource.res +1 -7
  90. package/src/sources/SimulateSource.res.mjs +1 -7
  91. package/src/sources/Source.res +10 -1
  92. package/src/sources/Source.res.mjs +3 -0
  93. package/src/sources/SourceManager.res +177 -8
  94. package/src/sources/SourceManager.res.mjs +141 -3
  95. package/src/sources/SourceManager.resi +19 -0
  96. package/src/tui/Tui.res +44 -6
  97. package/src/tui/Tui.res.mjs +56 -8
  98. package/src/tui/components/TuiData.res +3 -0
  99. package/svm.schema.json +11 -4
  100. package/src/sources/HyperSyncJsonApi.res +0 -390
  101. package/src/sources/HyperSyncJsonApi.res.mjs +0 -237
@@ -5,13 +5,9 @@ type selectionConfig = {
5
5
  ~addressesByContractName: dict<array<Address.t>>,
6
6
  ) => array<LogSelection.t>,
7
7
  fieldSelection: HyperSyncClient.QueryTypes.fieldSelection,
8
- nonOptionalBlockFieldNames: array<string>,
9
- nonOptionalTransactionFieldNames: array<string>,
10
8
  }
11
9
 
12
10
  let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
13
- let nonOptionalBlockFieldNames = Utils.Set.make()
14
- let nonOptionalTransactionFieldNames = Utils.Set.make()
15
11
  let capitalizedBlockFields = Utils.Set.make()
16
12
  let capitalizedTransactionFields = Utils.Set.make()
17
13
 
@@ -33,22 +29,18 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
33
29
  }) => {
34
30
  selectedBlockFields
35
31
  ->Utils.Set.toArray
36
- ->Array.forEach(name => {
37
- let nameStr = (name :> string)
38
- if !(Internal.evmNullableBlockFields->Utils.Set.has(name)) {
39
- nonOptionalBlockFieldNames->Utils.Set.add(nameStr)->ignore
40
- }
41
- capitalizedBlockFields->Utils.Set.add(nameStr->Utils.String.capitalize)->ignore
42
- })
32
+ ->Array.forEach(name =>
33
+ capitalizedBlockFields
34
+ ->Utils.Set.add((name :> string)->Utils.String.capitalize)
35
+ ->ignore
36
+ )
43
37
  selectedTransactionFields
44
38
  ->Utils.Set.toArray
45
- ->Array.forEach(name => {
46
- let nameStr = (name :> string)
47
- if !(Internal.evmNullableTransactionFields->Utils.Set.has(name)) {
48
- nonOptionalTransactionFieldNames->Utils.Set.add(nameStr)->ignore
49
- }
50
- capitalizedTransactionFields->Utils.Set.add(nameStr->Utils.String.capitalize)->ignore
51
- })
39
+ ->Array.forEach(name =>
40
+ capitalizedTransactionFields
41
+ ->Utils.Set.add((name :> string)->Utils.String.capitalize)
42
+ ->ignore
43
+ )
52
44
 
53
45
  let eventFilters = getEventFiltersOrThrow(chain)
54
46
  if dependsOnAddresses {
@@ -130,39 +122,42 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
130
122
  {
131
123
  getLogSelectionOrThrow,
132
124
  fieldSelection,
133
- nonOptionalBlockFieldNames: nonOptionalBlockFieldNames->Utils.Set.toArray,
134
- nonOptionalTransactionFieldNames: nonOptionalTransactionFieldNames->Utils.Set.toArray,
135
125
  }
136
126
  }
137
127
 
138
128
  let memoGetSelectionConfig = (~chain) =>
139
129
  Utils.WeakMap.memoize(selection => selection->getSelectionConfig(~chain))
140
130
 
131
+ // Surfaced by HyperSyncClient.getHeight (Rust) when HyperSync rejects the API
132
+ // token. The corrupted-token test feeds the real server error through this
133
+ // check so it can't silently drift away from what getHeightOrThrow guards on.
134
+ let isUnauthorizedError = (message: string) => message->String.includes("401 Unauthorized")
135
+
141
136
  type options = {
142
137
  chain: ChainMap.Chain.t,
143
138
  endpointUrl: string,
144
- allEventSignatures: array<string>,
139
+ allEventParams: array<HyperSyncClient.Decoder.eventParamsInput>,
145
140
  eventRouter: EventRouter.t<Internal.evmEventConfig>,
146
141
  apiToken: option<string>,
147
- clientMaxRetries: int,
148
142
  clientTimeoutMillis: int,
149
143
  lowercaseAddresses: bool,
150
144
  serializationFormat: HyperSyncClient.serializationFormat,
151
145
  enableQueryCaching: bool,
146
+ logLevel: HyperSyncClient.logLevel,
152
147
  }
153
148
 
154
149
  let make = (
155
150
  {
156
151
  chain,
157
152
  endpointUrl,
158
- allEventSignatures,
153
+ allEventParams,
159
154
  eventRouter,
160
155
  apiToken,
161
- clientMaxRetries,
162
156
  clientTimeoutMillis,
163
157
  lowercaseAddresses,
164
158
  serializationFormat,
165
159
  enableQueryCaching,
160
+ logLevel,
166
161
  }: options,
167
162
  ): t => {
168
163
  let name = "HyperSync"
@@ -177,45 +172,31 @@ Set the ENVIO_API_TOKEN environment variable in your .env file.
177
172
  Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
178
173
  }
179
174
 
180
- let client = HyperSyncClient.make(
175
+ let client = switch HyperSyncClient.make(
181
176
  ~url=endpointUrl,
182
177
  ~apiToken,
183
- ~maxNumRetries=clientMaxRetries,
184
178
  ~httpReqTimeoutMillis=clientTimeoutMillis,
179
+ ~eventParams=allEventParams,
185
180
  ~enableChecksumAddresses=!lowercaseAddresses,
186
181
  ~serializationFormat,
187
182
  ~enableQueryCaching,
188
- )
189
-
190
- let hscDecoder: ref<option<HyperSyncClient.Decoder.t>> = ref(None)
191
- let getHscDecoder = () => {
192
- switch hscDecoder.contents {
193
- | Some(decoder) => decoder
194
- | None =>
195
- switch HyperSyncClient.Decoder.fromSignatures(allEventSignatures) {
196
- | exception exn =>
197
- exn->ErrorHandling.mkLogAndRaise(
198
- ~msg="Failed to instantiate a decoder from hypersync client, please double check your ABI",
199
- )
200
- | decoder =>
201
- if lowercaseAddresses {
202
- decoder.disableChecksummedAddresses()
203
- } else {
204
- decoder.enableChecksummedAddresses()
205
- }
206
- decoder
207
- }
208
- }
183
+ ~logLevel,
184
+ ) {
185
+ | client => client
186
+ | exception exn =>
187
+ exn->ErrorHandling.mkLogAndRaise(
188
+ ~msg="Failed to instantiate the hypersync client, please double check your ABI",
189
+ )
209
190
  }
210
191
 
211
192
  exception UndefinedValue
212
193
 
213
194
  let makeEventBatchQueueItem = (
214
- item: HyperSync.logsQueryPageItem,
195
+ item: HyperSyncClient.EventItems.item,
215
196
  ~params: Internal.eventParams,
216
197
  ~eventConfig: Internal.evmEventConfig,
217
198
  ): Internal.item => {
218
- let {block, log, transaction} = item
199
+ let {block, transaction, logIndex, srcAddress} = item
219
200
  let chainId = chain->ChainMap.Chain.toChainId
220
201
 
221
202
  Internal.Event({
@@ -223,7 +204,7 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
223
204
  timestamp: block.timestamp->Belt.Option.getUnsafe,
224
205
  chain,
225
206
  blockNumber: block.number->Belt.Option.getUnsafe,
226
- logIndex: log.logIndex,
207
+ logIndex,
227
208
  event: {
228
209
  contractName: eventConfig.contractName,
229
210
  eventName: eventConfig.name,
@@ -231,8 +212,8 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
231
212
  params,
232
213
  transaction,
233
214
  block: block->(Utils.magic: HyperSyncClient.ResponseTypes.block => Internal.eventBlock),
234
- srcAddress: log.address,
235
- logIndex: log.logIndex,
215
+ srcAddress,
216
+ logIndex,
236
217
  }->Internal.fromGenericEvent,
237
218
  })
238
219
  }
@@ -248,7 +229,6 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
248
229
  ~retry,
249
230
  ~logger,
250
231
  ) => {
251
- let mkLogAndRaise = ErrorHandling.mkLogAndRaise(~logger, ...)
252
232
  let totalTimeRef = Hrtime.makeTimer()
253
233
 
254
234
  let selectionConfig = selection->getSelectionConfig
@@ -272,8 +252,6 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
272
252
  ~toBlock,
273
253
  ~logSelections,
274
254
  ~fieldSelection=selectionConfig.fieldSelection,
275
- ~nonOptionalBlockFieldNames=selectionConfig.nonOptionalBlockFieldNames,
276
- ~nonOptionalTransactionFieldNames=selectionConfig.nonOptionalTransactionFieldNames,
277
255
  ) catch {
278
256
  | HyperSync.GetLogs.Error(error) =>
279
257
  throw(
@@ -301,6 +279,7 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
301
279
  }),
302
280
  ),
303
281
  )
282
+ | Source.RateLimited(_) as exn => throw(exn)
304
283
  | exn =>
305
284
  throw(
306
285
  Source.GetItemsError(
@@ -329,64 +308,6 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
329
308
  //In the query
330
309
  let heighestBlockQueried = pageUnsafe.nextBlock - 1
331
310
 
332
- let lastBlockQueriedPromise = switch pageUnsafe.rollbackGuard {
333
- //In the case a rollbackGuard is returned (this only happens at the head for unconfirmed blocks)
334
- //use these values
335
- | Some({blockNumber, timestamp, hash}) =>
336
- (
337
- {
338
- blockNumber,
339
- blockTimestamp: timestamp,
340
- blockHash: hash,
341
- }: ReorgDetection.blockDataWithTimestamp
342
- )->Promise.resolve
343
- | None =>
344
- //The optional block and timestamp of the last item returned by the query
345
- //(Optional in the case that there are no logs returned in the query)
346
- switch pageUnsafe.items->Belt.Array.get(pageUnsafe.items->Belt.Array.length - 1) {
347
- | Some({block}) if block.number->Belt.Option.getUnsafe == heighestBlockQueried =>
348
- //If the last log item in the current page is equal to the
349
- //heighest block acounted for in the query. Simply return this
350
- //value without making an extra query
351
-
352
- (
353
- {
354
- blockNumber: block.number->Belt.Option.getUnsafe,
355
- blockTimestamp: block.timestamp->Belt.Option.getUnsafe,
356
- blockHash: block.hash->Belt.Option.getUnsafe,
357
- }: ReorgDetection.blockDataWithTimestamp
358
- )->Promise.resolve
359
- //If it does not match it means that there were no matching logs in the last
360
- //block so we should fetch the block data
361
- | Some(_)
362
- | None =>
363
- //If there were no logs at all in the current page query then fetch the
364
- //timestamp of the heighest block accounted for
365
- HyperSync.queryBlockData(
366
- ~client,
367
- ~blockNumber=heighestBlockQueried,
368
- ~sourceName=name,
369
- ~chainId=chain->ChainMap.Chain.toChainId,
370
- ~logger,
371
- )->Promise.thenResolve(res =>
372
- switch res {
373
- | Ok(Some(blockData)) => blockData
374
- | Ok(None) =>
375
- mkLogAndRaise(
376
- Not_found,
377
- ~msg=`Failure, blockData for block ${heighestBlockQueried->Int.toString} unexpectedly returned None`,
378
- )
379
- | Error(e) =>
380
- HyperSync.queryErrorToMsq(e)
381
- ->Obj.magic
382
- ->mkLogAndRaise(
383
- ~msg=`Failed to query blockData for block ${heighestBlockQueried->Int.toString}`,
384
- )
385
- }
386
- )
387
- }
388
- }
389
-
390
311
  let parsingTimeRef = Hrtime.makeTimer()
391
312
 
392
313
  //Parse page items into queue items
@@ -417,47 +338,29 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
417
338
  }
418
339
  }
419
340
 
420
- //Parse page items into queue items
421
- let parsedEvents = switch await getHscDecoder().decodeEvents(pageUnsafe.events) {
422
- | exception exn =>
423
- exn->mkLogAndRaise(
424
- ~msg="Failed to parse events using hypersync client, please double check your ABI.",
425
- )
426
- | parsedEvents => parsedEvents
427
- }
428
-
429
- pageUnsafe.items->Belt.Array.forEachWithIndex((index, item) => {
430
- let {block, log} = item
341
+ pageUnsafe.items->Belt.Array.forEach(item => {
431
342
  let chainId = chain->ChainMap.Chain.toChainId
432
- let topic0 = log.topics->Utils.Array.firstUnsafe
433
343
  let maybeEventConfig =
434
344
  eventRouter->EventRouter.get(
435
345
  ~tag=EventRouter.getEvmEventId(
436
- ~sighash=topic0->EvmTypes.Hex.toString,
437
- ~topicCount=log.topics->Array.length,
346
+ ~sighash=item.topic0->EvmTypes.Hex.toString,
347
+ ~topicCount=item.topicCount,
438
348
  ),
439
349
  ~indexingAddresses,
440
- ~contractAddress=log.address,
441
- ~blockNumber=block.number->Belt.Option.getUnsafe,
350
+ ~contractAddress=item.srcAddress,
351
+ ~blockNumber=item.block.number->Belt.Option.getUnsafe,
442
352
  )
443
- let maybeDecodedEvent = parsedEvents->Array.getUnsafe(index)
444
353
 
445
- switch (maybeEventConfig, maybeDecodedEvent) {
354
+ switch (maybeEventConfig, item.params) {
446
355
  | (Some(eventConfig), Value(decoded)) =>
447
356
  parsedQueueItems
448
- ->Array.push(
449
- makeEventBatchQueueItem(
450
- item,
451
- ~params=decoded->eventConfig.convertHyperSyncEventArgs,
452
- ~eventConfig,
453
- ),
454
- )
357
+ ->Array.push(makeEventBatchQueueItem(item, ~params=decoded, ~eventConfig))
455
358
  ->ignore
456
359
  | (Some(eventConfig), Null | Undefined) =>
457
360
  handleDecodeFailure(
458
361
  ~eventConfig,
459
- ~logIndex=log.logIndex,
460
- ~blockNumber=block.number->Belt.Option.getUnsafe,
362
+ ~logIndex=item.logIndex,
363
+ ~blockNumber=item.block.number->Belt.Option.getUnsafe,
461
364
  ~chainId,
462
365
  ~exn=UndefinedValue,
463
366
  )
@@ -467,14 +370,43 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
467
370
 
468
371
  let parsingTimeElapsed = parsingTimeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
469
372
 
470
- let rangeLastBlock = await lastBlockQueriedPromise
373
+ // Collect (blockNumber, blockHash) pairs we already have from the response —
374
+ // one per item's block plus, when present, the rollbackGuard's head block
375
+ // and the parent of the range's first block. Duplicates are allowed; reorg
376
+ // detection notices same-block-number-different-hash collisions itself.
377
+ let blockHashes = []
378
+ pageUnsafe.items->Belt.Array.forEach(({block}) => {
379
+ switch (block.number, block.hash) {
380
+ | (Some(blockNumber), Some(blockHash)) =>
381
+ blockHashes->Array.push({ReorgDetection.blockNumber, blockHash})->ignore
382
+ | _ => ()
383
+ }
384
+ })
385
+ switch pageUnsafe.rollbackGuard {
386
+ | None => ()
387
+ | Some({blockNumber, hash, firstBlockNumber, firstParentHash}) => {
388
+ blockHashes->Array.push({ReorgDetection.blockNumber, blockHash: hash})->ignore
389
+ blockHashes
390
+ ->Array.push({
391
+ ReorgDetection.blockNumber: firstBlockNumber - 1,
392
+ blockHash: firstParentHash,
393
+ })
394
+ ->ignore
395
+ }
396
+ }
471
397
 
472
- let reorgGuard: ReorgDetection.reorgGuard = {
473
- rangeLastBlock: rangeLastBlock->ReorgDetection.generalizeBlockDataWithTimestamp,
474
- prevRangeLastBlock: pageUnsafe.rollbackGuard->Option.map(v => {
475
- ReorgDetection.blockHash: v.firstParentHash,
476
- blockNumber: v.firstBlockNumber - 1,
477
- }),
398
+ // Best-effort timestamp for the queried-range head: prefer the rollbackGuard
399
+ // (set at the head for unconfirmed blocks), otherwise the last item if it
400
+ // happens to be in the range's last block. 0 is a tolerated placeholder
401
+ // when neither is available (FetchState already uses 0 in several spots).
402
+ let latestFetchedBlockTimestamp = switch pageUnsafe.rollbackGuard {
403
+ | Some({timestamp}) => timestamp
404
+ | None =>
405
+ switch pageUnsafe.items->Belt.Array.get(pageUnsafe.items->Belt.Array.length - 1) {
406
+ | Some({block}) if block.number->Belt.Option.getUnsafe == heighestBlockQueried =>
407
+ block.timestamp->Belt.Option.getUnsafe
408
+ | _ => 0
409
+ }
478
410
  }
479
411
 
480
412
  let totalTimeElapsed = totalTimeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
@@ -486,12 +418,12 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
486
418
  }
487
419
 
488
420
  {
489
- latestFetchedBlockTimestamp: rangeLastBlock.blockTimestamp,
421
+ latestFetchedBlockTimestamp,
490
422
  parsedQueueItems,
491
- latestFetchedBlockNumber: rangeLastBlock.blockNumber,
423
+ latestFetchedBlockNumber: heighestBlockQueried,
492
424
  stats,
493
425
  knownHeight,
494
- reorgGuard,
426
+ blockHashes,
495
427
  fromBlockQueried: fromBlock,
496
428
  }
497
429
  }
@@ -505,10 +437,6 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
505
437
  ~logger,
506
438
  )->Promise.thenResolve(HyperSync.mapExn)
507
439
 
508
- let jsonApiClient = Rest.client(endpointUrl)
509
-
510
- let malformedTokenMessage = `Your token is malformed. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens.`
511
-
512
440
  {
513
441
  name,
514
442
  sourceFor: Sync,
@@ -518,18 +446,18 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
518
446
  getBlockHashes,
519
447
  getHeightOrThrow: async () => {
520
448
  let timerRef = Hrtime.makeTimer()
521
- let result = switch await HyperSyncJsonApi.heightRoute->Rest.fetch(
522
- apiToken,
523
- ~client=jsonApiClient,
524
- ) {
525
- | Value(height) => height
526
- | ErrorMessage(m) if m === malformedTokenMessage =>
527
- Logging.error(`Your ENVIO_API_TOKEN is malformed. The indexer will not be able to fetch events. Update the token and restart the indexer using 'pnpm envio start'. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens`)
528
- // Don't want to retry if the token is malformed
529
- // So just block forever
530
- let _ = await Promise.make((_, _) => ())
531
- 0
532
- | ErrorMessage(m) => JsError.throwWithMessage(m)
449
+ let result = try {
450
+ await client.getHeight()
451
+ } catch {
452
+ | JsExn(e) =>
453
+ switch e->JsExn.message {
454
+ | Some(message) if message->isUnauthorizedError =>
455
+ Logging.error(`Your ENVIO_API_TOKEN was rejected by HyperSync (401 Unauthorized). The indexer will not be able to fetch events. Update the token and try again using 'envio start' or 'envio dev'. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens`)
456
+ // Retrying an unauthorized request can never succeed, so block forever
457
+ let _ = await Promise.make((_, _) => ())
458
+ 0
459
+ | _ => throw(JsExn(e))
460
+ }
533
461
  }
534
462
  let seconds = timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat
535
463
  Prometheus.SourceRequestCount.increment(