envio 3.7.0 → 3.9.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 +2 -2
- package/index.d.ts +399 -156
- package/package.json +6 -6
- package/src/AddressRows.res +121 -0
- package/src/AddressRows.res.mjs +143 -0
- package/src/Batch.res +2 -0
- package/src/Batch.res.mjs +2 -1
- package/src/ChainState.res +82 -68
- package/src/ChainState.res.mjs +81 -65
- package/src/ChainState.resi +14 -9
- package/src/Config.res +41 -91
- package/src/Config.res.mjs +34 -68
- package/src/ContractMapping.res +66 -0
- package/src/ContractMapping.res.mjs +73 -0
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +4 -0
- package/src/Envio.res +54 -76
- package/src/EventConfigBuilder.res +157 -30
- package/src/EventConfigBuilder.res.mjs +118 -24
- package/src/FetchState.res +59 -67
- package/src/FetchState.res.mjs +34 -44
- package/src/HandlerRegister.res +20 -11
- package/src/HandlerRegister.res.mjs +22 -5
- package/src/Hasura.res +30 -22
- package/src/Hasura.res.mjs +11 -5
- package/src/InMemoryStore.res +18 -36
- package/src/InMemoryStore.res.mjs +12 -26
- package/src/IndexerState.res +21 -1
- package/src/IndexerState.res.mjs +9 -3
- package/src/IndexerState.resi +1 -0
- package/src/Internal.res +33 -13
- package/src/Internal.res.mjs +12 -16
- package/src/Main.res +27 -20
- package/src/Main.res.mjs +19 -14
- package/src/MemoryStorage.res +78 -73
- package/src/MemoryStorage.res.mjs +66 -81
- package/src/Metrics.res +15 -1
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +34 -18
- package/src/Persistence.res.mjs +8 -5
- package/src/PgStorage.res +189 -66
- package/src/PgStorage.res.mjs +93 -59
- package/src/Rollback.res +14 -10
- package/src/Rollback.res.mjs +4 -2
- package/src/SimulateItems.res +254 -9
- package/src/SimulateItems.res.mjs +214 -47
- package/src/TestIndexer.res +119 -121
- package/src/TestIndexer.res.mjs +95 -100
- package/src/Utils.res +7 -0
- package/src/Utils.res.mjs +9 -2
- package/src/Writing.res +2 -0
- package/src/Writing.res.mjs +2 -1
- package/src/bindings/ClickHouse.res +39 -6
- package/src/bindings/ClickHouse.res.mjs +29 -4
- package/src/bindings/NodeJs.res +9 -0
- package/src/bindings/NodeJs.res.mjs +8 -1
- package/src/bindings/Postgres.res +9 -0
- package/src/bindings/Postgres.res.mjs +3 -0
- package/src/db/EntityHistory.res +12 -18
- package/src/db/EntityHistory.res.mjs +3 -14
- package/src/db/InternalTable.res +182 -65
- package/src/db/InternalTable.res.mjs +183 -73
- package/src/db/Table.res +24 -0
- package/src/db/Table.res.mjs +20 -1
- package/src/sources/AddressSet.res +0 -22
- package/src/sources/AddressStore.res +48 -88
- package/src/sources/AddressStore.res.mjs +11 -22
- package/src/sources/EvmHyperSyncSource.res +3 -2
- package/src/sources/SimulateSource.res +8 -4
- package/src/sources/SimulateSource.res.mjs +7 -3
- package/src/sources/Svm.res +34 -7
- package/src/sources/Svm.res.mjs +32 -4
- package/src/sources/SvmHyperSyncClient.res +24 -30
- package/src/sources/SvmHyperSyncClient.res.mjs +3 -2
- package/src/sources/SvmHyperSyncSource.res +88 -36
- package/src/sources/SvmHyperSyncSource.res.mjs +71 -39
- package/src/sources/TransactionStore.res +38 -0
- package/src/sources/TransactionStore.res.mjs +5 -0
- package/svm.schema.json +37 -82
package/src/Config.res.mjs
CHANGED
|
@@ -16,6 +16,7 @@ import * as BigDecimal from "./bindings/BigDecimal.res.mjs";
|
|
|
16
16
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
17
17
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
18
18
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
19
|
+
import * as ContractMapping from "./ContractMapping.res.mjs";
|
|
19
20
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
20
21
|
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
21
22
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
@@ -32,57 +33,6 @@ function chainIdColumnName(format) {
|
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
let name = "envio_addresses";
|
|
36
|
-
|
|
37
|
-
function makeId(chainId, address) {
|
|
38
|
-
return ChainId.toString(chainId) + "-" + address;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function getAddress(entity) {
|
|
42
|
-
let sepIdx = entity.id.indexOf("-");
|
|
43
|
-
return entity.id.slice(sepIdx + 1 | 0, entity.id.length);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
let schema = S$RescriptSchema.schema(s => ({
|
|
47
|
-
id: s.m(S$RescriptSchema.string),
|
|
48
|
-
chain_id: s.m(ChainId.schema),
|
|
49
|
-
registration_block: s.m(S$RescriptSchema.int),
|
|
50
|
-
registration_log_index: s.m(S$RescriptSchema.int),
|
|
51
|
-
contract_name: s.m(S$RescriptSchema.string)
|
|
52
|
-
}));
|
|
53
|
-
|
|
54
|
-
let table = Table.mkTable(name, undefined, [
|
|
55
|
-
Table.mkField("id", "String", S$RescriptSchema.string, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
56
|
-
Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
57
|
-
Table.mkField("registration_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
58
|
-
Table.mkField("registration_log_index", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
59
|
-
Table.mkField("contract_name", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
60
|
-
], undefined);
|
|
61
|
-
|
|
62
|
-
let entityConfig_storage = {
|
|
63
|
-
postgres: true,
|
|
64
|
-
clickhouse: false
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
let entityConfig = {
|
|
68
|
-
name: name,
|
|
69
|
-
index: -1,
|
|
70
|
-
schema: schema,
|
|
71
|
-
table: table,
|
|
72
|
-
storage: entityConfig_storage,
|
|
73
|
-
crossChain: true
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
let EnvioAddresses = {
|
|
77
|
-
name: name,
|
|
78
|
-
index: -1,
|
|
79
|
-
makeId: makeId,
|
|
80
|
-
getAddress: getAddress,
|
|
81
|
-
schema: schema,
|
|
82
|
-
table: table,
|
|
83
|
-
entityConfig: entityConfig
|
|
84
|
-
};
|
|
85
|
-
|
|
86
36
|
let rpcSourceForSchema = S$RescriptSchema.$$enum([
|
|
87
37
|
"sync",
|
|
88
38
|
"fallback",
|
|
@@ -124,9 +74,6 @@ let publicConfigChainSchema = S$RescriptSchema.schema(s => ({
|
|
|
124
74
|
let svmEventDescriptorSchema = S$RescriptSchema.schema(s => ({
|
|
125
75
|
discriminator: s.m(S$RescriptSchema.option(S$RescriptSchema.string)),
|
|
126
76
|
discriminatorByteLen: s.m(S$RescriptSchema.int),
|
|
127
|
-
transactionFields: s.m(S$RescriptSchema.array(Internal.svmTransactionFieldSchema)),
|
|
128
|
-
blockFields: s.m(S$RescriptSchema.option(S$RescriptSchema.array(Internal.svmBlockFieldSchema))),
|
|
129
|
-
includeLogs: s.m(S$RescriptSchema.bool),
|
|
130
77
|
accountFilters: s.m(S$RescriptSchema.option(S$RescriptSchema.array(S$RescriptSchema.array(S$RescriptSchema.schema(s => ({
|
|
131
78
|
position: s.m(S$RescriptSchema.int),
|
|
132
79
|
values: s.m(S$RescriptSchema.array(S$RescriptSchema.string))
|
|
@@ -204,10 +151,18 @@ let propertySchema = S$RescriptSchema.schema(s => ({
|
|
|
204
151
|
description: s.m(S$RescriptSchema.option(S$RescriptSchema.string))
|
|
205
152
|
}));
|
|
206
153
|
|
|
154
|
+
let clickhouseSkippingIndexSchema = S$RescriptSchema.object(s => ({
|
|
155
|
+
name: s.f("name", S$RescriptSchema.string),
|
|
156
|
+
expr: s.f("expr", S$RescriptSchema.string),
|
|
157
|
+
type: s.f("type", S$RescriptSchema.string),
|
|
158
|
+
granularity: s.f("granularity", S$RescriptSchema.option(S$RescriptSchema.int))
|
|
159
|
+
}));
|
|
160
|
+
|
|
207
161
|
let clickhouseTableOptionsSchema = S$RescriptSchema.object(s => ({
|
|
208
162
|
partitionBy: s.f("partitionBy", S$RescriptSchema.option(S$RescriptSchema.string)),
|
|
209
163
|
orderBy: s.f("orderBy", S$RescriptSchema.option(S$RescriptSchema.array(S$RescriptSchema.string))),
|
|
210
|
-
ttl: s.f("ttl", S$RescriptSchema.option(S$RescriptSchema.string))
|
|
164
|
+
ttl: s.f("ttl", S$RescriptSchema.option(S$RescriptSchema.string)),
|
|
165
|
+
skippingIndexes: s.f("skippingIndexes", S$RescriptSchema.option(S$RescriptSchema.array(clickhouseSkippingIndexSchema)))
|
|
211
166
|
}));
|
|
212
167
|
|
|
213
168
|
let entityClickhouseStorageJsonSchema = S$RescriptSchema.union([
|
|
@@ -230,6 +185,7 @@ let entityJsonSchema = S$RescriptSchema.schema(s => ({
|
|
|
230
185
|
name: s.m(S$RescriptSchema.string),
|
|
231
186
|
crossChain: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
232
187
|
storage: s.m(S$RescriptSchema.option(entityStorageSchema)),
|
|
188
|
+
internal: s.m(S$RescriptSchema.option(S$RescriptSchema.bool)),
|
|
233
189
|
properties: s.m(S$RescriptSchema.array(propertySchema)),
|
|
234
190
|
derivedFields: s.m(S$RescriptSchema.option(S$RescriptSchema.array(derivedFieldSchema))),
|
|
235
191
|
compositeIndices: s.m(S$RescriptSchema.option(S$RescriptSchema.array(S$RescriptSchema.array(compositeIndexFieldSchema)))),
|
|
@@ -400,7 +356,8 @@ function parseEntitiesFromJson(entitiesJson, enumConfigsByName, globalStorage, d
|
|
|
400
356
|
schema: schema,
|
|
401
357
|
table: table,
|
|
402
358
|
storage: storage,
|
|
403
|
-
crossChain: crossChain
|
|
359
|
+
crossChain: crossChain,
|
|
360
|
+
internal: Stdlib_Option.getOr(entityJson.internal, false)
|
|
404
361
|
};
|
|
405
362
|
});
|
|
406
363
|
}
|
|
@@ -436,6 +393,16 @@ let publicConfigSchema = S$RescriptSchema.schema(s => ({
|
|
|
436
393
|
entities: s.m(S$RescriptSchema.option(S$RescriptSchema.array(entityJsonSchema)))
|
|
437
394
|
}));
|
|
438
395
|
|
|
396
|
+
function contractMappingOf(chainConfigs) {
|
|
397
|
+
let names = [];
|
|
398
|
+
chainConfigs.forEach(chain => {
|
|
399
|
+
chain.contracts.forEach(contract => {
|
|
400
|
+
names.push(contract.name);
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
return ContractMapping.make(names);
|
|
404
|
+
}
|
|
405
|
+
|
|
439
406
|
function fromPublic(publicConfigJson) {
|
|
440
407
|
let publicConfig;
|
|
441
408
|
try {
|
|
@@ -564,7 +531,7 @@ function fromPublic(publicConfigJson) {
|
|
|
564
531
|
position: af.position,
|
|
565
532
|
values: af.values
|
|
566
533
|
})));
|
|
567
|
-
return EventConfigBuilder.buildSvmInstructionEventConfig(contractName, eventName, programId, svm.discriminator, svm.discriminatorByteLen,
|
|
534
|
+
return EventConfigBuilder.buildSvmInstructionEventConfig(contractName, eventName, programId, svm.discriminator, svm.discriminatorByteLen, accountFilters, svm.isInner, Stdlib_Option.getOr(svm.accounts, []), Stdlib_Option.getOr(svm.args, null), svmDefinedTypes);
|
|
568
535
|
}
|
|
569
536
|
});
|
|
570
537
|
} else {
|
|
@@ -614,16 +581,14 @@ function fromPublic(publicConfigJson) {
|
|
|
614
581
|
startBlock: startBlock
|
|
615
582
|
};
|
|
616
583
|
});
|
|
617
|
-
let
|
|
584
|
+
let seen = new Set();
|
|
618
585
|
contracts.forEach(contract => {
|
|
619
586
|
contract.addresses.forEach(address => {
|
|
620
|
-
let
|
|
621
|
-
if (
|
|
622
|
-
|
|
623
|
-
} else {
|
|
624
|
-
contractNameByAddress[address] = contract.name;
|
|
625
|
-
return;
|
|
587
|
+
let key = contract.name + "-" + address;
|
|
588
|
+
if (seen.has(key)) {
|
|
589
|
+
Stdlib_JsError.throwWithMessage(`Address ` + address + ` is listed multiple times for the contract ` + contract.name + ` on chain ` + ChainId.toString(chainId) + `. Please remove the duplicate from your config.`);
|
|
626
590
|
}
|
|
591
|
+
seen.add(key);
|
|
627
592
|
});
|
|
628
593
|
});
|
|
629
594
|
let sourceConfig;
|
|
@@ -696,6 +661,7 @@ function fromPublic(publicConfigJson) {
|
|
|
696
661
|
return {
|
|
697
662
|
name: chainName,
|
|
698
663
|
id: chainId,
|
|
664
|
+
ecosystem: ecosystemName,
|
|
699
665
|
startBlock: publicChainConfig.startBlock,
|
|
700
666
|
endBlock: publicChainConfig.endBlock,
|
|
701
667
|
maxReorgDepth: tmp,
|
|
@@ -725,7 +691,6 @@ function fromPublic(publicConfigJson) {
|
|
|
725
691
|
};
|
|
726
692
|
let defaultCrossChain = Stdlib_Option.getOr(publicConfig.defaultCrossChain, true);
|
|
727
693
|
let userEntities = parseEntitiesFromJson(Stdlib_Option.getOr(publicConfig.entities, []), enumConfigsByName, globalStorage, defaultCrossChain);
|
|
728
|
-
let allEntities = userEntities.concat([entityConfig]);
|
|
729
694
|
let userEntitiesByName = Object.fromEntries(userEntities.map(entityConfig => [
|
|
730
695
|
Utils.$$String.capitalize(entityConfig.name),
|
|
731
696
|
entityConfig
|
|
@@ -745,6 +710,7 @@ function fromPublic(publicConfigJson) {
|
|
|
745
710
|
storage: globalStorage,
|
|
746
711
|
chainIdMode: Stdlib_Option.getOr(publicConfig.chainIdMode, "int32"),
|
|
747
712
|
chainMap: chainMap,
|
|
713
|
+
contractMapping: contractMappingOf(chains),
|
|
748
714
|
defaultChain: chains[0],
|
|
749
715
|
ecosystem: ecosystem,
|
|
750
716
|
enableRawEvents: Stdlib_Option.getOr(publicConfig.rawEvents, false),
|
|
@@ -756,7 +722,6 @@ function fromPublic(publicConfigJson) {
|
|
|
756
722
|
isDev: Stdlib_Option.getOr(publicConfig.isDev, false),
|
|
757
723
|
userEntitiesByName: userEntitiesByName,
|
|
758
724
|
userEntities: userEntities,
|
|
759
|
-
allEntities: allEntities,
|
|
760
725
|
allEnums: allEnums
|
|
761
726
|
};
|
|
762
727
|
}
|
|
@@ -1083,7 +1048,6 @@ function getPgUserEntities(config) {
|
|
|
1083
1048
|
export {
|
|
1084
1049
|
chainIdFieldName,
|
|
1085
1050
|
chainIdColumnName,
|
|
1086
|
-
EnvioAddresses,
|
|
1087
1051
|
rpcSourceForSchema,
|
|
1088
1052
|
rpcConfigSchema,
|
|
1089
1053
|
chainContractSchema,
|
|
@@ -1097,6 +1061,7 @@ export {
|
|
|
1097
1061
|
compositeIndexFieldSchema,
|
|
1098
1062
|
derivedFieldSchema,
|
|
1099
1063
|
propertySchema,
|
|
1064
|
+
clickhouseSkippingIndexSchema,
|
|
1100
1065
|
clickhouseTableOptionsSchema,
|
|
1101
1066
|
entityClickhouseStorageJsonSchema,
|
|
1102
1067
|
entityStorageSchema,
|
|
@@ -1108,6 +1073,7 @@ export {
|
|
|
1108
1073
|
columnNameFormatSchema,
|
|
1109
1074
|
publicConfigStorageSchema,
|
|
1110
1075
|
publicConfigSchema,
|
|
1076
|
+
contractMappingOf,
|
|
1111
1077
|
fromPublic,
|
|
1112
1078
|
normalizeUserAddress,
|
|
1113
1079
|
normalizeSimulateAddress,
|
|
@@ -1124,4 +1090,4 @@ export {
|
|
|
1124
1090
|
load,
|
|
1125
1091
|
getPgUserEntities,
|
|
1126
1092
|
}
|
|
1127
|
-
/*
|
|
1093
|
+
/* rpcSourceForSchema Not a pure module */
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// The contract name <-> id mapping every stored address row references: a
|
|
2
|
+
// name's position in `names` is the id `envio_contracts` holds and
|
|
3
|
+
// `envio_addresses.contract_id` points at. Ids must mean the same thing on
|
|
4
|
+
// every chain and across restarts, so a mapping is built once — from the whole
|
|
5
|
+
// config, never from a filtered subset — and read everywhere else.
|
|
6
|
+
type t = {
|
|
7
|
+
// Id order. Index i is the name of contract id i.
|
|
8
|
+
names: array<string>,
|
|
9
|
+
idByName: dict<int>,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let indexNames = (names: array<string>): t => {
|
|
13
|
+
let idByName = Dict.make()
|
|
14
|
+
names->Array.forEachWithIndex((name, id) => idByName->Dict.set(name, id))
|
|
15
|
+
{names, idByName}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Ids are 0-based positions in a smallint column, so 32768 contracts fit.
|
|
19
|
+
let maxContracts = 32768
|
|
20
|
+
|
|
21
|
+
// Names in any order; the codec puts them in byte order so the ids never depend
|
|
22
|
+
// on the order contracts happen to be declared in.
|
|
23
|
+
let make = (~names: array<string>): t => {
|
|
24
|
+
let canonical = Core.getAddon().canonicalContractNames(names)
|
|
25
|
+
if canonical->Array.length > maxContracts {
|
|
26
|
+
JsError.throwWithMessage(
|
|
27
|
+
`The indexer declares ${canonical
|
|
28
|
+
->Array.length
|
|
29
|
+
->Int.toString} contracts, more than the ${maxContracts->Int.toString} a smallint contract id can hold.`,
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
indexNames(canonical)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// What a storage holds before it has been initialized: no contract has an id
|
|
36
|
+
// yet, so every lookup fails rather than resolving against a stale mapping.
|
|
37
|
+
let empty = indexNames([])
|
|
38
|
+
|
|
39
|
+
// A mapping read back from storage. Taken verbatim: the stored order *is* the
|
|
40
|
+
// id order the stored rows were written against, so re-canonicalizing it would
|
|
41
|
+
// paper over a mapping that no longer matches those rows.
|
|
42
|
+
let fromStoredNames = indexNames
|
|
43
|
+
|
|
44
|
+
let names = (mapping: t) => mapping.names
|
|
45
|
+
|
|
46
|
+
let idOfOrThrow = (mapping: t, name, ~context="") =>
|
|
47
|
+
switch mapping.idByName->Utils.Dict.dangerouslyGetNonOption(name) {
|
|
48
|
+
| Some(id) => id
|
|
49
|
+
| None =>
|
|
50
|
+
JsError.throwWithMessage(
|
|
51
|
+
`Contract "${name}"${context} is missing from the indexer's contract list.`,
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let nameOfOrThrow = (mapping: t, id) =>
|
|
56
|
+
switch mapping.names->Array.get(id) {
|
|
57
|
+
| Some(name) => name
|
|
58
|
+
| None =>
|
|
59
|
+
JsError.throwWithMessage(
|
|
60
|
+
`Contract id ${id->Int.toString} is outside the indexer's contract list.`,
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let isEqual = (a: t, b: t) =>
|
|
65
|
+
a.names->Array.length === b.names->Array.length &&
|
|
66
|
+
a.names->Array.everyWithIndex((name, idx) => b.names->Array.getUnsafe(idx) === name)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Core from "./Core.res.mjs";
|
|
4
|
+
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
5
|
+
|
|
6
|
+
function indexNames(names) {
|
|
7
|
+
let idByName = {};
|
|
8
|
+
names.forEach((name, id) => {
|
|
9
|
+
idByName[name] = id;
|
|
10
|
+
});
|
|
11
|
+
return {
|
|
12
|
+
names: names,
|
|
13
|
+
idByName: idByName
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function make(names) {
|
|
18
|
+
let canonical = Core.getAddon().canonicalContractNames(names);
|
|
19
|
+
if (canonical.length > 32768) {
|
|
20
|
+
Stdlib_JsError.throwWithMessage(`The indexer declares ` + canonical.length.toString() + ` contracts, more than the ` + (32768).toString() + ` a smallint contract id can hold.`);
|
|
21
|
+
}
|
|
22
|
+
return indexNames(canonical);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let empty = indexNames([]);
|
|
26
|
+
|
|
27
|
+
function names(mapping) {
|
|
28
|
+
return mapping.names;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function idOfOrThrow(mapping, name, contextOpt) {
|
|
32
|
+
let context = contextOpt !== undefined ? contextOpt : "";
|
|
33
|
+
let id = mapping.idByName[name];
|
|
34
|
+
if (id !== undefined) {
|
|
35
|
+
return id;
|
|
36
|
+
} else {
|
|
37
|
+
return Stdlib_JsError.throwWithMessage(`Contract "` + name + `"` + context + ` is missing from the indexer's contract list.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function nameOfOrThrow(mapping, id) {
|
|
42
|
+
let name = mapping.names[id];
|
|
43
|
+
if (name !== undefined) {
|
|
44
|
+
return name;
|
|
45
|
+
} else {
|
|
46
|
+
return Stdlib_JsError.throwWithMessage(`Contract id ` + id.toString() + ` is outside the indexer's contract list.`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function isEqual(a, b) {
|
|
51
|
+
if (a.names.length === b.names.length) {
|
|
52
|
+
return a.names.every((name, idx) => b.names[idx] === name);
|
|
53
|
+
} else {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let maxContracts = 32768;
|
|
59
|
+
|
|
60
|
+
let fromStoredNames = indexNames;
|
|
61
|
+
|
|
62
|
+
export {
|
|
63
|
+
indexNames,
|
|
64
|
+
maxContracts,
|
|
65
|
+
make,
|
|
66
|
+
empty,
|
|
67
|
+
fromStoredNames,
|
|
68
|
+
names,
|
|
69
|
+
idOfOrThrow,
|
|
70
|
+
nameOfOrThrow,
|
|
71
|
+
isEqual,
|
|
72
|
+
}
|
|
73
|
+
/* empty Not a pure module */
|
package/src/Core.res
CHANGED
|
@@ -47,6 +47,22 @@ type addon = {
|
|
|
47
47
|
addressStore: addressStoreCtor,
|
|
48
48
|
@as("MockHyperSyncServer")
|
|
49
49
|
mockHyperSyncServer: mockHyperSyncServerCtor,
|
|
50
|
+
encodeAddresses: (~ecosystem: string, ~addresses: array<Address.t>) => array<NodeJs.Buffer.t>,
|
|
51
|
+
renderAddresses: (
|
|
52
|
+
~ecosystem: string,
|
|
53
|
+
~shouldChecksum: bool,
|
|
54
|
+
~bytes: NodeJs.Buffer.t,
|
|
55
|
+
~lengths: array<int>,
|
|
56
|
+
) => array<Address.t>,
|
|
57
|
+
renderContractAddresses: (
|
|
58
|
+
~ecosystem: string,
|
|
59
|
+
~shouldChecksum: bool,
|
|
60
|
+
~bytes: NodeJs.Buffer.t,
|
|
61
|
+
~lengths: array<int>,
|
|
62
|
+
~contractIds: array<int>,
|
|
63
|
+
~contractId: int,
|
|
64
|
+
) => array<Address.t>,
|
|
65
|
+
canonicalContractNames: array<string> => array<string>,
|
|
50
66
|
// Ordered transaction-field names exposed for the field-code contract test
|
|
51
67
|
// (the ReScript `transactionFields` arrays must match the Rust ordinals).
|
|
52
68
|
evmTransactionFieldNames: unit => array<string>,
|
|
@@ -84,6 +100,10 @@ let loadDevAddon: ({..}, string) => addon = %raw(`function(req, envioDir) {
|
|
|
84
100
|
var path = Nodepath;
|
|
85
101
|
var fs = Nodefs;
|
|
86
102
|
|
|
103
|
+
// Vitest test.env points workers at the addon globalSetup already built.
|
|
104
|
+
var preBuilt = process.env.ENVIO_DEV_ADDON;
|
|
105
|
+
if (preBuilt && fs.existsSync(preBuilt)) return req(preBuilt);
|
|
106
|
+
|
|
87
107
|
var repoRoot = null;
|
|
88
108
|
var dir = path.resolve(envioDir);
|
|
89
109
|
for (var i = 0; i < 10; i++) {
|
package/src/Core.res.mjs
CHANGED
|
@@ -26,6 +26,10 @@ let loadDevAddon = (function(req, envioDir) {
|
|
|
26
26
|
var path = Nodepath;
|
|
27
27
|
var fs = Nodefs;
|
|
28
28
|
|
|
29
|
+
// Vitest test.env points workers at the addon globalSetup already built.
|
|
30
|
+
var preBuilt = process.env.ENVIO_DEV_ADDON;
|
|
31
|
+
if (preBuilt && fs.existsSync(preBuilt)) return req(preBuilt);
|
|
32
|
+
|
|
29
33
|
var repoRoot = null;
|
|
30
34
|
var dir = path.resolve(envioDir);
|
|
31
35
|
for (var i = 0; i < 10; i++) {
|
package/src/Envio.res
CHANGED
|
@@ -20,58 +20,48 @@ type svmOnSlotArgs<'context> = {
|
|
|
20
20
|
context: 'context,
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
discriminator didn't match any registered instruction. */
|
|
27
|
-
type svmInstructionParams = {
|
|
28
|
-
/** Schema-declared instruction name (matches the codegen module suffix). */
|
|
29
|
-
name: string,
|
|
30
|
-
/** Borsh-decoded args. `JSON.Object({})` for no-arg instructions
|
|
31
|
-
(e.g. `VerifyCollection`). POC types this as raw `JSON.t`; cast at the
|
|
32
|
-
handler with `(json :> MyArgsType)` until typed codegen lands. */
|
|
33
|
-
args: JSON.t,
|
|
34
|
-
/** Named accounts in schema order. Keys are exactly the schema-declared
|
|
35
|
-
names; values are base58 pubkey strings. */
|
|
36
|
-
accounts: dict<string>,
|
|
37
|
-
/** Accounts beyond the schema's named list (Anchor `remaining_accounts`,
|
|
38
|
-
IDL drift). `[]` when counts match. */
|
|
39
|
-
extraAccounts: array<string>,
|
|
23
|
+
type svmLamports = {
|
|
24
|
+
pre: bigint,
|
|
25
|
+
post: bigint,
|
|
40
26
|
}
|
|
41
27
|
|
|
42
|
-
type
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
when the account was closed during it. Pre and post owners differ only when
|
|
47
|
-
a `SetAuthority(AccountOwner)` runs mid-transaction. */
|
|
48
|
-
owner?: SvmTypes.Pubkey.t,
|
|
49
|
-
/** Mint decimals, for scaling the raw amounts below. */
|
|
50
|
-
decimals?: int,
|
|
51
|
-
/** Raw amount in base units before the transaction. Absent when the token
|
|
52
|
-
account was created during it. */
|
|
28
|
+
type svmAccountToken = {
|
|
29
|
+
mint: SvmTypes.Pubkey.t,
|
|
30
|
+
owner: SvmTypes.Pubkey.t,
|
|
31
|
+
decimals: int,
|
|
53
32
|
preAmount?: bigint,
|
|
54
|
-
/** Raw amount in base units after the transaction. Absent when the token
|
|
55
|
-
account was closed during it. */
|
|
56
33
|
postAmount?: bigint,
|
|
57
34
|
}
|
|
58
35
|
|
|
36
|
+
type svmAccountActivity = {
|
|
37
|
+
address: SvmTypes.Pubkey.t,
|
|
38
|
+
transactionAccountIndex?: int,
|
|
39
|
+
isSigner?: bool,
|
|
40
|
+
isWritable?: bool,
|
|
41
|
+
lamports?: svmLamports,
|
|
42
|
+
token?: svmAccountToken,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type svmInstructionAccount = {
|
|
46
|
+
address: SvmTypes.Pubkey.t,
|
|
47
|
+
accountName: string,
|
|
48
|
+
instructionAccountIndex: int,
|
|
49
|
+
activity?: svmAccountActivity,
|
|
50
|
+
}
|
|
51
|
+
|
|
59
52
|
type svmTransaction = {
|
|
60
53
|
transactionIndex?: int,
|
|
61
|
-
|
|
62
|
-
signature: string,
|
|
54
|
+
signature?: string,
|
|
63
55
|
feePayer?: SvmTypes.Pubkey.t,
|
|
64
56
|
success?: bool,
|
|
65
57
|
err?: string,
|
|
66
58
|
fee?: bigint,
|
|
67
59
|
computeUnitsConsumed?: bigint,
|
|
68
|
-
accountKeys
|
|
60
|
+
accountKeys?: array<SvmTypes.Pubkey.t>,
|
|
69
61
|
recentBlockhash?: string,
|
|
70
62
|
version?: string,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
allSignatures: array<string>,
|
|
74
|
-
tokenBalances?: array<svmTokenBalance>,
|
|
63
|
+
allSignatures?: array<string>,
|
|
64
|
+
accountActivities?: array<svmAccountActivity>,
|
|
75
65
|
}
|
|
76
66
|
|
|
77
67
|
type svmLog = {
|
|
@@ -79,57 +69,29 @@ type svmLog = {
|
|
|
79
69
|
message: string,
|
|
80
70
|
}
|
|
81
71
|
|
|
82
|
-
|
|
83
|
-
`time` can still be absent — HyperSync/Solana may not report a block time for
|
|
84
|
-
every slot. Every other field is opt-in via `field_selection.block_fields`,
|
|
85
|
-
materialised from the per-chain block store at batch prep. */
|
|
86
|
-
type svmInstructionBlock = {
|
|
87
|
-
/** Slot this instruction's block was matched in. */
|
|
72
|
+
type svmBlock = {
|
|
88
73
|
slot: int,
|
|
89
|
-
/** Unix block time (seconds). */
|
|
90
74
|
time?: int,
|
|
91
|
-
hash
|
|
92
|
-
/** Block height (distinct from slot). Absent when not selected via
|
|
93
|
-
`field_selection.block_fields`. */
|
|
75
|
+
hash?: string,
|
|
94
76
|
height?: int,
|
|
95
77
|
parentSlot?: int,
|
|
96
78
|
parentHash?: string,
|
|
97
79
|
}
|
|
98
80
|
|
|
99
|
-
/** The per-instruction payload handlers receive as their `instruction`
|
|
100
|
-
argument. Carries the matched instruction's own fields plus the
|
|
101
|
-
program/instruction names, parent transaction, scoped logs, and block. */
|
|
102
81
|
type svmInstruction = {
|
|
103
|
-
/** Program name as declared under `programs[].name` in `config.yaml`. */
|
|
104
82
|
programName: string,
|
|
105
|
-
/** Instruction name as declared under `instructions[].name` in
|
|
106
|
-
`config.yaml`. */
|
|
107
83
|
instructionName: string,
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
data
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
/** Discriminator prefixes pre-extracted by HyperSync. Each is `Some` only
|
|
117
|
-
when the underlying instruction is at least that long. */
|
|
118
|
-
d1?: string,
|
|
119
|
-
d2?: string,
|
|
120
|
-
d4?: string,
|
|
121
|
-
d8?: string,
|
|
122
|
-
/** Borsh-decoded params view. See [[svmInstructionParams]]. */
|
|
123
|
-
params?: svmInstructionParams,
|
|
124
|
-
/** Parent transaction. Carries only the fields selected via
|
|
125
|
-
`field_selection.transaction_fields`; absent when none are selected. */
|
|
84
|
+
discriminator: string,
|
|
85
|
+
programId?: SvmTypes.Pubkey.t,
|
|
86
|
+
data?: string,
|
|
87
|
+
path?: array<int>,
|
|
88
|
+
isInner?: bool,
|
|
89
|
+
args?: JSON.t,
|
|
90
|
+
accounts?: dict<svmInstructionAccount>,
|
|
91
|
+
accountArguments?: array<SvmTypes.Pubkey.t>,
|
|
126
92
|
transaction?: svmTransaction,
|
|
127
|
-
/** Program log entries scoped to this instruction. Absent when the
|
|
128
|
-
per-instruction `include_logs` flag is `false`. */
|
|
129
93
|
logs?: array<svmLog>,
|
|
130
|
-
|
|
131
|
-
// before a handler ever reads it.
|
|
132
|
-
block?: svmInstructionBlock,
|
|
94
|
+
block?: svmBlock,
|
|
133
95
|
}
|
|
134
96
|
|
|
135
97
|
/** Arguments passed to handlers registered via `indexer.onInstruction`. */
|
|
@@ -315,6 +277,22 @@ type fuelSimulateItem = {
|
|
|
315
277
|
transaction?: fuelTransactionInput,
|
|
316
278
|
}
|
|
317
279
|
|
|
280
|
+
type svmSimulateItem = {
|
|
281
|
+
program: string,
|
|
282
|
+
instruction: string,
|
|
283
|
+
slot?: int,
|
|
284
|
+
path?: array<int>,
|
|
285
|
+
programId?: string,
|
|
286
|
+
data?: string,
|
|
287
|
+
isInner?: bool,
|
|
288
|
+
args?: JSON.t,
|
|
289
|
+
accounts?: dict<{address: string}>,
|
|
290
|
+
accountArguments?: array<string>,
|
|
291
|
+
logs?: array<{kind?: string, message?: string}>,
|
|
292
|
+
block?: svmBlock,
|
|
293
|
+
transaction?: unknown,
|
|
294
|
+
}
|
|
295
|
+
|
|
318
296
|
// Detects contexts where a full-screen TUI is counter-productive: piped/redirected
|
|
319
297
|
// stdout, CI, and coding agents. `CLAUDECODE` is set by Claude Code; `CI` is the
|
|
320
298
|
// de-facto convention across CI providers; `TERM=dumb` is set by editors/tools
|