envio 3.10.0-subgraph → 3.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 +21 -4
- package/fuel.schema.json +21 -4
- package/index.d.ts +1 -1
- package/package.json +6 -6
- package/src/ChainState.res +9 -73
- package/src/ChainState.res.mjs +6 -58
- package/src/Config.res +73 -27
- package/src/Config.res.mjs +71 -21
- package/src/Core.res +0 -15
- package/src/Core.res.mjs +0 -11
- package/src/EventConfigBuilder.res +14 -10
- package/src/EventConfigBuilder.res.mjs +6 -4
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +6 -8
- package/src/HandlerLoader.res +8 -20
- package/src/HandlerLoader.res.mjs +2 -11
- package/src/HandlerRegister.res +12 -11
- package/src/HandlerRegister.res.mjs +6 -5
- package/src/Internal.res +20 -4
- package/src/Internal.res.mjs +9 -0
- package/src/Main.res +8 -1
- package/src/Main.res.mjs +3 -3
- package/src/Persistence.res +11 -1
- package/src/Persistence.res.mjs +6 -2
- package/src/PgStorage.res +1 -1
- package/src/PgStorage.res.mjs +1 -1
- package/src/SimulateItems.res +13 -6
- package/src/SimulateItems.res.mjs +7 -6
- package/src/TestIndexer.res +6 -5
- package/src/TestIndexer.res.mjs +5 -4
- package/src/UserContext.res +51 -358
- package/src/UserContext.res.mjs +35 -271
- package/src/db/InternalTable.res +1 -1
- package/src/db/InternalTable.res.mjs +2 -1
- package/src/sources/ChainSources.res +72 -0
- package/src/sources/ChainSources.res.mjs +55 -0
- package/src/sources/EvmHyperSyncSource.res +10 -22
- package/src/sources/EvmHyperSyncSource.res.mjs +9 -41
- package/src/sources/FuelHyperSyncSource.res +10 -18
- package/src/sources/FuelHyperSyncSource.res.mjs +8 -38
- package/src/sources/HyperSync.res +31 -0
- package/src/sources/HyperSync.res.mjs +31 -0
- package/src/sources/HyperSync.resi +16 -0
- package/src/sources/StartBlockResolver.res +173 -0
- package/src/sources/StartBlockResolver.res.mjs +134 -0
- package/src/sources/Svm.res +0 -51
- package/src/sources/Svm.res.mjs +0 -46
- package/src/sources/SvmHyperSyncSource.res +20 -9
- package/src/sources/SvmHyperSyncSource.res.mjs +34 -12
- package/svm.schema.json +78 -63
- package/src/subgraph/blocks.ts +0 -176
- package/src/subgraph/calls.ts +0 -217
- package/src/subgraph/conformance.ts +0 -102
- package/src/subgraph/division.ts +0 -133
- package/src/subgraph/errors.ts +0 -90
- package/src/subgraph/graph-ts-types/VERSION +0 -2
- package/src/subgraph/graph-ts-types/chain/arweave.d.ts +0 -70
- package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +0 -327
- package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +0 -233
- package/src/subgraph/graph-ts-types/chain/near.d.ts +0 -253
- package/src/subgraph/graph-ts-types/chain/starknet.d.ts +0 -32
- package/src/subgraph/graph-ts-types/common/collections.d.ts +0 -136
- package/src/subgraph/graph-ts-types/common/conversion.d.ts +0 -11
- package/src/subgraph/graph-ts-types/common/datasource.d.ts +0 -30
- package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
- package/src/subgraph/graph-ts-types/common/json.d.ts +0 -17
- package/src/subgraph/graph-ts-types/common/numbers.d.ts +0 -120
- package/src/subgraph/graph-ts-types/common/value.d.ts +0 -120
- package/src/subgraph/graph-ts-types/common/yaml.d.ts +0 -90
- package/src/subgraph/graph-ts-types/global/global.d.ts +0 -194
- package/src/subgraph/graph-ts-types/helper-functions.d.ts +0 -22
- package/src/subgraph/graph-ts-types/index.d.ts +0 -102
- package/src/subgraph/graph-ts.ts +0 -1948
- package/src/subgraph/hosts.ts +0 -148
- package/src/subgraph/runtime.ts +0 -863
- package/src/subgraph/scope.ts +0 -66
package/src/sources/Svm.res
CHANGED
|
@@ -80,54 +80,3 @@ let make = (~logger: Pino.t): Ecosystem.t => {
|
|
|
80
80
|
},
|
|
81
81
|
toRawEvent: _ => JsError.throwWithMessage("Raw events are not supported for SVM"),
|
|
82
82
|
}
|
|
83
|
-
|
|
84
|
-
module GetFinalizedSlot = {
|
|
85
|
-
let route = Rpc.makeRpcRoute(
|
|
86
|
-
"getSlot",
|
|
87
|
-
S.tuple(s => {
|
|
88
|
-
s.tag(0, {"commitment": "finalized"})
|
|
89
|
-
()
|
|
90
|
-
}),
|
|
91
|
-
S.int,
|
|
92
|
-
)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let makeRPCSource = (~chainId, ~rpc: string, ~sourceFor: Source.sourceFor=Sync): Source.t => {
|
|
96
|
-
let client = Rest.client(rpc)
|
|
97
|
-
|
|
98
|
-
let urlHost = switch Utils.Url.getHostFromUrl(rpc) {
|
|
99
|
-
| None =>
|
|
100
|
-
JsError.throwWithMessage(
|
|
101
|
-
`The RPC url for chain ${chainId->ChainId.toString} is in incorrect format. The RPC url needs to start with either http:// or https://`,
|
|
102
|
-
)
|
|
103
|
-
| Some(host) => host
|
|
104
|
-
}
|
|
105
|
-
let name = `RPC (${urlHost})`
|
|
106
|
-
|
|
107
|
-
{
|
|
108
|
-
name,
|
|
109
|
-
sourceFor,
|
|
110
|
-
chainId,
|
|
111
|
-
poweredByHyperSync: false,
|
|
112
|
-
pollingInterval: 10_000,
|
|
113
|
-
getBlockHashes: (~blockNumbers as _, ~logger as _) =>
|
|
114
|
-
JsError.throwWithMessage("Svm does not support getting block hashes"),
|
|
115
|
-
getHeightOrThrow: async () => {
|
|
116
|
-
let timerRef = Performance.now()
|
|
117
|
-
let height = await GetFinalizedSlot.route->Rest.fetch((), ~client)
|
|
118
|
-
let seconds = timerRef->Performance.secondsSince
|
|
119
|
-
{Source.height, requestStats: [{Source.method: "getSlot", seconds}]}
|
|
120
|
-
},
|
|
121
|
-
getItemsOrThrow: (
|
|
122
|
-
~fromBlock as _,
|
|
123
|
-
~toBlock as _,
|
|
124
|
-
~addressSet as _,
|
|
125
|
-
~knownHeight as _,
|
|
126
|
-
~partitionId as _,
|
|
127
|
-
~selection as _,
|
|
128
|
-
~itemsTarget as _,
|
|
129
|
-
~retry as _,
|
|
130
|
-
~logger as _,
|
|
131
|
-
) => JsError.throwWithMessage("Svm does not support getting items"),
|
|
132
|
-
}
|
|
133
|
-
}
|
package/src/sources/Svm.res.mjs
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as Rpc from "./Rpc.res.mjs";
|
|
4
|
-
import * as Rest from "../vendored/Rest.res.mjs";
|
|
5
|
-
import * as Utils from "../Utils.res.mjs";
|
|
6
|
-
import * as ChainId from "../ChainId.res.mjs";
|
|
7
3
|
import * as Logging from "../Logging.res.mjs";
|
|
8
4
|
import * as Internal from "../Internal.res.mjs";
|
|
9
5
|
import * as BlockStore from "./BlockStore.res.mjs";
|
|
10
|
-
import * as Performance from "../bindings/Performance.res.mjs";
|
|
11
6
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
12
7
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
13
8
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
@@ -79,45 +74,6 @@ function make(logger) {
|
|
|
79
74
|
};
|
|
80
75
|
}
|
|
81
76
|
|
|
82
|
-
let route = Rpc.makeRpcRoute("getSlot", S$RescriptSchema.tuple(s => {
|
|
83
|
-
s.tag(0, {
|
|
84
|
-
commitment: "finalized"
|
|
85
|
-
});
|
|
86
|
-
}), S$RescriptSchema.int);
|
|
87
|
-
|
|
88
|
-
let GetFinalizedSlot = {
|
|
89
|
-
route: route
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
function makeRPCSource(chainId, rpc, sourceForOpt) {
|
|
93
|
-
let sourceFor = sourceForOpt !== undefined ? sourceForOpt : "Sync";
|
|
94
|
-
let client = Rest.client(rpc, undefined);
|
|
95
|
-
let host = Utils.Url.getHostFromUrl(rpc);
|
|
96
|
-
let urlHost = host !== undefined ? host : Stdlib_JsError.throwWithMessage(`The RPC url for chain ` + ChainId.toString(chainId) + ` is in incorrect format. The RPC url needs to start with either http:// or https://`);
|
|
97
|
-
let name = `RPC (` + urlHost + `)`;
|
|
98
|
-
return {
|
|
99
|
-
name: name,
|
|
100
|
-
sourceFor: sourceFor,
|
|
101
|
-
chainId: chainId,
|
|
102
|
-
poweredByHyperSync: false,
|
|
103
|
-
pollingInterval: 10000,
|
|
104
|
-
getBlockHashes: (param, param$1) => Stdlib_JsError.throwWithMessage("Svm does not support getting block hashes"),
|
|
105
|
-
getHeightOrThrow: async () => {
|
|
106
|
-
let timerRef = Performance.now();
|
|
107
|
-
let height = await Rest.fetch(route, undefined, client);
|
|
108
|
-
let seconds = Performance.secondsSince(timerRef);
|
|
109
|
-
return {
|
|
110
|
-
height: height,
|
|
111
|
-
requestStats: [{
|
|
112
|
-
method: "getSlot",
|
|
113
|
-
seconds: seconds
|
|
114
|
-
}]
|
|
115
|
-
};
|
|
116
|
-
},
|
|
117
|
-
getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8) => Stdlib_JsError.throwWithMessage("Svm does not support getting items")
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
77
|
let transactionFields = Internal.allSvmTransactionFields;
|
|
122
78
|
|
|
123
79
|
export {
|
|
@@ -127,7 +83,5 @@ export {
|
|
|
127
83
|
eventBlockFieldMask,
|
|
128
84
|
attachAccountActivities,
|
|
129
85
|
make,
|
|
130
|
-
GetFinalizedSlot,
|
|
131
|
-
makeRPCSource,
|
|
132
86
|
}
|
|
133
87
|
/* eventTransactionFieldMask Not a pure module */
|
|
@@ -10,13 +10,17 @@ type options = {
|
|
|
10
10
|
addressStore: AddressStore.t,
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
let namedAccounts = (
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
let namedAccounts = (
|
|
14
|
+
~slots: array<Internal.svmAccountSlot>,
|
|
15
|
+
~accountArguments: array<string>,
|
|
16
|
+
~programId: string,
|
|
17
|
+
): dict<Envio.svmInstructionAccount> => {
|
|
16
18
|
let out = Dict.make()
|
|
17
|
-
|
|
18
|
-
switch accountArguments->Array.get(i) {
|
|
19
|
-
|
|
|
19
|
+
slots->Array.forEachWithIndex((slot, i) =>
|
|
20
|
+
switch (slot, accountArguments->Array.get(i)) {
|
|
21
|
+
| (Unnamed, _) | (_, None) => ()
|
|
22
|
+
| (Optional(_), Some(address)) if address === programId => ()
|
|
23
|
+
| (Required(name), Some(address)) | (Optional(name), Some(address)) =>
|
|
20
24
|
out->Dict.set(
|
|
21
25
|
name,
|
|
22
26
|
{
|
|
@@ -25,7 +29,6 @@ let namedAccounts = (~idlNames: array<string>, ~accountArguments: array<string>)
|
|
|
25
29
|
instructionAccountIndex: i,
|
|
26
30
|
},
|
|
27
31
|
)
|
|
28
|
-
| None => ()
|
|
29
32
|
}
|
|
30
33
|
)
|
|
31
34
|
out
|
|
@@ -94,7 +97,11 @@ let toSvmInstruction = (
|
|
|
94
97
|
if hasSelection("accounts") {
|
|
95
98
|
out->setField(
|
|
96
99
|
"accounts",
|
|
97
|
-
namedAccounts(
|
|
100
|
+
namedAccounts(
|
|
101
|
+
~slots=eventConfig.accounts,
|
|
102
|
+
~accountArguments=item.accounts,
|
|
103
|
+
~programId=item.programId,
|
|
104
|
+
),
|
|
98
105
|
)
|
|
99
106
|
}
|
|
100
107
|
if hasSelection("accountArguments") {
|
|
@@ -123,12 +130,14 @@ let make = (
|
|
|
123
130
|
): t => {
|
|
124
131
|
let name = "SvmHyperSync"
|
|
125
132
|
|
|
133
|
+
let apiToken = apiToken->HyperSync.requireApiToken
|
|
134
|
+
|
|
126
135
|
// The whole per-(instruction, chain) registration set crosses the boundary
|
|
127
136
|
// once at construction; the client derives instruction selections, field
|
|
128
137
|
// selections, Borsh decoders, and the routing index from it.
|
|
129
138
|
let client = SvmHyperSyncClient.make(
|
|
130
139
|
~url=endpointUrl,
|
|
131
|
-
~apiToken
|
|
140
|
+
~apiToken,
|
|
132
141
|
~httpReqTimeoutMillis=clientTimeoutMillis,
|
|
133
142
|
~programs=SvmHyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations),
|
|
134
143
|
~addressStore,
|
|
@@ -257,5 +266,7 @@ let make = (
|
|
|
257
266
|
{height, requestStats: [{method: "getHeight", seconds}]}
|
|
258
267
|
},
|
|
259
268
|
getItemsOrThrow,
|
|
269
|
+
createHeightSubscription: (~onHeight, ~onStatus) =>
|
|
270
|
+
HyperSyncSSE.subscribe(~hyperSyncUrl=endpointUrl, ~apiToken, ~onHeight, ~onStatus),
|
|
260
271
|
}
|
|
261
272
|
}
|
|
@@ -4,23 +4,42 @@ import * as Source from "./Source.res.mjs";
|
|
|
4
4
|
import * as HyperSync from "./HyperSync.res.mjs";
|
|
5
5
|
import * as Performance from "../bindings/Performance.res.mjs";
|
|
6
6
|
import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
|
|
7
|
+
import * as HyperSyncSSE from "./HyperSyncSSE.res.mjs";
|
|
7
8
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
8
9
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
9
10
|
import * as SvmHyperSyncClient from "./SvmHyperSyncClient.res.mjs";
|
|
10
11
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
11
12
|
|
|
12
|
-
function namedAccounts(
|
|
13
|
+
function namedAccounts(slots, accountArguments, programId) {
|
|
13
14
|
let out = {};
|
|
14
|
-
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
accountName: name,
|
|
20
|
-
instructionAccountIndex: i
|
|
21
|
-
};
|
|
15
|
+
slots.forEach((slot, i) => {
|
|
16
|
+
let match = accountArguments[i];
|
|
17
|
+
let name;
|
|
18
|
+
let address;
|
|
19
|
+
if (typeof slot !== "object") {
|
|
22
20
|
return;
|
|
23
21
|
}
|
|
22
|
+
if (slot.TAG === "Required") {
|
|
23
|
+
if (match === undefined) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
name = slot._0;
|
|
27
|
+
address = match;
|
|
28
|
+
} else {
|
|
29
|
+
if (match === undefined) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (match === programId) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
name = slot._0;
|
|
36
|
+
address = match;
|
|
37
|
+
}
|
|
38
|
+
out[name] = {
|
|
39
|
+
address: address,
|
|
40
|
+
accountName: name,
|
|
41
|
+
instructionAccountIndex: i
|
|
42
|
+
};
|
|
24
43
|
});
|
|
25
44
|
return out;
|
|
26
45
|
}
|
|
@@ -70,7 +89,7 @@ function toSvmInstruction(item, programName, instructionName, eventConfig, field
|
|
|
70
89
|
setField(out, "args", args);
|
|
71
90
|
}
|
|
72
91
|
if (fieldSelection.instructionFields.has("accounts")) {
|
|
73
|
-
setField(out, "accounts", namedAccounts(eventConfig.accounts, item.accounts));
|
|
92
|
+
setField(out, "accounts", namedAccounts(eventConfig.accounts, item.accounts, item.programId));
|
|
74
93
|
}
|
|
75
94
|
if (fieldSelection.instructionFields.has("accountArguments")) {
|
|
76
95
|
setField(out, "accountArguments", item.accounts);
|
|
@@ -83,8 +102,10 @@ function toSvmInstruction(item, programName, instructionName, eventConfig, field
|
|
|
83
102
|
|
|
84
103
|
function make(param) {
|
|
85
104
|
let onEventRegistrations = param.onEventRegistrations;
|
|
105
|
+
let endpointUrl = param.endpointUrl;
|
|
86
106
|
let chainId = param.chainId;
|
|
87
|
-
let
|
|
107
|
+
let apiToken = HyperSync.requireApiToken(param.apiToken);
|
|
108
|
+
let client = SvmHyperSyncClient.make(endpointUrl, apiToken, param.clientTimeoutMillis, undefined, undefined, SvmHyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations), param.addressStore);
|
|
88
109
|
let getItemsOrThrow = async (fromBlock, toBlock, addressSet, knownHeight, param, selection, itemsTarget, retry, param$1) => {
|
|
89
110
|
let totalTimeRef = Performance.now();
|
|
90
111
|
let pageFetchRef = Performance.now();
|
|
@@ -178,7 +199,8 @@ function make(param) {
|
|
|
178
199
|
}]
|
|
179
200
|
};
|
|
180
201
|
},
|
|
181
|
-
getItemsOrThrow: getItemsOrThrow
|
|
202
|
+
getItemsOrThrow: getItemsOrThrow,
|
|
203
|
+
createHeightSubscription: (onHeight, onStatus) => HyperSyncSSE.subscribe(endpointUrl, apiToken, onHeight, onStatus)
|
|
182
204
|
};
|
|
183
205
|
}
|
|
184
206
|
|
package/svm.schema.json
CHANGED
|
@@ -66,6 +66,13 @@
|
|
|
66
66
|
"items": {
|
|
67
67
|
"$ref": "#/$defs/Chain"
|
|
68
68
|
}
|
|
69
|
+
},
|
|
70
|
+
"programs": {
|
|
71
|
+
"description": "Solana programs to index. Programs are defined once for the whole project; `program_id` says where each one lives on every chain.",
|
|
72
|
+
"type": "array",
|
|
73
|
+
"items": {
|
|
74
|
+
"$ref": "#/$defs/Program"
|
|
75
|
+
}
|
|
69
76
|
}
|
|
70
77
|
},
|
|
71
78
|
"additionalProperties": false,
|
|
@@ -224,20 +231,18 @@
|
|
|
224
231
|
]
|
|
225
232
|
},
|
|
226
233
|
"rpc": {
|
|
227
|
-
"description": "RPC endpoint URL for
|
|
234
|
+
"description": "RPC endpoint URL for the Svm cluster. Accepted but unused: instruction sync is served by HyperSync.",
|
|
228
235
|
"type": [
|
|
229
236
|
"string",
|
|
230
237
|
"null"
|
|
231
238
|
]
|
|
232
239
|
},
|
|
233
|
-
"
|
|
234
|
-
"description": "The slot
|
|
235
|
-
"
|
|
236
|
-
"format": "uint64",
|
|
237
|
-
"minimum": 0
|
|
240
|
+
"start_slot": {
|
|
241
|
+
"description": "The slot at which the indexer should start ingesting data, or \"latest\" to start from the chain's current slot when the indexer is first deployed. Once resolved, the concrete slot is persisted and reused every time the indexer resumes normally (for example recovering from a crash), so downtime is backfilled instead of skipped. Running `envio start`/`dev` with -r (--restart) resets this like any other config change: \"latest\" resolves again, against the head at that time.",
|
|
242
|
+
"$ref": "#/$defs/StartBlock"
|
|
238
243
|
},
|
|
239
|
-
"
|
|
240
|
-
"description": "The slot
|
|
244
|
+
"end_slot": {
|
|
245
|
+
"description": "The slot at which the indexer should terminate.",
|
|
241
246
|
"type": [
|
|
242
247
|
"integer",
|
|
243
248
|
"null"
|
|
@@ -254,11 +259,11 @@
|
|
|
254
259
|
"format": "uint32",
|
|
255
260
|
"minimum": 0
|
|
256
261
|
},
|
|
257
|
-
"
|
|
258
|
-
"description": "
|
|
262
|
+
"hypersync_config": {
|
|
263
|
+
"description": "HyperSync Config for fetching historical instructions on this chain. Optional for the `solana` and `solana-devnet` chain ids, which default to their public HyperSync endpoints; required for any other chain id.",
|
|
259
264
|
"anyOf": [
|
|
260
265
|
{
|
|
261
|
-
"$ref": "#/$defs/
|
|
266
|
+
"$ref": "#/$defs/HypersyncConfig"
|
|
262
267
|
},
|
|
263
268
|
{
|
|
264
269
|
"type": "null"
|
|
@@ -269,7 +274,7 @@
|
|
|
269
274
|
"additionalProperties": false,
|
|
270
275
|
"required": [
|
|
271
276
|
"id",
|
|
272
|
-
"
|
|
277
|
+
"start_slot"
|
|
273
278
|
]
|
|
274
279
|
},
|
|
275
280
|
"ChainId": {
|
|
@@ -293,31 +298,23 @@
|
|
|
293
298
|
"solana-devnet"
|
|
294
299
|
]
|
|
295
300
|
},
|
|
296
|
-
"
|
|
297
|
-
"
|
|
298
|
-
"
|
|
299
|
-
|
|
300
|
-
"
|
|
301
|
-
"
|
|
302
|
-
|
|
303
|
-
"$ref": "#/$defs/HypersyncConfig"
|
|
304
|
-
},
|
|
305
|
-
{
|
|
306
|
-
"type": "null"
|
|
307
|
-
}
|
|
308
|
-
]
|
|
301
|
+
"StartBlock": {
|
|
302
|
+
"description": "A chain's configured start block: either a concrete block number or the\nliteral \"latest\". Config parsing never touches the network, so `Latest`\nstays unresolved here — it's resolved once at runtime, right before the\nindexer's first-ever persisted state is written, and never re-resolved\non a normal resume (see packages/envio/src/sources/StartBlockResolver.res).\nNote: this repo's `-r`/`--restart` CLI flag wipes the DB and re-deploys\nfrom scratch, so it re-resolves \"latest\" too — \"resume\" here means the\nopposite: recovering from a crash or process restart without `-r`.",
|
|
303
|
+
"anyOf": [
|
|
304
|
+
{
|
|
305
|
+
"type": "integer",
|
|
306
|
+
"format": "uint64",
|
|
307
|
+
"minimum": 0
|
|
309
308
|
},
|
|
310
|
-
|
|
311
|
-
"
|
|
312
|
-
"type": "array",
|
|
313
|
-
"items": {
|
|
314
|
-
"$ref": "#/$defs/Program"
|
|
315
|
-
}
|
|
309
|
+
{
|
|
310
|
+
"$ref": "#/$defs/StartBlockTag"
|
|
316
311
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
312
|
+
]
|
|
313
|
+
},
|
|
314
|
+
"StartBlockTag": {
|
|
315
|
+
"type": "string",
|
|
316
|
+
"enum": [
|
|
317
|
+
"latest"
|
|
321
318
|
]
|
|
322
319
|
},
|
|
323
320
|
"HypersyncConfig": {
|
|
@@ -341,8 +338,8 @@
|
|
|
341
338
|
"type": "string"
|
|
342
339
|
},
|
|
343
340
|
"program_id": {
|
|
344
|
-
"description": "Base58-encoded program id (32 bytes).",
|
|
345
|
-
"
|
|
341
|
+
"description": "Base58-encoded program id (32 bytes). A single value is allowed only when the config defines one chain; with several, give a mapping keyed by chain id that names every one of them, writing `_` for a chain the program is not deployed on.",
|
|
342
|
+
"$ref": "#/$defs/SvmProgramId"
|
|
346
343
|
},
|
|
347
344
|
"handler": {
|
|
348
345
|
"description": "Optional relative path to a file where handlers are registered for the given program. If not provided, handlers can be auto-loaded from the src directory.",
|
|
@@ -359,7 +356,7 @@
|
|
|
359
356
|
]
|
|
360
357
|
},
|
|
361
358
|
"instructions": {
|
|
362
|
-
"description": "Instructions to index. With `idl:`, omit this list to take the full usable IDL catalog. A
|
|
359
|
+
"description": "Instructions to index. With `idl:`, omit this list to take the full usable IDL catalog. A row whose name the IDL declares replaces that instruction, and must spell out `accounts` and `args`; every other row adds one. Give `accounts` where you want the slots named — an empty list names none, the same as leaving it out. `args` is not the same shape: setting it attaches a decoder that also filters, so leaving it out and setting it to `[]` are different asks.",
|
|
363
360
|
"type": "array",
|
|
364
361
|
"items": {
|
|
365
362
|
"$ref": "#/$defs/Instruction"
|
|
@@ -372,6 +369,28 @@
|
|
|
372
369
|
"program_id"
|
|
373
370
|
]
|
|
374
371
|
},
|
|
372
|
+
"SvmProgramId": {
|
|
373
|
+
"title": "Program id",
|
|
374
|
+
"description": "Base58-encoded program id (32 bytes).\nA single value is allowed only when the config defines one chain.\nWith several chains, give a mapping keyed by chain id that names every one of them; write `_` for a chain the program is not deployed on.",
|
|
375
|
+
"anyOf": [
|
|
376
|
+
{
|
|
377
|
+
"type": "string"
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"type": "object",
|
|
381
|
+
"additionalProperties": {
|
|
382
|
+
"type": "string"
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
],
|
|
386
|
+
"examples": [
|
|
387
|
+
"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s",
|
|
388
|
+
{
|
|
389
|
+
"solana": "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s",
|
|
390
|
+
"solana-devnet": "_"
|
|
391
|
+
}
|
|
392
|
+
]
|
|
393
|
+
},
|
|
375
394
|
"Instruction": {
|
|
376
395
|
"type": "object",
|
|
377
396
|
"properties": {
|
|
@@ -380,24 +399,21 @@
|
|
|
380
399
|
"type": "string"
|
|
381
400
|
},
|
|
382
401
|
"discriminator": {
|
|
383
|
-
"description": "
|
|
384
|
-
"type":
|
|
385
|
-
"string",
|
|
386
|
-
"null"
|
|
387
|
-
]
|
|
402
|
+
"description": "0x-prefixed hex instruction-data prefix to dispatch on, of any whole number of bytes; an 8-byte value matches the standard Anchor discriminator. The empty prefix, written \"0x\", is carried by every call, so it is how a row matches every instruction of the program. This is the form `instruction.discriminator` reads back, so a config value and a handler comparison are the same string. Every instruction whose prefix an on-chain call carries receives it, so a program-wide entry fires alongside a keyed one, and two entries may share a prefix (say, the layouts before and after a program upgrade): each decodes with its own `args`, and one whose layout rejects the data is skipped for that call.",
|
|
403
|
+
"type": "string"
|
|
388
404
|
},
|
|
389
405
|
"accounts": {
|
|
390
|
-
"description": "Optional positional account
|
|
406
|
+
"description": "Optional positional account slots, in the order the program expects them. The Nth entry names account slot N on the dispatched instruction; named slots surface as `instruction.accounts.<name>` when `fields.instruction` includes `accounts`. The raw slots are available either way, so this only adds the names. Required on a row that replaces an instruction the IDL declares.",
|
|
391
407
|
"type": [
|
|
392
408
|
"array",
|
|
393
409
|
"null"
|
|
394
410
|
],
|
|
395
411
|
"items": {
|
|
396
|
-
"
|
|
412
|
+
"$ref": "#/$defs/SvmAccountSlot"
|
|
397
413
|
}
|
|
398
414
|
},
|
|
399
415
|
"args": {
|
|
400
|
-
"description": "
|
|
416
|
+
"description": "Borsh argument schema. Each entry names one arg and gives its type; the decoder walks the instruction data after the discriminator in declared order, and a call whose data the layout rejects is skipped. Setting it is therefore also a filter: `[]` says the instruction takes no arguments, so only calls carrying nothing past the discriminator are indexed. Omit it instead to attach no decoder at all — every matched call is indexed and the payload stays raw, reachable as `instruction.data`. An `idl` always declares the layout of the instructions it names, empty included. Required on a row that replaces an instruction the IDL declares.",
|
|
401
417
|
"type": [
|
|
402
418
|
"array",
|
|
403
419
|
"null"
|
|
@@ -409,7 +425,19 @@
|
|
|
409
425
|
},
|
|
410
426
|
"additionalProperties": false,
|
|
411
427
|
"required": [
|
|
412
|
-
"name"
|
|
428
|
+
"name",
|
|
429
|
+
"discriminator"
|
|
430
|
+
]
|
|
431
|
+
},
|
|
432
|
+
"SvmAccountSlot": {
|
|
433
|
+
"title": "Account slot",
|
|
434
|
+
"description": "One positional account slot of the instruction.\n- `payer` names a slot the call always carries; it surfaces as `instruction.accounts.payer`.\n- `?authority` names an optional slot: the key is absent from `instruction.accounts` when the call leaves the slot out or fills it with the program id.\n- `_` holds a position without naming it, so the slots after it keep theirs. It is never surfaced and never filterable, and the list may not end with one.",
|
|
435
|
+
"type": "string",
|
|
436
|
+
"pattern": "^(?:_|\\??[A-Za-z0-9_]*[A-Za-z][A-Za-z0-9_]*)$",
|
|
437
|
+
"examples": [
|
|
438
|
+
"payer",
|
|
439
|
+
"?authority",
|
|
440
|
+
"_"
|
|
413
441
|
]
|
|
414
442
|
},
|
|
415
443
|
"ArgDef": {
|
|
@@ -432,7 +460,7 @@
|
|
|
432
460
|
]
|
|
433
461
|
},
|
|
434
462
|
"ArgType": {
|
|
435
|
-
"description": "User-facing Borsh type grammar. Mirrors\n`hypersync_client_solana::decode::FieldType`. The YAML accepts either:\n- A bare string for
|
|
463
|
+
"description": "User-facing Borsh type grammar. Mirrors\n`hypersync_client_solana::decode::FieldType`. The YAML accepts either:\n- A bare string for a primitive (`u64`, `pubkey`, `bool`, ...).\n- A one-key mapping for a composite (`{ vec: u8 }`, `{ option: pubkey }`,\n `{ array: [u8, 32] }`, `{ struct: [...] }`, `{ enum: [...] }`).\n\nA nominal type is declared inline with `struct` / `enum` at the field\nthat uses it. There is no way to name one and refer to it: attach an\n`idl` to the program when its types are shared between instructions.",
|
|
436
464
|
"anyOf": [
|
|
437
465
|
{
|
|
438
466
|
"$ref": "#/$defs/ArgPrimitive"
|
|
@@ -516,20 +544,7 @@
|
|
|
516
544
|
"additionalProperties": false
|
|
517
545
|
},
|
|
518
546
|
{
|
|
519
|
-
"description": "
|
|
520
|
-
"type": "object",
|
|
521
|
-
"properties": {
|
|
522
|
-
"defined": {
|
|
523
|
-
"type": "string"
|
|
524
|
-
}
|
|
525
|
-
},
|
|
526
|
-
"required": [
|
|
527
|
-
"defined"
|
|
528
|
-
],
|
|
529
|
-
"additionalProperties": false
|
|
530
|
-
},
|
|
531
|
-
{
|
|
532
|
-
"description": "Inline-or-registry struct. Used as a nominal type definition in\nthe `defined_types` registry; rarely seen at the field level.",
|
|
547
|
+
"description": "A struct, declared inline at the field that uses it or held in the\n`defined_types` registry.",
|
|
533
548
|
"type": "object",
|
|
534
549
|
"properties": {
|
|
535
550
|
"struct": {
|
|
@@ -545,7 +560,7 @@
|
|
|
545
560
|
"additionalProperties": false
|
|
546
561
|
},
|
|
547
562
|
{
|
|
548
|
-
"description": "
|
|
563
|
+
"description": "An enum, declared inline at the field that uses it or held in the\n`defined_types` registry. Borsh selects a variant by its position\nhere, with a one-byte tag.",
|
|
549
564
|
"type": "object",
|
|
550
565
|
"properties": {
|
|
551
566
|
"enum": {
|