envio 3.3.2 → 3.5.0-alpha.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.
Files changed (61) hide show
  1. package/package.json +6 -6
  2. package/src/Api.res +1 -8
  3. package/src/Api.res.mjs +1 -5
  4. package/src/Bin.res +2 -2
  5. package/src/ChainState.res +6 -1
  6. package/src/ChainState.res.mjs +4 -3
  7. package/src/Config.res +38 -5
  8. package/src/Config.res.mjs +35 -6
  9. package/src/Core.res +65 -20
  10. package/src/Core.res.mjs +36 -6
  11. package/src/EnvioGlobal.res +0 -2
  12. package/src/EnvioGlobal.res.mjs +0 -1
  13. package/src/ExitOnCaughtUp.res +6 -2
  14. package/src/ExitOnCaughtUp.res.mjs +4 -0
  15. package/src/FetchState.res +3 -3
  16. package/src/HandlerRegister.res +357 -434
  17. package/src/HandlerRegister.res.mjs +202 -242
  18. package/src/HandlerRegister.resi +7 -15
  19. package/src/IndexerState.res +10 -0
  20. package/src/IndexerState.res.mjs +9 -3
  21. package/src/IndexerState.resi +3 -0
  22. package/src/Internal.res +10 -1
  23. package/src/Main.res.mjs +4 -4
  24. package/src/PgStorage.res +16 -1
  25. package/src/PgStorage.res.mjs +9 -1
  26. package/src/SimulateItems.res +61 -40
  27. package/src/SimulateItems.res.mjs +37 -21
  28. package/src/TestIndexer.res +453 -454
  29. package/src/TestIndexer.res.mjs +321 -344
  30. package/src/bindings/ClickHouse.res +68 -2
  31. package/src/bindings/ClickHouse.res.mjs +47 -2
  32. package/src/sources/EvmChain.res +1 -1
  33. package/src/sources/EvmChain.res.mjs +2 -2
  34. package/src/sources/FuelHyperSync.res +74 -0
  35. package/src/sources/FuelHyperSync.res.mjs +80 -0
  36. package/src/sources/FuelHyperSync.resi +22 -0
  37. package/src/sources/FuelHyperSyncClient.res +120 -0
  38. package/src/sources/FuelHyperSyncClient.res.mjs +71 -0
  39. package/src/sources/FuelHyperSyncSource.res +257 -0
  40. package/src/sources/FuelHyperSyncSource.res.mjs +252 -0
  41. package/src/sources/HyperSyncClient.res +2 -2
  42. package/src/sources/HyperSyncClient.res.mjs +1 -1
  43. package/src/sources/SvmHyperSyncClient.res +139 -102
  44. package/src/sources/SvmHyperSyncClient.res.mjs +45 -5
  45. package/src/sources/SvmHyperSyncSource.res +60 -440
  46. package/src/sources/SvmHyperSyncSource.res.mjs +42 -363
  47. package/src/TestIndexerProxyStorage.res +0 -196
  48. package/src/TestIndexerProxyStorage.res.mjs +0 -121
  49. package/src/TestIndexerWorker.res +0 -4
  50. package/src/TestIndexerWorker.res.mjs +0 -7
  51. package/src/sources/EventRouter.res +0 -165
  52. package/src/sources/EventRouter.res.mjs +0 -153
  53. package/src/sources/HyperFuel.res +0 -179
  54. package/src/sources/HyperFuel.res.mjs +0 -146
  55. package/src/sources/HyperFuel.resi +0 -36
  56. package/src/sources/HyperFuelClient.res +0 -127
  57. package/src/sources/HyperFuelClient.res.mjs +0 -20
  58. package/src/sources/HyperFuelSource.res +0 -502
  59. package/src/sources/HyperFuelSource.res.mjs +0 -481
  60. /package/src/sources/{HyperSyncSource.res → EvmHyperSyncSource.res} +0 -0
  61. /package/src/sources/{HyperSyncSource.res.mjs → EvmHyperSyncSource.res.mjs} +0 -0
@@ -7,10 +7,78 @@ type cfg = {
7
7
  maxNumRetries?: int,
8
8
  retryBaseMs?: int,
9
9
  retryCeilingMs?: int,
10
- /// Per-program Borsh schema descriptors (JSON, one per program). The Rust
11
- /// client builds these into decoders at creation and decodes matching
12
- /// instructions inline on `get`.
13
- programSchemas?: array<string>,
10
+ }
11
+
12
+ module Registration = {
13
+ type accountFilter = {
14
+ position: int,
15
+ values: array<string>,
16
+ }
17
+
18
+ // The full per-(instruction, chain) registration passed to the Rust client
19
+ // at construction: routing identity, the fetch state queries are built
20
+ // from, and the Borsh schema pieces the client builds decoders from.
21
+ type input = {
22
+ // Chain-scoped sequential registration index, echoed back on routed items.
23
+ index: int,
24
+ instructionName: string,
25
+ contractName: string,
26
+ programId: string,
27
+ isWildcard: bool,
28
+ discriminator?: string,
29
+ discriminatorByteLen: int,
30
+ isInner?: bool,
31
+ includeLogs: bool,
32
+ // DNF: outer array is OR of AND-groups.
33
+ accountFilters: array<array<accountFilter>>,
34
+ // camelCase Internal.svmTransactionField / svmBlockField names.
35
+ transactionFields: array<string>,
36
+ blockFields: array<string>,
37
+ // Borsh schema pieces; empty accounts + absent argsJson = no schema.
38
+ accounts: array<string>,
39
+ argsJson?: string,
40
+ definedTypesJson?: string,
41
+ }
42
+
43
+ let fromOnEventRegistrations = (
44
+ onEventRegistrations: array<Internal.svmOnEventRegistration>,
45
+ ): array<input> =>
46
+ onEventRegistrations->Array.map(reg => {
47
+ let eventConfig =
48
+ reg.eventConfig->(Utils.magic: Internal.eventConfig => Internal.svmInstructionEventConfig)
49
+ {
50
+ index: reg.index,
51
+ instructionName: eventConfig.name,
52
+ contractName: eventConfig.contractName,
53
+ programId: eventConfig.programId->SvmTypes.Pubkey.toString,
54
+ isWildcard: reg.isWildcard,
55
+ discriminator: ?eventConfig.discriminator,
56
+ discriminatorByteLen: eventConfig.discriminatorByteLen,
57
+ isInner: ?eventConfig.isInner,
58
+ includeLogs: eventConfig.includeLogs,
59
+ accountFilters: eventConfig.accountFilters->Array.map(group =>
60
+ group->Array.map(
61
+ (filter): accountFilter => {
62
+ position: filter.position,
63
+ values: filter.values->SvmTypes.Pubkey.toStrings,
64
+ },
65
+ )
66
+ ),
67
+ transactionFields: eventConfig.selectedTransactionFields->Utils.Set.toArray,
68
+ blockFields: eventConfig.selectedBlockFields
69
+ ->(Utils.magic: Utils.Set.t<Internal.svmBlockField> => Utils.Set.t<string>)
70
+ ->Utils.Set.toArray,
71
+ accounts: eventConfig.accounts,
72
+ argsJson: ?switch eventConfig.args {
73
+ | JSON.Null => None
74
+ | args => Some(args->JSON.stringify)
75
+ },
76
+ definedTypesJson: ?switch eventConfig.definedTypes {
77
+ | JSON.Null => None
78
+ | definedTypes => Some(definedTypes->JSON.stringify)
79
+ },
80
+ }
81
+ })
14
82
  }
15
83
 
16
84
  module QueryTypes = {
@@ -37,54 +105,7 @@ module QueryTypes = {
37
105
  | @as("loaded_addresses_writable") LoadedAddressesWritable
38
106
  | @as("loaded_addresses_readonly") LoadedAddressesReadonly
39
107
 
40
- type instructionField =
41
- | @as("slot") Slot
42
- | @as("transaction_index") TransactionIndex
43
- | @as("instruction_address") InstructionAddress
44
- | @as("program_id") ProgramId
45
- | @as("accounts") Accounts
46
- | @as("data") Data
47
- | @as("d1") D1
48
- | @as("d2") D2
49
- | @as("d4") D4
50
- | @as("d8") D8
51
- | @as("a0") A0
52
- | @as("a1") A1
53
- | @as("a2") A2
54
- | @as("a3") A3
55
- | @as("a4") A4
56
- | @as("a5") A5
57
- | @as("a6") A6
58
- | @as("a7") A7
59
- | @as("a8") A8
60
- | @as("a9") A9
61
- | @as("is_inner") IsInner
62
- | @as("is_committed") IsCommitted
63
-
64
- type logField =
65
- | @as("slot") Slot
66
- | @as("transaction_index") TransactionIndex
67
- | @as("instruction_address") InstructionAddress
68
- | @as("program_id") ProgramId
69
- | @as("kind") Kind
70
- | @as("message") Message
71
-
72
- type tokenBalanceField =
73
- | @as("slot") Slot
74
- | @as("transaction_index") TransactionIndex
75
- | @as("account") Account
76
- | @as("mint") Mint
77
- | @as("owner") Owner
78
- | @as("pre_amount") PreAmount
79
- | @as("post_amount") PostAmount
80
-
81
- type fieldSelection = {
82
- block?: array<blockField>,
83
- transaction?: array<transactionField>,
84
- instruction?: array<instructionField>,
85
- log?: array<logField>,
86
- tokenBalance?: array<tokenBalanceField>,
87
- }
108
+ type fieldSelection = {block?: array<blockField>, transaction?: array<transactionField>}
88
109
 
89
110
  /** Filter for selecting instructions. All non-empty fields are AND-ed: an
90
111
  instruction must match at least one value in every non-empty field.
@@ -97,43 +118,19 @@ module QueryTypes = {
97
118
  d2?: array<string>,
98
119
  d4?: array<string>,
99
120
  d8?: array<string>,
100
- a0?: array<string>,
101
- a1?: array<string>,
102
- a2?: array<string>,
103
- a3?: array<string>,
104
- a4?: array<string>,
105
- a5?: array<string>,
106
- a6?: array<string>,
107
- a7?: array<string>,
108
- a8?: array<string>,
109
- a9?: array<string>,
110
121
  isInner?: bool,
111
122
  }
112
123
 
113
- type transactionSelection = {
114
- feePayer?: array<string>,
115
- success?: bool,
116
- }
117
-
118
- type logSelection = {
119
- programId?: array<string>,
120
- kind?: array<string>,
121
- }
122
-
124
+ // The `get` query surface, used only for block-data range queries; event
125
+ // fetching goes through `getEventItems`, which builds its query in Rust.
123
126
  type query = {
124
127
  fromSlot: int,
125
128
  toSlot?: int,
126
129
  instructions?: array<instructionSelection>,
127
- transactions?: array<transactionSelection>,
128
- logs?: array<logSelection>,
129
130
  includeAllBlocks?: bool,
130
- includeTokenBalances?: bool,
131
131
  fields?: fieldSelection,
132
132
  maxNumBlocks?: int,
133
- maxNumTransactions?: int,
134
133
  maxNumInstructions?: int,
135
- maxNumLogs?: int,
136
- maxNumTokenBalances?: int,
137
134
  }
138
135
  }
139
136
 
@@ -148,13 +145,6 @@ module ResponseTypes = {
148
145
 
149
146
  /// Borsh-decoded view attached by the Rust client. `argsJson`/`accountsJson`
150
147
  /// are stringified to side-step napi-rs's lack of native JSON passthrough.
151
- /** Solana instruction record.
152
-
153
- `data` is the raw instruction byte buffer, hex-encoded with a `0x` prefix.
154
- `d1`..`d8` are the same byte prefix as `data` but truncated to N bytes
155
- (only `Some` when the instruction is at least that long), exposed for
156
- handler-dispatch convenience.
157
- `accounts` is the full positional account list in base58. */
158
148
  type decodedInstruction = {
159
149
  name: string,
160
150
  argsJson: string,
@@ -175,22 +165,11 @@ module ResponseTypes = {
175
165
  d8?: string,
176
166
  isInner: bool,
177
167
  isCommitted: bool,
178
- decoded?: decodedInstruction,
179
- }
180
-
181
- type log = {
182
- slot: int,
183
- transactionIndex?: int,
184
- instructionAddress?: array<int>,
185
- programId?: string,
186
- kind?: string,
187
- message?: string,
188
168
  }
189
169
 
190
170
  type queryResponseData = {
191
171
  blocks: array<block>,
192
172
  instructions: array<instruction>,
193
- logs: array<log>,
194
173
  }
195
174
 
196
175
  type queryResponse = {
@@ -200,18 +179,76 @@ module ResponseTypes = {
200
179
  }
201
180
  }
202
181
 
182
+ module EventItems = {
183
+ // The whole per-query input: slot range, the partition's registration
184
+ // selection (by index), and its current addresses (program ids per program
185
+ // name). Instruction selections, field selection, and routing are derived
186
+ // on the Rust side.
187
+ type query = {
188
+ fromSlot: int,
189
+ // Inclusive; None queries to the end of available data.
190
+ toSlot: option<int>,
191
+ maxNumInstructions: int,
192
+ registrationIndexes: array<int>,
193
+ addressesByContractName: dict<array<Address.t>>,
194
+ }
195
+
196
+ type log = {
197
+ kind: string,
198
+ message: string,
199
+ }
200
+
201
+ // One routed instruction; `block` and `transaction` are materialised from
202
+ // the per-chain stores at batch prep.
203
+ type item = {
204
+ onEventRegistrationIndex: int,
205
+ slot: int,
206
+ transactionIndex: int,
207
+ instructionAddress: array<int>,
208
+ programId: string,
209
+ accounts: array<string>,
210
+ data: string,
211
+ d1?: string,
212
+ d2?: string,
213
+ d4?: string,
214
+ d8?: string,
215
+ isInner: bool,
216
+ decoded?: ResponseTypes.decodedInstruction,
217
+ // Present only when the routed registration opted in via `includeLogs`.
218
+ logs?: array<log>,
219
+ }
220
+
221
+ type response = {
222
+ nextSlot: int,
223
+ // One lean header per slot referenced by `items`; the full blocks live in
224
+ // the block store returned alongside.
225
+ blocks: array<ResponseTypes.block>,
226
+ items: array<item>,
227
+ }
228
+ }
229
+
203
230
  type query = QueryTypes.query
204
231
  type queryResponse = ResponseTypes.queryResponse
205
232
 
206
233
  type t = {
207
234
  getHeight: unit => promise<int>,
208
- // Returns the response plus pages of raw transactions and blocks (kept in
209
- // Rust), keyed by (slot, transactionIndex) / slot, materialised at batch prep.
235
+ // Block-data range queries only; the store pages it returns are empty.
210
236
  get: (~query: query) => promise<(queryResponse, TransactionStore.t, BlockStore.t)>,
237
+ // Returns the routed items plus pages of raw transactions and blocks (kept
238
+ // in Rust), keyed by (slot, transactionIndex) / slot, materialised at batch
239
+ // prep.
240
+ getEventItems: (
241
+ ~query: EventItems.query,
242
+ ) => promise<(EventItems.response, TransactionStore.t, BlockStore.t)>,
211
243
  }
212
244
 
213
245
  @send
214
- external classFromConfig: (Core.svmHypersyncClientCtor, cfg, string) => t = "fromConfig"
246
+ external classFromConfig: (
247
+ Core.svmHyperSyncClientCtor,
248
+ cfg,
249
+ string,
250
+ array<Registration.input>,
251
+ ) => t = "fromConfig"
215
252
 
216
253
  let make = (
217
254
  ~url,
@@ -220,10 +257,10 @@ let make = (
220
257
  ~maxNumRetries=?,
221
258
  ~retryBaseMs=?,
222
259
  ~retryCeilingMs=?,
223
- ~programSchemas=?,
260
+ ~eventRegistrations=[],
224
261
  ) => {
225
262
  let envioVersion = Utils.EnvioPackage.value.version
226
- Core.getAddon().svmHypersyncClient->classFromConfig(
263
+ Core.getAddon().svmHyperSyncClient->classFromConfig(
227
264
  {
228
265
  url,
229
266
  ?apiToken,
@@ -231,8 +268,8 @@ let make = (
231
268
  ?maxNumRetries,
232
269
  ?retryBaseMs,
233
270
  ?retryCeilingMs,
234
- ?programSchemas,
235
271
  },
236
272
  `hyperindex/${envioVersion}`,
273
+ eventRegistrations,
237
274
  )
238
275
  }
@@ -3,26 +3,66 @@
3
3
  import * as Core from "../Core.res.mjs";
4
4
  import * as Utils from "../Utils.res.mjs";
5
5
 
6
+ function fromOnEventRegistrations(onEventRegistrations) {
7
+ return onEventRegistrations.map(reg => {
8
+ let eventConfig = reg.eventConfig;
9
+ let args = eventConfig.args;
10
+ let tmp;
11
+ tmp = args === null ? undefined : JSON.stringify(args);
12
+ let definedTypes = eventConfig.definedTypes;
13
+ let tmp$1;
14
+ tmp$1 = definedTypes === null ? undefined : JSON.stringify(definedTypes);
15
+ return {
16
+ index: reg.index,
17
+ instructionName: eventConfig.name,
18
+ contractName: eventConfig.contractName,
19
+ programId: eventConfig.programId,
20
+ isWildcard: reg.isWildcard,
21
+ discriminator: eventConfig.discriminator,
22
+ discriminatorByteLen: eventConfig.discriminatorByteLen,
23
+ isInner: eventConfig.isInner,
24
+ includeLogs: eventConfig.includeLogs,
25
+ accountFilters: eventConfig.accountFilters.map(group => group.map(filter => ({
26
+ position: filter.position,
27
+ values: filter.values
28
+ }))),
29
+ transactionFields: Array.from(eventConfig.selectedTransactionFields),
30
+ blockFields: Array.from(eventConfig.selectedBlockFields),
31
+ accounts: eventConfig.accounts,
32
+ argsJson: tmp,
33
+ definedTypesJson: tmp$1
34
+ };
35
+ });
36
+ }
37
+
38
+ let Registration = {
39
+ fromOnEventRegistrations: fromOnEventRegistrations
40
+ };
41
+
6
42
  let QueryTypes = {};
7
43
 
8
44
  let ResponseTypes = {};
9
45
 
10
- function make(url, apiToken, httpReqTimeoutMillis, maxNumRetries, retryBaseMs, retryCeilingMs, programSchemas) {
46
+ let EventItems = {};
47
+
48
+ function make(url, apiToken, httpReqTimeoutMillis, maxNumRetries, retryBaseMs, retryCeilingMs, eventRegistrationsOpt) {
49
+ let eventRegistrations = eventRegistrationsOpt !== undefined ? eventRegistrationsOpt : [];
11
50
  let envioVersion = Utils.EnvioPackage.value.version;
12
- return Core.getAddon().SvmHypersyncClient.fromConfig({
51
+ return Core.getAddon().SvmHyperSyncClient.fromConfig({
13
52
  url: url,
14
53
  apiToken: apiToken,
15
54
  httpReqTimeoutMillis: httpReqTimeoutMillis,
16
55
  maxNumRetries: maxNumRetries,
17
56
  retryBaseMs: retryBaseMs,
18
- retryCeilingMs: retryCeilingMs,
19
- programSchemas: programSchemas
20
- }, `hyperindex/` + envioVersion);
57
+ retryCeilingMs: retryCeilingMs
58
+ }, `hyperindex/` + envioVersion, eventRegistrations);
21
59
  }
22
60
 
23
61
  export {
62
+ Registration,
24
63
  QueryTypes,
25
64
  ResponseTypes,
65
+ EventItems,
26
66
  make,
27
67
  }
28
68
  /* Core Not a pure module */