envio 3.0.0-alpha.3 → 3.0.0-alpha.4
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/evm.schema.json +0 -1
- package/index.d.ts +4 -2
- package/index.js +1 -0
- package/package.json +5 -5
- package/src/Config.res +1 -1
- package/src/Config.res.mjs +4 -4
- package/src/Ecosystem.res +2 -2
- package/src/Ecosystem.res.mjs +1 -1
- package/src/Envio.gen.ts +1 -1
- package/src/Envio.res +1 -1
- package/src/Internal.res +41 -0
- package/src/Types.ts +1 -1
- package/src/Utils.res +15 -0
- package/src/Utils.res.mjs +18 -0
- package/src/bindings/ClickHouse.res +31 -1
- package/src/bindings/ClickHouse.res.mjs +27 -1
- package/src/bindings/Ethers.res +27 -63
- package/src/bindings/Ethers.res.mjs +18 -65
- package/src/sources/HyperSyncHeightStream.res +28 -110
- package/src/sources/HyperSyncHeightStream.res.mjs +30 -63
- package/src/sources/HyperSyncSource.res +11 -13
- package/src/sources/HyperSyncSource.res.mjs +20 -20
- package/src/sources/Rpc.res +43 -0
- package/src/sources/Rpc.res.mjs +31 -0
- package/src/sources/RpcSource.res +9 -4
- package/src/sources/RpcSource.res.mjs +9 -4
- package/src/sources/Source.res +1 -0
- package/src/sources/SourceManager.res +164 -81
- package/src/sources/SourceManager.res.mjs +146 -83
- package/src/sources/{Solana.res → Svm.res} +4 -4
- package/src/sources/{Solana.res.mjs → Svm.res.mjs} +4 -4
- package/src/bindings/Ethers.gen.ts +0 -14
package/README.md
CHANGED
|
@@ -14,11 +14,11 @@ 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 10,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](https://docs.envio.dev/docs/HyperIndex/multichain-indexing)** – Index any EVM
|
|
17
|
+
- **[Multichain indexing](https://docs.envio.dev/docs/HyperIndex/multichain-indexing)** – Index any EVM-, SVM-, or Fuel-compatible blockchain
|
|
18
18
|
- **Real-time indexing** – Instantly track blockchain events
|
|
19
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
|
-
- **Flexible language support** –
|
|
21
|
+
- **Flexible language support** – TypeScript, JavaScript, and ReScript
|
|
22
22
|
- **Factory contract support** – Index data from 1M+ dynamically registered contracts seamlessly
|
|
23
23
|
- **On-chain & off-chain data integration** – Easily combine multiple data sources
|
|
24
24
|
- **[Self-hosted & managed options](https://docs.envio.dev/docs/HyperIndex/hosted-service)** – Run your own setup or use HyperIndex hosted services
|
package/evm.schema.json
CHANGED
package/index.d.ts
CHANGED
|
@@ -8,11 +8,12 @@ export type {
|
|
|
8
8
|
rateLimit as RateLimit,
|
|
9
9
|
blockEvent as BlockEvent,
|
|
10
10
|
fuelBlockEvent as FuelBlockEvent,
|
|
11
|
-
|
|
11
|
+
svmOnBlockArgs as SvmOnBlockArgs,
|
|
12
12
|
onBlockArgs as OnBlockArgs,
|
|
13
13
|
onBlockOptions as OnBlockOptions,
|
|
14
14
|
} from "./src/Envio.gen.ts";
|
|
15
|
-
|
|
15
|
+
import type { Address } from "./src/Types.ts";
|
|
16
|
+
export type { EffectCaller, Address } from "./src/Types.ts";
|
|
16
17
|
|
|
17
18
|
import type {
|
|
18
19
|
effect as Effect,
|
|
@@ -109,6 +110,7 @@ export declare namespace S {
|
|
|
109
110
|
export type Input<T> = Sury.Input<T>;
|
|
110
111
|
export type Schema<Output, Input = unknown> = Sury.Schema<Output, Input>;
|
|
111
112
|
export const string: typeof Sury.string;
|
|
113
|
+
export const address: Sury.Schema<Address, Address>;
|
|
112
114
|
export const jsonString: typeof Sury.jsonString;
|
|
113
115
|
export const boolean: typeof Sury.boolean;
|
|
114
116
|
export const int32: typeof Sury.int32;
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "v3.0.0-alpha.
|
|
3
|
+
"version": "v3.0.0-alpha.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
6
6
|
"bin": "./bin.js",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"node": ">=22.0.0"
|
|
30
30
|
},
|
|
31
31
|
"optionalDependencies": {
|
|
32
|
-
"envio-linux-x64": "v3.0.0-alpha.
|
|
33
|
-
"envio-linux-arm64": "v3.0.0-alpha.
|
|
34
|
-
"envio-darwin-x64": "v3.0.0-alpha.
|
|
35
|
-
"envio-darwin-arm64": "v3.0.0-alpha.
|
|
32
|
+
"envio-linux-x64": "v3.0.0-alpha.4",
|
|
33
|
+
"envio-linux-arm64": "v3.0.0-alpha.4",
|
|
34
|
+
"envio-darwin-x64": "v3.0.0-alpha.4",
|
|
35
|
+
"envio-darwin-arm64": "v3.0.0-alpha.4"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@clickhouse/client": "1.12.1",
|
package/src/Config.res
CHANGED
package/src/Config.res.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Evm from "./sources/Evm.res.mjs";
|
|
4
|
+
import * as Svm from "./sources/Svm.res.mjs";
|
|
4
5
|
import * as Fuel from "./sources/Fuel.res.mjs";
|
|
5
6
|
import * as Utils from "./Utils.res.mjs";
|
|
6
7
|
import * as Js_exn from "rescript/lib/es6/js_exn.js";
|
|
7
|
-
import * as Solana from "./sources/Solana.res.mjs";
|
|
8
8
|
import * as Js_dict from "rescript/lib/es6/js_dict.js";
|
|
9
9
|
import * as ChainMap from "./ChainMap.res.mjs";
|
|
10
10
|
import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
|
|
@@ -45,8 +45,8 @@ function make(shouldRollbackOnReorgOpt, shouldSaveFullHistoryOpt, chainsOpt, ena
|
|
|
45
45
|
case "fuel" :
|
|
46
46
|
ecosystem$1 = Fuel.ecosystem;
|
|
47
47
|
break;
|
|
48
|
-
case "
|
|
49
|
-
ecosystem$1 =
|
|
48
|
+
case "svm" :
|
|
49
|
+
ecosystem$1 = Svm.ecosystem;
|
|
50
50
|
break;
|
|
51
51
|
|
|
52
52
|
}
|
|
@@ -105,4 +105,4 @@ export {
|
|
|
105
105
|
shouldPruneHistory ,
|
|
106
106
|
getChain ,
|
|
107
107
|
}
|
|
108
|
-
/*
|
|
108
|
+
/* Svm Not a pure module */
|
package/src/Ecosystem.res
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type name = | @as("evm") Evm | @as("fuel") Fuel | @as("
|
|
1
|
+
type name = | @as("evm") Evm | @as("fuel") Fuel | @as("svm") Svm
|
|
2
2
|
|
|
3
3
|
type t = {
|
|
4
4
|
name: name,
|
|
@@ -15,7 +15,7 @@ type t = {
|
|
|
15
15
|
|
|
16
16
|
let makeOnBlockArgs = (~blockNumber: int, ~ecosystem: t, ~context): Internal.onBlockArgs => {
|
|
17
17
|
switch ecosystem.name {
|
|
18
|
-
|
|
|
18
|
+
| Svm => {slot: blockNumber, context}
|
|
19
19
|
| _ => {
|
|
20
20
|
let blockEvent = Js.Dict.empty()
|
|
21
21
|
blockEvent->Js.Dict.set(ecosystem.blockNumberName, blockNumber->Utils.magic)
|
package/src/Ecosystem.res.mjs
CHANGED
package/src/Envio.gen.ts
CHANGED
|
@@ -15,7 +15,7 @@ export type blockEvent = { readonly number: number };
|
|
|
15
15
|
|
|
16
16
|
export type fuelBlockEvent = { readonly height: number };
|
|
17
17
|
|
|
18
|
-
export type
|
|
18
|
+
export type svmOnBlockArgs<context> = { readonly slot: number; readonly context: context };
|
|
19
19
|
|
|
20
20
|
export type onBlockArgs<block,context> = { readonly block: block; readonly context: context };
|
|
21
21
|
|
package/src/Envio.res
CHANGED
|
@@ -9,7 +9,7 @@ type blockEvent = {number: int}
|
|
|
9
9
|
type fuelBlockEvent = {height: int}
|
|
10
10
|
|
|
11
11
|
@genType
|
|
12
|
-
type
|
|
12
|
+
type svmOnBlockArgs<'context> = {slot: int, context: 'context}
|
|
13
13
|
|
|
14
14
|
@genType
|
|
15
15
|
type onBlockArgs<'block, 'context> = {
|
package/src/Internal.res
CHANGED
|
@@ -2,6 +2,47 @@ type eventParams
|
|
|
2
2
|
type eventBlock
|
|
3
3
|
type eventTransaction
|
|
4
4
|
|
|
5
|
+
// Shared EVM transaction fields type used by both RPC and HyperSync sources
|
|
6
|
+
// Field names match HyperSyncClient.ResponseTypes.transaction for consistency
|
|
7
|
+
type evmTransactionFields = {
|
|
8
|
+
from?: Address.t,
|
|
9
|
+
to?: Address.t,
|
|
10
|
+
gas?: bigint,
|
|
11
|
+
gasPrice?: bigint,
|
|
12
|
+
hash?: string,
|
|
13
|
+
input?: string,
|
|
14
|
+
nonce?: bigint,
|
|
15
|
+
transactionIndex?: int,
|
|
16
|
+
value?: bigint,
|
|
17
|
+
// Signature fields - optional for ZKSync EIP-712 compatibility
|
|
18
|
+
v?: string,
|
|
19
|
+
r?: string,
|
|
20
|
+
s?: string,
|
|
21
|
+
yParity?: string,
|
|
22
|
+
// EIP-1559 fields
|
|
23
|
+
maxPriorityFeePerGas?: bigint,
|
|
24
|
+
maxFeePerGas?: bigint,
|
|
25
|
+
// EIP-4844 blob fields
|
|
26
|
+
maxFeePerBlobGas?: bigint,
|
|
27
|
+
blobVersionedHashes?: array<string>,
|
|
28
|
+
// Receipt fields (from joined transaction receipts)
|
|
29
|
+
cumulativeGasUsed?: bigint,
|
|
30
|
+
effectiveGasPrice?: bigint,
|
|
31
|
+
gasUsed?: bigint,
|
|
32
|
+
contractAddress?: string,
|
|
33
|
+
logsBloom?: string,
|
|
34
|
+
@as("type")
|
|
35
|
+
type_?: int,
|
|
36
|
+
root?: string,
|
|
37
|
+
status?: int,
|
|
38
|
+
// L2 specific fields (Optimism, Arbitrum, etc.)
|
|
39
|
+
l1Fee?: bigint,
|
|
40
|
+
l1GasPrice?: bigint,
|
|
41
|
+
l1GasUsed?: bigint,
|
|
42
|
+
l1FeeScalar?: int,
|
|
43
|
+
gasUsedForL1?: bigint,
|
|
44
|
+
}
|
|
45
|
+
|
|
5
46
|
@genType
|
|
6
47
|
type genericEvent<'params, 'block, 'transaction> = {
|
|
7
48
|
params: 'params,
|
package/src/Types.ts
CHANGED
package/src/Utils.res
CHANGED
|
@@ -175,6 +175,15 @@ module Dict = {
|
|
|
175
175
|
}
|
|
176
176
|
`)
|
|
177
177
|
|
|
178
|
+
let unsafeDeleteUndefinedFieldsInPlace: 'a => unit = %raw(`(dict) => {
|
|
179
|
+
for (var key in dict) {
|
|
180
|
+
if (dict[key] === undefined) {
|
|
181
|
+
delete dict[key];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
`)
|
|
186
|
+
|
|
178
187
|
let updateImmutable: (
|
|
179
188
|
dict<'a>,
|
|
180
189
|
string,
|
|
@@ -472,6 +481,12 @@ module Schema = {
|
|
|
472
481
|
->(magic: S.t<Js.Json.t> => S.t<Js.Date.t>)
|
|
473
482
|
->S.preprocess(_ => {serializer: date => date->magic->Js.Date.toISOString})
|
|
474
483
|
|
|
484
|
+
// ClickHouse expects timestamps as numbers (milliseconds), not ISO strings
|
|
485
|
+
let clickHouseDate =
|
|
486
|
+
S.json(~validate=false)
|
|
487
|
+
->(magic: S.t<Js.Json.t> => S.t<Js.Date.t>)
|
|
488
|
+
->S.preprocess(_ => {serializer: date => date->magic->Js.Date.getTime})
|
|
489
|
+
|
|
475
490
|
// When trying to serialize data to Json pg type, it will fail with
|
|
476
491
|
// PostgresError: column "params" is of type json but expression is of type boolean
|
|
477
492
|
// If there's bool or null on the root level. It works fine as object field values.
|
package/src/Utils.res.mjs
CHANGED
|
@@ -151,6 +151,14 @@ var deleteInPlace = ((dict, key) => {
|
|
|
151
151
|
delete dict[key];
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
+
var unsafeDeleteUndefinedFieldsInPlace = ((dict) => {
|
|
155
|
+
for (var key in dict) {
|
|
156
|
+
if (dict[key] === undefined) {
|
|
157
|
+
delete dict[key];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
154
162
|
var updateImmutable = ((dict, key, value) => ({...dict, [key]: value}));
|
|
155
163
|
|
|
156
164
|
var shallowCopy = ((dict) => ({...dict}));
|
|
@@ -172,6 +180,7 @@ var Dict = {
|
|
|
172
180
|
size: size,
|
|
173
181
|
isEmpty: isEmpty,
|
|
174
182
|
deleteInPlace: deleteInPlace,
|
|
183
|
+
unsafeDeleteUndefinedFieldsInPlace: unsafeDeleteUndefinedFieldsInPlace,
|
|
175
184
|
updateImmutable: updateImmutable,
|
|
176
185
|
shallowCopy: shallowCopy,
|
|
177
186
|
incrementByInt: incrementByInt
|
|
@@ -449,6 +458,14 @@ var dbDate = S$RescriptSchema.preprocess(S$RescriptSchema.json(false), (function
|
|
|
449
458
|
};
|
|
450
459
|
}));
|
|
451
460
|
|
|
461
|
+
var clickHouseDate = S$RescriptSchema.preprocess(S$RescriptSchema.json(false), (function (param) {
|
|
462
|
+
return {
|
|
463
|
+
s: (function (date) {
|
|
464
|
+
return date.getTime();
|
|
465
|
+
})
|
|
466
|
+
};
|
|
467
|
+
}));
|
|
468
|
+
|
|
452
469
|
function coerceToJsonPgType(schema) {
|
|
453
470
|
return S$RescriptSchema.preprocess(schema, (function (s) {
|
|
454
471
|
var match = s.schema.t;
|
|
@@ -485,6 +502,7 @@ var Schema = {
|
|
|
485
502
|
getNonOptionalFieldNames: getNonOptionalFieldNames,
|
|
486
503
|
getCapitalizedFieldNames: getCapitalizedFieldNames,
|
|
487
504
|
dbDate: dbDate,
|
|
505
|
+
clickHouseDate: clickHouseDate,
|
|
488
506
|
coerceToJsonPgType: coerceToJsonPgType
|
|
489
507
|
};
|
|
490
508
|
|
|
@@ -98,6 +98,36 @@ let getClickHouseFieldType = (
|
|
|
98
98
|
isNullable ? `Nullable(${baseType})` : baseType
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
// Creates an entity schema from table definition, using clickHouseDate for Date fields
|
|
102
|
+
let makeClickHouseEntitySchema = (table: Table.table): S.t<Internal.entity> => {
|
|
103
|
+
S.schema(s => {
|
|
104
|
+
let dict = Js.Dict.empty()
|
|
105
|
+
table.fields->Belt.Array.forEach(field => {
|
|
106
|
+
switch field {
|
|
107
|
+
| Field(f) => {
|
|
108
|
+
let fieldName = f->Table.getDbFieldName
|
|
109
|
+
let fieldSchema = switch f.fieldType {
|
|
110
|
+
| Date => {
|
|
111
|
+
let dateSchema = Utils.Schema.clickHouseDate->S.toUnknown
|
|
112
|
+
if f.isNullable {
|
|
113
|
+
S.null(dateSchema)->S.toUnknown
|
|
114
|
+
} else if f.isArray {
|
|
115
|
+
S.array(dateSchema)->S.toUnknown
|
|
116
|
+
} else {
|
|
117
|
+
dateSchema
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
| _ => f.fieldSchema
|
|
121
|
+
}
|
|
122
|
+
dict->Js.Dict.set(fieldName, s.matches(fieldSchema))
|
|
123
|
+
}
|
|
124
|
+
| DerivedFrom(_) => () // Skip derived fields
|
|
125
|
+
}
|
|
126
|
+
})
|
|
127
|
+
dict->Utils.magic
|
|
128
|
+
})
|
|
129
|
+
}
|
|
130
|
+
|
|
101
131
|
let setCheckpointsOrThrow = async (client, ~batch: Batch.t, ~database: string) => {
|
|
102
132
|
let checkpointsCount = batch.checkpointIds->Array.length
|
|
103
133
|
if checkpointsCount === 0 {
|
|
@@ -154,7 +184,7 @@ let setUpdatesOrThrow = async (
|
|
|
154
184
|
)}\``,
|
|
155
185
|
convertOrThrow: S.compile(
|
|
156
186
|
S.union([
|
|
157
|
-
EntityHistory.makeSetUpdateSchema(entityConfig.
|
|
187
|
+
EntityHistory.makeSetUpdateSchema(makeClickHouseEntitySchema(entityConfig.table)),
|
|
158
188
|
S.object(s => {
|
|
159
189
|
s.tag(EntityHistory.changeFieldName, EntityHistory.RowAction.DELETE)
|
|
160
190
|
Change.Delete({
|
|
@@ -76,6 +76,31 @@ function getClickHouseFieldType(fieldType, isNullable, isArray) {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
function makeClickHouseEntitySchema(table) {
|
|
80
|
+
return S$RescriptSchema.schema(function (s) {
|
|
81
|
+
var dict = {};
|
|
82
|
+
Belt_Array.forEach(table.fields, (function (field) {
|
|
83
|
+
if (field.TAG !== "Field") {
|
|
84
|
+
return ;
|
|
85
|
+
}
|
|
86
|
+
var f = field._0;
|
|
87
|
+
var fieldName = Table.getDbFieldName(f);
|
|
88
|
+
var match = f.fieldType;
|
|
89
|
+
var fieldSchema;
|
|
90
|
+
if (typeof match !== "object" && match === "Date") {
|
|
91
|
+
var dateSchema = Utils.Schema.clickHouseDate;
|
|
92
|
+
fieldSchema = f.isNullable ? S$RescriptSchema.$$null(dateSchema) : (
|
|
93
|
+
f.isArray ? S$RescriptSchema.array(dateSchema) : dateSchema
|
|
94
|
+
);
|
|
95
|
+
} else {
|
|
96
|
+
fieldSchema = f.fieldSchema;
|
|
97
|
+
}
|
|
98
|
+
dict[fieldName] = s.m(fieldSchema);
|
|
99
|
+
}));
|
|
100
|
+
return dict;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
79
104
|
async function setCheckpointsOrThrow(client, batch, database) {
|
|
80
105
|
var checkpointsCount = batch.checkpointIds.length;
|
|
81
106
|
if (checkpointsCount === 0) {
|
|
@@ -120,7 +145,7 @@ async function setUpdatesOrThrow(client, updates, entityConfig, database) {
|
|
|
120
145
|
} else {
|
|
121
146
|
var cache_tableName = database + ".\`" + EntityHistory.historyTableName(entityConfig.name, entityConfig.index) + "\`";
|
|
122
147
|
var cache_convertOrThrow = S$RescriptSchema.compile(S$RescriptSchema.union([
|
|
123
|
-
EntityHistory.makeSetUpdateSchema(entityConfig.
|
|
148
|
+
EntityHistory.makeSetUpdateSchema(makeClickHouseEntitySchema(entityConfig.table)),
|
|
124
149
|
S$RescriptSchema.object(function (s) {
|
|
125
150
|
s.tag(EntityHistory.changeFieldName, "DELETE");
|
|
126
151
|
return {
|
|
@@ -264,6 +289,7 @@ async function resume(client, database, checkpointId) {
|
|
|
264
289
|
|
|
265
290
|
export {
|
|
266
291
|
getClickHouseFieldType ,
|
|
292
|
+
makeClickHouseEntitySchema ,
|
|
267
293
|
setCheckpointsOrThrow ,
|
|
268
294
|
setUpdatesOrThrow ,
|
|
269
295
|
makeCreateHistoryTableQuery ,
|
package/src/bindings/Ethers.res
CHANGED
|
@@ -2,15 +2,6 @@ type abi = EvmTypes.Abi.t
|
|
|
2
2
|
|
|
3
3
|
let makeAbi = (abi: Js.Json.t): abi => abi->Utils.magic
|
|
4
4
|
|
|
5
|
-
@deprecated("Use Address.t instead. The type will be removed in v3")
|
|
6
|
-
type ethAddress = Address.t
|
|
7
|
-
@deprecated("Use Address.Evm.fromStringOrThrow instead. The function will be removed in v3")
|
|
8
|
-
let getAddressFromStringUnsafe = Address.Evm.fromStringOrThrow
|
|
9
|
-
@deprecated("Use Address.toString instead. The function will be removed in v3")
|
|
10
|
-
let ethAddressToString = Address.toString
|
|
11
|
-
@deprecated("Use Address.schema instead. The function will be removed in v3")
|
|
12
|
-
let ethAddressSchema = Address.schema
|
|
13
|
-
|
|
14
5
|
type txHash = string
|
|
15
6
|
|
|
16
7
|
module Constants = {
|
|
@@ -18,35 +9,6 @@ module Constants = {
|
|
|
18
9
|
@module("ethers") @scope("ethers") external zeroAddress: Address.t = "ZeroAddress"
|
|
19
10
|
}
|
|
20
11
|
|
|
21
|
-
module Addresses = {
|
|
22
|
-
@genType
|
|
23
|
-
let mockAddresses = [
|
|
24
|
-
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
|
25
|
-
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
|
|
26
|
-
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
|
|
27
|
-
"0x90F79bf6EB2c4f870365E785982E1f101E93b906",
|
|
28
|
-
"0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65",
|
|
29
|
-
"0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
|
|
30
|
-
"0x976EA74026E726554dB657fA54763abd0C3a0aa9",
|
|
31
|
-
"0x14dC79964da2C08b23698B3D3cc7Ca32193d9955",
|
|
32
|
-
"0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f",
|
|
33
|
-
"0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
|
|
34
|
-
"0xBcd4042DE499D14e55001CcbB24a551F3b954096",
|
|
35
|
-
"0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
|
|
36
|
-
"0xFABB0ac9d68B0B445fB7357272Ff202C5651694a",
|
|
37
|
-
"0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec",
|
|
38
|
-
"0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097",
|
|
39
|
-
"0xcd3B766CCDd6AE721141F452C550Ca635964ce71",
|
|
40
|
-
"0x2546BcD3c84621e976D8185a91A922aE77ECEc30",
|
|
41
|
-
"0xbDA5747bFD65F08deb54cb465eB87D40e51B197E",
|
|
42
|
-
"0xdD2FD4581271e230360230F9337D5c0430Bf44C0",
|
|
43
|
-
"0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199",
|
|
44
|
-
]->Belt.Array.map(getAddressFromStringUnsafe)
|
|
45
|
-
@genType
|
|
46
|
-
let defaultAddress =
|
|
47
|
-
mockAddresses[0]
|
|
48
|
-
}
|
|
49
|
-
|
|
50
12
|
module Filter = {
|
|
51
13
|
type t
|
|
52
14
|
}
|
|
@@ -144,41 +106,43 @@ module JsonRpcProvider = {
|
|
|
144
106
|
@send
|
|
145
107
|
external getLogs: (t, ~filter: Filter.t) => promise<array<log>> = "getLogs"
|
|
146
108
|
|
|
147
|
-
@send
|
|
148
|
-
external getTransaction: (t, ~transactionHash: string) => promise<transaction> = "getTransaction"
|
|
149
|
-
|
|
150
109
|
let makeGetTransactionFields = (~getTransactionByHash, ~lowercaseAddresses: bool) => async (
|
|
151
110
|
log: log,
|
|
152
|
-
): promise<
|
|
153
|
-
let transaction = await getTransactionByHash(log.transactionHash)
|
|
111
|
+
): promise<Internal.evmTransactionFields> => {
|
|
112
|
+
let transaction: Internal.evmTransactionFields = await getTransactionByHash(log.transactionHash)
|
|
154
113
|
// Mutating should be fine, since the transaction isn't used anywhere else outside the function
|
|
155
114
|
let fields: {..} = transaction->Obj.magic
|
|
156
115
|
|
|
157
|
-
//
|
|
116
|
+
// RPC may return null for transactionIndex on pending transactions
|
|
158
117
|
fields["transactionIndex"] = log.transactionIndex
|
|
159
|
-
fields["input"] = fields["data"]
|
|
160
118
|
|
|
161
119
|
// NOTE: this is wasteful if these fields are not selected in the users config.
|
|
162
120
|
// There might be a better way to do this in the `makeThrowingGetEventTransaction` function rather based on the schema.
|
|
163
121
|
// However this is not extremely expensive and good enough for now (only on rpc sync also).
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
122
|
+
open Js.Nullable
|
|
123
|
+
switch fields["from"] {
|
|
124
|
+
| Value(from) =>
|
|
125
|
+
fields["from"] = lowercaseAddresses
|
|
126
|
+
? from->Js.String2.toLowerCase->Address.unsafeFromString
|
|
127
|
+
: from->Address.Evm.fromStringOrThrow
|
|
128
|
+
| Undefined => ()
|
|
129
|
+
| Null => ()
|
|
130
|
+
}
|
|
131
|
+
switch fields["to"] {
|
|
132
|
+
| Value(to) =>
|
|
133
|
+
fields["to"] = lowercaseAddresses
|
|
134
|
+
? to->Js.String2.toLowerCase->Address.unsafeFromString
|
|
135
|
+
: to->Address.Evm.fromStringOrThrow
|
|
136
|
+
| Undefined => ()
|
|
137
|
+
| Null => ()
|
|
138
|
+
}
|
|
139
|
+
switch fields["contractAddress"] {
|
|
140
|
+
| Value(contractAddress) =>
|
|
141
|
+
fields["contractAddress"] = lowercaseAddresses
|
|
142
|
+
? contractAddress->Js.String2.toLowerCase->Address.unsafeFromString
|
|
143
|
+
: contractAddress->Address.Evm.fromStringOrThrow
|
|
144
|
+
| Undefined => ()
|
|
145
|
+
| Null => ()
|
|
182
146
|
}
|
|
183
147
|
|
|
184
148
|
fields->Obj.magic
|
|
@@ -2,52 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Ethers from "ethers";
|
|
4
4
|
import * as Address from "../Address.res.mjs";
|
|
5
|
-
import * as Belt_Array from "rescript/lib/es6/belt_Array.js";
|
|
6
|
-
import * as Caml_array from "rescript/lib/es6/caml_array.js";
|
|
7
5
|
import * as Caml_option from "rescript/lib/es6/caml_option.js";
|
|
8
6
|
|
|
9
7
|
function makeAbi(abi) {
|
|
10
8
|
return abi;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
var getAddressFromStringUnsafe = Address.Evm.fromStringOrThrow;
|
|
14
|
-
|
|
15
|
-
function ethAddressToString(prim) {
|
|
16
|
-
return prim;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
11
|
var Constants = {};
|
|
20
12
|
|
|
21
|
-
var mockAddresses = Belt_Array.map([
|
|
22
|
-
"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
|
|
23
|
-
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
|
|
24
|
-
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
|
|
25
|
-
"0x90F79bf6EB2c4f870365E785982E1f101E93b906",
|
|
26
|
-
"0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65",
|
|
27
|
-
"0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc",
|
|
28
|
-
"0x976EA74026E726554dB657fA54763abd0C3a0aa9",
|
|
29
|
-
"0x14dC79964da2C08b23698B3D3cc7Ca32193d9955",
|
|
30
|
-
"0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f",
|
|
31
|
-
"0xa0Ee7A142d267C1f36714E4a8F75612F20a79720",
|
|
32
|
-
"0xBcd4042DE499D14e55001CcbB24a551F3b954096",
|
|
33
|
-
"0x71bE63f3384f5fb98995898A86B02Fb2426c5788",
|
|
34
|
-
"0xFABB0ac9d68B0B445fB7357272Ff202C5651694a",
|
|
35
|
-
"0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec",
|
|
36
|
-
"0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097",
|
|
37
|
-
"0xcd3B766CCDd6AE721141F452C550Ca635964ce71",
|
|
38
|
-
"0x2546BcD3c84621e976D8185a91A922aE77ECEc30",
|
|
39
|
-
"0xbDA5747bFD65F08deb54cb465eB87D40e51B197E",
|
|
40
|
-
"0xdD2FD4581271e230360230F9337D5c0430Bf44C0",
|
|
41
|
-
"0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199"
|
|
42
|
-
], getAddressFromStringUnsafe);
|
|
43
|
-
|
|
44
|
-
var defaultAddress = Caml_array.get(mockAddresses, 0);
|
|
45
|
-
|
|
46
|
-
var Addresses = {
|
|
47
|
-
mockAddresses: mockAddresses,
|
|
48
|
-
defaultAddress: defaultAddress
|
|
49
|
-
};
|
|
50
|
-
|
|
51
13
|
var Filter = {};
|
|
52
14
|
|
|
53
15
|
function toFilter(combinedFilter) {
|
|
@@ -81,26 +43,23 @@ function makeGetTransactionFields(getTransactionByHash, lowercaseAddresses) {
|
|
|
81
43
|
return async function (log) {
|
|
82
44
|
var transaction = await getTransactionByHash(log.transactionHash);
|
|
83
45
|
transaction.transactionIndex = log.transactionIndex;
|
|
84
|
-
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
} else {
|
|
102
|
-
transaction.contractAddress = contractAddress.toLowerCase();
|
|
103
|
-
}
|
|
46
|
+
var from = transaction.from;
|
|
47
|
+
if (from === null || from === undefined) {
|
|
48
|
+
from === null;
|
|
49
|
+
} else {
|
|
50
|
+
transaction.from = lowercaseAddresses ? from.toLowerCase() : Address.Evm.fromStringOrThrow(from);
|
|
51
|
+
}
|
|
52
|
+
var to = transaction.to;
|
|
53
|
+
if (to === null || to === undefined) {
|
|
54
|
+
to === null;
|
|
55
|
+
} else {
|
|
56
|
+
transaction.to = lowercaseAddresses ? to.toLowerCase() : Address.Evm.fromStringOrThrow(to);
|
|
57
|
+
}
|
|
58
|
+
var contractAddress = transaction.contractAddress;
|
|
59
|
+
if (contractAddress === null || contractAddress === undefined) {
|
|
60
|
+
contractAddress === null;
|
|
61
|
+
} else {
|
|
62
|
+
transaction.contractAddress = lowercaseAddresses ? contractAddress.toLowerCase() : Address.Evm.fromStringOrThrow(contractAddress);
|
|
104
63
|
}
|
|
105
64
|
return transaction;
|
|
106
65
|
};
|
|
@@ -112,19 +71,13 @@ var JsonRpcProvider = {
|
|
|
112
71
|
makeGetTransactionFields: makeGetTransactionFields
|
|
113
72
|
};
|
|
114
73
|
|
|
115
|
-
var ethAddressSchema = Address.schema;
|
|
116
|
-
|
|
117
74
|
export {
|
|
118
75
|
makeAbi ,
|
|
119
|
-
getAddressFromStringUnsafe ,
|
|
120
|
-
ethAddressToString ,
|
|
121
|
-
ethAddressSchema ,
|
|
122
76
|
Constants ,
|
|
123
|
-
Addresses ,
|
|
124
77
|
Filter ,
|
|
125
78
|
CombinedFilter ,
|
|
126
79
|
logToMinimumParseableLogData ,
|
|
127
80
|
Network ,
|
|
128
81
|
JsonRpcProvider ,
|
|
129
82
|
}
|
|
130
|
-
/*
|
|
83
|
+
/* ethers Not a pure module */
|