envio 3.13.0 → 3.14.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 (69) hide show
  1. package/bin.mjs +10 -1
  2. package/index.d.ts +11 -0
  3. package/package.json +8 -20
  4. package/rescript.json +1 -4
  5. package/src/Config.res +69 -100
  6. package/src/Config.res.mjs +50 -63
  7. package/src/Core.res +46 -6
  8. package/src/Core.res.mjs +41 -4
  9. package/src/EventConfigBuilder.res +4 -10
  10. package/src/EventConfigBuilder.res.mjs +1 -3
  11. package/src/ExitOnCaughtUp.res +5 -1
  12. package/src/ExitOnCaughtUp.res.mjs +8 -3
  13. package/src/HandlerLoader.res +74 -32
  14. package/src/HandlerLoader.res.mjs +69 -23
  15. package/src/HandlerTypeCheck.mjs +14 -0
  16. package/src/HandlerTypeCheckWorker.mjs +68 -0
  17. package/src/Internal.res +1 -1
  18. package/src/Main.res +17 -12
  19. package/src/Main.res.mjs +9 -3
  20. package/src/NodeVersion.mjs +13 -0
  21. package/src/Persistence.res +79 -38
  22. package/src/Persistence.res.mjs +41 -10
  23. package/src/PgStorage.res +62 -34
  24. package/src/PgStorage.res.mjs +65 -31
  25. package/src/ResumePlan.res +172 -0
  26. package/src/ResumePlan.res.mjs +122 -0
  27. package/src/Supervisor.res +8 -8
  28. package/src/Supervisor.res.mjs +6 -1
  29. package/src/TestIndexer.res +14 -4
  30. package/src/TestIndexer.res.mjs +3 -2
  31. package/src/TsModuleHooks.mjs +121 -0
  32. package/src/Utils.res +0 -8
  33. package/src/Worker.res +8 -0
  34. package/src/Worker.res.mjs +11 -0
  35. package/src/bindings/NodeJs.res +8 -7
  36. package/src/bindings/NodeJs.res.mjs +0 -3
  37. package/src/bindings/Pino.res +2 -2
  38. package/src/db/InternalTable.res +52 -2
  39. package/src/db/InternalTable.res.mjs +32 -3
  40. package/src/sources/FuelHyperSync.res +2 -0
  41. package/src/sources/FuelHyperSync.res.mjs +1 -0
  42. package/src/sources/FuelHyperSync.resi +1 -0
  43. package/src/sources/FuelHyperSyncClient.res +25 -8
  44. package/src/sources/FuelHyperSyncClient.res.mjs +8 -2
  45. package/src/sources/FuelHyperSyncSource.res +24 -22
  46. package/src/sources/FuelHyperSyncSource.res.mjs +18 -13
  47. package/src/tui/InitApi.res +85 -0
  48. package/src/tui/{components/CustomHooks.res.mjs → InitApi.res.mjs} +11 -64
  49. package/src/tui/Tui.res +142 -249
  50. package/src/tui/Tui.res.mjs +123 -332
  51. package/src/Js.shim.ts +0 -11
  52. package/src/bindings/DateFns.res +0 -74
  53. package/src/bindings/DateFns.res.mjs +0 -22
  54. package/src/sources/FuelSDK.res +0 -38
  55. package/src/sources/FuelSDK.res.mjs +0 -27
  56. package/src/sources/vendored-fuel-abi-coder.js +0 -1792
  57. package/src/tui/bindings/Ink.res +0 -369
  58. package/src/tui/bindings/Ink.res.mjs +0 -66
  59. package/src/tui/bindings/Style.res +0 -123
  60. package/src/tui/bindings/Style.res.mjs +0 -2
  61. package/src/tui/components/BufferedProgressBar.res +0 -40
  62. package/src/tui/components/BufferedProgressBar.res.mjs +0 -57
  63. package/src/tui/components/CustomHooks.res +0 -122
  64. package/src/tui/components/Messages.res +0 -40
  65. package/src/tui/components/Messages.res.mjs +0 -71
  66. package/src/tui/components/SyncETA.res +0 -179
  67. package/src/tui/components/SyncETA.res.mjs +0 -249
  68. package/src/tui/components/TuiData.res +0 -98
  69. package/src/tui/components/TuiData.res.mjs +0 -73
@@ -159,12 +159,14 @@ WHERE "${table.tableName}"."chain_id" = dead.chain_id
159
159
  ->Utils.Promise.ignoreValue
160
160
  }
161
161
 
162
- let makeGetRowsQuery = (~pgSchema) =>
162
+ let makeGetRowsQuery = (~pgSchema, ~onlyConfig=false) =>
163
163
  `SELECT "chain_id" as "chainId",
164
164
  "address" as "address",
165
165
  "contract_id" as "contractId",
166
166
  "registration_block" as "registrationBlock"
167
- FROM "${pgSchema}"."${table.tableName}";`
167
+ FROM "${pgSchema}"."${table.tableName}"${onlyConfig
168
+ ? ` WHERE "registration_block" = ${AddressRows.configRegistrationBlock->Int.toString}`
169
+ : ""};`
168
170
  }
169
171
 
170
172
  module Chains = {
@@ -391,6 +393,54 @@ WHERE "${(#id: field :> string)}" = $2
391
393
  checkpointId: string,
392
394
  }
393
395
 
396
+ let readStoredChains = async (sql, ~pgSchema): array<ResumePlan.storedChain> => {
397
+ let (rows, configAddressRows) = await Promise.all2((
398
+ sql
399
+ ->Postgres.unsafe(
400
+ `SELECT "${(#id: field :> string)}" as "id",
401
+ "${(#ecosystem: field :> string)}" as "ecosystem",
402
+ "${(#start_block: field :> string)}" as "startBlock",
403
+ "${(#end_block: field :> string)}" as "endBlock",
404
+ "${(#max_reorg_depth: field :> string)}" as "maxReorgDepth"
405
+ FROM "${pgSchema}"."${table.tableName}";`,
406
+ )
407
+ ->(
408
+ Utils.magic: promise<array<unknown>> => promise<
409
+ array<{
410
+ "id": ChainId.t,
411
+ "ecosystem": string,
412
+ "startBlock": int,
413
+ "endBlock": Null.t<int>,
414
+ "maxReorgDepth": int,
415
+ }>,
416
+ >
417
+ ),
418
+ sql
419
+ ->Postgres.unsafe(EnvioAddresses.makeGetRowsQuery(~pgSchema, ~onlyConfig=true))
420
+ ->(Utils.magic: promise<array<unknown>> => promise<array<AddressRows.row>>),
421
+ ))
422
+ let configAddressesByChain = Dict.make()
423
+ configAddressRows->Array.forEach(addressRow =>
424
+ configAddressesByChain->Utils.Dict.push(
425
+ addressRow.chainId->ChainId.normalizeOrThrow->ChainId.toString,
426
+ addressRow,
427
+ )
428
+ )
429
+ rows->Array.map((row): ResumePlan.storedChain => {
430
+ let id = row["id"]->ChainId.normalizeOrThrow
431
+ {
432
+ id,
433
+ ecosystem: row["ecosystem"],
434
+ startBlock: row["startBlock"],
435
+ endBlock: row["endBlock"]->Null.toOption,
436
+ maxReorgDepth: row["maxReorgDepth"],
437
+ configAddresses: configAddressesByChain
438
+ ->Utils.Dict.dangerouslyGetNonOption(id->ChainId.toString)
439
+ ->Option.getOr([]),
440
+ }
441
+ })
442
+ }
443
+
394
444
  let makeGetInitialStateQuery = (~pgSchema) => {
395
445
  `SELECT "${(#id: field :> string)}" as "id",
396
446
  "${(#start_block: field :> string)}" as "startBlock",
@@ -133,12 +133,15 @@ function $$delete(sql, pgSchema, keys, chainIdModeOpt) {
133
133
  ], {prepare: true});
134
134
  }
135
135
 
136
- function makeGetRowsQuery(pgSchema) {
136
+ function makeGetRowsQuery(pgSchema, onlyConfigOpt) {
137
+ let onlyConfig = onlyConfigOpt !== undefined ? onlyConfigOpt : false;
137
138
  return `SELECT "chain_id" as "chainId",
138
139
  "address" as "address",
139
140
  "contract_id" as "contractId",
140
141
  "registration_block" as "registrationBlock"
141
- FROM "` + pgSchema + `"."` + table$1.tableName + `";`;
142
+ FROM "` + pgSchema + `"."` + table$1.tableName + `"` + (
143
+ onlyConfig ? ` WHERE "registration_block" = ` + AddressRows.configRegistrationBlock.toString() : ""
144
+ ) + `;`;
142
145
  }
143
146
 
144
147
  let EnvioAddresses = {
@@ -264,6 +267,31 @@ WHERE "` + "id" + `" = $2
264
267
  AND "` + "ready_at" + `" IS NULL;`;
265
268
  }
266
269
 
270
+ async function readStoredChains(sql, pgSchema) {
271
+ let match = await Promise.all([
272
+ sql.unsafe(`SELECT "` + "id" + `" as "id",
273
+ "` + "ecosystem" + `" as "ecosystem",
274
+ "` + "start_block" + `" as "startBlock",
275
+ "` + "end_block" + `" as "endBlock",
276
+ "` + "max_reorg_depth" + `" as "maxReorgDepth"
277
+ FROM "` + pgSchema + `"."` + table$2.tableName + `";`),
278
+ sql.unsafe(makeGetRowsQuery(pgSchema, true))
279
+ ]);
280
+ let configAddressesByChain = {};
281
+ match[1].forEach(addressRow => Utils.Dict.push(configAddressesByChain, ChainId.toString(ChainId.normalizeOrThrow(addressRow.chainId)), addressRow));
282
+ return match[0].map(row => {
283
+ let id = ChainId.normalizeOrThrow(row.id);
284
+ return {
285
+ id: id,
286
+ ecosystem: row.ecosystem,
287
+ startBlock: row.startBlock,
288
+ endBlock: Primitive_option.fromNull(row.endBlock),
289
+ maxReorgDepth: row.maxReorgDepth,
290
+ configAddresses: Stdlib_Option.getOr(configAddressesByChain[ChainId.toString(id)], [])
291
+ };
292
+ });
293
+ }
294
+
267
295
  function makeGetInitialStateQuery(pgSchema) {
268
296
  return `SELECT "` + "id" + `" as "id",
269
297
  "` + "start_block" + `" as "startBlock",
@@ -282,7 +310,7 @@ FROM "` + pgSchema + `"."` + table$2.tableName + `";`;
282
310
  async function getInitialState(sql, pgSchema) {
283
311
  let match = await Promise.all([
284
312
  sql.unsafe(makeGetInitialStateQuery(pgSchema)),
285
- sql.unsafe(makeGetRowsQuery(pgSchema))
313
+ sql.unsafe(makeGetRowsQuery(pgSchema, undefined))
286
314
  ]);
287
315
  let addressRowsByChainId = AddressRows.group(match[1]);
288
316
  return match[0].map(rawInitialState => {
@@ -384,6 +412,7 @@ let Chains = {
384
412
  metaFields: metaFields,
385
413
  makeMetaFieldsUpdateQuery: makeMetaFieldsUpdateQuery,
386
414
  makeSetReadyAtQuery: makeSetReadyAtQuery,
415
+ readStoredChains: readStoredChains,
387
416
  makeGetInitialStateQuery: makeGetInitialStateQuery,
388
417
  getInitialState: getInitialState,
389
418
  blockTimeToDb: blockTimeToDb,
@@ -1,5 +1,6 @@
1
1
  type logsQueryPage = {
2
2
  items: array<FuelHyperSyncClient.EventItems.item>,
3
+ rejectedLogData: array<FuelHyperSyncClient.EventItems.rejectedLogData>,
3
4
  // Blocks referenced by `items`, one per height.
4
5
  nextBlock: int,
5
6
  archiveHeight: int,
@@ -72,6 +73,7 @@ module GetLogs = {
72
73
  }
73
74
  {
74
75
  items: res.items,
76
+ rejectedLogData: res.rejectedLogData,
75
77
  nextBlock: res.nextBlock,
76
78
  archiveHeight: res.archiveHeight->Option.getOr(0), // TODO: FIXME: Shouldn't have a default here
77
79
  blockStore,
@@ -64,6 +64,7 @@ async function query(client, fromBlock, toBlock, registrationIndexes, addressSet
64
64
  }
65
65
  return {
66
66
  items: res.items,
67
+ rejectedLogData: res.rejectedLogData,
67
68
  nextBlock: res.nextBlock,
68
69
  archiveHeight: Stdlib_Option.getOr(res.archiveHeight, 0),
69
70
  blockStore: match[1]
@@ -1,5 +1,6 @@
1
1
  type logsQueryPage = {
2
2
  items: array<FuelHyperSyncClient.EventItems.item>,
3
+ rejectedLogData: array<FuelHyperSyncClient.EventItems.rejectedLogData>,
3
4
  nextBlock: int,
4
5
  archiveHeight: int,
5
6
  // Page store owning this page's raw blocks (built on the Rust side); its ids
@@ -27,6 +27,9 @@ module Registration = {
27
27
  kind: kind,
28
28
  // The LogData `rb` value as a decimal string; absent for other kinds.
29
29
  logId?: string,
30
+ // The contract's Fuel ABI, which LogData receipts are decoded against in
31
+ // Rust; absent for other kinds.
32
+ abi?: JSON.t,
30
33
  }
31
34
 
32
35
  let fromOnEventRegistrations = (
@@ -35,12 +38,12 @@ module Registration = {
35
38
  onEventRegistrations->Array.map(reg => {
36
39
  let eventConfig =
37
40
  reg.eventConfig->(Utils.magic: Internal.eventConfig => Internal.fuelEventConfig)
38
- let (kind, logId) = switch eventConfig.kind {
39
- | LogData({logId}) => (LogData, Some(logId))
40
- | Mint => (Mint, None)
41
- | Burn => (Burn, None)
42
- | Transfer => (Transfer, None)
43
- | Call => (Call, None)
41
+ let (kind, logId, abi) = switch eventConfig.kind {
42
+ | LogData({logId, abi}) => (LogData, Some(logId), Some(abi))
43
+ | Mint => (Mint, None, None)
44
+ | Burn => (Burn, None, None)
45
+ | Transfer => (Transfer, None, None)
46
+ | Call => (Call, None, None)
44
47
  }
45
48
  {
46
49
  index: reg.index,
@@ -50,6 +53,7 @@ module Registration = {
50
53
  startBlock: reg.startBlock,
51
54
  kind,
52
55
  ?logId,
56
+ ?abi,
53
57
  }
54
58
  })
55
59
  }
@@ -70,7 +74,8 @@ module EventItems = {
70
74
  }
71
75
 
72
76
  // One routed receipt with its kind-specific columns flattened: LogData
73
- // carries `data` (decoded here in JS), Mint/Burn carry `val`/`subId`,
77
+ // carries `params` decoded against the ABI (a receipt its logged type
78
+ // rejects is dropped in Rust), Mint/Burn carry `val`/`subId`,
74
79
  // Transfer/TransferOut/Call carry `amount`/`assetId`/`to` (TransferOut's
75
80
  // wallet recipient normalised into `to`).
76
81
  type item = {
@@ -79,7 +84,7 @@ module EventItems = {
79
84
  txId: string,
80
85
  blockHeight: int,
81
86
  srcAddress: Address.t,
82
- data?: string,
87
+ params?: Internal.eventParams,
83
88
  subId?: string,
84
89
  val?: bigint,
85
90
  amount?: bigint,
@@ -87,10 +92,22 @@ module EventItems = {
87
92
  to?: string,
88
93
  }
89
94
 
95
+ // The page's first LogData receipt a contract-bound registration's ABI
96
+ // rejected, with how many it rejected. The receipts themselves are dropped.
97
+ type rejectedLogData = {
98
+ onEventRegistrationIndex: int,
99
+ blockHeight: int,
100
+ receiptIndex: int,
101
+ txId: string,
102
+ dataLength: int,
103
+ count: int,
104
+ }
105
+
90
106
  type response = {
91
107
  archiveHeight: option<int>,
92
108
  nextBlock: int,
93
109
  items: array<item>,
110
+ rejectedLogData: array<rejectedLogData>,
94
111
  }
95
112
  }
96
113
 
@@ -13,24 +13,28 @@ function fromOnEventRegistrations(onEventRegistrations) {
13
13
  case "Mint" :
14
14
  match$1 = [
15
15
  "Mint",
16
+ undefined,
16
17
  undefined
17
18
  ];
18
19
  break;
19
20
  case "Burn" :
20
21
  match$1 = [
21
22
  "Burn",
23
+ undefined,
22
24
  undefined
23
25
  ];
24
26
  break;
25
27
  case "Transfer" :
26
28
  match$1 = [
27
29
  "Transfer",
30
+ undefined,
28
31
  undefined
29
32
  ];
30
33
  break;
31
34
  case "Call" :
32
35
  match$1 = [
33
36
  "Call",
37
+ undefined,
34
38
  undefined
35
39
  ];
36
40
  break;
@@ -38,7 +42,8 @@ function fromOnEventRegistrations(onEventRegistrations) {
38
42
  } else {
39
43
  match$1 = [
40
44
  "LogData",
41
- match.logId
45
+ match.logId,
46
+ match.abi
42
47
  ];
43
48
  }
44
49
  return {
@@ -48,7 +53,8 @@ function fromOnEventRegistrations(onEventRegistrations) {
48
53
  isWildcard: reg.isWildcard,
49
54
  startBlock: reg.startBlock,
50
55
  kind: match$1[0],
51
- logId: match$1[1]
56
+ logId: match$1[1],
57
+ abi: match$1[2]
52
58
  };
53
59
  });
54
60
  }
@@ -16,6 +16,9 @@ let make = ({chainId, endpointUrl, apiToken, onEventRegistrations, addressStore}
16
16
  // Per source, so one rejected token is reported once rather than on every
17
17
  // height retry for the life of the process.
18
18
  let unauthorizedWarned = ref(false)
19
+ // Registration indexes already warned about undecodable LogData — a stale
20
+ // ABI rejects every receipt, so one line per event is enough.
21
+ let rejectedLogDataWarned = Utils.Set.make()
19
22
 
20
23
  let apiToken = apiToken->HyperSync.requireApiToken
21
24
 
@@ -106,6 +109,24 @@ let make = ({chainId, endpointUrl, apiToken, onEventRegistrations, addressStore}
106
109
 
107
110
  let parsingTimeRef = Performance.now()
108
111
 
112
+ pageUnsafe.rejectedLogData->Array.forEach(rejected => {
113
+ if !(rejectedLogDataWarned->Utils.Set.has(rejected.onEventRegistrationIndex)) {
114
+ rejectedLogDataWarned->Utils.Set.add(rejected.onEventRegistrationIndex)->ignore
115
+ let eventConfig = (
116
+ onEventRegistrations->Array.getUnsafe(rejected.onEventRegistrationIndex)
117
+ ).eventConfig
118
+ logger->Logging.childWarn({
119
+ "msg": `Skipped ${eventConfig.contractName}.${eventConfig.name} LogData receipts whose data doesn't decode against the contract ABI. Check that the ABI matches the deployed contract.`,
120
+ "chainId": chainId,
121
+ "blockNumber": rejected.blockHeight,
122
+ "logIndex": rejected.receiptIndex,
123
+ "txId": rejected.txId,
124
+ "dataLength": rejected.dataLength,
125
+ "skippedInPage": rejected.count,
126
+ })
127
+ }
128
+ })
129
+
109
130
  let parsedQueueItems = pageUnsafe.items->Array.map(item => {
110
131
  // Routing happened in Rust; the item references its registration by
111
132
  // chain-scoped index.
@@ -116,24 +137,8 @@ let make = ({chainId, endpointUrl, apiToken, onEventRegistrations, addressStore}
116
137
  )
117
138
 
118
139
  let params = switch eventConfig.kind {
119
- | LogData({decode}) =>
120
- // Kind-required columns are validated present in Rust before the item
121
- // crosses the boundary.
122
- let data = item.data->Option.getOr("")
123
- try decode(data) catch {
124
- | exn => {
125
- let params = {
126
- "chainId": chainId,
127
- "blockNumber": item.blockHeight,
128
- "logIndex": item.receiptIndex,
129
- }
130
- let logger = Logging.createChildFrom(~logger, ~params)
131
- exn->ErrorHandling.mkLogAndRaise(
132
- ~msg="Failed to decode Fuel LogData receipt, please double check your ABI.",
133
- ~logger,
134
- )
135
- }
136
- }
140
+ // Rust only routes a LogData receipt once its data decoded.
141
+ | LogData(_) => item.params->Option.getUnsafe
137
142
  | Mint | Burn =>
138
143
  (
139
144
  {
@@ -213,10 +218,7 @@ let make = ({chainId, endpointUrl, apiToken, onEventRegistrations, addressStore}
213
218
  let timerRef = Performance.now()
214
219
  let height = try await client->FuelHyperSyncClient.getHeight catch {
215
220
  | exn =>
216
- exn->HyperSync.rethrowLoggingUnauthorized(
217
- ~warned=unauthorizedWarned,
218
- ~product="HyperFuel",
219
- )
221
+ exn->HyperSync.rethrowLoggingUnauthorized(~warned=unauthorizedWarned, ~product="HyperFuel")
220
222
  }
221
223
  let seconds = timerRef->Performance.secondsSince
222
224
  {height, requestStats: [{method: "getHeight", seconds}]}
@@ -18,6 +18,7 @@ function make(param) {
18
18
  let unauthorizedWarned = {
19
19
  contents: false
20
20
  };
21
+ let rejectedLogDataWarned = new Set();
21
22
  let apiToken = HyperSync.requireApiToken(param.apiToken);
22
23
  let client;
23
24
  try {
@@ -82,6 +83,22 @@ function make(param) {
82
83
  let knownHeight$1 = pageUnsafe.archiveHeight;
83
84
  let heighestBlockQueried = pageUnsafe.nextBlock - 1 | 0;
84
85
  let parsingTimeRef = Performance.now();
86
+ pageUnsafe.rejectedLogData.forEach(rejected => {
87
+ if (rejectedLogDataWarned.has(rejected.onEventRegistrationIndex)) {
88
+ return;
89
+ }
90
+ rejectedLogDataWarned.add(rejected.onEventRegistrationIndex);
91
+ let eventConfig = onEventRegistrations[rejected.onEventRegistrationIndex].eventConfig;
92
+ Logging.childWarn(logger, {
93
+ msg: `Skipped ` + eventConfig.contractName + `.` + eventConfig.name + ` LogData receipts whose data doesn't decode against the contract ABI. Check that the ABI matches the deployed contract.`,
94
+ chainId: chainId,
95
+ blockNumber: rejected.blockHeight,
96
+ logIndex: rejected.receiptIndex,
97
+ txId: rejected.txId,
98
+ dataLength: rejected.dataLength,
99
+ skippedInPage: rejected.count
100
+ });
101
+ });
85
102
  let parsedQueueItems = pageUnsafe.items.map(item => {
86
103
  let onEventRegistration = onEventRegistrations[item.onEventRegistrationIndex];
87
104
  let eventConfig = onEventRegistration.eventConfig;
@@ -100,19 +117,7 @@ function make(param) {
100
117
  break;
101
118
  }
102
119
  } else {
103
- let data = Stdlib_Option.getOr(item.data, "");
104
- try {
105
- params = match.decode(data);
106
- } catch (raw_exn) {
107
- let exn = Primitive_exceptions.internalToException(raw_exn);
108
- let params$1 = {
109
- chainId: chainId,
110
- blockNumber: item.blockHeight,
111
- logIndex: item.receiptIndex
112
- };
113
- let logger$1 = Logging.createChildFrom(logger, params$1);
114
- params = ErrorHandling.mkLogAndRaise(logger$1, "Failed to decode Fuel LogData receipt, please double check your ABI.", exn);
115
- }
120
+ params = item.params;
116
121
  }
117
122
  switch (exit) {
118
123
  case 1 :
@@ -0,0 +1,85 @@
1
+ type ecosystem = | @as("evm") Evm | @as("fuel") Fuel | @as("svm") Svm
2
+ type body = {
3
+ envioVersion: string,
4
+ envioApiToken: option<string>,
5
+ ecosystem: ecosystem,
6
+ hyperSyncNetworks: array<ChainId.t>,
7
+ rpcNetworks: array<ChainId.t>,
8
+ }
9
+
10
+ let bodySchema = S.object(s => {
11
+ envioVersion: s.field("envioVersion", S.string),
12
+ envioApiToken: s.field("envioApiToken", S.option(S.string)),
13
+ ecosystem: s.field("ecosystem", S.enum([Evm, Fuel, Svm])),
14
+ hyperSyncNetworks: s.field("hyperSyncNetworks", S.array(ChainId.schema)),
15
+ rpcNetworks: s.field("rpcNetworks", S.array(ChainId.schema)),
16
+ })
17
+
18
+ let makeBody = (~envioVersion, ~envioApiToken, ~config: Config.t) => {
19
+ let hyperSyncNetworks = []
20
+ let rpcNetworks = []
21
+ config.chainMap
22
+ ->ChainMap.values
23
+ ->Array.forEach(({sourceConfig, id}) => {
24
+ let usesHyperSync = switch sourceConfig {
25
+ | Config.EvmSourceConfig({hypersync: Some(_)}) => true
26
+ | Config.EvmSourceConfig({hypersync: None}) => false
27
+ | Config.FuelSourceConfig(_) => true // Fuel always uses HyperFuel
28
+ | Config.SvmSourceConfig(_) => false
29
+ | Config.SimulateSourceConfig(_) => false
30
+ | Config.CustomSources(sources) => sources->Array.some(s => s.poweredByHyperSync)
31
+ }
32
+ switch usesHyperSync {
33
+ | true => hyperSyncNetworks
34
+ | false => rpcNetworks
35
+ }
36
+ ->Array.push(id)
37
+ ->ignore
38
+ })
39
+
40
+ {
41
+ envioVersion,
42
+ envioApiToken,
43
+ ecosystem: (config.ecosystem.name :> ecosystem),
44
+ hyperSyncNetworks,
45
+ rpcNetworks,
46
+ }
47
+ }
48
+
49
+ type messageColor =
50
+ | @as("primary") Primary
51
+ | @as("secondary") Secondary
52
+ | @as("info") Info
53
+ | @as("danger") Danger
54
+ | @as("success") Success
55
+ | @as("white") White
56
+ | @as("gray") Gray
57
+
58
+ type message = {
59
+ color: messageColor,
60
+ content: string,
61
+ }
62
+
63
+ let messageSchema = S.object(s => {
64
+ color: s.field("color", S.enum([Primary, Secondary, Info, Danger, Success, White, Gray])),
65
+ content: s.field("content", S.string),
66
+ })
67
+
68
+ let client = Rest.client(Env.envioAppUrl ++ "/api")
69
+
70
+ let route = Rest.route(() => {
71
+ method: Post,
72
+ path: "/hyperindex/init",
73
+ input: s => s.body(bodySchema),
74
+ responses: [s => s.field("messages", S.array(messageSchema))],
75
+ })
76
+
77
+ let getMessages = async (~config) => {
78
+ let envioVersion = Utils.EnvioPackage.value.version
79
+ let body = makeBody(~envioVersion, ~envioApiToken=Env.envioApiToken, ~config)
80
+
81
+ switch await route->Rest.fetch(body, ~client) {
82
+ | exception exn => Error(exn)
83
+ | messages => Ok(messages)
84
+ }
85
+ }
@@ -1,12 +1,10 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
- import * as Env from "../../Env.res.mjs";
4
- import * as Rest from "../../vendored/Rest.res.mjs";
5
- import * as Utils from "../../Utils.res.mjs";
6
- import * as React from "react";
7
- import * as ChainId from "../../ChainId.res.mjs";
8
- import * as Logging from "../../Logging.res.mjs";
9
- import * as ChainMap from "../../ChainMap.res.mjs";
3
+ import * as Env from "../Env.res.mjs";
4
+ import * as Rest from "../vendored/Rest.res.mjs";
5
+ import * as Utils from "../Utils.res.mjs";
6
+ import * as ChainId from "../ChainId.res.mjs";
7
+ import * as ChainMap from "../ChainMap.res.mjs";
10
8
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
11
9
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
12
10
 
@@ -56,25 +54,6 @@ function makeBody(envioVersion, envioApiToken, config) {
56
54
  };
57
55
  }
58
56
 
59
- function toTheme(color) {
60
- switch (color) {
61
- case "primary" :
62
- return "#9860E5";
63
- case "secondary" :
64
- return "#FFBB2F";
65
- case "info" :
66
- return "#6CBFEE";
67
- case "danger" :
68
- return "#FF8269";
69
- case "success" :
70
- return "#3B8C3D";
71
- case "white" :
72
- return "white";
73
- case "gray" :
74
- return "gray";
75
- }
76
- }
77
-
78
57
  let messageSchema = S$RescriptSchema.object(s => ({
79
58
  color: s.f("color", S$RescriptSchema.$$enum([
80
59
  "primary",
@@ -118,44 +97,12 @@ async function getMessages(config) {
118
97
  };
119
98
  }
120
99
 
121
- let InitApi = {
122
- bodySchema: bodySchema,
123
- makeBody: makeBody,
124
- toTheme: toTheme,
125
- messageSchema: messageSchema,
126
- client: client,
127
- route: route,
128
- getMessages: getMessages
129
- };
130
-
131
- function useMessages(config) {
132
- let match = React.useState(() => "Loading");
133
- let setRequest = match[1];
134
- React.useEffect(() => {
135
- getMessages(config).then(res => {
136
- if (res.TAG === "Ok") {
137
- let data = res._0;
138
- return setRequest(param => ({
139
- TAG: "Data",
140
- _0: data
141
- }));
142
- }
143
- let e = res._0;
144
- Logging.error({
145
- msg: "Failed to load messages from envio server",
146
- err: Utils.prettifyExn(e)
147
- });
148
- setRequest(param => ({
149
- TAG: "Err",
150
- _0: e
151
- }));
152
- });
153
- }, []);
154
- return match[0];
155
- }
156
-
157
100
  export {
158
- InitApi,
159
- useMessages,
101
+ bodySchema,
102
+ makeBody,
103
+ messageSchema,
104
+ client,
105
+ route,
106
+ getMessages,
160
107
  }
161
108
  /* bodySchema Not a pure module */