envio 2.14.3 → 2.16.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/README.md +4 -4
- package/package.json +5 -5
- package/src/Internal.gen.ts +4 -0
- package/src/Internal.res +54 -18
- package/src/LogSelection.res +126 -12
- package/src/Utils.res +29 -2
- package/src/bindings/Ethers.res +11 -10
- package/src/bindings/OpaqueTypes.ts +1 -0
- package/src/sources/HyperSyncClient.res +2 -4
- package/src/sources/HyperSyncJsonApi.res +6 -2
- package/src/sources/Rpc.res +1 -1
package/README.md
CHANGED
|
@@ -14,17 +14,17 @@ HyperIndex is a fast, developer-friendly multichain indexer, optimized for both
|
|
|
14
14
|
- **[Indexer auto-generation](https://docs.envio.dev/docs/HyperIndex/contract-import)** – Generate Indexers directly from smart contract addresses
|
|
15
15
|
- **High performance** – Historical backfills at over 5,000+ events per second ([fastest in market](https://docs.envio.dev/blog/indexer-benchmarking-results))
|
|
16
16
|
- **Local development** – Full-featured local environment with Docker
|
|
17
|
-
- **Multichain indexing** – Index any EVM-compatible blockchain and Fuel (simultaneously)
|
|
17
|
+
- **[Multichain indexing](https://docs.envio.dev/docs/HyperIndex/multichain-indexing)** – Index any EVM-compatible blockchain and Fuel (simultaneously)
|
|
18
18
|
- **Real-time indexing** – Instantly track blockchain events
|
|
19
|
-
- **Reorg support** – Graceful handling of blockchain reorganizations
|
|
19
|
+
- **[Reorg support](https://docs.envio.dev/docs/HyperIndex/reorgs-support)** – Graceful handling of blockchain reorganizations
|
|
20
20
|
- **GraphQL API** – Easy-to-query indexed data
|
|
21
21
|
- **Flexible language support** – JavaScript, TypeScript, and ReScript
|
|
22
22
|
- **Factory contract support** – Index data from 100,000+ factory contracts seamlessly
|
|
23
23
|
- **On-chain & off-chain data integration** – Easily combine multiple data sources
|
|
24
|
-
- **Self-hosted & managed options** – Run your own setup or use HyperIndex hosted services
|
|
24
|
+
- **[Self-hosted & managed options](https://docs.envio.dev/docs/HyperIndex/hosted-service)** – Run your own setup or use HyperIndex hosted services
|
|
25
25
|
- **Detailed logging & error reporting** – Debug and optimize with clarity
|
|
26
26
|
- **External API actions** – Trigger external services based on blockchain events
|
|
27
|
-
- **Wildcard topic indexing** – Flexible indexing based on event topics
|
|
27
|
+
- **[Wildcard topic indexing](https://docs.envio.dev/docs/HyperIndex/wildcard-indexing)** – Flexible indexing based on event topics
|
|
28
28
|
- **Fallback RPC data sources** – Enhanced reliability with RPC connections
|
|
29
29
|
|
|
30
30
|
## Getting Started
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "v2.
|
|
3
|
+
"version": "v2.16.0",
|
|
4
4
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
5
5
|
"bin": "./bin.js",
|
|
6
6
|
"repository": {
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://envio.dev",
|
|
25
25
|
"optionalDependencies": {
|
|
26
|
-
"envio-linux-x64": "v2.
|
|
27
|
-
"envio-linux-arm64": "v2.
|
|
28
|
-
"envio-darwin-x64": "v2.
|
|
29
|
-
"envio-darwin-arm64": "v2.
|
|
26
|
+
"envio-linux-x64": "v2.16.0",
|
|
27
|
+
"envio-linux-arm64": "v2.16.0",
|
|
28
|
+
"envio-darwin-x64": "v2.16.0",
|
|
29
|
+
"envio-darwin-arm64": "v2.16.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@envio-dev/hypersync-client": "0.6.3",
|
package/src/Internal.gen.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
/* eslint-disable */
|
|
4
4
|
/* tslint:disable */
|
|
5
5
|
|
|
6
|
+
import type {invalid as $$noEventFilters} from './bindings/OpaqueTypes.ts';
|
|
7
|
+
|
|
6
8
|
import type {t as Address_t} from './Address.gen';
|
|
7
9
|
|
|
8
10
|
export type genericEvent<params,block,transaction> = {
|
|
@@ -45,3 +47,5 @@ export type fuelTransferParams = {
|
|
|
45
47
|
readonly assetId: string;
|
|
46
48
|
readonly amount: bigint
|
|
47
49
|
};
|
|
50
|
+
|
|
51
|
+
export type noEventFilters = $$noEventFilters;
|
package/src/Internal.res
CHANGED
|
@@ -64,22 +64,23 @@ type genericHandlerWithLoader<'loader, 'handler, 'eventFilters> = {
|
|
|
64
64
|
preRegisterDynamicContracts?: bool,
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
// This is private so it's not manually constructed internally
|
|
68
|
+
// The idea is that it can only be coerced from fuel/evmEventConfig
|
|
69
|
+
// and it can include their fields. We prevent manual creation,
|
|
70
|
+
// so the fields are not overwritten and we can safely cast the type back to fuel/evmEventConfig
|
|
71
|
+
type eventConfig = private {
|
|
72
|
+
id: string,
|
|
73
|
+
name: string,
|
|
69
74
|
contractName: string,
|
|
75
|
+
isWildcard: bool,
|
|
76
|
+
// Usually always false for wildcard events
|
|
77
|
+
// But might be true for wildcard event with dynamic event filter by addresses
|
|
78
|
+
dependsOnAddresses: bool,
|
|
79
|
+
preRegisterDynamicContracts: bool,
|
|
70
80
|
loader: option<loader>,
|
|
71
81
|
handler: option<handler>,
|
|
72
82
|
contractRegister: option<contractRegister>,
|
|
73
|
-
timestamp: int,
|
|
74
|
-
chain: ChainMap.Chain.t,
|
|
75
|
-
blockNumber: int,
|
|
76
|
-
logIndex: int,
|
|
77
|
-
event: event,
|
|
78
83
|
paramsRawEventSchema: S.schema<eventParams>,
|
|
79
|
-
//Default to false, if an event needs to
|
|
80
|
-
//be reprocessed after it has loaded dynamic contracts
|
|
81
|
-
//This gets set to true and does not try and reload events
|
|
82
|
-
hasRegisteredDynamicContracts?: bool,
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
type fuelEventKind =
|
|
@@ -89,20 +90,52 @@ type fuelEventKind =
|
|
|
89
90
|
| Transfer
|
|
90
91
|
| Call
|
|
91
92
|
type fuelEventConfig = {
|
|
92
|
-
|
|
93
|
-
contractName: string,
|
|
93
|
+
...eventConfig,
|
|
94
94
|
kind: fuelEventKind,
|
|
95
|
-
isWildcard: bool,
|
|
96
|
-
loader: option<loader>,
|
|
97
|
-
handler: option<handler>,
|
|
98
|
-
contractRegister: option<contractRegister>,
|
|
99
|
-
paramsRawEventSchema: S.schema<eventParams>,
|
|
100
95
|
}
|
|
101
96
|
type fuelContractConfig = {
|
|
102
97
|
name: string,
|
|
103
98
|
events: array<fuelEventConfig>,
|
|
104
99
|
}
|
|
105
100
|
|
|
101
|
+
type topicSelection = {
|
|
102
|
+
topic0: array<EvmTypes.Hex.t>,
|
|
103
|
+
topic1: array<EvmTypes.Hex.t>,
|
|
104
|
+
topic2: array<EvmTypes.Hex.t>,
|
|
105
|
+
topic3: array<EvmTypes.Hex.t>,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
type eventFiltersArgs = {chainId: int, addresses: array<Address.t>}
|
|
109
|
+
|
|
110
|
+
type eventFilters =
|
|
111
|
+
Static(array<topicSelection>) | Dynamic(array<Address.t> => array<topicSelection>)
|
|
112
|
+
|
|
113
|
+
type evmEventConfig = {
|
|
114
|
+
...eventConfig,
|
|
115
|
+
getEventFiltersOrThrow: ChainMap.Chain.t => eventFilters,
|
|
116
|
+
blockSchema: S.schema<eventBlock>,
|
|
117
|
+
transactionSchema: S.schema<eventTransaction>,
|
|
118
|
+
convertHyperSyncEventArgs: HyperSyncClient.Decoder.decodedEvent => eventParams,
|
|
119
|
+
}
|
|
120
|
+
type evmContractConfig = {
|
|
121
|
+
name: string,
|
|
122
|
+
abi: EvmTypes.Abi.t,
|
|
123
|
+
events: array<evmEventConfig>,
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
type eventItem = {
|
|
127
|
+
eventConfig: eventConfig,
|
|
128
|
+
timestamp: int,
|
|
129
|
+
chain: ChainMap.Chain.t,
|
|
130
|
+
blockNumber: int,
|
|
131
|
+
logIndex: int,
|
|
132
|
+
event: event,
|
|
133
|
+
//Default to false, if an event needs to
|
|
134
|
+
//be reprocessed after it has loaded dynamic contracts
|
|
135
|
+
//This gets set to true and does not try and reload events
|
|
136
|
+
hasRegisteredDynamicContracts?: bool,
|
|
137
|
+
}
|
|
138
|
+
|
|
106
139
|
@genType
|
|
107
140
|
type fuelSupplyParams = {
|
|
108
141
|
subId: string,
|
|
@@ -125,3 +158,6 @@ let fuelTransferParamsSchema = S.schema(s => {
|
|
|
125
158
|
})
|
|
126
159
|
|
|
127
160
|
type entity = private {id: string}
|
|
161
|
+
|
|
162
|
+
@genType.import(("./bindings/OpaqueTypes.ts", "invalid"))
|
|
163
|
+
type noEventFilters
|
package/src/LogSelection.res
CHANGED
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
type topicSelection = {
|
|
2
|
-
topic0: array<EvmTypes.Hex.t>,
|
|
3
|
-
topic1: array<EvmTypes.Hex.t>,
|
|
4
|
-
topic2: array<EvmTypes.Hex.t>,
|
|
5
|
-
topic3: array<EvmTypes.Hex.t>,
|
|
6
|
-
}
|
|
7
|
-
|
|
8
1
|
exception MissingRequiredTopic0
|
|
9
2
|
let makeTopicSelection = (~topic0, ~topic1=[], ~topic2=[], ~topic3=[]) =>
|
|
10
3
|
if topic0->Utils.Array.isEmpty {
|
|
11
4
|
Error(MissingRequiredTopic0)
|
|
12
5
|
} else {
|
|
13
6
|
{
|
|
14
|
-
topic0,
|
|
7
|
+
Internal.topic0,
|
|
15
8
|
topic1,
|
|
16
9
|
topic2,
|
|
17
10
|
topic3,
|
|
18
11
|
}->Ok
|
|
19
12
|
}
|
|
20
13
|
|
|
21
|
-
let hasFilters = ({topic1, topic2, topic3}: topicSelection) => {
|
|
14
|
+
let hasFilters = ({topic1, topic2, topic3}: Internal.topicSelection) => {
|
|
22
15
|
[topic1, topic2, topic3]->Js.Array2.find(topic => !Utils.Array.isEmpty(topic))->Belt.Option.isSome
|
|
23
16
|
}
|
|
24
17
|
|
|
@@ -26,7 +19,7 @@ let hasFilters = ({topic1, topic2, topic3}: topicSelection) => {
|
|
|
26
19
|
For a group of topic selections, if multiple only use topic0, then they can be compressed into one
|
|
27
20
|
selection combining the topic0s
|
|
28
21
|
*/
|
|
29
|
-
let compressTopicSelections = (topicSelections: array<topicSelection>) => {
|
|
22
|
+
let compressTopicSelections = (topicSelections: array<Internal.topicSelection>) => {
|
|
30
23
|
let topic0sOfSelectionsWithoutFilters = []
|
|
31
24
|
|
|
32
25
|
let selectionsWithFilters = []
|
|
@@ -45,7 +38,7 @@ let compressTopicSelections = (topicSelections: array<topicSelection>) => {
|
|
|
45
38
|
| [] => selectionsWithFilters
|
|
46
39
|
| topic0 =>
|
|
47
40
|
let selectionWithoutFilters = {
|
|
48
|
-
topic0,
|
|
41
|
+
Internal.topic0,
|
|
49
42
|
topic1: [],
|
|
50
43
|
topic2: [],
|
|
51
44
|
topic3: [],
|
|
@@ -56,10 +49,131 @@ let compressTopicSelections = (topicSelections: array<topicSelection>) => {
|
|
|
56
49
|
|
|
57
50
|
type t = {
|
|
58
51
|
addresses: array<Address.t>,
|
|
59
|
-
topicSelections: array<topicSelection>,
|
|
52
|
+
topicSelections: array<Internal.topicSelection>,
|
|
60
53
|
}
|
|
61
54
|
|
|
62
55
|
let make = (~addresses, ~topicSelections) => {
|
|
63
56
|
let topicSelections = compressTopicSelections(topicSelections)
|
|
64
57
|
{addresses, topicSelections}
|
|
65
58
|
}
|
|
59
|
+
|
|
60
|
+
type parsedEventFilters = {
|
|
61
|
+
getEventFiltersOrThrow: ChainMap.Chain.t => Internal.eventFilters,
|
|
62
|
+
dependsOnAddresses: bool,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let parseEventFiltersOrThrow = {
|
|
66
|
+
let emptyTopics = []
|
|
67
|
+
let noopGetter = _ => emptyTopics
|
|
68
|
+
|
|
69
|
+
(
|
|
70
|
+
~eventFilters: option<Js.Json.t>,
|
|
71
|
+
~sighash,
|
|
72
|
+
~params,
|
|
73
|
+
~topic1=noopGetter,
|
|
74
|
+
~topic2=noopGetter,
|
|
75
|
+
~topic3=noopGetter,
|
|
76
|
+
): parsedEventFilters => {
|
|
77
|
+
let dependsOnAddresses = ref(false)
|
|
78
|
+
let topic0 = [sighash->EvmTypes.Hex.fromStringUnsafe]
|
|
79
|
+
let default = {
|
|
80
|
+
Internal.topic0,
|
|
81
|
+
topic1: emptyTopics,
|
|
82
|
+
topic2: emptyTopics,
|
|
83
|
+
topic3: emptyTopics,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let parse = (eventFilters: Js.Json.t): array<Internal.topicSelection> => {
|
|
87
|
+
switch eventFilters {
|
|
88
|
+
| Array([]) => [%raw(`{}`)]
|
|
89
|
+
| Array(a) => a
|
|
90
|
+
| _ => [eventFilters]
|
|
91
|
+
}->Js.Array2.map(eventFilter => {
|
|
92
|
+
switch eventFilter {
|
|
93
|
+
| Object(eventFilter) => {
|
|
94
|
+
let filterKeys = eventFilter->Js.Dict.keys
|
|
95
|
+
switch filterKeys {
|
|
96
|
+
| [] => default
|
|
97
|
+
| _ => {
|
|
98
|
+
filterKeys->Js.Array2.forEach(key => {
|
|
99
|
+
if params->Js.Array2.includes(key)->not {
|
|
100
|
+
// In TS type validation doesn't catch this
|
|
101
|
+
// when we have eventFilters as a callback
|
|
102
|
+
Js.Exn.raiseError(
|
|
103
|
+
`Invalid event filters configuration. The event doesn't have an indexed parameter "${key}" and can't use it for filtering`,
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
{
|
|
108
|
+
Internal.topic0,
|
|
109
|
+
topic1: topic1(eventFilter),
|
|
110
|
+
topic2: topic2(eventFilter),
|
|
111
|
+
topic3: topic3(eventFilter),
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
| _ => Js.Exn.raiseError("Invalid event filters configuration. Expected an object")
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let getEventFiltersOrThrow = switch eventFilters {
|
|
122
|
+
| None => {
|
|
123
|
+
let static: Internal.eventFilters = Static([default])
|
|
124
|
+
_ => static
|
|
125
|
+
}
|
|
126
|
+
| Some(eventFilters) =>
|
|
127
|
+
if Js.typeof(eventFilters) === "function" {
|
|
128
|
+
let fn = eventFilters->(Utils.magic: Js.Json.t => Internal.eventFiltersArgs => Js.Json.t)
|
|
129
|
+
// When user passess a function to event filters we need to
|
|
130
|
+
// first determine whether it uses addresses or not
|
|
131
|
+
// Because the fetching logic will be different for wildcard events
|
|
132
|
+
// 1. If wildcard event doesn't use addresses,
|
|
133
|
+
// it should start fetching even without static addresses in the config
|
|
134
|
+
// 2. If wildcard event uses addresses in event filters,
|
|
135
|
+
// it should first wait for dynamic contract registration
|
|
136
|
+
// So to deterimine which case we run the function with dummy args
|
|
137
|
+
// and check if it uses addresses by using the getter.
|
|
138
|
+
try {
|
|
139
|
+
let args = (
|
|
140
|
+
{
|
|
141
|
+
chainId: 0,
|
|
142
|
+
addresses: [],
|
|
143
|
+
}: Internal.eventFiltersArgs
|
|
144
|
+
)->Utils.Object.defineProperty(
|
|
145
|
+
"addresses",
|
|
146
|
+
{
|
|
147
|
+
get: () => {
|
|
148
|
+
dependsOnAddresses := true
|
|
149
|
+
[]
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
)
|
|
153
|
+
let _ = fn(args)
|
|
154
|
+
} catch {
|
|
155
|
+
| _ => ()
|
|
156
|
+
}
|
|
157
|
+
if dependsOnAddresses.contents {
|
|
158
|
+
chain => Internal.Dynamic(
|
|
159
|
+
addresses => fn({chainId: chain->ChainMap.Chain.toChainId, addresses})->parse,
|
|
160
|
+
)
|
|
161
|
+
} else {
|
|
162
|
+
// When we don't depend on addresses, can mark the event filter
|
|
163
|
+
// as static and avoid recalculating on every batch
|
|
164
|
+
chain => Internal.Static(
|
|
165
|
+
fn({chainId: chain->ChainMap.Chain.toChainId, addresses: []})->parse,
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
let static: Internal.eventFilters = Static(eventFilters->parse)
|
|
170
|
+
_ => static
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
getEventFiltersOrThrow,
|
|
176
|
+
dependsOnAddresses: dependsOnAddresses.contents,
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
package/src/Utils.res
CHANGED
|
@@ -7,6 +7,21 @@ let delay = milliseconds =>
|
|
|
7
7
|
}, milliseconds)
|
|
8
8
|
})
|
|
9
9
|
|
|
10
|
+
module Object = {
|
|
11
|
+
// Define a type for the property descriptor
|
|
12
|
+
type propertyDescriptor<'a> = {
|
|
13
|
+
configurable?: bool,
|
|
14
|
+
enumerable?: bool,
|
|
15
|
+
writable?: bool,
|
|
16
|
+
value?: 'a,
|
|
17
|
+
get?: unit => 'a,
|
|
18
|
+
set?: 'a => unit,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@val @scope("Object")
|
|
22
|
+
external defineProperty: ('obj, string, propertyDescriptor<'a>) => 'obj = "defineProperty"
|
|
23
|
+
}
|
|
24
|
+
|
|
10
25
|
module Option = {
|
|
11
26
|
let mapNone = (opt: option<'a>, val: 'b): option<'b> => {
|
|
12
27
|
switch opt {
|
|
@@ -50,6 +65,20 @@ module Dict = {
|
|
|
50
65
|
*/
|
|
51
66
|
external dangerouslyGetNonOption: (dict<'a>, string) => option<'a> = ""
|
|
52
67
|
|
|
68
|
+
let push = (dict, key, value) => {
|
|
69
|
+
switch dict->dangerouslyGetNonOption(key) {
|
|
70
|
+
| Some(arr) => arr->Js.Array2.push(value)->ignore
|
|
71
|
+
| None => dict->Js.Dict.set(key, [value])
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let pushMany = (dict, key, values) => {
|
|
76
|
+
switch dict->dangerouslyGetNonOption(key) {
|
|
77
|
+
| Some(arr) => arr->Js.Array2.pushMany(values)->ignore
|
|
78
|
+
| None => dict->Js.Dict.set(key, values)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
53
82
|
let merge: (dict<'a>, dict<'a>) => dict<'a> = %raw(`(dictA, dictB) => ({...dictA, ...dictB})`)
|
|
54
83
|
|
|
55
84
|
let map = (dict, fn) => {
|
|
@@ -267,8 +296,6 @@ let unwrapResultExn = res =>
|
|
|
267
296
|
external queueMicrotask: (unit => unit) => unit = "queueMicrotask"
|
|
268
297
|
|
|
269
298
|
module Schema = {
|
|
270
|
-
let enum = S.enum
|
|
271
|
-
|
|
272
299
|
let getNonOptionalFieldNames = schema => {
|
|
273
300
|
let acc = []
|
|
274
301
|
switch schema->S.classify {
|
package/src/bindings/Ethers.res
CHANGED
|
@@ -55,7 +55,7 @@ module CombinedFilter = {
|
|
|
55
55
|
type combinedFilterRecord = {
|
|
56
56
|
address?: array<Address.t>,
|
|
57
57
|
//The second element of the tuple is the
|
|
58
|
-
topics:
|
|
58
|
+
topics: Rpc.GetLogs.topicQuery,
|
|
59
59
|
fromBlock: int,
|
|
60
60
|
toBlock: int,
|
|
61
61
|
}
|
|
@@ -147,17 +147,18 @@ module JsonRpcProvider = {
|
|
|
147
147
|
@send
|
|
148
148
|
external getTransaction: (t, ~transactionHash: string) => promise<transaction> = "getTransaction"
|
|
149
149
|
|
|
150
|
-
let makeGetTransactionFields = (~getTransactionByHash) =>
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
let makeGetTransactionFields = (~getTransactionByHash) =>
|
|
151
|
+
async (log: log): promise<unknown> => {
|
|
152
|
+
let transaction = await getTransactionByHash(log.transactionHash)
|
|
153
|
+
// Mutating should be fine, since the transaction isn't used anywhere else outside the function
|
|
154
|
+
let fields: {..} = transaction->Obj.magic
|
|
154
155
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
// Make it compatible with HyperSync transaction fields
|
|
157
|
+
fields["transactionIndex"] = log.transactionIndex
|
|
158
|
+
fields["input"] = fields["data"]
|
|
158
159
|
|
|
159
|
-
|
|
160
|
-
|
|
160
|
+
fields->Obj.magic
|
|
161
|
+
}
|
|
161
162
|
|
|
162
163
|
type block = {
|
|
163
164
|
_difficulty: bigint,
|
|
@@ -422,13 +422,11 @@ type t = {
|
|
|
422
422
|
|
|
423
423
|
@module("@envio-dev/hypersync-client") @scope("HypersyncClient") external new: cfg => t = "new"
|
|
424
424
|
|
|
425
|
-
let
|
|
426
|
-
|
|
427
|
-
let make = (~url, ~bearerToken: option<string>, ~httpReqTimeoutMillis, ~maxNumRetries) =>
|
|
425
|
+
let make = (~url, ~apiToken, ~httpReqTimeoutMillis, ~maxNumRetries) =>
|
|
428
426
|
new({
|
|
429
427
|
url,
|
|
430
428
|
enableChecksumAddresses: true,
|
|
431
|
-
bearerToken:
|
|
429
|
+
bearerToken: apiToken,
|
|
432
430
|
httpReqTimeoutMillis,
|
|
433
431
|
maxNumRetries,
|
|
434
432
|
})
|
|
@@ -360,13 +360,17 @@ module ResponseTypes = {
|
|
|
360
360
|
let queryRoute = Rest.route(() => {
|
|
361
361
|
path: "/query",
|
|
362
362
|
method: Post,
|
|
363
|
-
input: s =>
|
|
363
|
+
input: s =>
|
|
364
|
+
{
|
|
365
|
+
"query": s.body(QueryTypes.postQueryBodySchema),
|
|
366
|
+
"token": s.auth(Bearer),
|
|
367
|
+
},
|
|
364
368
|
responses: [s => s.data(ResponseTypes.queryResponseSchema)],
|
|
365
369
|
})
|
|
366
370
|
|
|
367
371
|
let heightRoute = Rest.route(() => {
|
|
368
372
|
path: "/height",
|
|
369
373
|
method: Get,
|
|
370
|
-
input:
|
|
374
|
+
input: s => s.auth(Bearer),
|
|
371
375
|
responses: [s => s.field("height", S.int)],
|
|
372
376
|
})
|
package/src/sources/Rpc.res
CHANGED
|
@@ -71,7 +71,7 @@ module GetLogs = {
|
|
|
71
71
|
topics->Belt.Array.map(toTopicFilter)
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
let mapTopicQuery = ({topic0, topic1, topic2, topic3}:
|
|
74
|
+
let mapTopicQuery = ({topic0, topic1, topic2, topic3}: Internal.topicSelection): topicQuery =>
|
|
75
75
|
makeTopicQuery(~topic0, ~topic1, ~topic2, ~topic3)
|
|
76
76
|
|
|
77
77
|
type param = {
|