envio 2.8.2 → 2.9.1
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/package.json +6 -6
- package/src/Enum.res +22 -0
- package/src/LogSelection.res +60 -0
- package/src/Utils.res +2 -0
- package/src/bindings/BigInt.res +57 -0
- package/src/bindings/Express.res +29 -0
- package/src/bindings/Postgres.res +98 -0
- package/src/bindings/Promise.res +52 -0
- package/src/db/EntityHistory.res +335 -0
- package/src/db/Schema.res +18 -0
- package/src/db/Table.res +251 -0
- package/src/sources/Rpc.res +181 -0
- package/src/vendored/Rest.res +661 -0
- package/src/vendored/Rest.resi +182 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
let makeRpcRoute = (method: string, paramsSchema, resultSchema) => {
|
|
2
|
+
let idSchema = S.literal(1)
|
|
3
|
+
let versionSchema = S.literal("2.0")
|
|
4
|
+
Rest.route(() => {
|
|
5
|
+
method: Post,
|
|
6
|
+
path: "",
|
|
7
|
+
variables: s => {
|
|
8
|
+
let _ = s.field("method", S.literal(method))
|
|
9
|
+
let _ = s.field("id", idSchema)
|
|
10
|
+
let _ = s.field("jsonrpc", versionSchema)
|
|
11
|
+
s.field("params", paramsSchema)
|
|
12
|
+
},
|
|
13
|
+
responses: [
|
|
14
|
+
s => {
|
|
15
|
+
let _ = s.field("jsonrpc", versionSchema)
|
|
16
|
+
let _ = s.field("id", idSchema)
|
|
17
|
+
s.field("result", resultSchema)
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type hex = string
|
|
24
|
+
let makeHexSchema = fromStr =>
|
|
25
|
+
S.string->S.transform(s => {
|
|
26
|
+
parser: str =>
|
|
27
|
+
switch str->fromStr {
|
|
28
|
+
| Some(v) => v
|
|
29
|
+
| None => s.fail("The string is not valid hex")
|
|
30
|
+
},
|
|
31
|
+
serializer: value => value->Viem.toHex->Utils.magic,
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
let hexBigintSchema: S.schema<bigint> = makeHexSchema(BigInt.fromString)
|
|
35
|
+
external number: string => int = "Number"
|
|
36
|
+
let hexIntSchema: S.schema<int> = makeHexSchema(v => v->number->Some)
|
|
37
|
+
|
|
38
|
+
module GetLogs = {
|
|
39
|
+
@unboxed
|
|
40
|
+
type topicFilter = Single(hex) | Multiple(array<hex>) | @as(null) Null
|
|
41
|
+
let topicFilterSchema = S.union([
|
|
42
|
+
S.literal(Null),
|
|
43
|
+
S.schema(s => Multiple(s.matches(S.array(S.string)))),
|
|
44
|
+
S.schema(s => Single(s.matches(S.string))),
|
|
45
|
+
])
|
|
46
|
+
type topicQuery = array<topicFilter>
|
|
47
|
+
let topicQuerySchema = S.array(topicFilterSchema)
|
|
48
|
+
|
|
49
|
+
let makeTopicQuery = (~topic0=[], ~topic1=[], ~topic2=[], ~topic3=[]) => {
|
|
50
|
+
let topics = [topic0, topic1, topic2, topic3]
|
|
51
|
+
|
|
52
|
+
let isLastTopicEmpty = () =>
|
|
53
|
+
switch topics->Utils.Array.last {
|
|
54
|
+
| Some([]) => true
|
|
55
|
+
| _ => false
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//Remove all empty topics from the end of the array
|
|
59
|
+
while isLastTopicEmpty() {
|
|
60
|
+
topics->Js.Array2.pop->ignore
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let toTopicFilter = topic => {
|
|
64
|
+
switch topic {
|
|
65
|
+
| [] => Null
|
|
66
|
+
| [single] => Single(single->EvmTypes.Hex.toString)
|
|
67
|
+
| multiple => Multiple(multiple->EvmTypes.Hex.toStrings)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
topics->Belt.Array.map(toTopicFilter)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let mapTopicQuery = ({topic0, topic1, topic2, topic3}: LogSelection.topicSelection): topicQuery =>
|
|
75
|
+
makeTopicQuery(~topic0, ~topic1, ~topic2, ~topic3)
|
|
76
|
+
|
|
77
|
+
type param = {
|
|
78
|
+
fromBlock: int,
|
|
79
|
+
toBlock: int,
|
|
80
|
+
address: array<Address.t>,
|
|
81
|
+
topics: topicQuery,
|
|
82
|
+
// blockHash?: string,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let paramsSchema = S.object((s): param => {
|
|
86
|
+
fromBlock: s.field("fromBlock", hexIntSchema),
|
|
87
|
+
toBlock: s.field("toBlock", hexIntSchema),
|
|
88
|
+
address: s.field("address", S.array(Address.schema)),
|
|
89
|
+
topics: s.field("topics", topicQuerySchema),
|
|
90
|
+
// blockHash: ?s.field("blockHash", S.option(S.string)),
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
type log = {
|
|
94
|
+
address: Address.t,
|
|
95
|
+
topics: array<hex>,
|
|
96
|
+
data: hex,
|
|
97
|
+
blockNumber: int,
|
|
98
|
+
transactionHash: hex,
|
|
99
|
+
transactionIndex: int,
|
|
100
|
+
blockHash: hex,
|
|
101
|
+
logIndex: int,
|
|
102
|
+
removed: bool,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
let logSchema = S.object((s): log => {
|
|
106
|
+
address: s.field("address", Address.schema),
|
|
107
|
+
topics: s.field("topics", S.array(S.string)),
|
|
108
|
+
data: s.field("data", S.string),
|
|
109
|
+
blockNumber: s.field("blockNumber", hexIntSchema),
|
|
110
|
+
transactionHash: s.field("transactionHash", S.string),
|
|
111
|
+
transactionIndex: s.field("transactionIndex", hexIntSchema),
|
|
112
|
+
blockHash: s.field("blockHash", S.string),
|
|
113
|
+
logIndex: s.field("logIndex", hexIntSchema),
|
|
114
|
+
removed: s.field("removed", S.bool),
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
let route = makeRpcRoute("eth_getLogs", S.tuple1(paramsSchema), S.array(logSchema))
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module GetBlockByNumber = {
|
|
121
|
+
type block = {
|
|
122
|
+
difficulty: option<bigint>,
|
|
123
|
+
extraData: hex,
|
|
124
|
+
gasLimit: bigint,
|
|
125
|
+
gasUsed: bigint,
|
|
126
|
+
hash: hex,
|
|
127
|
+
logsBloom: hex,
|
|
128
|
+
miner: Address.t,
|
|
129
|
+
mixHash: option<hex>,
|
|
130
|
+
nonce: option<bigint>,
|
|
131
|
+
number: int,
|
|
132
|
+
parentHash: hex,
|
|
133
|
+
receiptsRoot: hex,
|
|
134
|
+
sha3Uncles: hex,
|
|
135
|
+
size: bigint,
|
|
136
|
+
stateRoot: hex,
|
|
137
|
+
timestamp: int,
|
|
138
|
+
totalDifficulty: option<bigint>,
|
|
139
|
+
transactions: array<Js.Json.t>,
|
|
140
|
+
transactionsRoot: hex,
|
|
141
|
+
uncles: option<array<hex>>,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
let blockSchema = S.object((s): block => {
|
|
145
|
+
difficulty: s.field("difficulty", S.null(hexBigintSchema)),
|
|
146
|
+
extraData: s.field("extraData", S.string),
|
|
147
|
+
gasLimit: s.field("gasLimit", hexBigintSchema),
|
|
148
|
+
gasUsed: s.field("gasUsed", hexBigintSchema),
|
|
149
|
+
hash: s.field("hash", S.string),
|
|
150
|
+
logsBloom: s.field("logsBloom", S.string),
|
|
151
|
+
miner: s.field("miner", Address.schema),
|
|
152
|
+
mixHash: s.field("mixHash", S.null(S.string)),
|
|
153
|
+
nonce: s.field("nonce", S.null(hexBigintSchema)),
|
|
154
|
+
number: s.field("number", hexIntSchema),
|
|
155
|
+
parentHash: s.field("parentHash", S.string),
|
|
156
|
+
receiptsRoot: s.field("receiptsRoot", S.string),
|
|
157
|
+
sha3Uncles: s.field("sha3Uncles", S.string),
|
|
158
|
+
size: s.field("size", hexBigintSchema),
|
|
159
|
+
stateRoot: s.field("stateRoot", S.string),
|
|
160
|
+
timestamp: s.field("timestamp", hexIntSchema),
|
|
161
|
+
totalDifficulty: s.field("totalDifficulty", S.null(hexBigintSchema)),
|
|
162
|
+
transactions: s.field("transactions", S.array(S.json(~validate=false))),
|
|
163
|
+
transactionsRoot: s.field("transactionsRoot", S.string),
|
|
164
|
+
uncles: s.field("uncles", S.null(S.array(S.string))),
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
let route = makeRpcRoute(
|
|
168
|
+
"eth_getBlockByNumber",
|
|
169
|
+
S.tuple(s =>
|
|
170
|
+
{
|
|
171
|
+
"blockNumber": s.item(0, hexIntSchema),
|
|
172
|
+
"includeTransactions": s.item(1, S.bool),
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
S.null(blockSchema),
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
module GetBlockHeight = {
|
|
180
|
+
let route = makeRpcRoute("eth_blockNumber", S.tuple(_ => ()), hexIntSchema)
|
|
181
|
+
}
|