envio 2.9.1 → 2.11.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/evm.schema.json +103 -92
- package/package.json +5 -5
- package/src/Internal.gen.ts +47 -0
- package/src/Internal.res +124 -0
- package/src/LazyLoader.res +134 -0
- package/src/ReorgDetection.res +432 -0
- package/src/TopicFilter.res +27 -0
- package/src/Utils.res +26 -0
- package/src/bindings/BigInt.res +15 -3
- package/src/bindings/Ethers.gen.ts +14 -0
- package/src/bindings/Ethers.res +259 -0
- package/src/bindings/SDSL.res +12 -0
- package/src/sources/HyperSyncJsonApi.res +376 -0
- /package/src/{bindings → sources}/HyperSyncClient.res +0 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
type abi = EvmTypes.Abi.t
|
|
2
|
+
|
|
3
|
+
let makeAbi = (abi: Js.Json.t): abi => abi->Utils.magic
|
|
4
|
+
|
|
5
|
+
@deprecated("Use Address.t instead. The type will be removed in v3")
|
|
6
|
+
type ethAddress = Address.t
|
|
7
|
+
@deprecated("Use Address.Evm.fromStringOrThrow instead. The function will be removed in v3")
|
|
8
|
+
let getAddressFromStringUnsafe = Address.Evm.fromStringOrThrow
|
|
9
|
+
@deprecated("Use Address.toString instead. The function will be removed in v3")
|
|
10
|
+
let ethAddressToString = Address.toString
|
|
11
|
+
@deprecated("Use Address.schema instead. The function will be removed in v3")
|
|
12
|
+
let ethAddressSchema = Address.schema
|
|
13
|
+
|
|
14
|
+
type txHash = string
|
|
15
|
+
|
|
16
|
+
module Constants = {
|
|
17
|
+
@module("ethers") @scope("ethers") external zeroHash: string = "ZeroHash"
|
|
18
|
+
@module("ethers") @scope("ethers") external zeroAddress: Address.t = "ZeroAddress"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module Addresses = {
|
|
22
|
+
@genType
|
|
23
|
+
let mockAddresses = [
|
|
24
|
+
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
|
25
|
+
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
|
|
26
|
+
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
|
|
27
|
+
"0x90F79bf6EB2c4f870365E785982E1f101E93b906",
|
|
28
|
+
"0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65",
|
|
29
|
+
"0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
|
|
30
|
+
"0x976EA74026E726554dB657fA54763abd0C3a0aa9",
|
|
31
|
+
"0x14dC79964da2C08b23698B3D3cc7Ca32193d9955",
|
|
32
|
+
"0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f",
|
|
33
|
+
"0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
|
|
34
|
+
"0xBcd4042DE499D14e55001CcbB24a551F3b954096",
|
|
35
|
+
"0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
|
|
36
|
+
"0xFABB0ac9d68B0B445fB7357272Ff202C5651694a",
|
|
37
|
+
"0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec",
|
|
38
|
+
"0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097",
|
|
39
|
+
"0xcd3B766CCDd6AE721141F452C550Ca635964ce71",
|
|
40
|
+
"0x2546BcD3c84621e976D8185a91A922aE77ECEc30",
|
|
41
|
+
"0xbDA5747bFD65F08deb54cb465eB87D40e51B197E",
|
|
42
|
+
"0xdD2FD4581271e230360230F9337D5c0430Bf44C0",
|
|
43
|
+
"0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199",
|
|
44
|
+
]->Belt.Array.map(getAddressFromStringUnsafe)
|
|
45
|
+
@genType
|
|
46
|
+
let defaultAddress =
|
|
47
|
+
mockAddresses[0]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module BlockTag = {
|
|
51
|
+
type t
|
|
52
|
+
|
|
53
|
+
type semanticTag = [#latest | #earliest | #pending]
|
|
54
|
+
type hexString = string
|
|
55
|
+
type blockNumber = int
|
|
56
|
+
|
|
57
|
+
type blockTagVariant = Latest | Earliest | Pending | HexString(string) | BlockNumber(int)
|
|
58
|
+
|
|
59
|
+
let blockTagFromSemantic = (semanticTag: semanticTag): t => semanticTag->Utils.magic
|
|
60
|
+
let blockTagFromBlockNumber = (blockNumber: blockNumber): t => blockNumber->Utils.magic
|
|
61
|
+
let blockTagFromHexString = (hexString: hexString): t => hexString->Utils.magic
|
|
62
|
+
|
|
63
|
+
let blockTagFromVariant = variant =>
|
|
64
|
+
switch variant {
|
|
65
|
+
| Latest => #latest->blockTagFromSemantic
|
|
66
|
+
| Earliest => #earliest->blockTagFromSemantic
|
|
67
|
+
| Pending => #pending->blockTagFromSemantic
|
|
68
|
+
| HexString(str) => str->blockTagFromHexString
|
|
69
|
+
| BlockNumber(num) => num->blockTagFromBlockNumber
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module EventFilter = {
|
|
74
|
+
type topic = EvmTypes.Hex.t
|
|
75
|
+
type t = {
|
|
76
|
+
address: Address.t,
|
|
77
|
+
topics: array<topic>,
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
module Filter = {
|
|
81
|
+
type t
|
|
82
|
+
|
|
83
|
+
//This can be used as a filter but should not assume all filters are the same type
|
|
84
|
+
//address could be an array of addresses like in combined filter
|
|
85
|
+
type filterRecord = {
|
|
86
|
+
address: Address.t,
|
|
87
|
+
topics: array<EventFilter.topic>,
|
|
88
|
+
fromBlock: BlockTag.t,
|
|
89
|
+
toBlock: BlockTag.t,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let filterFromRecord = (filterRecord: filterRecord): t => filterRecord->Utils.magic
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module CombinedFilter = {
|
|
96
|
+
type combinedFilterRecord = {
|
|
97
|
+
address: array<Address.t>,
|
|
98
|
+
//The second element of the tuple is the
|
|
99
|
+
topics: array<array<EventFilter.topic>>,
|
|
100
|
+
fromBlock: BlockTag.t,
|
|
101
|
+
toBlock: BlockTag.t,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let combinedFilterToFilter = (combinedFilter: combinedFilterRecord): Filter.t =>
|
|
105
|
+
combinedFilter->Utils.magic
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
type log = {
|
|
109
|
+
blockNumber: int,
|
|
110
|
+
blockHash: string,
|
|
111
|
+
removed: option<bool>,
|
|
112
|
+
//Note: this is the index of the log in the transaction and should be used whenever we use "logIndex"
|
|
113
|
+
address: Address.t,
|
|
114
|
+
data: string,
|
|
115
|
+
topics: array<EventFilter.topic>,
|
|
116
|
+
transactionHash: txHash,
|
|
117
|
+
transactionIndex: int,
|
|
118
|
+
//Note: this logIndex is the index of the log in the block, not the transaction
|
|
119
|
+
@as("index") logIndex: int,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
type transaction
|
|
123
|
+
|
|
124
|
+
type minimumParseableLogData = {topics: array<EventFilter.topic>, data: string}
|
|
125
|
+
|
|
126
|
+
//Can safely convert from log to minimumParseableLogData since it contains
|
|
127
|
+
//both data points required
|
|
128
|
+
let logToMinimumParseableLogData: log => minimumParseableLogData = Utils.magic
|
|
129
|
+
|
|
130
|
+
type logDescription<'a> = {
|
|
131
|
+
args: 'a,
|
|
132
|
+
name: string,
|
|
133
|
+
signature: string,
|
|
134
|
+
topic: string,
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module Network = {
|
|
138
|
+
type t
|
|
139
|
+
|
|
140
|
+
@module("ethers") @new
|
|
141
|
+
external make: (~name: string, ~chainId: int) => t = "Network"
|
|
142
|
+
|
|
143
|
+
@module("ethers") @scope("Network")
|
|
144
|
+
external fromChainId: (~chainId: int) => t = "from"
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
module JsonRpcProvider = {
|
|
148
|
+
type t
|
|
149
|
+
|
|
150
|
+
type rpcOptions = {
|
|
151
|
+
staticNetwork?: Network.t,
|
|
152
|
+
// Options for FallbackProvider
|
|
153
|
+
/**
|
|
154
|
+
* The amount of time to wait before kicking off the next provider.
|
|
155
|
+
*
|
|
156
|
+
* Any providers that have not responded can still respond and be
|
|
157
|
+
* counted, but this ensures new providers start.
|
|
158
|
+
* Default: 400ms
|
|
159
|
+
*/
|
|
160
|
+
stallTimeout?: int,
|
|
161
|
+
/**
|
|
162
|
+
* The priority. Lower priority providers are dispatched first.
|
|
163
|
+
* Default: 1
|
|
164
|
+
*/
|
|
165
|
+
priority?: int,
|
|
166
|
+
/**
|
|
167
|
+
* The amount of weight a provider is given against the quorum.
|
|
168
|
+
* Default: 1
|
|
169
|
+
*/
|
|
170
|
+
weight?: int,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
type fallbackProviderOptions = {
|
|
174
|
+
// How many providers must agree on a value before reporting
|
|
175
|
+
// back the response
|
|
176
|
+
// Note: Default the half of the providers weight, so we need to set it to accept result from the first rpc
|
|
177
|
+
quorum?: int,
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@module("ethers") @scope("ethers") @new
|
|
181
|
+
external makeWithOptions: (~rpcUrl: string, ~network: Network.t, ~options: rpcOptions) => t =
|
|
182
|
+
"JsonRpcProvider"
|
|
183
|
+
|
|
184
|
+
@module("ethers") @scope("ethers") @new
|
|
185
|
+
external makeFallbackProvider: (
|
|
186
|
+
~providers: array<t>,
|
|
187
|
+
~network: Network.t,
|
|
188
|
+
~options: fallbackProviderOptions,
|
|
189
|
+
) => t = "FallbackProvider"
|
|
190
|
+
|
|
191
|
+
let makeStatic = (~rpcUrl: string, ~network: Network.t, ~priority=?, ~stallTimeout=?): t => {
|
|
192
|
+
makeWithOptions(~rpcUrl, ~network, ~options={staticNetwork: network, ?priority, ?stallTimeout})
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
let make = (~rpcUrls: array<string>, ~chainId: int, ~fallbackStallTimeout): t => {
|
|
196
|
+
let network = Network.fromChainId(~chainId)
|
|
197
|
+
switch rpcUrls {
|
|
198
|
+
| [rpcUrl] => makeStatic(~rpcUrl, ~network)
|
|
199
|
+
| rpcUrls =>
|
|
200
|
+
makeFallbackProvider(
|
|
201
|
+
~providers=rpcUrls->Js.Array2.mapi((rpcUrl, index) =>
|
|
202
|
+
makeStatic(~rpcUrl, ~network, ~priority=index, ~stallTimeout=fallbackStallTimeout)
|
|
203
|
+
),
|
|
204
|
+
~network,
|
|
205
|
+
~options={
|
|
206
|
+
quorum: 1,
|
|
207
|
+
},
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
@send
|
|
213
|
+
external getLogs: (t, ~filter: Filter.t) => promise<array<log>> = "getLogs"
|
|
214
|
+
|
|
215
|
+
@send
|
|
216
|
+
external getTransaction: (t, ~transactionHash: string) => promise<transaction> = "getTransaction"
|
|
217
|
+
|
|
218
|
+
let makeGetTransactionFields = (~getTransactionByHash) => async (log: log): promise<unknown> => {
|
|
219
|
+
let transaction = await getTransactionByHash(log.transactionHash)
|
|
220
|
+
// Mutating should be fine, since the transaction isn't used anywhere else outside the function
|
|
221
|
+
let fields: {..} = transaction->Obj.magic
|
|
222
|
+
|
|
223
|
+
// Make it compatible with HyperSync transaction fields
|
|
224
|
+
fields["transactionIndex"] = log.transactionIndex
|
|
225
|
+
fields["input"] = fields["data"]
|
|
226
|
+
|
|
227
|
+
fields->Obj.magic
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
type listenerEvent = [#block]
|
|
231
|
+
@send external onEventListener: (t, listenerEvent, int => unit) => unit = "on"
|
|
232
|
+
|
|
233
|
+
@send external offAllEventListeners: (t, listenerEvent) => unit = "off"
|
|
234
|
+
|
|
235
|
+
let onBlock = (t, callback: int => unit) => t->onEventListener(#block, callback)
|
|
236
|
+
|
|
237
|
+
let removeOnBlockEventListener = t => t->offAllEventListeners(#block)
|
|
238
|
+
|
|
239
|
+
@send
|
|
240
|
+
external getBlockNumber: t => promise<int> = "getBlockNumber"
|
|
241
|
+
|
|
242
|
+
type block = {
|
|
243
|
+
_difficulty: bigint,
|
|
244
|
+
difficulty: int,
|
|
245
|
+
extraData: Address.t,
|
|
246
|
+
gasLimit: bigint,
|
|
247
|
+
gasUsed: bigint,
|
|
248
|
+
hash: string,
|
|
249
|
+
miner: Address.t,
|
|
250
|
+
nonce: int,
|
|
251
|
+
number: int,
|
|
252
|
+
parentHash: Address.t,
|
|
253
|
+
timestamp: int,
|
|
254
|
+
transactions: array<Address.t>,
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@send
|
|
258
|
+
external getBlock: (t, int) => promise<Js.nullable<block>> = "getBlock"
|
|
259
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Queue = {
|
|
2
|
+
type t<'a>
|
|
3
|
+
|
|
4
|
+
@module("js-sdsl") @new external make: unit => t<'a> = "Queue"
|
|
5
|
+
|
|
6
|
+
type containerSize = int
|
|
7
|
+
@send external size: t<'a> => containerSize = "size"
|
|
8
|
+
@send external push: (t<'a>, 'a) => containerSize = "push"
|
|
9
|
+
@send external pop: t<'a> => option<'a> = "pop"
|
|
10
|
+
//Returns the front item without popping it
|
|
11
|
+
@send external front: t<'a> => option<'a> = "front"
|
|
12
|
+
}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
type unchecksummedEthAddress = string
|
|
2
|
+
|
|
3
|
+
module QueryTypes = {
|
|
4
|
+
type blockFieldOptions =
|
|
5
|
+
| @as("number") Number
|
|
6
|
+
| @as("hash") Hash
|
|
7
|
+
| @as("parent_hash") ParentHash
|
|
8
|
+
| @as("nonce") Nonce
|
|
9
|
+
| @as("sha3_uncles") Sha3Uncles
|
|
10
|
+
| @as("logs_bloom") LogsBloom
|
|
11
|
+
| @as("transactions_root") TransactionsRoot
|
|
12
|
+
| @as("state_root") StateRoot
|
|
13
|
+
| @as("receipts_root") ReceiptsRoot
|
|
14
|
+
| @as("miner") Miner
|
|
15
|
+
| @as("difficulty") Difficulty
|
|
16
|
+
| @as("total_difficulty") TotalDifficulty
|
|
17
|
+
| @as("extra_data") ExtraData
|
|
18
|
+
| @as("size") Size
|
|
19
|
+
| @as("gas_limit") GasLimit
|
|
20
|
+
| @as("gas_used") GasUsed
|
|
21
|
+
| @as("timestamp") Timestamp
|
|
22
|
+
| @as("uncles") Uncles
|
|
23
|
+
| @as("base_fee_per_gas") BaseFeePerGas
|
|
24
|
+
|
|
25
|
+
let blockFieldOptionsSchema = Utils.Schema.enum([
|
|
26
|
+
Number,
|
|
27
|
+
Hash,
|
|
28
|
+
ParentHash,
|
|
29
|
+
Nonce,
|
|
30
|
+
Sha3Uncles,
|
|
31
|
+
LogsBloom,
|
|
32
|
+
TransactionsRoot,
|
|
33
|
+
StateRoot,
|
|
34
|
+
ReceiptsRoot,
|
|
35
|
+
Miner,
|
|
36
|
+
Difficulty,
|
|
37
|
+
TotalDifficulty,
|
|
38
|
+
ExtraData,
|
|
39
|
+
Size,
|
|
40
|
+
GasLimit,
|
|
41
|
+
GasUsed,
|
|
42
|
+
Timestamp,
|
|
43
|
+
Uncles,
|
|
44
|
+
BaseFeePerGas,
|
|
45
|
+
])
|
|
46
|
+
|
|
47
|
+
type blockFieldSelection = array<blockFieldOptions>
|
|
48
|
+
|
|
49
|
+
let blockFieldSelectionSchema = S.array(blockFieldOptionsSchema)
|
|
50
|
+
|
|
51
|
+
type transactionFieldOptions =
|
|
52
|
+
| @as("block_hash") BlockHash
|
|
53
|
+
| @as("block_number") BlockNumber
|
|
54
|
+
| @as("from") From
|
|
55
|
+
| @as("gas") Gas
|
|
56
|
+
| @as("gas_price") GasPrice
|
|
57
|
+
| @as("hash") Hash
|
|
58
|
+
| @as("input") Input
|
|
59
|
+
| @as("nonce") Nonce
|
|
60
|
+
| @as("to") To
|
|
61
|
+
| @as("transaction_index") TransactionIndex
|
|
62
|
+
| @as("value") Value
|
|
63
|
+
| @as("v") V
|
|
64
|
+
| @as("r") R
|
|
65
|
+
| @as("s") S
|
|
66
|
+
| @as("max_priority_fee_per_gas") MaxPriorityFeePerGas
|
|
67
|
+
| @as("max_fee_per_gas") MaxFeePerGas
|
|
68
|
+
| @as("chain_id") ChainId
|
|
69
|
+
| @as("cumulative_gas_used") CumulativeGasUsed
|
|
70
|
+
| @as("effective_gas_price") EffectiveGasPrice
|
|
71
|
+
| @as("gas_used") GasUsed
|
|
72
|
+
| @as("contract_address") ContractAddress
|
|
73
|
+
| @as("logs_bloom") LogsBloom
|
|
74
|
+
| @as("type") Type
|
|
75
|
+
| @as("root") Root
|
|
76
|
+
| @as("status") Status
|
|
77
|
+
| @as("sighash") Sighash
|
|
78
|
+
|
|
79
|
+
let transactionFieldOptionsSchema = Utils.Schema.enum([
|
|
80
|
+
BlockHash,
|
|
81
|
+
BlockNumber,
|
|
82
|
+
From,
|
|
83
|
+
Gas,
|
|
84
|
+
GasPrice,
|
|
85
|
+
Hash,
|
|
86
|
+
Input,
|
|
87
|
+
Nonce,
|
|
88
|
+
To,
|
|
89
|
+
TransactionIndex,
|
|
90
|
+
Value,
|
|
91
|
+
V,
|
|
92
|
+
R,
|
|
93
|
+
S,
|
|
94
|
+
MaxPriorityFeePerGas,
|
|
95
|
+
MaxFeePerGas,
|
|
96
|
+
ChainId,
|
|
97
|
+
CumulativeGasUsed,
|
|
98
|
+
EffectiveGasPrice,
|
|
99
|
+
GasUsed,
|
|
100
|
+
ContractAddress,
|
|
101
|
+
LogsBloom,
|
|
102
|
+
Type,
|
|
103
|
+
Root,
|
|
104
|
+
Status,
|
|
105
|
+
Sighash,
|
|
106
|
+
])
|
|
107
|
+
|
|
108
|
+
type transactionFieldSelection = array<transactionFieldOptions>
|
|
109
|
+
|
|
110
|
+
let transactionFieldSelectionSchema = S.array(transactionFieldOptionsSchema)
|
|
111
|
+
|
|
112
|
+
type logFieldOptions =
|
|
113
|
+
| @as("removed") Removed
|
|
114
|
+
| @as("log_index") LogIndex
|
|
115
|
+
| @as("transaction_index") TransactionIndex
|
|
116
|
+
| @as("transaction_hash") TransactionHash
|
|
117
|
+
| @as("block_hash") BlockHash
|
|
118
|
+
| @as("block_number") BlockNumber
|
|
119
|
+
| @as("address") Address
|
|
120
|
+
| @as("data") Data
|
|
121
|
+
| @as("topic0") Topic0
|
|
122
|
+
| @as("topic1") Topic1
|
|
123
|
+
| @as("topic2") Topic2
|
|
124
|
+
| @as("topic3") Topic3
|
|
125
|
+
|
|
126
|
+
let logFieldOptionsSchema = Utils.Schema.enum([
|
|
127
|
+
Removed,
|
|
128
|
+
LogIndex,
|
|
129
|
+
TransactionIndex,
|
|
130
|
+
TransactionHash,
|
|
131
|
+
BlockHash,
|
|
132
|
+
BlockNumber,
|
|
133
|
+
Address,
|
|
134
|
+
Data,
|
|
135
|
+
Topic0,
|
|
136
|
+
Topic1,
|
|
137
|
+
Topic2,
|
|
138
|
+
Topic3,
|
|
139
|
+
])
|
|
140
|
+
|
|
141
|
+
type logFieldSelection = array<logFieldOptions>
|
|
142
|
+
|
|
143
|
+
let logFieldSelectionSchema = S.array(logFieldOptionsSchema)
|
|
144
|
+
|
|
145
|
+
type fieldSelection = {
|
|
146
|
+
block?: blockFieldSelection,
|
|
147
|
+
transaction?: transactionFieldSelection,
|
|
148
|
+
log?: logFieldSelection,
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
let fieldSelectionSchema = S.object(s => {
|
|
152
|
+
block: ?s.field("block", S.option(blockFieldSelectionSchema)),
|
|
153
|
+
transaction: ?s.field("transaction", S.option(transactionFieldSelectionSchema)),
|
|
154
|
+
log: ?s.field("log", S.option(logFieldSelectionSchema)),
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
type logParams = {
|
|
158
|
+
address?: array<Address.t>,
|
|
159
|
+
topics: array<array<Ethers.EventFilter.topic>>,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let logParamsSchema = S.object(s => {
|
|
163
|
+
address: ?s.field("address", S.option(S.array(Address.schema))),
|
|
164
|
+
topics: s.field("topics", S.array(S.array(EvmTypes.Hex.schema))),
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
type transactionParams = {
|
|
168
|
+
from?: array<Address.t>,
|
|
169
|
+
to?: array<Address.t>,
|
|
170
|
+
sighash?: array<string>,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let transactionParamsSchema = S.object(s => {
|
|
174
|
+
from: ?s.field("from", S.option(S.array(Address.schema))),
|
|
175
|
+
to: ?s.field("to", S.option(S.array(Address.schema))),
|
|
176
|
+
sighash: ?s.field("sighash", S.option(S.array(S.string))),
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
type postQueryBody = {
|
|
180
|
+
fromBlock: int,
|
|
181
|
+
toBlockExclusive?: int,
|
|
182
|
+
logs?: array<logParams>,
|
|
183
|
+
transactions?: array<transactionParams>,
|
|
184
|
+
fieldSelection: fieldSelection,
|
|
185
|
+
maxNumLogs?: int,
|
|
186
|
+
includeAllBlocks?: bool,
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
let postQueryBodySchema = S.object(s => {
|
|
190
|
+
fromBlock: s.field("from_block", S.int),
|
|
191
|
+
toBlockExclusive: ?s.field("to_block", S.option(S.int)),
|
|
192
|
+
logs: ?s.field("logs", S.option(S.array(logParamsSchema))),
|
|
193
|
+
transactions: ?s.field("transactions", S.option(S.array(transactionParamsSchema))),
|
|
194
|
+
fieldSelection: s.field("field_selection", fieldSelectionSchema),
|
|
195
|
+
maxNumLogs: ?s.field("max_num_logs", S.option(S.int)),
|
|
196
|
+
includeAllBlocks: ?s.field("include_all_blocks", S.option(S.bool)),
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
module ResponseTypes = {
|
|
201
|
+
type blockData = {
|
|
202
|
+
number?: int,
|
|
203
|
+
hash?: string,
|
|
204
|
+
parentHash?: string,
|
|
205
|
+
nonce?: option<int>,
|
|
206
|
+
sha3Uncles?: string,
|
|
207
|
+
logsBloom?: string,
|
|
208
|
+
transactionsRoot?: string,
|
|
209
|
+
stateRoot?: string,
|
|
210
|
+
receiptsRoot?: string,
|
|
211
|
+
miner?: unchecksummedEthAddress,
|
|
212
|
+
difficulty?: option<bigint>,
|
|
213
|
+
totalDifficulty?: option<bigint>,
|
|
214
|
+
extraData?: string,
|
|
215
|
+
size?: bigint,
|
|
216
|
+
gasLimit?: bigint,
|
|
217
|
+
gasUsed?: bigint,
|
|
218
|
+
timestamp?: bigint,
|
|
219
|
+
uncles?: option<string>,
|
|
220
|
+
baseFeePerGas?: option<bigint>,
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
let blockDataSchema = S.object(s => {
|
|
224
|
+
number: ?s.field("number", S.option(S.int)),
|
|
225
|
+
hash: ?s.field("hash", S.option(S.string)),
|
|
226
|
+
parentHash: ?s.field("parent_hash", S.option(S.string)),
|
|
227
|
+
nonce: ?s.field("nonce", S.option(S.null(S.int))),
|
|
228
|
+
sha3Uncles: ?s.field("sha3_uncles", S.option(S.string)),
|
|
229
|
+
logsBloom: ?s.field("logs_bloom", S.option(S.string)),
|
|
230
|
+
transactionsRoot: ?s.field("transactions_root", S.option(S.string)),
|
|
231
|
+
stateRoot: ?s.field("state_root", S.option(S.string)),
|
|
232
|
+
receiptsRoot: ?s.field("receipts_root", S.option(S.string)),
|
|
233
|
+
miner: ?s.field("miner", S.option(S.string)),
|
|
234
|
+
difficulty: ?s.field("difficulty", S.option(S.null(BigInt.schema))),
|
|
235
|
+
totalDifficulty: ?s.field("total_difficulty", S.option(S.null(BigInt.schema))),
|
|
236
|
+
extraData: ?s.field("extra_data", S.option(S.string)),
|
|
237
|
+
size: ?s.field("size", S.option(BigInt.schema)),
|
|
238
|
+
gasLimit: ?s.field("gas_limit", S.option(BigInt.schema)),
|
|
239
|
+
gasUsed: ?s.field("gas_used", S.option(BigInt.schema)),
|
|
240
|
+
timestamp: ?s.field("timestamp", S.option(BigInt.schema)),
|
|
241
|
+
uncles: ?s.field("unclus", S.option(S.null(S.string))),
|
|
242
|
+
baseFeePerGas: ?s.field("base_fee_per_gas", S.option(S.null(BigInt.schema))),
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
type transactionData = {
|
|
246
|
+
blockHash?: string,
|
|
247
|
+
blockNumber?: int,
|
|
248
|
+
from?: option<unchecksummedEthAddress>,
|
|
249
|
+
gas?: bigint,
|
|
250
|
+
gasPrice?: option<bigint>,
|
|
251
|
+
hash?: string,
|
|
252
|
+
input?: string,
|
|
253
|
+
nonce?: int,
|
|
254
|
+
to?: option<unchecksummedEthAddress>,
|
|
255
|
+
transactionIndex?: int,
|
|
256
|
+
value?: bigint,
|
|
257
|
+
v?: option<string>,
|
|
258
|
+
r?: option<string>,
|
|
259
|
+
s?: option<string>,
|
|
260
|
+
maxPriorityFeePerGas?: option<bigint>,
|
|
261
|
+
maxFeePerGas?: option<bigint>,
|
|
262
|
+
chainId?: option<int>,
|
|
263
|
+
cumulativeGasUsed?: bigint,
|
|
264
|
+
effectiveGasPrice?: bigint,
|
|
265
|
+
gasUsed?: bigint,
|
|
266
|
+
contractAddress?: option<unchecksummedEthAddress>,
|
|
267
|
+
logsBoom?: string,
|
|
268
|
+
type_?: option<int>,
|
|
269
|
+
root?: option<string>,
|
|
270
|
+
status?: option<int>,
|
|
271
|
+
sighash?: option<string>,
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
let transactionDataSchema = S.object(s => {
|
|
275
|
+
blockHash: ?s.field("block_hash", S.option(S.string)),
|
|
276
|
+
blockNumber: ?s.field("block_number", S.option(S.int)),
|
|
277
|
+
from: ?s.field("from", S.option(S.null(S.string))),
|
|
278
|
+
gas: ?s.field("gas", S.option(BigInt.schema)),
|
|
279
|
+
gasPrice: ?s.field("gas_price", S.option(S.null(BigInt.schema))),
|
|
280
|
+
hash: ?s.field("hash", S.option(S.string)),
|
|
281
|
+
input: ?s.field("input", S.option(S.string)),
|
|
282
|
+
nonce: ?s.field("nonce", S.option(S.int)),
|
|
283
|
+
to: ?s.field("to", S.option(S.null(S.string))),
|
|
284
|
+
transactionIndex: ?s.field("transaction_index", S.option(S.int)),
|
|
285
|
+
value: ?s.field("value", S.option(BigInt.schema)),
|
|
286
|
+
v: ?s.field("v", S.option(S.null(S.string))),
|
|
287
|
+
r: ?s.field("r", S.option(S.null(S.string))),
|
|
288
|
+
s: ?s.field("s", S.option(S.null(S.string))),
|
|
289
|
+
maxPriorityFeePerGas: ?s.field("max_priority_fee_per_gas", S.option(S.null(BigInt.schema))),
|
|
290
|
+
maxFeePerGas: ?s.field("max_fee_per_gas", S.option(S.null(BigInt.schema))),
|
|
291
|
+
chainId: ?s.field("chain_id", S.option(S.null(S.int))),
|
|
292
|
+
cumulativeGasUsed: ?s.field("cumulative_gas_used", S.option(BigInt.schema)),
|
|
293
|
+
effectiveGasPrice: ?s.field("effective_gas_price", S.option(BigInt.schema)),
|
|
294
|
+
gasUsed: ?s.field("gas_used", S.option(BigInt.schema)),
|
|
295
|
+
contractAddress: ?s.field("contract_address", S.option(S.null(S.string))),
|
|
296
|
+
logsBoom: ?s.field("logs_bloom", S.option(S.string)),
|
|
297
|
+
type_: ?s.field("type", S.option(S.null(S.int))),
|
|
298
|
+
root: ?s.field("root", S.option(S.null(S.string))),
|
|
299
|
+
status: ?s.field("status", S.option(S.null(S.int))),
|
|
300
|
+
sighash: ?s.field("sighash", S.option(S.null(S.string))),
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
type logData = {
|
|
304
|
+
removed?: option<bool>,
|
|
305
|
+
index?: int,
|
|
306
|
+
transactionIndex?: int,
|
|
307
|
+
transactionHash?: string,
|
|
308
|
+
blockHash?: string,
|
|
309
|
+
blockNumber?: int,
|
|
310
|
+
address?: unchecksummedEthAddress,
|
|
311
|
+
data?: string,
|
|
312
|
+
topic0?: option<Ethers.EventFilter.topic>,
|
|
313
|
+
topic1?: option<Ethers.EventFilter.topic>,
|
|
314
|
+
topic2?: option<Ethers.EventFilter.topic>,
|
|
315
|
+
topic3?: option<Ethers.EventFilter.topic>,
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
let logDataSchema = S.object(s => {
|
|
319
|
+
removed: ?s.field("removed", S.option(S.null(S.bool))),
|
|
320
|
+
index: ?s.field("log_index", S.option(S.int)),
|
|
321
|
+
transactionIndex: ?s.field("transaction_index", S.option(S.int)),
|
|
322
|
+
transactionHash: ?s.field("transaction_hash", S.option(S.string)),
|
|
323
|
+
blockHash: ?s.field("block_hash", S.option(S.string)),
|
|
324
|
+
blockNumber: ?s.field("block_number", S.option(S.int)),
|
|
325
|
+
address: ?s.field("address", S.option(S.string)),
|
|
326
|
+
data: ?s.field("data", S.option(S.string)),
|
|
327
|
+
topic0: ?s.field("topic0", S.option(S.null(EvmTypes.Hex.schema))),
|
|
328
|
+
topic1: ?s.field("topic1", S.option(S.null(EvmTypes.Hex.schema))),
|
|
329
|
+
topic2: ?s.field("topic2", S.option(S.null(EvmTypes.Hex.schema))),
|
|
330
|
+
topic3: ?s.field("topic3", S.option(S.null(EvmTypes.Hex.schema))),
|
|
331
|
+
})
|
|
332
|
+
|
|
333
|
+
type data = {
|
|
334
|
+
blocks?: array<blockData>,
|
|
335
|
+
transactions?: array<transactionData>,
|
|
336
|
+
logs?: array<logData>,
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
let dataSchema = S.object(s => {
|
|
340
|
+
blocks: ?s.field("blocks", S.array(blockDataSchema)->S.option),
|
|
341
|
+
transactions: ?s.field("transactions", S.array(transactionDataSchema)->S.option),
|
|
342
|
+
logs: ?s.field("logs", S.array(logDataSchema)->S.option),
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
type queryResponse = {
|
|
346
|
+
data: array<data>,
|
|
347
|
+
archiveHeight: int,
|
|
348
|
+
nextBlock: int,
|
|
349
|
+
totalTime: int,
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
let queryResponseSchema = S.object(s => {
|
|
353
|
+
data: s.field("data", S.array(dataSchema)),
|
|
354
|
+
archiveHeight: s.field("archive_height", S.int),
|
|
355
|
+
nextBlock: s.field("next_block", S.int),
|
|
356
|
+
totalTime: s.field("total_execution_time", S.int),
|
|
357
|
+
})
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
let queryRoute = Rest.route(() => {
|
|
361
|
+
path: "/query",
|
|
362
|
+
method: Post,
|
|
363
|
+
variables: s => s.body(QueryTypes.postQueryBodySchema),
|
|
364
|
+
responses: [
|
|
365
|
+
s => s.data(ResponseTypes.queryResponseSchema),
|
|
366
|
+
]
|
|
367
|
+
})
|
|
368
|
+
|
|
369
|
+
let heightRoute = Rest.route(() => {
|
|
370
|
+
path: "/height",
|
|
371
|
+
method: Get,
|
|
372
|
+
variables: _ => (),
|
|
373
|
+
responses: [
|
|
374
|
+
s => s.field("height", S.int),
|
|
375
|
+
]
|
|
376
|
+
})
|
|
File without changes
|