envio 3.0.0-alpha.0 → 3.0.0-alpha.10

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 (136) hide show
  1. package/README.md +2 -2
  2. package/evm.schema.json +53 -57
  3. package/fuel.schema.json +35 -31
  4. package/index.d.ts +446 -1
  5. package/index.js +4 -0
  6. package/package.json +23 -11
  7. package/rescript.json +4 -1
  8. package/src/Batch.res.mjs +1 -1
  9. package/src/Benchmark.res +394 -0
  10. package/src/Benchmark.res.mjs +398 -0
  11. package/src/ChainFetcher.res +526 -0
  12. package/src/ChainFetcher.res.mjs +343 -0
  13. package/src/ChainManager.res +182 -0
  14. package/src/ChainManager.res.mjs +150 -0
  15. package/src/Config.res +367 -27
  16. package/src/Config.res.mjs +338 -28
  17. package/src/{Indexer.res → Ctx.res} +1 -1
  18. package/src/Ecosystem.res +25 -0
  19. package/src/Ecosystem.res.mjs +29 -0
  20. package/src/Env.res +252 -0
  21. package/src/Env.res.mjs +271 -0
  22. package/src/Envio.gen.ts +9 -1
  23. package/src/Envio.res +12 -9
  24. package/src/EventProcessing.res +476 -0
  25. package/src/EventProcessing.res.mjs +341 -0
  26. package/src/EventRegister.res +4 -15
  27. package/src/EventRegister.res.mjs +3 -9
  28. package/src/EventRegister.resi +2 -8
  29. package/src/FetchState.res +54 -29
  30. package/src/FetchState.res.mjs +62 -35
  31. package/src/GlobalState.res +1163 -0
  32. package/src/GlobalState.res.mjs +1196 -0
  33. package/src/GlobalStateManager.res +68 -0
  34. package/src/GlobalStateManager.res.mjs +75 -0
  35. package/src/GlobalStateManager.resi +7 -0
  36. package/src/HandlerLoader.res +89 -0
  37. package/src/HandlerLoader.res.mjs +79 -0
  38. package/src/Internal.gen.ts +3 -14
  39. package/src/Internal.res +45 -13
  40. package/src/LoadLayer.res +444 -0
  41. package/src/LoadLayer.res.mjs +296 -0
  42. package/src/LoadLayer.resi +32 -0
  43. package/src/LogSelection.res +33 -27
  44. package/src/LogSelection.res.mjs +6 -0
  45. package/src/Logging.res +11 -4
  46. package/src/Logging.res.mjs +14 -6
  47. package/src/Main.res +351 -0
  48. package/src/Main.res.mjs +312 -0
  49. package/src/Persistence.res +1 -2
  50. package/src/PgStorage.gen.ts +10 -0
  51. package/src/PgStorage.res +28 -34
  52. package/src/PgStorage.res.d.mts +5 -0
  53. package/src/PgStorage.res.mjs +27 -27
  54. package/src/Prometheus.res +8 -8
  55. package/src/Prometheus.res.mjs +10 -10
  56. package/src/ReorgDetection.res +6 -10
  57. package/src/ReorgDetection.res.mjs +6 -6
  58. package/src/TestIndexer.res +536 -0
  59. package/src/TestIndexer.res.mjs +412 -0
  60. package/src/TestIndexerProxyStorage.res +210 -0
  61. package/src/TestIndexerProxyStorage.res.mjs +157 -0
  62. package/src/Types.ts +1 -1
  63. package/src/UserContext.res +355 -0
  64. package/src/UserContext.res.mjs +236 -0
  65. package/src/Utils.res +28 -0
  66. package/src/Utils.res.mjs +18 -0
  67. package/src/bindings/ClickHouse.res +31 -1
  68. package/src/bindings/ClickHouse.res.mjs +27 -1
  69. package/src/bindings/DateFns.res +71 -0
  70. package/src/bindings/DateFns.res.mjs +22 -0
  71. package/src/bindings/Ethers.res +27 -67
  72. package/src/bindings/Ethers.res.mjs +18 -70
  73. package/src/bindings/EventSource.res +13 -0
  74. package/src/bindings/EventSource.res.mjs +2 -0
  75. package/src/bindings/NodeJs.res +44 -3
  76. package/src/bindings/NodeJs.res.mjs +11 -3
  77. package/src/bindings/Pino.res +21 -7
  78. package/src/bindings/Pino.res.mjs +11 -5
  79. package/src/bindings/Postgres.gen.ts +8 -0
  80. package/src/bindings/Postgres.res +3 -0
  81. package/src/bindings/Postgres.res.d.mts +5 -0
  82. package/src/bindings/RescriptMocha.res +123 -0
  83. package/src/bindings/RescriptMocha.res.mjs +18 -0
  84. package/src/bindings/Vitest.res +134 -0
  85. package/src/bindings/Vitest.res.mjs +9 -0
  86. package/src/bindings/Yargs.res +8 -0
  87. package/src/bindings/Yargs.res.mjs +2 -0
  88. package/src/db/InternalTable.res +2 -0
  89. package/src/db/InternalTable.res.mjs +1 -1
  90. package/src/sources/Evm.res +87 -0
  91. package/src/sources/Evm.res.mjs +105 -0
  92. package/src/sources/EvmChain.res +90 -0
  93. package/src/sources/EvmChain.res.mjs +57 -0
  94. package/src/sources/Fuel.res +19 -34
  95. package/src/sources/Fuel.res.mjs +34 -16
  96. package/src/sources/FuelSDK.res +38 -0
  97. package/src/sources/FuelSDK.res.mjs +29 -0
  98. package/src/sources/HyperFuel.res +2 -2
  99. package/src/sources/HyperFuel.resi +1 -1
  100. package/src/sources/HyperFuelClient.res +2 -2
  101. package/src/sources/HyperFuelSource.res +8 -8
  102. package/src/sources/HyperFuelSource.res.mjs +5 -5
  103. package/src/sources/HyperSyncHeightStream.res +97 -0
  104. package/src/sources/HyperSyncHeightStream.res.mjs +94 -0
  105. package/src/sources/HyperSyncSource.res +64 -172
  106. package/src/sources/HyperSyncSource.res.mjs +73 -155
  107. package/src/sources/Rpc.res +43 -0
  108. package/src/sources/Rpc.res.mjs +31 -0
  109. package/src/sources/RpcSource.res +32 -130
  110. package/src/sources/RpcSource.res.mjs +47 -121
  111. package/src/sources/Source.res +3 -2
  112. package/src/sources/SourceManager.res +183 -108
  113. package/src/sources/SourceManager.res.mjs +162 -99
  114. package/src/sources/SourceManager.resi +4 -5
  115. package/src/sources/Svm.res +59 -0
  116. package/src/sources/Svm.res.mjs +79 -0
  117. package/src/tui/Tui.res +266 -0
  118. package/src/tui/Tui.res.mjs +342 -0
  119. package/src/tui/bindings/Ink.res +376 -0
  120. package/src/tui/bindings/Ink.res.mjs +75 -0
  121. package/src/tui/bindings/Style.res +123 -0
  122. package/src/tui/bindings/Style.res.mjs +2 -0
  123. package/src/tui/components/BufferedProgressBar.res +40 -0
  124. package/src/tui/components/BufferedProgressBar.res.mjs +57 -0
  125. package/src/tui/components/CustomHooks.res +122 -0
  126. package/src/tui/components/CustomHooks.res.mjs +179 -0
  127. package/src/tui/components/Messages.res +41 -0
  128. package/src/tui/components/Messages.res.mjs +75 -0
  129. package/src/tui/components/SyncETA.res +193 -0
  130. package/src/tui/components/SyncETA.res.mjs +269 -0
  131. package/src/tui/components/TuiData.res +46 -0
  132. package/src/tui/components/TuiData.res.mjs +29 -0
  133. package/src/Platform.res +0 -140
  134. package/src/Platform.res.mjs +0 -170
  135. package/src/bindings/Ethers.gen.ts +0 -14
  136. /package/src/{Indexer.res.mjs → Ctx.res.mjs} +0 -0
@@ -0,0 +1,157 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Js_exn from "rescript/lib/es6/js_exn.js";
4
+ import * as Js_dict from "rescript/lib/es6/js_dict.js";
5
+ import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
6
+ import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
7
+
8
+ function make(parentPort, initialState) {
9
+ var proxy = {
10
+ parentPort: parentPort,
11
+ initialState: initialState,
12
+ pendingRequests: {},
13
+ requestCounter: 0
14
+ };
15
+ parentPort.on("message", (function (msg) {
16
+ var idStr = String(msg.id);
17
+ var pending = proxy.pendingRequests[idStr];
18
+ var match = pending !== undefined ? pending : Js_exn.raiseError("TestIndexer: No pending request found for id " + idStr);
19
+ Js_dict.unsafeDeleteKey(proxy.pendingRequests, idStr);
20
+ var match$1 = msg.payload;
21
+ if (match$1.type === "response") {
22
+ return match.resolve(match$1.data);
23
+ } else {
24
+ return match.reject(new Error(match$1.message));
25
+ }
26
+ }));
27
+ return proxy;
28
+ }
29
+
30
+ function nextRequestId(proxy) {
31
+ proxy.requestCounter = proxy.requestCounter + 1 | 0;
32
+ return proxy.requestCounter;
33
+ }
34
+
35
+ function sendRequest(proxy, payload) {
36
+ return new Promise((function (resolve, reject) {
37
+ var id = nextRequestId(proxy);
38
+ proxy.pendingRequests[String(id)] = {
39
+ resolve: resolve,
40
+ reject: reject
41
+ };
42
+ proxy.parentPort.postMessage({
43
+ id: id,
44
+ payload: payload
45
+ });
46
+ }));
47
+ }
48
+
49
+ function makeStorage(proxy) {
50
+ return {
51
+ isInitialized: (async function () {
52
+ return true;
53
+ }),
54
+ initialize: (async function (param, param$1, param$2) {
55
+ return Js_exn.raiseError("TestIndexer: initialize should not be called. Use resumeInitialState instead.");
56
+ }),
57
+ resumeInitialState: (async function () {
58
+ return proxy.initialState;
59
+ }),
60
+ loadByIdsOrThrow: (async function (ids, table, rowsSchema) {
61
+ var response = await sendRequest(proxy, {
62
+ type: "loadByIds",
63
+ tableName: table.tableName,
64
+ ids: ids
65
+ });
66
+ return S$RescriptSchema.parseOrThrow(response, rowsSchema);
67
+ }),
68
+ loadByFieldOrThrow: (async function (fieldName, fieldSchema, fieldValue, operator, table, rowsSchema) {
69
+ var response = await sendRequest(proxy, {
70
+ type: "loadByField",
71
+ tableName: table.tableName,
72
+ fieldName: fieldName,
73
+ fieldValue: S$RescriptSchema.reverseConvertToJsonOrThrow(fieldValue, fieldSchema),
74
+ operator: operator
75
+ });
76
+ return S$RescriptSchema.parseOrThrow(response, rowsSchema);
77
+ }),
78
+ setOrThrow: (async function (param, param$1, param$2) {
79
+
80
+ }),
81
+ setEffectCacheOrThrow: (async function (param, param$1, param$2) {
82
+
83
+ }),
84
+ dumpEffectCache: (async function () {
85
+
86
+ }),
87
+ executeUnsafe: (async function (param) {
88
+
89
+ }),
90
+ setChainMeta: (async function (param) {
91
+
92
+ }),
93
+ pruneStaleCheckpoints: (async function (param) {
94
+
95
+ }),
96
+ pruneStaleEntityHistory: (async function (param, param$1, param$2) {
97
+
98
+ }),
99
+ getRollbackTargetCheckpoint: (async function (param, param$1) {
100
+ return Js_exn.raiseError("TestIndexer: Rollback is not supported. Set rollbackOnReorg to false in config.");
101
+ }),
102
+ getRollbackProgressDiff: (async function (param) {
103
+ return Js_exn.raiseError("TestIndexer: Rollback is not supported. Set rollbackOnReorg to false in config.");
104
+ }),
105
+ getRollbackData: (async function (param, param$1) {
106
+ return Js_exn.raiseError("TestIndexer: Rollback is not supported. Set rollbackOnReorg to false in config.");
107
+ }),
108
+ writeBatch: (async function (batch, param, param$1, param$2, param$3, param$4, param$5, updatedEntities) {
109
+ var serializableEntities = Belt_Array.map(updatedEntities, (function (param) {
110
+ var entityConfig = param.entityConfig;
111
+ var encodeChange = function (change) {
112
+ if (change.type === "SET") {
113
+ return {
114
+ type: "SET",
115
+ entityId: change.entityId,
116
+ entity: S$RescriptSchema.reverseConvertToJsonOrThrow(change.entity, entityConfig.schema),
117
+ checkpointId: change.checkpointId
118
+ };
119
+ } else {
120
+ return {
121
+ type: "DELETE",
122
+ entityId: change.entityId,
123
+ checkpointId: change.checkpointId
124
+ };
125
+ }
126
+ };
127
+ return {
128
+ entityName: entityConfig.name,
129
+ updates: Belt_Array.map(param.updates, (function (update) {
130
+ return {
131
+ latestChange: encodeChange(update.latestChange),
132
+ history: Belt_Array.map(update.history, encodeChange),
133
+ containsRollbackDiffChange: update.containsRollbackDiffChange
134
+ };
135
+ }))
136
+ };
137
+ }));
138
+ await sendRequest(proxy, {
139
+ type: "writeBatch",
140
+ updatedEntities: serializableEntities,
141
+ checkpointIds: batch.checkpointIds,
142
+ checkpointChainIds: batch.checkpointChainIds,
143
+ checkpointBlockNumbers: batch.checkpointBlockNumbers,
144
+ checkpointBlockHashes: batch.checkpointBlockHashes,
145
+ checkpointEventsProcessed: batch.checkpointEventsProcessed
146
+ });
147
+ })
148
+ };
149
+ }
150
+
151
+ export {
152
+ make ,
153
+ nextRequestId ,
154
+ sendRequest ,
155
+ makeStorage ,
156
+ }
157
+ /* S-RescriptSchema Not a pure module */
package/src/Types.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export type Invalid = never;
2
2
 
3
- export type Address = string;
3
+ export type Address = `0x${string}`;
4
4
 
5
5
  export type Logger = {
6
6
  readonly debug: (
@@ -0,0 +1,355 @@
1
+ let codegenHelpMessage = `Rerun 'pnpm dev' to update generated code after schema.graphql changes.`
2
+
3
+ type contextParams = {
4
+ item: Internal.item,
5
+ checkpointId: float,
6
+ inMemoryStore: InMemoryStore.t,
7
+ loadManager: LoadManager.t,
8
+ persistence: Persistence.t,
9
+ isPreload: bool,
10
+ shouldSaveHistory: bool,
11
+ chains: Internal.chains,
12
+ config: Config.t,
13
+ mutable isResolved: bool,
14
+ }
15
+
16
+ // We don't want to expose the params to the user
17
+ // so instead of storing _params on the context object,
18
+ // we use an external WeakMap
19
+ let paramsByThis: Utils.WeakMap.t<unknown, contextParams> = Utils.WeakMap.make()
20
+
21
+ let effectContextPrototype = %raw(`Object.create(null)`)
22
+ Utils.Object.defineProperty(
23
+ effectContextPrototype,
24
+ "log",
25
+ {
26
+ get: () => {
27
+ (paramsByThis->Utils.WeakMap.unsafeGet(%raw(`this`))).item->Logging.getUserLogger
28
+ },
29
+ },
30
+ )
31
+ %%raw(`
32
+ var EffectContext = function(params, defaultShouldCache, callEffect) {
33
+ paramsByThis.set(this, params);
34
+ this.effect = callEffect;
35
+ this.cache = defaultShouldCache;
36
+ };
37
+ EffectContext.prototype = effectContextPrototype;
38
+ `)
39
+
40
+ @new
41
+ external makeEffectContext: (
42
+ contextParams,
43
+ ~defaultShouldCache: bool,
44
+ ~callEffect: (Internal.effect, Internal.effectInput) => promise<Internal.effectOutput>,
45
+ ) => Internal.effectContext = "EffectContext"
46
+
47
+ let initEffect = (params: contextParams) => {
48
+ let rec callEffect = (effect: Internal.effect, input: Internal.effectInput) => {
49
+ let effectContext = makeEffectContext(
50
+ params,
51
+ ~defaultShouldCache=effect.defaultShouldCache,
52
+ ~callEffect,
53
+ )
54
+ let effectArgs: Internal.effectArgs = {
55
+ input,
56
+ context: effectContext,
57
+ cacheKey: input->S.reverseConvertOrThrow(effect.input)->Utils.Hash.makeOrThrow,
58
+ }
59
+ LoadLayer.loadEffect(
60
+ ~loadManager=params.loadManager,
61
+ ~persistence=params.persistence,
62
+ ~effect,
63
+ ~effectArgs,
64
+ ~inMemoryStore=params.inMemoryStore,
65
+ ~shouldGroup=params.isPreload,
66
+ ~item=params.item,
67
+ )
68
+ }
69
+ callEffect
70
+ }
71
+
72
+ type entityContextParams = {
73
+ ...contextParams,
74
+ entityConfig: Internal.entityConfig,
75
+ }
76
+
77
+ let getWhereTraps: Utils.Proxy.traps<entityContextParams> = {
78
+ get: (~target as params, ~prop: unknown) => {
79
+ let entityConfig = params.entityConfig
80
+ if prop->Js.typeof !== "string" {
81
+ Js.Exn.raiseError(
82
+ `Invalid context.${entityConfig.name}.getWhere access by a non-string property.`,
83
+ )
84
+ } else {
85
+ let dbFieldName = prop->(Utils.magic: unknown => string)
86
+ switch entityConfig.table->Table.getFieldByDbName(dbFieldName) {
87
+ | None =>
88
+ Js.Exn.raiseError(
89
+ `Invalid context.${entityConfig.name}.getWhere.${dbFieldName} - the field doesn't exist. ${codegenHelpMessage}`,
90
+ )
91
+ | Some(field) =>
92
+ let fieldValueSchema = switch field {
93
+ | Field({fieldSchema}) => fieldSchema
94
+ | DerivedFrom(_) => S.string->S.toUnknown
95
+ }
96
+ {
97
+ Envio.eq: fieldValue =>
98
+ LoadLayer.loadByField(
99
+ ~loadManager=params.loadManager,
100
+ ~persistence=params.persistence,
101
+ ~operator=Eq,
102
+ ~entityConfig,
103
+ ~fieldName=dbFieldName,
104
+ ~fieldValueSchema,
105
+ ~inMemoryStore=params.inMemoryStore,
106
+ ~shouldGroup=params.isPreload,
107
+ ~item=params.item,
108
+ ~fieldValue,
109
+ ),
110
+ gt: fieldValue =>
111
+ LoadLayer.loadByField(
112
+ ~loadManager=params.loadManager,
113
+ ~persistence=params.persistence,
114
+ ~operator=Gt,
115
+ ~entityConfig,
116
+ ~fieldName=dbFieldName,
117
+ ~fieldValueSchema,
118
+ ~inMemoryStore=params.inMemoryStore,
119
+ ~shouldGroup=params.isPreload,
120
+ ~item=params.item,
121
+ ~fieldValue,
122
+ ),
123
+ lt: fieldValue =>
124
+ LoadLayer.loadByField(
125
+ ~loadManager=params.loadManager,
126
+ ~persistence=params.persistence,
127
+ ~operator=Lt,
128
+ ~entityConfig,
129
+ ~fieldName=dbFieldName,
130
+ ~fieldValueSchema,
131
+ ~inMemoryStore=params.inMemoryStore,
132
+ ~shouldGroup=params.isPreload,
133
+ ~item=params.item,
134
+ ~fieldValue,
135
+ ),
136
+ }->Utils.magic
137
+ }
138
+ }
139
+ },
140
+ }
141
+
142
+ let noopSet = (_entity: Internal.entity) => ()
143
+ let noopDeleteUnsafe = (_entityId: string) => ()
144
+
145
+ let entityTraps: Utils.Proxy.traps<entityContextParams> = {
146
+ get: (~target as params, ~prop: unknown) => {
147
+ let prop = prop->(Utils.magic: unknown => string)
148
+
149
+ let set = params.isPreload
150
+ ? noopSet
151
+ : (entity: Internal.entity) => {
152
+ params.inMemoryStore
153
+ ->InMemoryStore.getInMemTable(~entityConfig=params.entityConfig)
154
+ ->InMemoryTable.Entity.set(
155
+ Set({
156
+ entityId: entity.id,
157
+ checkpointId: params.checkpointId,
158
+ entity,
159
+ }),
160
+ ~shouldSaveHistory=params.shouldSaveHistory,
161
+ )
162
+ }
163
+
164
+ switch prop {
165
+ | "get" =>
166
+ (
167
+ entityId =>
168
+ LoadLayer.loadById(
169
+ ~loadManager=params.loadManager,
170
+ ~persistence=params.persistence,
171
+ ~entityConfig=params.entityConfig,
172
+ ~inMemoryStore=params.inMemoryStore,
173
+ ~shouldGroup=params.isPreload,
174
+ ~item=params.item,
175
+ ~entityId,
176
+ )
177
+ )->Utils.magic
178
+ | "getWhere" => params->Utils.Proxy.make(getWhereTraps)->Utils.magic
179
+ | "getOrThrow" =>
180
+ (
181
+ (entityId, ~message=?) =>
182
+ LoadLayer.loadById(
183
+ ~loadManager=params.loadManager,
184
+ ~persistence=params.persistence,
185
+ ~entityConfig=params.entityConfig,
186
+ ~inMemoryStore=params.inMemoryStore,
187
+ ~shouldGroup=params.isPreload,
188
+ ~item=params.item,
189
+ ~entityId,
190
+ )->Promise.thenResolve(entity => {
191
+ switch entity {
192
+ | Some(entity) => entity
193
+ | None =>
194
+ Js.Exn.raiseError(
195
+ message->Belt.Option.getWithDefault(
196
+ `Entity '${params.entityConfig.name}' with ID '${entityId}' is expected to exist.`,
197
+ ),
198
+ )
199
+ }
200
+ })
201
+ )->Utils.magic
202
+ | "getOrCreate" =>
203
+ (
204
+ (entity: Internal.entity) =>
205
+ LoadLayer.loadById(
206
+ ~loadManager=params.loadManager,
207
+ ~persistence=params.persistence,
208
+ ~entityConfig=params.entityConfig,
209
+ ~inMemoryStore=params.inMemoryStore,
210
+ ~shouldGroup=params.isPreload,
211
+ ~item=params.item,
212
+ ~entityId=entity.id,
213
+ )->Promise.thenResolve(storageEntity => {
214
+ switch storageEntity {
215
+ | Some(entity) => entity
216
+ | None => {
217
+ set(entity)
218
+ entity
219
+ }
220
+ }
221
+ })
222
+ )->Utils.magic
223
+ | "set" => set->Utils.magic
224
+ | "deleteUnsafe" =>
225
+ if params.isPreload {
226
+ noopDeleteUnsafe
227
+ } else {
228
+ entityId => {
229
+ params.inMemoryStore
230
+ ->InMemoryStore.getInMemTable(~entityConfig=params.entityConfig)
231
+ ->InMemoryTable.Entity.set(
232
+ Delete({
233
+ entityId,
234
+ checkpointId: params.checkpointId,
235
+ }),
236
+ ~shouldSaveHistory=params.shouldSaveHistory,
237
+ )
238
+ }
239
+ }->Utils.magic
240
+ | _ => Js.Exn.raiseError(`Invalid context.${params.entityConfig.name}.${prop} operation.`)
241
+ }
242
+ },
243
+ }
244
+
245
+ let handlerTraps: Utils.Proxy.traps<contextParams> = {
246
+ get: (~target as params, ~prop: unknown) => {
247
+ let prop = prop->(Utils.magic: unknown => string)
248
+ if params.isResolved {
249
+ Utils.Error.make(
250
+ `Impossible to access context.${prop} after the handler is resolved. Make sure you didn't miss an await in the handler.`,
251
+ )->ErrorHandling.mkLogAndRaise(~logger=params.item->Logging.getItemLogger)
252
+ }
253
+ switch prop {
254
+ | "log" =>
255
+ (params.isPreload ? Logging.noopLogger : params.item->Logging.getUserLogger)->Utils.magic
256
+ | "effect" =>
257
+ initEffect((params :> contextParams))->(
258
+ Utils.magic: (
259
+ (Internal.effect, Internal.effectInput) => promise<Internal.effectOutput>
260
+ ) => unknown
261
+ )
262
+
263
+ | "isPreload" => params.isPreload->Utils.magic
264
+ | "chain" =>
265
+ let chainId = params.item->Internal.getItemChainId
266
+ params.chains->Utils.Dict.dangerouslyGetByIntNonOption(chainId)->Utils.magic
267
+ | _ =>
268
+ switch params.config.userEntitiesByName->Utils.Dict.dangerouslyGetNonOption(prop) {
269
+ | Some(entityConfig) =>
270
+ {
271
+ item: params.item,
272
+ isPreload: params.isPreload,
273
+ inMemoryStore: params.inMemoryStore,
274
+ loadManager: params.loadManager,
275
+ persistence: params.persistence,
276
+ shouldSaveHistory: params.shouldSaveHistory,
277
+ checkpointId: params.checkpointId,
278
+ chains: params.chains,
279
+ isResolved: params.isResolved,
280
+ config: params.config,
281
+ entityConfig,
282
+ }
283
+ ->Utils.Proxy.make(entityTraps)
284
+ ->Utils.magic
285
+ | None =>
286
+ Js.Exn.raiseError(`Invalid context access by '${prop}' property. ${codegenHelpMessage}`)
287
+ }
288
+ }
289
+ },
290
+ }
291
+
292
+ let getHandlerContext = (params: contextParams): Internal.handlerContext => {
293
+ params->Utils.Proxy.make(handlerTraps)->Utils.magic
294
+ }
295
+
296
+ // Contract register context creation
297
+ type contractRegisterParams = {
298
+ item: Internal.item,
299
+ onRegister: (~item: Internal.item, ~contractAddress: Address.t, ~contractName: string) => unit,
300
+ config: Config.t,
301
+ mutable isResolved: bool,
302
+ }
303
+
304
+ let contractRegisterTraps: Utils.Proxy.traps<contractRegisterParams> = {
305
+ get: (~target as params, ~prop: unknown) => {
306
+ let prop = prop->(Utils.magic: unknown => string)
307
+ if params.isResolved {
308
+ Utils.Error.make(
309
+ `Impossible to access context.${prop} after the contract register is resolved. Make sure you didn't miss an await in the handler.`,
310
+ )->ErrorHandling.mkLogAndRaise(~logger=params.item->Logging.getItemLogger)
311
+ }
312
+ switch prop {
313
+ | "log" => params.item->Logging.getUserLogger->Utils.magic
314
+ | _ =>
315
+ // Use the pre-built mapping for efficient lookup
316
+ switch params.config.addContractNameToContractNameMapping->Utils.Dict.dangerouslyGetNonOption(
317
+ prop,
318
+ ) {
319
+ | Some(contractName) => {
320
+ let addFunction = (contractAddress: Address.t) => {
321
+ let validatedAddress = if params.config.ecosystem.name === Evm {
322
+ // The value is passed from the user-land,
323
+ // so we need to validate and checksum/lowercase the address.
324
+ if params.config.lowercaseAddresses {
325
+ contractAddress->Address.Evm.fromAddressLowercaseOrThrow
326
+ } else {
327
+ contractAddress->Address.Evm.fromAddressOrThrow
328
+ }
329
+ } else {
330
+ // TODO: Ideally we should do the same for other ecosystems
331
+ contractAddress
332
+ }
333
+
334
+ params.onRegister(~item=params.item, ~contractAddress=validatedAddress, ~contractName)
335
+ }
336
+
337
+ addFunction->Utils.magic
338
+ }
339
+ | None =>
340
+ Js.Exn.raiseError(`Invalid context access by '${prop}' property. ${codegenHelpMessage}`)
341
+ }
342
+ }
343
+ },
344
+ }
345
+
346
+ let getContractRegisterContext = (params: contractRegisterParams) => {
347
+ params
348
+ ->Utils.Proxy.make(contractRegisterTraps)
349
+ ->Utils.magic
350
+ }
351
+
352
+ let getContractRegisterArgs = (params: contractRegisterParams): Internal.contractRegisterArgs => {
353
+ event: (params.item->Internal.castUnsafeEventItem).event,
354
+ context: getContractRegisterContext(params),
355
+ }