envio 3.3.2 → 3.4.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/package.json +6 -6
- package/src/Api.res +1 -8
- package/src/Api.res.mjs +1 -5
- package/src/ChainState.res +6 -1
- package/src/ChainState.res.mjs +4 -3
- package/src/Config.res +33 -4
- package/src/Config.res.mjs +34 -5
- package/src/Core.res +30 -19
- package/src/Core.res.mjs +5 -5
- package/src/EnvioGlobal.res +0 -2
- package/src/EnvioGlobal.res.mjs +0 -1
- package/src/ExitOnCaughtUp.res +6 -2
- package/src/ExitOnCaughtUp.res.mjs +4 -0
- package/src/FetchState.res +3 -3
- package/src/HandlerRegister.res +357 -434
- package/src/HandlerRegister.res.mjs +202 -242
- package/src/HandlerRegister.resi +7 -15
- package/src/IndexerState.res +10 -0
- package/src/IndexerState.res.mjs +9 -3
- package/src/IndexerState.resi +3 -0
- package/src/Internal.res +10 -1
- package/src/Main.res.mjs +4 -4
- package/src/PgStorage.res +16 -1
- package/src/PgStorage.res.mjs +9 -1
- package/src/SimulateItems.res +61 -40
- package/src/SimulateItems.res.mjs +37 -21
- package/src/TestIndexer.res +446 -453
- package/src/TestIndexer.res.mjs +320 -343
- package/src/bindings/ClickHouse.res +68 -2
- package/src/bindings/ClickHouse.res.mjs +47 -2
- package/src/sources/EvmChain.res +1 -1
- package/src/sources/EvmChain.res.mjs +2 -2
- package/src/sources/FuelHyperSync.res +74 -0
- package/src/sources/FuelHyperSync.res.mjs +80 -0
- package/src/sources/FuelHyperSync.resi +22 -0
- package/src/sources/FuelHyperSyncClient.res +120 -0
- package/src/sources/FuelHyperSyncClient.res.mjs +71 -0
- package/src/sources/FuelHyperSyncSource.res +257 -0
- package/src/sources/FuelHyperSyncSource.res.mjs +252 -0
- package/src/sources/HyperSyncClient.res +2 -2
- package/src/sources/HyperSyncClient.res.mjs +1 -1
- package/src/sources/SvmHyperSyncClient.res +139 -102
- package/src/sources/SvmHyperSyncClient.res.mjs +45 -5
- package/src/sources/SvmHyperSyncSource.res +60 -440
- package/src/sources/SvmHyperSyncSource.res.mjs +42 -363
- package/src/TestIndexerProxyStorage.res +0 -196
- package/src/TestIndexerProxyStorage.res.mjs +0 -121
- package/src/TestIndexerWorker.res +0 -4
- package/src/TestIndexerWorker.res.mjs +0 -7
- package/src/sources/EventRouter.res +0 -165
- package/src/sources/EventRouter.res.mjs +0 -153
- package/src/sources/HyperFuel.res +0 -179
- package/src/sources/HyperFuel.res.mjs +0 -146
- package/src/sources/HyperFuel.resi +0 -36
- package/src/sources/HyperFuelClient.res +0 -127
- package/src/sources/HyperFuelClient.res.mjs +0 -20
- package/src/sources/HyperFuelSource.res +0 -502
- package/src/sources/HyperFuelSource.res.mjs +0 -481
- /package/src/sources/{HyperSyncSource.res → EvmHyperSyncSource.res} +0 -0
- /package/src/sources/{HyperSyncSource.res.mjs → EvmHyperSyncSource.res.mjs} +0 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
open Source
|
|
2
|
+
|
|
3
|
+
let isUnauthorizedError = (message: string) => message->String.includes("401 Unauthorized")
|
|
4
|
+
|
|
5
|
+
type options = {
|
|
6
|
+
chain: ChainMap.Chain.t,
|
|
7
|
+
endpointUrl: string,
|
|
8
|
+
apiToken: option<string>,
|
|
9
|
+
// The chain's registrations, indexed by their sequential `index`.
|
|
10
|
+
onEventRegistrations: array<Internal.fuelOnEventRegistration>,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let make = ({chain, endpointUrl, apiToken, onEventRegistrations}: options): t => {
|
|
14
|
+
let name = "HyperFuel"
|
|
15
|
+
|
|
16
|
+
let apiToken = switch apiToken {
|
|
17
|
+
| Some(token) => token
|
|
18
|
+
| None =>
|
|
19
|
+
JsError.throwWithMessage(`An Envio API token is required for using HyperFuel as a data-source.
|
|
20
|
+
Set the ENVIO_API_TOKEN environment variable in your .env file.
|
|
21
|
+
Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let client = switch FuelHyperSyncClient.make(
|
|
25
|
+
{url: endpointUrl, apiToken},
|
|
26
|
+
~eventRegistrations=FuelHyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations),
|
|
27
|
+
) {
|
|
28
|
+
| client => client
|
|
29
|
+
| exception exn =>
|
|
30
|
+
exn->ErrorHandling.mkLogAndRaise(~msg="Failed to instantiate the HyperFuel client")
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let getItemsOrThrow = async (
|
|
34
|
+
~fromBlock,
|
|
35
|
+
~toBlock,
|
|
36
|
+
~addressesByContractName,
|
|
37
|
+
~contractNameByAddress as _,
|
|
38
|
+
~knownHeight,
|
|
39
|
+
~partitionId as _,
|
|
40
|
+
~selection: FetchState.selection,
|
|
41
|
+
~itemsTarget as _,
|
|
42
|
+
~retry,
|
|
43
|
+
~logger,
|
|
44
|
+
) => {
|
|
45
|
+
let totalTimeRef = Performance.now()
|
|
46
|
+
|
|
47
|
+
let startFetchingBatchTimeRef = Performance.now()
|
|
48
|
+
|
|
49
|
+
//fetch batch
|
|
50
|
+
let pageUnsafe = try await FuelHyperSync.GetLogs.query(
|
|
51
|
+
~client,
|
|
52
|
+
~fromBlock,
|
|
53
|
+
~toBlock,
|
|
54
|
+
~registrationIndexes=selection.onEventRegistrations->Array.map(reg => reg.index),
|
|
55
|
+
~addressesByContractName,
|
|
56
|
+
) catch {
|
|
57
|
+
| FuelHyperSync.GetLogs.Error(error) =>
|
|
58
|
+
throw(
|
|
59
|
+
Source.GetItemsError(
|
|
60
|
+
Source.FailedGettingItems({
|
|
61
|
+
exn: %raw(`null`),
|
|
62
|
+
attemptedToBlock: toBlock->Option.getOr(knownHeight),
|
|
63
|
+
retry: switch error {
|
|
64
|
+
| WrongInstance =>
|
|
65
|
+
let backoffMillis = switch retry {
|
|
66
|
+
| 0 => 100
|
|
67
|
+
| _ => 500 * retry
|
|
68
|
+
}
|
|
69
|
+
WithBackoff({
|
|
70
|
+
message: `Block #${fromBlock->Int.toString} not found in FuelHyperSync. HyperFuel has multiple instances and it's possible that they drift independently slightly from the head. Indexing should continue correctly after retrying the query in ${backoffMillis->Int.toString}ms.`,
|
|
71
|
+
backoffMillis,
|
|
72
|
+
})
|
|
73
|
+
| UnexpectedMissingParams({missingParams}) =>
|
|
74
|
+
ImpossibleForTheQuery({
|
|
75
|
+
message: `Source returned invalid data with missing required fields: ${missingParams->Array.joinUnsafe(
|
|
76
|
+
", ",
|
|
77
|
+
)}`,
|
|
78
|
+
})
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
81
|
+
),
|
|
82
|
+
)
|
|
83
|
+
| exn =>
|
|
84
|
+
throw(
|
|
85
|
+
Source.GetItemsError(
|
|
86
|
+
Source.FailedGettingItems({
|
|
87
|
+
exn,
|
|
88
|
+
attemptedToBlock: toBlock->Option.getOr(knownHeight),
|
|
89
|
+
retry: WithBackoff({
|
|
90
|
+
message: `Unexpected issue while fetching events from HyperFuel client. Attempt a retry.`,
|
|
91
|
+
backoffMillis: switch retry {
|
|
92
|
+
| 0 => 500
|
|
93
|
+
| _ => 1000 * retry
|
|
94
|
+
},
|
|
95
|
+
}),
|
|
96
|
+
}),
|
|
97
|
+
),
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let pageFetchTime = startFetchingBatchTimeRef->Performance.secondsSince
|
|
102
|
+
let requestStats = [{Source.method: "getLogs", seconds: pageFetchTime}]
|
|
103
|
+
|
|
104
|
+
//set height and next from block
|
|
105
|
+
let knownHeight = pageUnsafe.archiveHeight
|
|
106
|
+
|
|
107
|
+
//The heighest (biggest) blocknumber that was accounted for in
|
|
108
|
+
//Our query. Not necessarily the blocknumber of the last log returned
|
|
109
|
+
//In the query
|
|
110
|
+
let heighestBlockQueried = pageUnsafe.nextBlock - 1
|
|
111
|
+
|
|
112
|
+
let parsingTimeRef = Performance.now()
|
|
113
|
+
|
|
114
|
+
// Blocks are returned once per height; items reference them by blockHeight.
|
|
115
|
+
let blocksByHeight = Utils.Map.make()
|
|
116
|
+
pageUnsafe.blocks->Array.forEach(block => {
|
|
117
|
+
blocksByHeight->Utils.Map.set(block.height, block)->ignore
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
let chainId = chain->ChainMap.Chain.toChainId
|
|
121
|
+
|
|
122
|
+
let parsedQueueItems = pageUnsafe.items->Array.map(item => {
|
|
123
|
+
// Routing happened in Rust; the item references its registration by
|
|
124
|
+
// chain-scoped index.
|
|
125
|
+
let onEventRegistration = onEventRegistrations->Array.getUnsafe(item.onEventRegistrationIndex)
|
|
126
|
+
let eventConfig =
|
|
127
|
+
onEventRegistration.eventConfig->(
|
|
128
|
+
Utils.magic: Internal.eventConfig => Internal.fuelEventConfig
|
|
129
|
+
)
|
|
130
|
+
// Presence of every routed item's block is validated in Rust.
|
|
131
|
+
let block = blocksByHeight->Utils.Map.unsafeGet(item.blockHeight)
|
|
132
|
+
|
|
133
|
+
let params = switch eventConfig.kind {
|
|
134
|
+
| LogData({decode}) =>
|
|
135
|
+
// Kind-required columns are validated present in Rust before the item
|
|
136
|
+
// crosses the boundary.
|
|
137
|
+
let data = item.data->Option.getOr("")
|
|
138
|
+
try decode(data) catch {
|
|
139
|
+
| exn => {
|
|
140
|
+
let params = {
|
|
141
|
+
"chainId": chainId,
|
|
142
|
+
"blockNumber": item.blockHeight,
|
|
143
|
+
"logIndex": item.receiptIndex,
|
|
144
|
+
}
|
|
145
|
+
let logger = Logging.createChildFrom(~logger, ~params)
|
|
146
|
+
exn->ErrorHandling.mkLogAndRaise(
|
|
147
|
+
~msg="Failed to decode Fuel LogData receipt, please double check your ABI.",
|
|
148
|
+
~logger,
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
| Mint | Burn =>
|
|
153
|
+
(
|
|
154
|
+
{
|
|
155
|
+
subId: item.subId->Option.getOr(""),
|
|
156
|
+
amount: item.val->Option.getOr(0n),
|
|
157
|
+
}: Internal.fuelSupplyParams
|
|
158
|
+
)->Obj.magic
|
|
159
|
+
| Transfer | Call =>
|
|
160
|
+
(
|
|
161
|
+
{
|
|
162
|
+
to: item.to->Option.getOr("")->Address.unsafeFromString,
|
|
163
|
+
assetId: item.assetId->Option.getOr(""),
|
|
164
|
+
amount: item.amount->Option.getOr(0n),
|
|
165
|
+
}: Internal.fuelTransferParams
|
|
166
|
+
)->Obj.magic
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
Internal.Event({
|
|
170
|
+
onEventRegistration,
|
|
171
|
+
chain,
|
|
172
|
+
blockNumber: item.blockHeight,
|
|
173
|
+
logIndex: item.receiptIndex,
|
|
174
|
+
// Fuel carries the transaction inline on the payload; the store key is
|
|
175
|
+
// unused (Fuel identifies transactions by hash, kept on the payload).
|
|
176
|
+
transactionIndex: 0,
|
|
177
|
+
payload: {
|
|
178
|
+
contractName: eventConfig.contractName,
|
|
179
|
+
eventName: eventConfig.name,
|
|
180
|
+
chainId,
|
|
181
|
+
params,
|
|
182
|
+
transaction: {
|
|
183
|
+
"id": item.txId,
|
|
184
|
+
}->Obj.magic, // TODO: Obj.magic needed until the field selection types are not configurable for Fuel and Evm separately
|
|
185
|
+
block: block->Obj.magic,
|
|
186
|
+
srcAddress: item.srcAddress,
|
|
187
|
+
logIndex: item.receiptIndex,
|
|
188
|
+
}->Fuel.fromPayload,
|
|
189
|
+
})
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
let parsingTimeElapsed = parsingTimeRef->Performance.secondsSince
|
|
193
|
+
|
|
194
|
+
// Fuel never rolls back on reorg, so block hashes here are purely informational
|
|
195
|
+
// for detect-only logging via ReorgDetection.
|
|
196
|
+
let blockHashes = pageUnsafe.blocks->Array.map(block => {
|
|
197
|
+
ReorgDetection.blockNumber: block.height,
|
|
198
|
+
blockHash: block.id,
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
let latestFetchedBlockTimestamp = switch blocksByHeight->Utils.Map.get(heighestBlockQueried) {
|
|
202
|
+
| Some(block) => block.time
|
|
203
|
+
| None => 0
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
let totalTimeElapsed = totalTimeRef->Performance.secondsSince
|
|
207
|
+
|
|
208
|
+
let stats = {
|
|
209
|
+
totalTimeElapsed,
|
|
210
|
+
parsingTimeElapsed,
|
|
211
|
+
pageFetchTime,
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
{
|
|
215
|
+
latestFetchedBlockTimestamp,
|
|
216
|
+
parsedQueueItems,
|
|
217
|
+
// Fuel keeps transaction and block on the payload; no store pages.
|
|
218
|
+
transactionStore: None,
|
|
219
|
+
blockStore: None,
|
|
220
|
+
latestFetchedBlockNumber: heighestBlockQueried,
|
|
221
|
+
stats,
|
|
222
|
+
knownHeight,
|
|
223
|
+
blockHashes,
|
|
224
|
+
fromBlockQueried: fromBlock,
|
|
225
|
+
requestStats,
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
let getBlockHashes = (~blockNumbers as _, ~logger as _) =>
|
|
230
|
+
JsError.throwWithMessage("HyperFuel does not support getting block hashes")
|
|
231
|
+
|
|
232
|
+
{
|
|
233
|
+
name,
|
|
234
|
+
sourceFor: Sync,
|
|
235
|
+
chain,
|
|
236
|
+
getBlockHashes,
|
|
237
|
+
pollingInterval: 100,
|
|
238
|
+
poweredByHyperSync: true,
|
|
239
|
+
getHeightOrThrow: async () => {
|
|
240
|
+
let timerRef = Performance.now()
|
|
241
|
+
let height = try await client->FuelHyperSyncClient.getHeight catch {
|
|
242
|
+
| JsExn(e) =>
|
|
243
|
+
switch e->JsExn.message {
|
|
244
|
+
| Some(message) if message->isUnauthorizedError =>
|
|
245
|
+
Logging.error(`Your ENVIO_API_TOKEN was rejected by HyperFuel (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`)
|
|
246
|
+
// Retrying an unauthorized request can never succeed, so block forever
|
|
247
|
+
let _ = await Promise.make((_, _) => ())
|
|
248
|
+
0
|
|
249
|
+
| _ => throw(JsExn(e))
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
let seconds = timerRef->Performance.secondsSince
|
|
253
|
+
{height, requestStats: [{method: "getHeight", seconds}]}
|
|
254
|
+
},
|
|
255
|
+
getItemsOrThrow,
|
|
256
|
+
}
|
|
257
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Source from "./Source.res.mjs";
|
|
4
|
+
import * as Logging from "../Logging.res.mjs";
|
|
5
|
+
import * as Performance from "../bindings/Performance.res.mjs";
|
|
6
|
+
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
7
|
+
import * as ErrorHandling from "../ErrorHandling.res.mjs";
|
|
8
|
+
import * as FuelHyperSync from "./FuelHyperSync.res.mjs";
|
|
9
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
10
|
+
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
11
|
+
import * as FuelHyperSyncClient from "./FuelHyperSyncClient.res.mjs";
|
|
12
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
13
|
+
|
|
14
|
+
function isUnauthorizedError(message) {
|
|
15
|
+
return message.includes("401 Unauthorized");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function make(param) {
|
|
19
|
+
let onEventRegistrations = param.onEventRegistrations;
|
|
20
|
+
let apiToken = param.apiToken;
|
|
21
|
+
let chain = param.chain;
|
|
22
|
+
let apiToken$1 = apiToken !== undefined ? apiToken : Stdlib_JsError.throwWithMessage(`An Envio API token is required for using HyperFuel as a data-source.
|
|
23
|
+
Set the ENVIO_API_TOKEN environment variable in your .env file.
|
|
24
|
+
Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
25
|
+
let client;
|
|
26
|
+
try {
|
|
27
|
+
client = FuelHyperSyncClient.make({
|
|
28
|
+
url: param.endpointUrl,
|
|
29
|
+
apiToken: apiToken$1
|
|
30
|
+
}, FuelHyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations));
|
|
31
|
+
} catch (raw_exn) {
|
|
32
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
33
|
+
client = ErrorHandling.mkLogAndRaise(undefined, "Failed to instantiate the HyperFuel client", exn);
|
|
34
|
+
}
|
|
35
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, param, knownHeight, param$1, selection, param$2, retry, logger) => {
|
|
36
|
+
let totalTimeRef = Performance.now();
|
|
37
|
+
let startFetchingBatchTimeRef = Performance.now();
|
|
38
|
+
let pageUnsafe;
|
|
39
|
+
try {
|
|
40
|
+
pageUnsafe = await FuelHyperSync.GetLogs.query(client, fromBlock, toBlock, selection.onEventRegistrations.map(reg => reg.index), addressesByContractName);
|
|
41
|
+
} catch (raw_error) {
|
|
42
|
+
let error = Primitive_exceptions.internalToException(raw_error);
|
|
43
|
+
if (error.RE_EXN_ID === FuelHyperSync.GetLogs.$$Error) {
|
|
44
|
+
let error$1 = error._1;
|
|
45
|
+
let tmp;
|
|
46
|
+
if (typeof error$1 !== "object") {
|
|
47
|
+
let backoffMillis = retry !== 0 ? 500 * retry | 0 : 100;
|
|
48
|
+
tmp = {
|
|
49
|
+
TAG: "WithBackoff",
|
|
50
|
+
message: `Block #` + fromBlock.toString() + ` not found in FuelHyperSync. HyperFuel has multiple instances and it's possible that they drift independently slightly from the head. Indexing should continue correctly after retrying the query in ` + backoffMillis.toString() + `ms.`,
|
|
51
|
+
backoffMillis: backoffMillis
|
|
52
|
+
};
|
|
53
|
+
} else {
|
|
54
|
+
tmp = {
|
|
55
|
+
TAG: "ImpossibleForTheQuery",
|
|
56
|
+
message: `Source returned invalid data with missing required fields: ` + error$1.missingParams.join(", ")
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
throw {
|
|
60
|
+
RE_EXN_ID: Source.GetItemsError,
|
|
61
|
+
_1: {
|
|
62
|
+
TAG: "FailedGettingItems",
|
|
63
|
+
exn: null,
|
|
64
|
+
attemptedToBlock: Stdlib_Option.getOr(toBlock, knownHeight),
|
|
65
|
+
retry: tmp
|
|
66
|
+
},
|
|
67
|
+
Error: new Error()
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
throw {
|
|
71
|
+
RE_EXN_ID: Source.GetItemsError,
|
|
72
|
+
_1: {
|
|
73
|
+
TAG: "FailedGettingItems",
|
|
74
|
+
exn: error,
|
|
75
|
+
attemptedToBlock: Stdlib_Option.getOr(toBlock, knownHeight),
|
|
76
|
+
retry: {
|
|
77
|
+
TAG: "WithBackoff",
|
|
78
|
+
message: `Unexpected issue while fetching events from HyperFuel client. Attempt a retry.`,
|
|
79
|
+
backoffMillis: retry !== 0 ? 1000 * retry | 0 : 500
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
Error: new Error()
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
let pageFetchTime = Performance.secondsSince(startFetchingBatchTimeRef);
|
|
86
|
+
let requestStats = [{
|
|
87
|
+
method: "getLogs",
|
|
88
|
+
seconds: pageFetchTime
|
|
89
|
+
}];
|
|
90
|
+
let knownHeight$1 = pageUnsafe.archiveHeight;
|
|
91
|
+
let heighestBlockQueried = pageUnsafe.nextBlock - 1 | 0;
|
|
92
|
+
let parsingTimeRef = Performance.now();
|
|
93
|
+
let blocksByHeight = new Map();
|
|
94
|
+
pageUnsafe.blocks.forEach(block => {
|
|
95
|
+
blocksByHeight.set(block.height, block);
|
|
96
|
+
});
|
|
97
|
+
let parsedQueueItems = pageUnsafe.items.map(item => {
|
|
98
|
+
let onEventRegistration = onEventRegistrations[item.onEventRegistrationIndex];
|
|
99
|
+
let eventConfig = onEventRegistration.eventConfig;
|
|
100
|
+
let block = blocksByHeight.get(item.blockHeight);
|
|
101
|
+
let match = eventConfig.kind;
|
|
102
|
+
let params;
|
|
103
|
+
let exit = 0;
|
|
104
|
+
if (typeof match !== "object") {
|
|
105
|
+
switch (match) {
|
|
106
|
+
case "Mint" :
|
|
107
|
+
case "Burn" :
|
|
108
|
+
exit = 1;
|
|
109
|
+
break;
|
|
110
|
+
case "Transfer" :
|
|
111
|
+
case "Call" :
|
|
112
|
+
exit = 2;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
116
|
+
let data = Stdlib_Option.getOr(item.data, "");
|
|
117
|
+
try {
|
|
118
|
+
params = match.decode(data);
|
|
119
|
+
} catch (raw_exn) {
|
|
120
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
121
|
+
let params$1 = {
|
|
122
|
+
chainId: chain,
|
|
123
|
+
blockNumber: item.blockHeight,
|
|
124
|
+
logIndex: item.receiptIndex
|
|
125
|
+
};
|
|
126
|
+
let logger$1 = Logging.createChildFrom(logger, params$1);
|
|
127
|
+
params = ErrorHandling.mkLogAndRaise(logger$1, "Failed to decode Fuel LogData receipt, please double check your ABI.", exn);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
switch (exit) {
|
|
131
|
+
case 1 :
|
|
132
|
+
params = {
|
|
133
|
+
subId: Stdlib_Option.getOr(item.subId, ""),
|
|
134
|
+
amount: Stdlib_Option.getOr(item.val, 0n)
|
|
135
|
+
};
|
|
136
|
+
break;
|
|
137
|
+
case 2 :
|
|
138
|
+
params = {
|
|
139
|
+
to: Stdlib_Option.getOr(item.to, ""),
|
|
140
|
+
assetId: Stdlib_Option.getOr(item.assetId, ""),
|
|
141
|
+
amount: Stdlib_Option.getOr(item.amount, 0n)
|
|
142
|
+
};
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
kind: 0,
|
|
147
|
+
onEventRegistration: onEventRegistration,
|
|
148
|
+
chain: chain,
|
|
149
|
+
blockNumber: item.blockHeight,
|
|
150
|
+
logIndex: item.receiptIndex,
|
|
151
|
+
transactionIndex: 0,
|
|
152
|
+
payload: {
|
|
153
|
+
contractName: eventConfig.contractName,
|
|
154
|
+
eventName: eventConfig.name,
|
|
155
|
+
params: params,
|
|
156
|
+
chainId: chain,
|
|
157
|
+
srcAddress: item.srcAddress,
|
|
158
|
+
logIndex: item.receiptIndex,
|
|
159
|
+
transaction: {
|
|
160
|
+
id: item.txId
|
|
161
|
+
},
|
|
162
|
+
block: block
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
let parsingTimeElapsed = Performance.secondsSince(parsingTimeRef);
|
|
167
|
+
let blockHashes = pageUnsafe.blocks.map(block => ({
|
|
168
|
+
blockHash: block.id,
|
|
169
|
+
blockNumber: block.height
|
|
170
|
+
}));
|
|
171
|
+
let block = blocksByHeight.get(heighestBlockQueried);
|
|
172
|
+
let latestFetchedBlockTimestamp = block !== undefined ? block.time : 0;
|
|
173
|
+
let totalTimeElapsed = Performance.secondsSince(totalTimeRef);
|
|
174
|
+
let stats_parsing$unknowntime$unknown$lpars$rpar = parsingTimeElapsed;
|
|
175
|
+
let stats_page$unknownfetch$unknowntime$unknown$lpars$rpar = pageFetchTime;
|
|
176
|
+
let stats = {
|
|
177
|
+
"total time elapsed (s)": totalTimeElapsed,
|
|
178
|
+
"parsing time (s)": stats_parsing$unknowntime$unknown$lpars$rpar,
|
|
179
|
+
"page fetch time (s)": stats_page$unknownfetch$unknowntime$unknown$lpars$rpar
|
|
180
|
+
};
|
|
181
|
+
return {
|
|
182
|
+
knownHeight: knownHeight$1,
|
|
183
|
+
blockHashes: blockHashes,
|
|
184
|
+
parsedQueueItems: parsedQueueItems,
|
|
185
|
+
transactionStore: undefined,
|
|
186
|
+
blockStore: undefined,
|
|
187
|
+
fromBlockQueried: fromBlock,
|
|
188
|
+
latestFetchedBlockNumber: heighestBlockQueried,
|
|
189
|
+
latestFetchedBlockTimestamp: latestFetchedBlockTimestamp,
|
|
190
|
+
stats: stats,
|
|
191
|
+
requestStats: requestStats
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
let getBlockHashes = (param, param$1) => Stdlib_JsError.throwWithMessage("HyperFuel does not support getting block hashes");
|
|
195
|
+
return {
|
|
196
|
+
name: "HyperFuel",
|
|
197
|
+
sourceFor: "Sync",
|
|
198
|
+
chain: chain,
|
|
199
|
+
poweredByHyperSync: true,
|
|
200
|
+
pollingInterval: 100,
|
|
201
|
+
getBlockHashes: getBlockHashes,
|
|
202
|
+
getHeightOrThrow: async () => {
|
|
203
|
+
let timerRef = Performance.now();
|
|
204
|
+
let height;
|
|
205
|
+
try {
|
|
206
|
+
height = await client.getHeight();
|
|
207
|
+
} catch (raw_e) {
|
|
208
|
+
let e = Primitive_exceptions.internalToException(raw_e);
|
|
209
|
+
if (e.RE_EXN_ID === "JsExn") {
|
|
210
|
+
let e$1 = e._1;
|
|
211
|
+
let message = Stdlib_JsExn.message(e$1);
|
|
212
|
+
if (message !== undefined) {
|
|
213
|
+
if (message.includes("401 Unauthorized")) {
|
|
214
|
+
Logging.error(`Your ENVIO_API_TOKEN was rejected by HyperFuel (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`);
|
|
215
|
+
await new Promise((param, param$1) => {});
|
|
216
|
+
height = 0;
|
|
217
|
+
} else {
|
|
218
|
+
throw {
|
|
219
|
+
RE_EXN_ID: "JsExn",
|
|
220
|
+
_1: e$1,
|
|
221
|
+
Error: new Error()
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
} else {
|
|
225
|
+
throw {
|
|
226
|
+
RE_EXN_ID: "JsExn",
|
|
227
|
+
_1: e$1,
|
|
228
|
+
Error: new Error()
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
throw e;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
let seconds = Performance.secondsSince(timerRef);
|
|
236
|
+
return {
|
|
237
|
+
height: height,
|
|
238
|
+
requestStats: [{
|
|
239
|
+
method: "getHeight",
|
|
240
|
+
seconds: seconds
|
|
241
|
+
}]
|
|
242
|
+
};
|
|
243
|
+
},
|
|
244
|
+
getItemsOrThrow: getItemsOrThrow
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export {
|
|
249
|
+
isUnauthorizedError,
|
|
250
|
+
make,
|
|
251
|
+
}
|
|
252
|
+
/* Logging Not a pure module */
|
|
@@ -358,11 +358,11 @@ type t = {
|
|
|
358
358
|
}
|
|
359
359
|
|
|
360
360
|
@send
|
|
361
|
-
external classNew: (Core.
|
|
361
|
+
external classNew: (Core.evmHyperSyncClientCtor, cfg, string, array<Registration.input>) => t =
|
|
362
362
|
"new"
|
|
363
363
|
|
|
364
364
|
let makeWithAgent = (cfg, ~userAgent, ~eventRegistrations) =>
|
|
365
|
-
Core.getAddon().
|
|
365
|
+
Core.getAddon().evmHyperSyncClient->classNew(cfg, userAgent, eventRegistrations)
|
|
366
366
|
|
|
367
367
|
type logLevel = [#trace | #debug | #info | #warn | #error]
|
|
368
368
|
let logLevelSchema: S.t<logLevel> = S.enum([#trace, #debug, #info, #warn, #error])
|
|
@@ -74,7 +74,7 @@ let Registration = {
|
|
|
74
74
|
let EventItems = {};
|
|
75
75
|
|
|
76
76
|
function makeWithAgent(cfg, userAgent, eventRegistrations) {
|
|
77
|
-
return Core.getAddon().
|
|
77
|
+
return Core.getAddon().EvmHyperSyncClient.new(cfg, userAgent, eventRegistrations);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
let logLevelSchema = S$RescriptSchema.$$enum([
|