@apibara/evm 2.0.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/.turbo/turbo-build.log +17 -0
- package/CHANGELOG.md +1 -0
- package/LICENSE.txt +202 -0
- package/README.md +27 -0
- package/buf.gen.yaml +14 -0
- package/build.config.ts +11 -0
- package/dist/index.cjs +2994 -0
- package/dist/index.d.cts +1900 -0
- package/dist/index.d.mts +1900 -0
- package/dist/index.d.ts +1900 -0
- package/dist/index.mjs +2953 -0
- package/package.json +49 -0
- package/proto/common.proto +37 -0
- package/proto/data.proto +192 -0
- package/proto/filter.proto +61 -0
- package/src/block.ts +167 -0
- package/src/common.test.ts +79 -0
- package/src/common.ts +117 -0
- package/src/filter.test.ts +191 -0
- package/src/filter.ts +117 -0
- package/src/index.ts +15 -0
- package/src/proto/common.ts +561 -0
- package/src/proto/data.ts +2111 -0
- package/src/proto/filter.ts +658 -0
- package/src/proto/google/protobuf/timestamp.ts +220 -0
- package/src/proto/index.ts +3 -0
- package/tsconfig.json +11 -0
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@apibara/evm",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"source": "./src/index.ts",
|
|
6
|
+
"main": "./dist/index.mjs",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.mjs",
|
|
11
|
+
"require": "./dist/index.cjs",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src",
|
|
19
|
+
"README.md"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@bufbuild/buf": "^1.32.1",
|
|
24
|
+
"@types/long": "^5.0.0",
|
|
25
|
+
"@types/node": "^20.12.12",
|
|
26
|
+
"unbuild": "^2.0.0",
|
|
27
|
+
"vitest": "^1.6.0"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@effect/schema": "^0.67.15",
|
|
31
|
+
"effect": "^3.2.6",
|
|
32
|
+
"long": "^5.2.1",
|
|
33
|
+
"nice-grpc-common": "^2.0.2",
|
|
34
|
+
"protobufjs": "^7.1.2",
|
|
35
|
+
"viem": "^2.12.4",
|
|
36
|
+
"@apibara/protocol": "2.0.0-beta.1"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "pnpm build:proto && unbuild",
|
|
40
|
+
"build:proto": "buf generate proto",
|
|
41
|
+
"typecheck": "tsc --noEmit",
|
|
42
|
+
"test": "vitest",
|
|
43
|
+
"test:ci": "vitest run",
|
|
44
|
+
"lint": "biome check .",
|
|
45
|
+
"lint:fix": "pnpm lint --write",
|
|
46
|
+
"format": "biome format . --write"
|
|
47
|
+
},
|
|
48
|
+
"types": "./dist/index.d.ts"
|
|
49
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package evm.v2;
|
|
4
|
+
|
|
5
|
+
// An address of 160 bits.
|
|
6
|
+
//
|
|
7
|
+
// As a separate type so that the API is clearer.
|
|
8
|
+
message Address {
|
|
9
|
+
fixed64 x0 = 1;
|
|
10
|
+
fixed64 x1 = 2;
|
|
11
|
+
fixed32 x2 = 3;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// A bloom filter of 256 bytes.
|
|
15
|
+
message Bloom { bytes value = 1; }
|
|
16
|
+
|
|
17
|
+
// Unsigned integer of 128 bits.
|
|
18
|
+
message U128 {
|
|
19
|
+
fixed64 x0 = 1;
|
|
20
|
+
fixed64 x1 = 2;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Unsigned integer of 256 bits.
|
|
24
|
+
message U256 {
|
|
25
|
+
fixed64 x0 = 1;
|
|
26
|
+
fixed64 x1 = 2;
|
|
27
|
+
fixed64 x2 = 3;
|
|
28
|
+
fixed64 x3 = 4;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Byte array of 256 bits.
|
|
32
|
+
message B256 {
|
|
33
|
+
fixed64 x0 = 1;
|
|
34
|
+
fixed64 x1 = 2;
|
|
35
|
+
fixed64 x2 = 3;
|
|
36
|
+
fixed64 x3 = 4;
|
|
37
|
+
}
|
package/proto/data.proto
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// EVM DNA definitions (data).
|
|
2
|
+
syntax = "proto3";
|
|
3
|
+
|
|
4
|
+
package evm.v2;
|
|
5
|
+
|
|
6
|
+
import "google/protobuf/timestamp.proto";
|
|
7
|
+
import "common.proto";
|
|
8
|
+
|
|
9
|
+
// Requested data, grouped by block.
|
|
10
|
+
message Block {
|
|
11
|
+
// The header.
|
|
12
|
+
BlockHeader header = 1;
|
|
13
|
+
// List of withdrawals.
|
|
14
|
+
repeated Withdrawal withdrawals = 2;
|
|
15
|
+
// List of transactions.
|
|
16
|
+
repeated Transaction transactions = 3;
|
|
17
|
+
// List of receipts.
|
|
18
|
+
repeated TransactionReceipt receipts = 4;
|
|
19
|
+
// List of logs.
|
|
20
|
+
repeated Log logs = 5;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Block header.
|
|
24
|
+
message BlockHeader {
|
|
25
|
+
// Block number.
|
|
26
|
+
uint64 number = 1;
|
|
27
|
+
// Hash of the block.
|
|
28
|
+
B256 hash = 2;
|
|
29
|
+
// Hash of the parent block.
|
|
30
|
+
B256 parent_hash = 3;
|
|
31
|
+
// Hash of the uncles.
|
|
32
|
+
B256 uncles_hash = 4;
|
|
33
|
+
// Author of the block.
|
|
34
|
+
Address miner = 5;
|
|
35
|
+
// State root hash.
|
|
36
|
+
B256 state_root = 6;
|
|
37
|
+
// Transactions root hash.
|
|
38
|
+
B256 transactions_root = 7;
|
|
39
|
+
// Receipts root hash.
|
|
40
|
+
B256 receipts_root = 8;
|
|
41
|
+
// Logs bloom.
|
|
42
|
+
Bloom logs_bloom = 9;
|
|
43
|
+
// Difficulty.
|
|
44
|
+
U256 difficulty = 10;
|
|
45
|
+
// Gas limit.
|
|
46
|
+
U256 gas_limit = 11;
|
|
47
|
+
// Gas used.
|
|
48
|
+
U256 gas_used = 12;
|
|
49
|
+
// Timestamp.
|
|
50
|
+
google.protobuf.Timestamp timestamp = 13;
|
|
51
|
+
// Extra data.
|
|
52
|
+
bytes extra_data = 14;
|
|
53
|
+
// Mix hash.
|
|
54
|
+
B256 mix_hash = 15;
|
|
55
|
+
// Nonce.
|
|
56
|
+
uint64 nonce = 16;
|
|
57
|
+
// Base fee per unit of gas.
|
|
58
|
+
U256 base_fee_per_gas = 17;
|
|
59
|
+
// Withdrawals root hash.
|
|
60
|
+
B256 withdrawals_root = 18;
|
|
61
|
+
|
|
62
|
+
// Additional fields.
|
|
63
|
+
|
|
64
|
+
// Total difficulty.
|
|
65
|
+
U256 total_difficulty = 19;
|
|
66
|
+
// Uncles' hashes.
|
|
67
|
+
repeated B256 uncles = 20;
|
|
68
|
+
// The size of this block in bytes.
|
|
69
|
+
U256 size = 21;
|
|
70
|
+
|
|
71
|
+
// SKIPPED: withdrawals - included at top level.
|
|
72
|
+
|
|
73
|
+
// Blob gas used.
|
|
74
|
+
uint64 blob_gas_used = 22;
|
|
75
|
+
// Excess blob gas.
|
|
76
|
+
uint64 excess_blob_gas = 23;
|
|
77
|
+
// Parent beacon block root.
|
|
78
|
+
B256 parent_beacon_block_root = 24;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// A validator's withdrawal from the consensus layer.
|
|
82
|
+
message Withdrawal {
|
|
83
|
+
// Increasing index of the withdrawal.
|
|
84
|
+
uint64 index = 1;
|
|
85
|
+
// Index of the validator.
|
|
86
|
+
uint64 validator_index = 2;
|
|
87
|
+
// Withdrawal index in the block.
|
|
88
|
+
uint64 withdrawal_index = 3;
|
|
89
|
+
// Target address of the withdrawal.
|
|
90
|
+
Address address = 4;
|
|
91
|
+
// Value of the withdrawal, in gwei.
|
|
92
|
+
U256 amount = 5;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
message Transaction {
|
|
96
|
+
// Transaction hash.
|
|
97
|
+
B256 hash = 1;
|
|
98
|
+
// Nonce.
|
|
99
|
+
uint64 nonce = 2;
|
|
100
|
+
// Transaction index in the block.
|
|
101
|
+
uint64 transaction_index = 3;
|
|
102
|
+
// Sender.
|
|
103
|
+
Address from = 4;
|
|
104
|
+
// Recipient.
|
|
105
|
+
Address to = 5;
|
|
106
|
+
// Amount of wei transferred.
|
|
107
|
+
U256 value = 6;
|
|
108
|
+
// Gas price.
|
|
109
|
+
U128 gas_price = 7;
|
|
110
|
+
// Gas amount.
|
|
111
|
+
U256 gas = 8;
|
|
112
|
+
// Max base fee per gas the sender is willing to pay.
|
|
113
|
+
U128 max_fee_per_gas = 9;
|
|
114
|
+
// Miner's tip.
|
|
115
|
+
U128 max_priority_fee_per_gas = 10;
|
|
116
|
+
// Data.
|
|
117
|
+
bytes input = 11;
|
|
118
|
+
// The signature's r,s,v,yParity values.
|
|
119
|
+
Signature signature = 12;
|
|
120
|
+
// Chain ID.
|
|
121
|
+
uint64 chain_id = 13;
|
|
122
|
+
// EIP-2930 access list.
|
|
123
|
+
repeated AccessListItem access_list = 14;
|
|
124
|
+
// EIP-2718 transaction type.
|
|
125
|
+
uint64 transaction_type = 15;
|
|
126
|
+
// EIP-4844 max gas fee per blob.
|
|
127
|
+
U128 max_fee_per_blob_gas = 16;
|
|
128
|
+
// EIP-4844 blob hashes.
|
|
129
|
+
repeated B256 blob_versioned_hashes = 17;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
message TransactionReceipt {
|
|
133
|
+
// Transaction hash.
|
|
134
|
+
B256 transaction_hash = 1;
|
|
135
|
+
// Index of the transaction in the block.
|
|
136
|
+
uint64 transaction_index = 2;
|
|
137
|
+
// Cumulative gas used in the block after this transaction has been executed.
|
|
138
|
+
U256 cumulative_gas_used = 3;
|
|
139
|
+
// Gas used by this transaction.
|
|
140
|
+
U256 gas_used = 4;
|
|
141
|
+
// The price paid by the transaction.
|
|
142
|
+
U128 effective_gas_price = 5;
|
|
143
|
+
// Sender.
|
|
144
|
+
Address from = 6;
|
|
145
|
+
// Recipient, if any.
|
|
146
|
+
Address to = 7;
|
|
147
|
+
// Contract address created, if any.
|
|
148
|
+
Address contract_address = 8;
|
|
149
|
+
// Logs bloom.
|
|
150
|
+
Bloom logs_bloom = 9;
|
|
151
|
+
// Either 1 (success) or 0 (failure).
|
|
152
|
+
uint64 status_code = 10;
|
|
153
|
+
// EIP-2718 transaction type.
|
|
154
|
+
uint64 transaction_type = 11;
|
|
155
|
+
// EIP-4844 blob gas used.
|
|
156
|
+
U128 blob_gas_used = 12;
|
|
157
|
+
// EIP-4844 blob gas paid by the transaction.
|
|
158
|
+
U128 blob_gas_price = 13;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
message Log {
|
|
162
|
+
// Address of the contract that emitted the log.
|
|
163
|
+
Address address = 1;
|
|
164
|
+
// Log topics.
|
|
165
|
+
repeated B256 topics = 2;
|
|
166
|
+
// Additional data.
|
|
167
|
+
bytes data = 3;
|
|
168
|
+
// Index of the log in the block.
|
|
169
|
+
uint64 log_index = 4;
|
|
170
|
+
// Index of the transaction that emitted the log.
|
|
171
|
+
uint64 transaction_index = 5;
|
|
172
|
+
// Hash of the transaction that emitted the log.
|
|
173
|
+
B256 transaction_hash = 6;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
message Signature {
|
|
177
|
+
// The signature's r value.
|
|
178
|
+
U256 r = 1;
|
|
179
|
+
// The signature's s value.
|
|
180
|
+
U256 s = 2;
|
|
181
|
+
// The signature's v value.
|
|
182
|
+
U256 v = 3;
|
|
183
|
+
// The signature's parity byte.
|
|
184
|
+
bool y_parity = 4;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
message AccessListItem {
|
|
188
|
+
// Account address to be loaded at the start of the transaction.
|
|
189
|
+
Address address = 1;
|
|
190
|
+
// Storage keys to be loaded at the start of the transaction.
|
|
191
|
+
repeated B256 storage_keys = 2;
|
|
192
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// EVM DNA definitions (filter).
|
|
2
|
+
syntax = "proto3";
|
|
3
|
+
|
|
4
|
+
package evm.v2;
|
|
5
|
+
|
|
6
|
+
import "common.proto";
|
|
7
|
+
|
|
8
|
+
message Filter {
|
|
9
|
+
// Include header.
|
|
10
|
+
HeaderFilter header = 1;
|
|
11
|
+
// Filter withdrawals.
|
|
12
|
+
repeated WithdrawalFilter withdrawals = 2;
|
|
13
|
+
// Filter transactions.
|
|
14
|
+
repeated TransactionFilter transactions = 3;
|
|
15
|
+
// Filter logs.
|
|
16
|
+
repeated LogFilter logs = 4;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
message HeaderFilter {
|
|
20
|
+
// Always include header data. Defaults to `false`.
|
|
21
|
+
optional bool always = 1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
message WithdrawalFilter {
|
|
25
|
+
// Filter based on the validator index.
|
|
26
|
+
optional uint64 validator_index = 1;
|
|
27
|
+
// Filter based on the withdrawal's target address.
|
|
28
|
+
Address address = 2;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
message TransactionFilter {
|
|
32
|
+
// Filter based on the transaction's sender address.
|
|
33
|
+
Address from = 1;
|
|
34
|
+
// Filter based on the transaction's recipient address.
|
|
35
|
+
Address to = 2;
|
|
36
|
+
// Flag to request the transaction's receipt. Defaults to `false`.
|
|
37
|
+
optional bool include_receipt = 3;
|
|
38
|
+
// Flag to request the transaction's logs. Defaults to `false`.
|
|
39
|
+
optional bool include_logs = 4;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
message LogFilter {
|
|
43
|
+
// Filter based on the log's contract address.
|
|
44
|
+
Address address = 1;
|
|
45
|
+
// Filter based on the log's topics.
|
|
46
|
+
repeated Topic topics = 2;
|
|
47
|
+
// Only returns logs with topics of exactly the same length as the filter.
|
|
48
|
+
//
|
|
49
|
+
// Defaults to `false`.
|
|
50
|
+
optional bool strict = 3;
|
|
51
|
+
// Flag to request the log's transaction. Defaults to `false`.
|
|
52
|
+
optional bool include_transaction = 4;
|
|
53
|
+
// Flag to request the log's receipt. Defaults to `false`.
|
|
54
|
+
optional bool include_receipt = 5;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Topic filter.
|
|
58
|
+
message Topic {
|
|
59
|
+
// Topic value. Leave empty to match any topic.
|
|
60
|
+
B256 value = 1;
|
|
61
|
+
}
|
package/src/block.ts
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { Bytes, BytesFromUint8Array } from "@apibara/protocol";
|
|
2
|
+
import { Schema } from "@effect/schema";
|
|
3
|
+
|
|
4
|
+
import { Address, B256, U128, U256 } from "./common";
|
|
5
|
+
import * as proto from "./proto";
|
|
6
|
+
|
|
7
|
+
export const HexData = Schema.transform(
|
|
8
|
+
Schema.Struct({
|
|
9
|
+
value: BytesFromUint8Array,
|
|
10
|
+
}),
|
|
11
|
+
Bytes,
|
|
12
|
+
{
|
|
13
|
+
strict: false,
|
|
14
|
+
encode(value) {
|
|
15
|
+
throw new Error("Not implemented");
|
|
16
|
+
},
|
|
17
|
+
decode({ value }) {
|
|
18
|
+
// return value;
|
|
19
|
+
throw new Error("Not implemented");
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export const Bloom = Schema.transform(
|
|
25
|
+
Schema.Struct({
|
|
26
|
+
value: BytesFromUint8Array,
|
|
27
|
+
}),
|
|
28
|
+
Bytes,
|
|
29
|
+
{
|
|
30
|
+
strict: false,
|
|
31
|
+
encode(value) {
|
|
32
|
+
throw new Error("Not implemented");
|
|
33
|
+
},
|
|
34
|
+
decode({ value }) {
|
|
35
|
+
throw new Error("Not implemented");
|
|
36
|
+
// return value;
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
export const BlockHeader = Schema.Struct({
|
|
42
|
+
number: Schema.BigIntFromSelf,
|
|
43
|
+
hash: Schema.optional(B256),
|
|
44
|
+
parentHash: Schema.optional(B256),
|
|
45
|
+
uncleHash: Schema.optional(B256),
|
|
46
|
+
miner: Schema.optional(Address),
|
|
47
|
+
stateRoot: Schema.optional(B256),
|
|
48
|
+
transactionRoot: Schema.optional(B256),
|
|
49
|
+
receiptRoot: Schema.optional(B256),
|
|
50
|
+
logsBloom: Schema.optional(Bloom),
|
|
51
|
+
difficulty: Schema.optional(U256),
|
|
52
|
+
gasLimit: Schema.optional(U256),
|
|
53
|
+
gasUsed: Schema.optional(U256),
|
|
54
|
+
timestamp: Schema.optional(Schema.DateFromSelf),
|
|
55
|
+
// extraData: Schema.optional(HexData),
|
|
56
|
+
mixHash: Schema.optional(B256),
|
|
57
|
+
nonce: Schema.BigIntFromSelf,
|
|
58
|
+
baseFeePerGas: Schema.optional(U256),
|
|
59
|
+
withdrawalsRoot: Schema.optional(B256),
|
|
60
|
+
totalDifficulty: Schema.optional(U256),
|
|
61
|
+
uncles: Schema.Array(B256),
|
|
62
|
+
size: Schema.optional(U256),
|
|
63
|
+
blobGasUsed: Schema.BigIntFromSelf,
|
|
64
|
+
excessBlobGas: Schema.BigIntFromSelf,
|
|
65
|
+
parentBeaconBlockRoot: Schema.optional(B256),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export type BlockHeader = typeof BlockHeader.Type;
|
|
69
|
+
|
|
70
|
+
export const Withdrawal = Schema.Struct({
|
|
71
|
+
index: Schema.BigIntFromSelf,
|
|
72
|
+
validatorIndex: Schema.BigIntFromSelf,
|
|
73
|
+
withdrawalIndex: Schema.BigIntFromSelf,
|
|
74
|
+
address: Schema.optional(Address),
|
|
75
|
+
amount: Schema.optional(U256),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
export const AccessListItem = Schema.Struct({
|
|
79
|
+
address: Schema.optional(Address),
|
|
80
|
+
storageKeys: Schema.Array(B256),
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
export const Signature = Schema.Struct({
|
|
84
|
+
r: Schema.optional(U256),
|
|
85
|
+
s: Schema.optional(U256),
|
|
86
|
+
v: Schema.optional(U256),
|
|
87
|
+
YParity: Schema.optional(Schema.Boolean),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
export const Transaction = Schema.Struct({
|
|
91
|
+
hash: Schema.optional(B256),
|
|
92
|
+
nonce: Schema.BigIntFromSelf,
|
|
93
|
+
transactionIndex: Schema.BigIntFromSelf,
|
|
94
|
+
from: Schema.optional(Address),
|
|
95
|
+
to: Schema.optional(Address),
|
|
96
|
+
value: Schema.optional(U256),
|
|
97
|
+
gasPrice: Schema.optional(U128),
|
|
98
|
+
gas: Schema.optional(U256),
|
|
99
|
+
maxFeePerGas: Schema.optional(U128),
|
|
100
|
+
maxPriorityFeePerGas: Schema.optional(U128),
|
|
101
|
+
// TODO
|
|
102
|
+
// input: Schema.optional(HexData),
|
|
103
|
+
signature: Schema.optional(Signature),
|
|
104
|
+
chainId: Schema.BigIntFromSelf,
|
|
105
|
+
accessList: Schema.Array(AccessListItem),
|
|
106
|
+
transactionType: Schema.BigIntFromSelf,
|
|
107
|
+
maxFeePerBlobGas: Schema.optional(U128),
|
|
108
|
+
blobVersionedHashes: Schema.Array(B256),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
export const TransactionReceipt = Schema.Struct({
|
|
112
|
+
transactionHash: Schema.optional(B256),
|
|
113
|
+
transactionIndex: Schema.BigIntFromSelf,
|
|
114
|
+
cumulativeGasUsed: Schema.optional(U256),
|
|
115
|
+
gasUsed: Schema.optional(U256),
|
|
116
|
+
effectiveGasPrice: Schema.optional(U128),
|
|
117
|
+
from: Schema.optional(Address),
|
|
118
|
+
to: Schema.optional(Address),
|
|
119
|
+
contractAddress: Schema.optional(Address),
|
|
120
|
+
logsBloom: Schema.optional(Bloom),
|
|
121
|
+
statusCode: Schema.BigIntFromSelf,
|
|
122
|
+
transactionType: Schema.BigIntFromSelf,
|
|
123
|
+
blobGasUsed: Schema.optional(U128),
|
|
124
|
+
blobGasPrice: Schema.optional(U128),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export const Log = Schema.Struct({
|
|
128
|
+
address: Schema.optional(Address),
|
|
129
|
+
topics: Schema.Array(B256),
|
|
130
|
+
// TODO
|
|
131
|
+
// data: Bytes,
|
|
132
|
+
logIndex: Schema.BigIntFromSelf,
|
|
133
|
+
transactionIndex: Schema.BigIntFromSelf,
|
|
134
|
+
transactionHash: Schema.optional(B256),
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
export type Log = typeof Log.Type;
|
|
138
|
+
|
|
139
|
+
export const Block = Schema.Struct({
|
|
140
|
+
header: Schema.optional(BlockHeader),
|
|
141
|
+
withdrawals: Schema.Array(Withdrawal),
|
|
142
|
+
transactions: Schema.Array(Transaction),
|
|
143
|
+
receipts: Schema.Array(TransactionReceipt),
|
|
144
|
+
logs: Schema.Array(Log),
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
export type Block = typeof Block.Type;
|
|
148
|
+
|
|
149
|
+
export const BlockFromBytes = Schema.transform(
|
|
150
|
+
Schema.Uint8ArrayFromSelf,
|
|
151
|
+
Schema.NullOr(Block),
|
|
152
|
+
{
|
|
153
|
+
strict: false,
|
|
154
|
+
decode(value) {
|
|
155
|
+
if (value.length === 0) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
return proto.data.Block.decode(value);
|
|
159
|
+
},
|
|
160
|
+
encode(value) {
|
|
161
|
+
if (value === null) {
|
|
162
|
+
return new Uint8Array();
|
|
163
|
+
}
|
|
164
|
+
return proto.data.Block.encode(value).finish();
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { Schema } from "@effect/schema";
|
|
4
|
+
import { pad } from "viem";
|
|
5
|
+
|
|
6
|
+
import { Address, B256, U128, U256 } from "./common";
|
|
7
|
+
|
|
8
|
+
describe("Address", () => {
|
|
9
|
+
const encode = Schema.encodeSync(Address);
|
|
10
|
+
const decode = Schema.decodeSync(Address);
|
|
11
|
+
|
|
12
|
+
it("should convert to and from proto", () => {
|
|
13
|
+
const address = "0x27504265a9bc4330e3fe82061a60cd8b6369b4dc";
|
|
14
|
+
|
|
15
|
+
const message = encode(address);
|
|
16
|
+
|
|
17
|
+
expect(message.x0).toBeDefined();
|
|
18
|
+
expect(message.x1).toBeDefined();
|
|
19
|
+
expect(message.x2).toBeDefined();
|
|
20
|
+
|
|
21
|
+
const back = decode(message);
|
|
22
|
+
expect(back).toEqual(pad(address, { size: 20 }));
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("B256", () => {
|
|
27
|
+
const encode = Schema.encodeSync(B256);
|
|
28
|
+
const decode = Schema.decodeSync(B256);
|
|
29
|
+
|
|
30
|
+
it("should convert to and from proto", () => {
|
|
31
|
+
const value =
|
|
32
|
+
"0x9df92d765b5aa041fd4bbe8d5878eb89290efa78e444c1a603eecfae2ea05fa4";
|
|
33
|
+
const message = encode(value);
|
|
34
|
+
|
|
35
|
+
expect(message.x0).toBeDefined();
|
|
36
|
+
expect(message.x1).toBeDefined();
|
|
37
|
+
expect(message.x2).toBeDefined();
|
|
38
|
+
expect(message.x3).toBeDefined();
|
|
39
|
+
|
|
40
|
+
const back = decode(message);
|
|
41
|
+
expect(back).toEqual(pad(value, { size: 32 }));
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe("U256", () => {
|
|
46
|
+
const encode = Schema.encodeSync(U256);
|
|
47
|
+
const decode = Schema.decodeSync(U256);
|
|
48
|
+
|
|
49
|
+
it("should convert to and from proto", () => {
|
|
50
|
+
const value = BigInt(
|
|
51
|
+
"0x9df92d765b5aa041fd4bbe8d5878eb89290efa78e444c1a603eecfae2ea05fa4",
|
|
52
|
+
);
|
|
53
|
+
const message = encode(value);
|
|
54
|
+
|
|
55
|
+
expect(message.x0).toBeDefined();
|
|
56
|
+
expect(message.x1).toBeDefined();
|
|
57
|
+
expect(message.x2).toBeDefined();
|
|
58
|
+
expect(message.x3).toBeDefined();
|
|
59
|
+
|
|
60
|
+
const back = decode(message);
|
|
61
|
+
expect(back).toEqual(value);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe("U128", () => {
|
|
66
|
+
const encode = Schema.encodeSync(U128);
|
|
67
|
+
const decode = Schema.decodeSync(U128);
|
|
68
|
+
|
|
69
|
+
it("should convert to and from proto", () => {
|
|
70
|
+
const value = BigInt("0x090efa78e444c1a603eecfae2ea05fa4");
|
|
71
|
+
const message = encode(value);
|
|
72
|
+
|
|
73
|
+
expect(message.x0).toBeDefined();
|
|
74
|
+
expect(message.x1).toBeDefined();
|
|
75
|
+
|
|
76
|
+
const back = decode(message);
|
|
77
|
+
expect(back).toEqual(value);
|
|
78
|
+
});
|
|
79
|
+
});
|
package/src/common.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Schema } from "@effect/schema";
|
|
2
|
+
import { hexToBytes, pad } from "viem";
|
|
3
|
+
|
|
4
|
+
const MAX_U64 = 0xffffffffffffffffn;
|
|
5
|
+
|
|
6
|
+
const _Address = Schema.TemplateLiteral(Schema.Literal("0x"), Schema.String);
|
|
7
|
+
|
|
8
|
+
/** Wire representation of `Address`. */
|
|
9
|
+
const AddressProto = Schema.Struct({
|
|
10
|
+
x0: Schema.BigIntFromSelf,
|
|
11
|
+
x1: Schema.BigIntFromSelf,
|
|
12
|
+
x2: Schema.Number,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
/** An Ethereum address. */
|
|
16
|
+
export const Address = Schema.transform(AddressProto, _Address, {
|
|
17
|
+
decode(value) {
|
|
18
|
+
const x0 = value.x0.toString(16).padStart(16, "0");
|
|
19
|
+
const x1 = value.x1.toString(16).padStart(16, "0");
|
|
20
|
+
const x2 = value.x2.toString(16).padStart(8, "0");
|
|
21
|
+
return `0x${x0}${x1}${x2}` as `0x${string}`;
|
|
22
|
+
},
|
|
23
|
+
encode(value) {
|
|
24
|
+
const bytes = hexToBytes(pad(value, { size: 20, dir: "left" }));
|
|
25
|
+
const dv = new DataView(bytes.buffer);
|
|
26
|
+
const x0 = dv.getBigUint64(0);
|
|
27
|
+
const x1 = dv.getBigUint64(8);
|
|
28
|
+
const x2 = dv.getUint32(16);
|
|
29
|
+
return { x0, x1, x2 };
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export type Address = typeof Address.Type;
|
|
34
|
+
|
|
35
|
+
const _B256 = Schema.TemplateLiteral(Schema.Literal("0x"), Schema.String);
|
|
36
|
+
|
|
37
|
+
/** Wire representation of `B256`. */
|
|
38
|
+
const B256Proto = Schema.Struct({
|
|
39
|
+
x0: Schema.BigIntFromSelf,
|
|
40
|
+
x1: Schema.BigIntFromSelf,
|
|
41
|
+
x2: Schema.BigIntFromSelf,
|
|
42
|
+
x3: Schema.BigIntFromSelf,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/** Data with length 256 bits. */
|
|
46
|
+
export const B256 = Schema.transform(B256Proto, _B256, {
|
|
47
|
+
decode(value) {
|
|
48
|
+
const x0 = value.x0.toString(16).padStart(16, "0");
|
|
49
|
+
const x1 = value.x1.toString(16).padStart(16, "0");
|
|
50
|
+
const x2 = value.x2.toString(16).padStart(16, "0");
|
|
51
|
+
const x3 = value.x3.toString(16).padStart(16, "0");
|
|
52
|
+
return `0x${x0}${x1}${x2}${x3}` as `0x${string}`;
|
|
53
|
+
},
|
|
54
|
+
encode(value) {
|
|
55
|
+
const bytes = hexToBytes(pad(value, { size: 32, dir: "left" }));
|
|
56
|
+
const dv = new DataView(bytes.buffer);
|
|
57
|
+
const x0 = dv.getBigUint64(0);
|
|
58
|
+
const x1 = dv.getBigUint64(8);
|
|
59
|
+
const x2 = dv.getBigUint64(16);
|
|
60
|
+
const x3 = dv.getBigUint64(24);
|
|
61
|
+
return { x0, x1, x2, x3 };
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export const b256ToProto = Schema.encodeSync(B256);
|
|
66
|
+
export const b256FromProto = Schema.decodeSync(B256);
|
|
67
|
+
|
|
68
|
+
/** Wire representation of `U256`. */
|
|
69
|
+
const U256Proto = Schema.Struct({
|
|
70
|
+
x0: Schema.BigIntFromSelf,
|
|
71
|
+
x1: Schema.BigIntFromSelf,
|
|
72
|
+
x2: Schema.BigIntFromSelf,
|
|
73
|
+
x3: Schema.BigIntFromSelf,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
/** Data with length 256 bits. */
|
|
77
|
+
export const U256 = Schema.transform(U256Proto, Schema.BigIntFromSelf, {
|
|
78
|
+
decode(value) {
|
|
79
|
+
return (
|
|
80
|
+
(value.x0 << (8n * 24n)) +
|
|
81
|
+
(value.x1 << (8n * 16n)) +
|
|
82
|
+
(value.x2 << (8n * 8n)) +
|
|
83
|
+
value.x3
|
|
84
|
+
);
|
|
85
|
+
},
|
|
86
|
+
encode(value) {
|
|
87
|
+
const x0 = (value >> (8n * 24n)) & MAX_U64;
|
|
88
|
+
const x1 = (value >> (8n * 16n)) & MAX_U64;
|
|
89
|
+
const x2 = (value >> (8n * 8n)) & MAX_U64;
|
|
90
|
+
const x3 = value & MAX_U64;
|
|
91
|
+
return { x0, x1, x2, x3 };
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
export const u256ToProto = Schema.encodeSync(U256);
|
|
96
|
+
export const u256FromProto = Schema.decodeSync(U256);
|
|
97
|
+
|
|
98
|
+
/** Wire representation of `U128`. */
|
|
99
|
+
const U128Proto = Schema.Struct({
|
|
100
|
+
x0: Schema.BigIntFromSelf,
|
|
101
|
+
x1: Schema.BigIntFromSelf,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
/** Data with length 128 bits. */
|
|
105
|
+
export const U128 = Schema.transform(U128Proto, Schema.BigIntFromSelf, {
|
|
106
|
+
decode(value) {
|
|
107
|
+
return (value.x0 << (8n * 8n)) + value.x1;
|
|
108
|
+
},
|
|
109
|
+
encode(value) {
|
|
110
|
+
const x0 = (value >> (8n * 8n)) & MAX_U64;
|
|
111
|
+
const x1 = value & MAX_U64;
|
|
112
|
+
return { x0, x1 };
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
export const u128ToProto = Schema.encodeSync(U128);
|
|
117
|
+
export const u128FromProto = Schema.decodeSync(U128);
|