envio 3.3.0-alpha.3 → 3.3.0-alpha.5
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/evm.schema.json +10 -0
- package/package.json +7 -7
- package/src/Batch.res.mjs +1 -1
- package/src/Bin.res +3 -0
- package/src/Bin.res.mjs +4 -0
- package/src/ChainFetching.res +1 -3
- package/src/ChainFetching.res.mjs +3 -3
- package/src/ChainState.res +44 -19
- package/src/ChainState.res.mjs +25 -23
- package/src/ChainState.resi +3 -3
- package/src/Config.res +3 -0
- package/src/Config.res.mjs +3 -1
- package/src/Core.res +0 -3
- package/src/Ecosystem.res +0 -4
- package/src/EventConfigBuilder.res +3 -0
- package/src/EventConfigBuilder.res.mjs +7 -1
- package/src/FetchState.res +73 -160
- package/src/FetchState.res.mjs +120 -222
- package/src/IndexingAddresses.res +105 -0
- package/src/IndexingAddresses.res.mjs +100 -0
- package/src/IndexingAddresses.resi +32 -0
- package/src/Internal.res +5 -0
- package/src/Main.res +21 -24
- package/src/Main.res.mjs +21 -20
- package/src/Metrics.res +33 -0
- package/src/Metrics.res.mjs +39 -0
- package/src/Prometheus.res +2 -20
- package/src/Prometheus.res.mjs +83 -95
- package/src/SimulateItems.res +4 -0
- package/src/TestIndexer.res +43 -17
- package/src/TestIndexer.res.mjs +16 -9
- package/src/bindings/Viem.res +0 -41
- package/src/bindings/Viem.res.mjs +1 -43
- package/src/sources/Evm.res +17 -39
- package/src/sources/Evm.res.mjs +8 -40
- package/src/sources/EvmChain.res +3 -1
- package/src/sources/EvmChain.res.mjs +2 -1
- package/src/sources/EvmRpcClient.res +36 -5
- package/src/sources/EvmRpcClient.res.mjs +7 -4
- package/src/sources/Fuel.res +0 -2
- package/src/sources/Fuel.res.mjs +0 -1
- package/src/sources/HyperSyncClient.res +0 -35
- package/src/sources/HyperSyncClient.res.mjs +1 -8
- package/src/sources/Rpc.res +15 -47
- package/src/sources/Rpc.res.mjs +25 -56
- package/src/sources/RpcSource.res +30 -73
- package/src/sources/RpcSource.res.mjs +24 -73
- package/src/sources/SourceManager.res +1 -1
- package/src/sources/SourceManager.res.mjs +1 -1
- package/src/sources/Svm.res +10 -17
- package/src/sources/Svm.res.mjs +6 -18
- package/src/sources/TransactionStore.res +98 -76
- package/src/sources/TransactionStore.res.mjs +49 -35
package/src/sources/Evm.res
CHANGED
|
@@ -15,44 +15,17 @@ type payload = {
|
|
|
15
15
|
external fromPayload: payload => Internal.eventPayload = "%identity"
|
|
16
16
|
external toPayload: Internal.eventPayload => payload = "%identity"
|
|
17
17
|
|
|
18
|
-
// Ordered transaction field names
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"gas",
|
|
26
|
-
"gasPrice",
|
|
27
|
-
"maxPriorityFeePerGas",
|
|
28
|
-
"maxFeePerGas",
|
|
29
|
-
"cumulativeGasUsed",
|
|
30
|
-
"effectiveGasPrice",
|
|
31
|
-
"gasUsed",
|
|
32
|
-
"input",
|
|
33
|
-
"nonce",
|
|
34
|
-
"value",
|
|
35
|
-
"v",
|
|
36
|
-
"r",
|
|
37
|
-
"s",
|
|
38
|
-
"contractAddress",
|
|
39
|
-
"logsBloom",
|
|
40
|
-
"root",
|
|
41
|
-
"status",
|
|
42
|
-
"yParity",
|
|
43
|
-
"maxFeePerBlobGas",
|
|
44
|
-
"blobVersionedHashes",
|
|
45
|
-
"type",
|
|
46
|
-
"l1Fee",
|
|
47
|
-
"l1GasPrice",
|
|
48
|
-
"l1GasUsed",
|
|
49
|
-
"l1FeeScalar",
|
|
50
|
-
"gasUsedForL1",
|
|
51
|
-
"accessList",
|
|
52
|
-
"authorizationList",
|
|
53
|
-
]
|
|
18
|
+
// Ordered transaction field names, the field codes shared with the Rust store
|
|
19
|
+
// (`EvmTxField`). Derived from the typed field list so the two can't drift;
|
|
20
|
+
// `Internal.allEvmTransactionFields` is pinned to the Rust ordinal order by a test.
|
|
21
|
+
let transactionFields =
|
|
22
|
+
Internal.allEvmTransactionFields->(
|
|
23
|
+
Utils.magic: array<Internal.evmTransactionField> => array<string>
|
|
24
|
+
)
|
|
54
25
|
|
|
55
|
-
|
|
26
|
+
// One event's selected transaction fields → store selection bitmask. Computed
|
|
27
|
+
// per event at config build and cached on the event config.
|
|
28
|
+
let eventTransactionFieldMask = TransactionStore.makeMaskFn(transactionFields)
|
|
56
29
|
|
|
57
30
|
let cleanUpRawEventFieldsInPlace: JSON.t => unit = %raw(`fields => {
|
|
58
31
|
delete fields.hash
|
|
@@ -83,7 +56,6 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
83
56
|
s.field("block", S.option(S.object(s2 => s2.field("number", S.unknown))))
|
|
84
57
|
),
|
|
85
58
|
logger,
|
|
86
|
-
transactionFieldMask,
|
|
87
59
|
// The payload carries `transaction` by batch prep (HyperSync) or inline
|
|
88
60
|
// (RPC/simulate), so the event is the payload as-is.
|
|
89
61
|
toEvent: eventItem => eventItem.payload->(Utils.magic: Internal.eventPayload => Internal.event),
|
|
@@ -101,10 +73,16 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
101
73
|
),
|
|
102
74
|
toRawEvent: eventItem => {
|
|
103
75
|
let payload = eventItem.payload->toPayload
|
|
76
|
+
let eventConfig =
|
|
77
|
+
eventItem.eventConfig->(Utils.magic: Internal.eventConfig => Internal.evmEventConfig)
|
|
104
78
|
eventItem->RawEvent.make(
|
|
105
79
|
~block=payload.block,
|
|
106
80
|
~transaction=payload.transaction,
|
|
107
|
-
|
|
81
|
+
// The decoder emits `{}` for zero-parameter events, which the params
|
|
82
|
+
// schema rejects; pass unit so it serializes to the "null" sentinel.
|
|
83
|
+
~params=eventConfig.paramsMetadata->Array.length == 0
|
|
84
|
+
? ()->(Utils.magic: unit => Internal.eventParams)
|
|
85
|
+
: payload.params,
|
|
108
86
|
~srcAddress=payload.srcAddress,
|
|
109
87
|
~cleanUpRawEventFieldsInPlace,
|
|
110
88
|
)
|
package/src/sources/Evm.res.mjs
CHANGED
|
@@ -1,46 +1,12 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Logging from "../Logging.res.mjs";
|
|
4
|
+
import * as Internal from "../Internal.res.mjs";
|
|
4
5
|
import * as RawEvent from "../RawEvent.res.mjs";
|
|
5
6
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
6
7
|
import * as TransactionStore from "./TransactionStore.res.mjs";
|
|
7
8
|
|
|
8
|
-
let
|
|
9
|
-
"transactionIndex",
|
|
10
|
-
"hash",
|
|
11
|
-
"from",
|
|
12
|
-
"to",
|
|
13
|
-
"gas",
|
|
14
|
-
"gasPrice",
|
|
15
|
-
"maxPriorityFeePerGas",
|
|
16
|
-
"maxFeePerGas",
|
|
17
|
-
"cumulativeGasUsed",
|
|
18
|
-
"effectiveGasPrice",
|
|
19
|
-
"gasUsed",
|
|
20
|
-
"input",
|
|
21
|
-
"nonce",
|
|
22
|
-
"value",
|
|
23
|
-
"v",
|
|
24
|
-
"r",
|
|
25
|
-
"s",
|
|
26
|
-
"contractAddress",
|
|
27
|
-
"logsBloom",
|
|
28
|
-
"root",
|
|
29
|
-
"status",
|
|
30
|
-
"yParity",
|
|
31
|
-
"maxFeePerBlobGas",
|
|
32
|
-
"blobVersionedHashes",
|
|
33
|
-
"type",
|
|
34
|
-
"l1Fee",
|
|
35
|
-
"l1GasPrice",
|
|
36
|
-
"l1GasUsed",
|
|
37
|
-
"l1FeeScalar",
|
|
38
|
-
"gasUsedForL1",
|
|
39
|
-
"accessList",
|
|
40
|
-
"authorizationList"
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
let transactionFieldMask = TransactionStore.makeMaskFn(transactionFields);
|
|
9
|
+
let eventTransactionFieldMask = TransactionStore.makeMaskFn(Internal.allEvmTransactionFields);
|
|
44
10
|
|
|
45
11
|
let cleanUpRawEventFieldsInPlace = (fields => {
|
|
46
12
|
delete fields.hash
|
|
@@ -60,7 +26,6 @@ function make(logger) {
|
|
|
60
26
|
onEventBlockFilterSchema: S$RescriptSchema.object(s => s.f("block", S$RescriptSchema.option(S$RescriptSchema.object(s2 => s2.f("number", S$RescriptSchema.unknown))))),
|
|
61
27
|
logger: logger,
|
|
62
28
|
toEvent: eventItem => eventItem.payload,
|
|
63
|
-
transactionFieldMask: transactionFieldMask,
|
|
64
29
|
toEventLogger: eventItem => Logging.createChildFrom(logger, {
|
|
65
30
|
contract: eventItem.eventConfig.contractName,
|
|
66
31
|
event: eventItem.eventConfig.name,
|
|
@@ -71,15 +36,18 @@ function make(logger) {
|
|
|
71
36
|
}),
|
|
72
37
|
toRawEvent: eventItem => {
|
|
73
38
|
let payload = eventItem.payload;
|
|
74
|
-
|
|
39
|
+
let eventConfig = eventItem.eventConfig;
|
|
40
|
+
return RawEvent.make(eventItem, payload.block, payload.transaction, eventConfig.paramsMetadata.length === 0 ? undefined : payload.params, payload.srcAddress, cleanUpRawEventFieldsInPlace);
|
|
75
41
|
}
|
|
76
42
|
};
|
|
77
43
|
}
|
|
78
44
|
|
|
45
|
+
let transactionFields = Internal.allEvmTransactionFields;
|
|
46
|
+
|
|
79
47
|
export {
|
|
80
48
|
transactionFields,
|
|
81
|
-
|
|
49
|
+
eventTransactionFieldMask,
|
|
82
50
|
cleanUpRawEventFieldsInPlace,
|
|
83
51
|
make,
|
|
84
52
|
}
|
|
85
|
-
/*
|
|
53
|
+
/* eventTransactionFieldMask Not a pure module */
|
package/src/sources/EvmChain.res
CHANGED
|
@@ -3,6 +3,7 @@ type rpc = {
|
|
|
3
3
|
sourceFor: Source.sourceFor,
|
|
4
4
|
syncConfig?: Config.sourceSyncOptions,
|
|
5
5
|
ws?: string,
|
|
6
|
+
headers?: dict<string>,
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
let getSyncConfig = (
|
|
@@ -89,7 +90,7 @@ let makeSources = (
|
|
|
89
90
|
]
|
|
90
91
|
| _ => []
|
|
91
92
|
}
|
|
92
|
-
rpcs->Array.forEach(({?syncConfig, url, sourceFor, ?ws}) => {
|
|
93
|
+
rpcs->Array.forEach(({?syncConfig, url, sourceFor, ?ws, ?headers}) => {
|
|
93
94
|
let source = RpcSource.make({
|
|
94
95
|
chain,
|
|
95
96
|
sourceFor,
|
|
@@ -99,6 +100,7 @@ let makeSources = (
|
|
|
99
100
|
allEventParams,
|
|
100
101
|
lowercaseAddresses,
|
|
101
102
|
?ws,
|
|
103
|
+
?headers,
|
|
102
104
|
})
|
|
103
105
|
let _ = sources->Array.push(source)
|
|
104
106
|
})
|
|
@@ -60,7 +60,8 @@ function makeSources(chain, contracts, hyperSync, rpcs, lowercaseAddresses) {
|
|
|
60
60
|
eventRouter: eventRouter,
|
|
61
61
|
allEventParams: allEventParams,
|
|
62
62
|
lowercaseAddresses: lowercaseAddresses,
|
|
63
|
-
ws: param.ws
|
|
63
|
+
ws: param.ws,
|
|
64
|
+
headers: param.headers
|
|
64
65
|
});
|
|
65
66
|
sources.push(source);
|
|
66
67
|
});
|
|
@@ -1,9 +1,34 @@
|
|
|
1
|
-
type cfg = {url: string, httpReqTimeoutMillis?: int}
|
|
1
|
+
type cfg = {url: string, httpReqTimeoutMillis?: int, headers?: dict<string>}
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// `addresses` omitted matches any address (a wildcard selection). Each `topics`
|
|
4
|
+
// position is `null` (match any) or a list of accepted topic hashes; the
|
|
5
|
+
// single-match case is a one-element list.
|
|
6
|
+
type getLogsParams = {
|
|
7
|
+
fromBlock: int,
|
|
8
|
+
toBlock: int,
|
|
9
|
+
addresses?: array<Address.t>,
|
|
10
|
+
topics: array<Nullable.t<array<string>>>,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Decoded `params` keyed by contract name, matching the HyperSync decoder's
|
|
14
|
+
// shape so the caller routes by address then picks its contract's params.
|
|
15
|
+
type rpcEventItem = {
|
|
16
|
+
log: Rpc.GetLogs.log,
|
|
17
|
+
params: Nullable.t<dict<Internal.eventParams>>,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type t = {
|
|
21
|
+
getHeight: unit => promise<int>,
|
|
22
|
+
getLogs: getLogsParams => promise<array<rpcEventItem>>,
|
|
23
|
+
}
|
|
4
24
|
|
|
5
25
|
@send
|
|
6
|
-
external classNew: (
|
|
26
|
+
external classNew: (
|
|
27
|
+
Core.evmRpcClientCtor,
|
|
28
|
+
cfg,
|
|
29
|
+
array<HyperSyncClient.Decoder.eventParamsInput>,
|
|
30
|
+
~checksumAddresses: bool,
|
|
31
|
+
) => t = "new"
|
|
7
32
|
|
|
8
33
|
// Rust encodes JSON-RPC errors as a JSON payload in the napi error's
|
|
9
34
|
// message: `{"kind":"JsonRpcError","code":-32005,"message":"..."}`.
|
|
@@ -34,9 +59,15 @@ let coerceErrorOrThrow = exn =>
|
|
|
34
59
|
| None => exn->throw
|
|
35
60
|
}
|
|
36
61
|
|
|
37
|
-
let make = (~url, ~httpReqTimeoutMillis
|
|
38
|
-
let client =
|
|
62
|
+
let make = (~url, ~checksumAddresses, ~httpReqTimeoutMillis=?, ~headers=?, ~allEventParams=[]) => {
|
|
63
|
+
let client =
|
|
64
|
+
Core.getAddon().evmRpcClient->classNew(
|
|
65
|
+
{url, ?httpReqTimeoutMillis, ?headers},
|
|
66
|
+
allEventParams,
|
|
67
|
+
~checksumAddresses,
|
|
68
|
+
)
|
|
39
69
|
{
|
|
40
70
|
getHeight: () => client.getHeight()->Promise.catch(coerceErrorOrThrow),
|
|
71
|
+
getLogs: params => client.getLogs(params)->Promise.catch(coerceErrorOrThrow),
|
|
41
72
|
}
|
|
42
73
|
}
|
|
@@ -46,13 +46,16 @@ function coerceErrorOrThrow(exn) {
|
|
|
46
46
|
throw exn;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function make(url, httpReqTimeoutMillis) {
|
|
49
|
+
function make(url, checksumAddresses, httpReqTimeoutMillis, headers, allEventParamsOpt) {
|
|
50
|
+
let allEventParams = allEventParamsOpt !== undefined ? allEventParamsOpt : [];
|
|
50
51
|
let client = Core.getAddon().EvmRpcClient.new({
|
|
51
52
|
url: url,
|
|
52
|
-
httpReqTimeoutMillis: httpReqTimeoutMillis
|
|
53
|
-
|
|
53
|
+
httpReqTimeoutMillis: httpReqTimeoutMillis,
|
|
54
|
+
headers: headers
|
|
55
|
+
}, allEventParams, checksumAddresses);
|
|
54
56
|
return {
|
|
55
|
-
getHeight: () => Stdlib_Promise.$$catch(client.getHeight(), coerceErrorOrThrow)
|
|
57
|
+
getHeight: () => Stdlib_Promise.$$catch(client.getHeight(), coerceErrorOrThrow),
|
|
58
|
+
getLogs: params => Stdlib_Promise.$$catch(client.getLogs(params), coerceErrorOrThrow)
|
|
56
59
|
};
|
|
57
60
|
}
|
|
58
61
|
|
package/src/sources/Fuel.res
CHANGED
|
@@ -39,8 +39,6 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
39
39
|
s.field("block", S.option(S.object(s2 => s2.field("height", S.unknown))))
|
|
40
40
|
),
|
|
41
41
|
logger,
|
|
42
|
-
// Fuel carries the transaction inline on the payload.
|
|
43
|
-
transactionFieldMask: _ => 0.,
|
|
44
42
|
toEvent: eventItem => eventItem.payload->(Utils.magic: Internal.eventPayload => Internal.event),
|
|
45
43
|
toEventLogger: eventItem =>
|
|
46
44
|
Logging.createChildFrom(
|
package/src/sources/Fuel.res.mjs
CHANGED
|
@@ -22,7 +22,6 @@ function make(logger) {
|
|
|
22
22
|
onEventBlockFilterSchema: S$RescriptSchema.object(s => s.f("block", S$RescriptSchema.option(S$RescriptSchema.object(s2 => s2.f("height", S$RescriptSchema.unknown))))),
|
|
23
23
|
logger: logger,
|
|
24
24
|
toEvent: eventItem => eventItem.payload,
|
|
25
|
-
transactionFieldMask: param => 0,
|
|
26
25
|
toEventLogger: eventItem => Logging.createChildFrom(logger, {
|
|
27
26
|
contract: eventItem.eventConfig.contractName,
|
|
28
27
|
event: eventItem.eventConfig.name,
|
|
@@ -208,22 +208,6 @@ module ResponseTypes = {
|
|
|
208
208
|
mixHash?: string,
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
type log = {
|
|
212
|
-
removed?: bool,
|
|
213
|
-
@as("logIndex") index?: int,
|
|
214
|
-
transactionIndex?: int,
|
|
215
|
-
transactionHash?: string,
|
|
216
|
-
blockHash?: string,
|
|
217
|
-
blockNumber?: int,
|
|
218
|
-
address?: Address.t,
|
|
219
|
-
data?: string,
|
|
220
|
-
topics?: array<Nullable.t<EvmTypes.Hex.t>>,
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Only the log is needed for decoding; the transaction/block are served from
|
|
224
|
-
// the store (event items) or unused (block-hash query).
|
|
225
|
-
type event = {log: log}
|
|
226
|
-
|
|
227
211
|
type rollbackGuard = {
|
|
228
212
|
blockNumber: int,
|
|
229
213
|
timestamp: int,
|
|
@@ -253,25 +237,6 @@ module Decoder = {
|
|
|
253
237
|
contractName: string,
|
|
254
238
|
params: array<Internal.paramMeta>,
|
|
255
239
|
}
|
|
256
|
-
|
|
257
|
-
// Decoded params keyed by contract name. Contracts that emit the same-signature
|
|
258
|
-
// event share one decode but get their own param names, so the caller picks the
|
|
259
|
-
// entry for the contract its router resolved the log to.
|
|
260
|
-
type tWithParams = {
|
|
261
|
-
decodeLogs: array<ResponseTypes.event> => promise<
|
|
262
|
-
array<Nullable.t<dict<Internal.eventParams>>>,
|
|
263
|
-
>,
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
@send
|
|
267
|
-
external classFromParams: (
|
|
268
|
-
Core.evmDecoderCtor,
|
|
269
|
-
array<eventParamsInput>,
|
|
270
|
-
~checksumAddresses: bool=?,
|
|
271
|
-
) => tWithParams = "fromParams"
|
|
272
|
-
|
|
273
|
-
let fromParams = (eventParams, ~checksumAddresses=?) =>
|
|
274
|
-
Core.getAddon().evmDecoder->classFromParams(eventParams, ~checksumAddresses?)
|
|
275
240
|
}
|
|
276
241
|
|
|
277
242
|
module EventItems = {
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Core from "../Core.res.mjs";
|
|
4
4
|
import * as Utils from "../Utils.res.mjs";
|
|
5
|
-
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
6
5
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
7
6
|
|
|
8
7
|
let serializationFormatSchema = S$RescriptSchema.$$enum([
|
|
@@ -37,13 +36,7 @@ let QueryTypes = {
|
|
|
37
36
|
|
|
38
37
|
let ResponseTypes = {};
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
return Core.getAddon().EvmDecoder.fromParams(eventParams, checksumAddresses !== undefined ? Primitive_option.valFromOption(checksumAddresses) : undefined);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
let Decoder = {
|
|
45
|
-
fromParams: fromParams
|
|
46
|
-
};
|
|
39
|
+
let Decoder = {};
|
|
47
40
|
|
|
48
41
|
let EventItems = {};
|
|
49
42
|
|
package/src/sources/Rpc.res
CHANGED
|
@@ -38,7 +38,21 @@ let jsonRpcFetcher: Rest.ApiFetcher.t = async args => {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
let makeClient =
|
|
41
|
+
let makeClient = (url, ~headers=?) => {
|
|
42
|
+
let fetcher: Rest.ApiFetcher.t = switch headers {
|
|
43
|
+
| None => jsonRpcFetcher
|
|
44
|
+
| Some(customHeaders) =>
|
|
45
|
+
async args => {
|
|
46
|
+
let headers = switch args.headers {
|
|
47
|
+
| Some(headers) => headers
|
|
48
|
+
| None => Dict.make()
|
|
49
|
+
}
|
|
50
|
+
customHeaders->Dict.forEachWithKey((value, key) => headers->Dict.set(key, value->Obj.magic))
|
|
51
|
+
await jsonRpcFetcher({...args, headers: Some(headers)})
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
Rest.client(url, ~fetcher)
|
|
55
|
+
}
|
|
42
56
|
|
|
43
57
|
type hex = string
|
|
44
58
|
let makeHexSchema = fromStr =>
|
|
@@ -70,13 +84,7 @@ let decimalFloatSchema: S.schema<float> = S.string->S.transform(s => {
|
|
|
70
84
|
module GetLogs = {
|
|
71
85
|
@unboxed
|
|
72
86
|
type topicFilter = Single(hex) | Multiple(array<hex>) | @as(null) Null
|
|
73
|
-
let topicFilterSchema = S.union([
|
|
74
|
-
S.literal(Null),
|
|
75
|
-
S.schema(s => Multiple(s.matches(S.array(S.string)))),
|
|
76
|
-
S.schema(s => Single(s.matches(S.string))),
|
|
77
|
-
])
|
|
78
87
|
type topicQuery = array<topicFilter>
|
|
79
|
-
let topicQuerySchema = S.array(topicFilterSchema)
|
|
80
88
|
|
|
81
89
|
let makeTopicQuery = (~topic0=[], ~topic1=[], ~topic2=[], ~topic3=[]) => {
|
|
82
90
|
let topics = [topic0, topic1, topic2, topic3]
|
|
@@ -106,51 +114,15 @@ module GetLogs = {
|
|
|
106
114
|
let mapTopicQuery = ({topic0, topic1, topic2, topic3}: Internal.topicSelection): topicQuery =>
|
|
107
115
|
makeTopicQuery(~topic0, ~topic1, ~topic2, ~topic3)
|
|
108
116
|
|
|
109
|
-
type param = {
|
|
110
|
-
fromBlock: int,
|
|
111
|
-
toBlock: int,
|
|
112
|
-
address?: array<Address.t>,
|
|
113
|
-
topics: topicQuery,
|
|
114
|
-
// blockHash?: string,
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
let paramsSchema = S.object((s): param => {
|
|
118
|
-
fromBlock: s.field("fromBlock", hexIntSchema),
|
|
119
|
-
toBlock: s.field("toBlock", hexIntSchema),
|
|
120
|
-
address: ?s.field("address", S.option(S.array(Address.schema))),
|
|
121
|
-
topics: s.field("topics", topicQuerySchema),
|
|
122
|
-
// blockHash: ?s.field("blockHash", S.option(S.string)),
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
let fullParamsSchema = S.tuple1(paramsSchema)
|
|
126
|
-
|
|
127
117
|
type log = {
|
|
128
118
|
address: Address.t,
|
|
129
119
|
topics: array<hex>,
|
|
130
|
-
data: hex,
|
|
131
120
|
blockNumber: int,
|
|
132
121
|
transactionHash: hex,
|
|
133
122
|
transactionIndex: int,
|
|
134
123
|
blockHash: hex,
|
|
135
124
|
logIndex: int,
|
|
136
|
-
removed: bool,
|
|
137
125
|
}
|
|
138
|
-
|
|
139
|
-
let logSchema = S.object((s): log => {
|
|
140
|
-
address: s.field("address", Address.schema),
|
|
141
|
-
topics: s.field("topics", S.array(S.string)),
|
|
142
|
-
data: s.field("data", S.string),
|
|
143
|
-
blockNumber: s.field("blockNumber", hexIntSchema),
|
|
144
|
-
transactionHash: s.field("transactionHash", S.string),
|
|
145
|
-
transactionIndex: s.field("transactionIndex", hexIntSchema),
|
|
146
|
-
blockHash: s.field("blockHash", S.string),
|
|
147
|
-
logIndex: s.field("logIndex", hexIntSchema),
|
|
148
|
-
removed: s.field("removed", S.bool),
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
let resultSchema = S.array(logSchema)
|
|
152
|
-
|
|
153
|
-
let route = makeRpcRoute("eth_getLogs", fullParamsSchema, resultSchema)
|
|
154
126
|
}
|
|
155
127
|
|
|
156
128
|
module GetBlockByNumber = {
|
|
@@ -230,10 +202,6 @@ module GetTransactionReceipt = {
|
|
|
230
202
|
)
|
|
231
203
|
}
|
|
232
204
|
|
|
233
|
-
let getLogs = async (~client: Rest.client, ~param: GetLogs.param) => {
|
|
234
|
-
await GetLogs.route->Rest.fetch(param, ~client)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
205
|
let getBlock = async (~client: Rest.client, ~blockNumber: int) => {
|
|
238
206
|
await GetBlockByNumber.route->Rest.fetch(
|
|
239
207
|
{"blockNumber": blockNumber, "includeTransactions": false},
|
package/src/sources/Rpc.res.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import * as Rest from "../vendored/Rest.res.mjs";
|
|
|
4
4
|
import * as Viem from "viem";
|
|
5
5
|
import * as Utils from "../Utils.res.mjs";
|
|
6
6
|
import * as Address from "../Address.res.mjs";
|
|
7
|
+
import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
|
|
7
8
|
import * as Stdlib_BigInt from "@rescript/runtime/lib/es6/Stdlib_BigInt.js";
|
|
8
9
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
9
10
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
@@ -48,8 +49,21 @@ async function jsonRpcFetcher(args) {
|
|
|
48
49
|
return response;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
function makeClient(url) {
|
|
52
|
-
|
|
52
|
+
function makeClient(url, headers) {
|
|
53
|
+
let fetcher = headers !== undefined ? async args => {
|
|
54
|
+
let headers$1 = args.headers;
|
|
55
|
+
let headers$2 = headers$1 !== undefined ? headers$1 : ({});
|
|
56
|
+
Stdlib_Dict.forEachWithKey(headers, (value, key) => {
|
|
57
|
+
headers$2[key] = value;
|
|
58
|
+
});
|
|
59
|
+
return await jsonRpcFetcher({
|
|
60
|
+
body: args.body,
|
|
61
|
+
headers: headers$2,
|
|
62
|
+
method: args.method,
|
|
63
|
+
path: args.path
|
|
64
|
+
});
|
|
65
|
+
} : jsonRpcFetcher;
|
|
66
|
+
return Rest.client(url, fetcher);
|
|
53
67
|
}
|
|
54
68
|
|
|
55
69
|
function makeHexSchema(fromStr) {
|
|
@@ -81,14 +95,6 @@ let decimalFloatSchema = S$RescriptSchema.transform(S$RescriptSchema.string, s =
|
|
|
81
95
|
}
|
|
82
96
|
}));
|
|
83
97
|
|
|
84
|
-
let topicFilterSchema = S$RescriptSchema.union([
|
|
85
|
-
S$RescriptSchema.literal(null),
|
|
86
|
-
S$RescriptSchema.schema(s => (s.m(S$RescriptSchema.array(S$RescriptSchema.string)))),
|
|
87
|
-
S$RescriptSchema.schema(s => (s.m(S$RescriptSchema.string)))
|
|
88
|
-
]);
|
|
89
|
-
|
|
90
|
-
let topicQuerySchema = S$RescriptSchema.array(topicFilterSchema);
|
|
91
|
-
|
|
92
98
|
function makeTopicQuery(topic0Opt, topic1Opt, topic2Opt, topic3Opt) {
|
|
93
99
|
let topic0 = topic0Opt !== undefined ? topic0Opt : [];
|
|
94
100
|
let topic1 = topic1Opt !== undefined ? topic1Opt : [];
|
|
@@ -130,41 +136,9 @@ function mapTopicQuery(param) {
|
|
|
130
136
|
return makeTopicQuery(param.topic0, param.topic1, param.topic2, param.topic3);
|
|
131
137
|
}
|
|
132
138
|
|
|
133
|
-
let paramsSchema = S$RescriptSchema.object(s => ({
|
|
134
|
-
fromBlock: s.f("fromBlock", hexIntSchema),
|
|
135
|
-
toBlock: s.f("toBlock", hexIntSchema),
|
|
136
|
-
address: s.f("address", S$RescriptSchema.option(S$RescriptSchema.array(Address.schema))),
|
|
137
|
-
topics: s.f("topics", topicQuerySchema)
|
|
138
|
-
}));
|
|
139
|
-
|
|
140
|
-
let fullParamsSchema = S$RescriptSchema.tuple1(paramsSchema);
|
|
141
|
-
|
|
142
|
-
let logSchema = S$RescriptSchema.object(s => ({
|
|
143
|
-
address: s.f("address", Address.schema),
|
|
144
|
-
topics: s.f("topics", S$RescriptSchema.array(S$RescriptSchema.string)),
|
|
145
|
-
data: s.f("data", S$RescriptSchema.string),
|
|
146
|
-
blockNumber: s.f("blockNumber", hexIntSchema),
|
|
147
|
-
transactionHash: s.f("transactionHash", S$RescriptSchema.string),
|
|
148
|
-
transactionIndex: s.f("transactionIndex", hexIntSchema),
|
|
149
|
-
blockHash: s.f("blockHash", S$RescriptSchema.string),
|
|
150
|
-
logIndex: s.f("logIndex", hexIntSchema),
|
|
151
|
-
removed: s.f("removed", S$RescriptSchema.bool)
|
|
152
|
-
}));
|
|
153
|
-
|
|
154
|
-
let resultSchema = S$RescriptSchema.array(logSchema);
|
|
155
|
-
|
|
156
|
-
let route = makeRpcRoute("eth_getLogs", fullParamsSchema, resultSchema);
|
|
157
|
-
|
|
158
139
|
let GetLogs = {
|
|
159
|
-
topicFilterSchema: topicFilterSchema,
|
|
160
|
-
topicQuerySchema: topicQuerySchema,
|
|
161
140
|
makeTopicQuery: makeTopicQuery,
|
|
162
|
-
mapTopicQuery: mapTopicQuery
|
|
163
|
-
paramsSchema: paramsSchema,
|
|
164
|
-
fullParamsSchema: fullParamsSchema,
|
|
165
|
-
logSchema: logSchema,
|
|
166
|
-
resultSchema: resultSchema,
|
|
167
|
-
route: route
|
|
141
|
+
mapTopicQuery: mapTopicQuery
|
|
168
142
|
};
|
|
169
143
|
|
|
170
144
|
let blockSchema = S$RescriptSchema.object(s => ({
|
|
@@ -190,22 +164,22 @@ let blockSchema = S$RescriptSchema.object(s => ({
|
|
|
190
164
|
uncles: s.f("uncles", S$RescriptSchema.$$null(S$RescriptSchema.array(S$RescriptSchema.string)))
|
|
191
165
|
}));
|
|
192
166
|
|
|
193
|
-
let paramsSchema
|
|
167
|
+
let paramsSchema = S$RescriptSchema.tuple(s => ({
|
|
194
168
|
blockNumber: s.item(0, hexIntSchema),
|
|
195
169
|
includeTransactions: s.item(1, S$RescriptSchema.bool)
|
|
196
170
|
}));
|
|
197
171
|
|
|
198
|
-
let resultSchema
|
|
172
|
+
let resultSchema = S$RescriptSchema.$$null(blockSchema);
|
|
199
173
|
|
|
200
|
-
let route
|
|
174
|
+
let route = makeRpcRoute("eth_getBlockByNumber", paramsSchema, resultSchema);
|
|
201
175
|
|
|
202
|
-
let rawRoute = makeRpcRoute("eth_getBlockByNumber", paramsSchema
|
|
176
|
+
let rawRoute = makeRpcRoute("eth_getBlockByNumber", paramsSchema, S$RescriptSchema.$$null(S$RescriptSchema.json(false)));
|
|
203
177
|
|
|
204
178
|
let GetBlockByNumber = {
|
|
205
179
|
blockSchema: blockSchema,
|
|
206
|
-
paramsSchema: paramsSchema
|
|
207
|
-
resultSchema: resultSchema
|
|
208
|
-
route: route
|
|
180
|
+
paramsSchema: paramsSchema,
|
|
181
|
+
resultSchema: resultSchema,
|
|
182
|
+
route: route,
|
|
209
183
|
rawRoute: rawRoute
|
|
210
184
|
};
|
|
211
185
|
|
|
@@ -221,12 +195,8 @@ let GetTransactionReceipt = {
|
|
|
221
195
|
rawRoute: rawRoute$2
|
|
222
196
|
};
|
|
223
197
|
|
|
224
|
-
async function getLogs(client, param) {
|
|
225
|
-
return await Rest.fetch(route, param, client);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
198
|
async function getBlock(client, blockNumber) {
|
|
229
|
-
return await Rest.fetch(route
|
|
199
|
+
return await Rest.fetch(route, {
|
|
230
200
|
blockNumber: blockNumber,
|
|
231
201
|
includeTransactions: false
|
|
232
202
|
}, client);
|
|
@@ -252,7 +222,6 @@ export {
|
|
|
252
222
|
GetBlockByNumber,
|
|
253
223
|
GetTransactionByHash,
|
|
254
224
|
GetTransactionReceipt,
|
|
255
|
-
getLogs,
|
|
256
225
|
getBlock,
|
|
257
226
|
getRawBlock,
|
|
258
227
|
}
|