@lodestar/api 1.35.0-dev.f80d2d52da → 1.35.0-dev.fcf8d024ea
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/lib/beacon/client/beacon.d.ts.map +1 -0
- package/lib/beacon/client/config.d.ts.map +1 -0
- package/lib/beacon/client/debug.d.ts.map +1 -0
- package/lib/beacon/client/events.d.ts.map +1 -0
- package/lib/beacon/client/index.d.ts.map +1 -0
- package/lib/beacon/client/index.js.map +1 -1
- package/lib/beacon/client/lightclient.d.ts.map +1 -0
- package/lib/beacon/client/lodestar.d.ts.map +1 -0
- package/lib/beacon/client/node.d.ts.map +1 -0
- package/lib/beacon/client/proof.d.ts.map +1 -0
- package/lib/beacon/client/validator.d.ts.map +1 -0
- package/lib/beacon/index.d.ts +1 -1
- package/lib/beacon/index.d.ts.map +1 -0
- package/lib/beacon/index.js.map +1 -1
- package/lib/beacon/routes/beacon/block.d.ts.map +1 -0
- package/lib/beacon/routes/beacon/index.d.ts +3 -3
- package/lib/beacon/routes/beacon/index.d.ts.map +1 -0
- package/lib/beacon/routes/beacon/index.js.map +1 -1
- package/lib/beacon/routes/beacon/pool.d.ts +1 -1
- package/lib/beacon/routes/beacon/pool.d.ts.map +1 -0
- package/lib/beacon/routes/beacon/rewards.d.ts.map +1 -0
- package/lib/beacon/routes/beacon/rewards.js.map +1 -1
- package/lib/beacon/routes/beacon/state.d.ts +2 -2
- package/lib/beacon/routes/beacon/state.d.ts.map +1 -0
- package/lib/beacon/routes/config.d.ts +1 -1
- package/lib/beacon/routes/config.d.ts.map +1 -0
- package/lib/beacon/routes/debug.d.ts.map +1 -0
- package/lib/beacon/routes/events.d.ts.map +1 -0
- package/lib/beacon/routes/events.js.map +1 -1
- package/lib/beacon/routes/index.d.ts.map +1 -0
- package/lib/beacon/routes/index.js.map +1 -1
- package/lib/beacon/routes/lightclient.d.ts.map +1 -0
- package/lib/beacon/routes/lodestar.d.ts.map +1 -0
- package/lib/beacon/routes/node.d.ts.map +1 -0
- package/lib/beacon/routes/proof.d.ts.map +1 -0
- package/lib/beacon/routes/validator.d.ts +1 -1
- package/lib/beacon/routes/validator.d.ts.map +1 -0
- package/lib/beacon/server/beacon.d.ts.map +1 -0
- package/lib/beacon/server/config.d.ts.map +1 -0
- package/lib/beacon/server/debug.d.ts.map +1 -0
- package/lib/beacon/server/events.d.ts.map +1 -0
- package/lib/beacon/server/index.d.ts +1 -1
- package/lib/beacon/server/index.d.ts.map +1 -0
- package/lib/beacon/server/index.js.map +1 -1
- package/lib/beacon/server/lightclient.d.ts.map +1 -0
- package/lib/beacon/server/lodestar.d.ts.map +1 -0
- package/lib/beacon/server/node.d.ts.map +1 -0
- package/lib/beacon/server/proof.d.ts.map +1 -0
- package/lib/beacon/server/validator.d.ts.map +1 -0
- package/lib/builder/client.d.ts.map +1 -0
- package/lib/builder/index.d.ts.map +1 -0
- package/lib/builder/index.js.map +1 -1
- package/lib/builder/routes.d.ts.map +1 -0
- package/lib/builder/routes.js.map +1 -1
- package/lib/builder/server/index.d.ts +1 -1
- package/lib/builder/server/index.d.ts.map +1 -0
- package/lib/index.d.ts +6 -6
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +3 -3
- package/lib/index.js.map +1 -1
- package/lib/keymanager/client.d.ts.map +1 -0
- package/lib/keymanager/index.d.ts +2 -2
- package/lib/keymanager/index.d.ts.map +1 -0
- package/lib/keymanager/index.js +1 -2
- package/lib/keymanager/index.js.map +1 -1
- package/lib/keymanager/routes.d.ts.map +1 -0
- package/lib/keymanager/server/index.d.ts +1 -1
- package/lib/keymanager/server/index.d.ts.map +1 -0
- package/lib/server/index.d.ts.map +1 -0
- package/lib/utils/client/error.d.ts.map +1 -0
- package/lib/utils/client/error.js +2 -0
- package/lib/utils/client/error.js.map +1 -1
- package/lib/utils/client/eventSource.d.ts.map +1 -0
- package/lib/utils/client/format.d.ts.map +1 -0
- package/lib/utils/client/httpClient.d.ts +1 -2
- package/lib/utils/client/httpClient.d.ts.map +1 -0
- package/lib/utils/client/httpClient.js +13 -9
- package/lib/utils/client/httpClient.js.map +1 -1
- package/lib/utils/client/index.d.ts +1 -1
- package/lib/utils/client/index.d.ts.map +1 -0
- package/lib/utils/client/index.js +1 -1
- package/lib/utils/client/index.js.map +1 -1
- package/lib/utils/client/method.d.ts.map +1 -0
- package/lib/utils/client/metrics.d.ts.map +1 -0
- package/lib/utils/client/request.d.ts.map +1 -0
- package/lib/utils/client/response.d.ts.map +1 -0
- package/lib/utils/client/response.js +6 -0
- package/lib/utils/client/response.js.map +1 -1
- package/lib/utils/codecs.d.ts.map +1 -0
- package/lib/utils/fork.d.ts.map +1 -0
- package/lib/utils/headers.d.ts.map +1 -0
- package/lib/utils/httpStatusCode.d.ts.map +1 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/metadata.d.ts.map +1 -0
- package/lib/utils/schema.d.ts.map +1 -0
- package/lib/utils/serdes.d.ts.map +1 -0
- package/lib/utils/server/error.d.ts.map +1 -0
- package/lib/utils/server/error.js +1 -0
- package/lib/utils/server/error.js.map +1 -1
- package/lib/utils/server/handler.d.ts.map +1 -0
- package/lib/utils/server/index.d.ts.map +1 -0
- package/lib/utils/server/method.d.ts.map +1 -0
- package/lib/utils/server/parser.d.ts.map +1 -0
- package/lib/utils/server/route.d.ts.map +1 -0
- package/lib/utils/server/route.js.map +1 -1
- package/lib/utils/types.d.ts.map +1 -0
- package/lib/utils/urlFormat.d.ts.map +1 -0
- package/lib/utils/wireFormat.d.ts.map +1 -0
- package/package.json +17 -11
- package/src/beacon/client/beacon.ts +12 -0
- package/src/beacon/client/config.ts +12 -0
- package/src/beacon/client/debug.ts +12 -0
- package/src/beacon/client/events.ts +69 -0
- package/src/beacon/client/index.ts +46 -0
- package/src/beacon/client/lightclient.ts +12 -0
- package/src/beacon/client/lodestar.ts +12 -0
- package/src/beacon/client/node.ts +12 -0
- package/src/beacon/client/proof.ts +12 -0
- package/src/beacon/client/validator.ts +12 -0
- package/src/beacon/index.ts +24 -0
- package/src/beacon/routes/beacon/block.ts +602 -0
- package/src/beacon/routes/beacon/index.ts +66 -0
- package/src/beacon/routes/beacon/pool.ts +503 -0
- package/src/beacon/routes/beacon/rewards.ts +216 -0
- package/src/beacon/routes/beacon/state.ts +588 -0
- package/src/beacon/routes/config.ts +114 -0
- package/src/beacon/routes/debug.ts +231 -0
- package/src/beacon/routes/events.ts +337 -0
- package/src/beacon/routes/index.ts +33 -0
- package/src/beacon/routes/lightclient.ts +241 -0
- package/src/beacon/routes/lodestar.ts +456 -0
- package/src/beacon/routes/node.ts +286 -0
- package/src/beacon/routes/proof.ts +79 -0
- package/src/beacon/routes/validator.ts +1014 -0
- package/src/beacon/server/beacon.ts +7 -0
- package/src/beacon/server/config.ts +7 -0
- package/src/beacon/server/debug.ts +7 -0
- package/src/beacon/server/events.ts +73 -0
- package/src/beacon/server/index.ts +55 -0
- package/src/beacon/server/lightclient.ts +7 -0
- package/src/beacon/server/lodestar.ts +7 -0
- package/src/beacon/server/node.ts +7 -0
- package/src/beacon/server/proof.ts +7 -0
- package/src/beacon/server/validator.ts +7 -0
- package/src/builder/client.ts +9 -0
- package/src/builder/index.ts +26 -0
- package/src/builder/routes.ts +227 -0
- package/src/builder/server/index.ts +19 -0
- package/src/index.ts +19 -0
- package/src/keymanager/client.ts +9 -0
- package/src/keymanager/index.ts +39 -0
- package/src/keymanager/routes.ts +699 -0
- package/src/keymanager/server/index.ts +19 -0
- package/src/server/index.ts +2 -0
- package/src/utils/client/error.ts +10 -0
- package/src/utils/client/eventSource.ts +7 -0
- package/src/utils/client/format.ts +22 -0
- package/src/utils/client/httpClient.ts +444 -0
- package/src/utils/client/index.ts +6 -0
- package/src/utils/client/method.ts +50 -0
- package/src/utils/client/metrics.ts +9 -0
- package/src/utils/client/request.ts +113 -0
- package/src/utils/client/response.ts +205 -0
- package/src/utils/codecs.ts +143 -0
- package/src/utils/fork.ts +44 -0
- package/src/utils/headers.ts +173 -0
- package/src/utils/httpStatusCode.ts +392 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/metadata.ts +170 -0
- package/src/utils/schema.ts +141 -0
- package/src/utils/serdes.ts +120 -0
- package/src/utils/server/error.ts +9 -0
- package/src/utils/server/handler.ts +149 -0
- package/src/utils/server/index.ts +5 -0
- package/src/utils/server/method.ts +38 -0
- package/src/utils/server/parser.ts +15 -0
- package/src/utils/server/route.ts +45 -0
- package/src/utils/types.ts +161 -0
- package/src/utils/urlFormat.ts +112 -0
- package/src/utils/wireFormat.ts +24 -0
|
@@ -0,0 +1,1014 @@
|
|
|
1
|
+
import {ContainerType, Type, ValueOf} from "@chainsafe/ssz";
|
|
2
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
+
import {
|
|
4
|
+
ForkPostDeneb,
|
|
5
|
+
ForkPreDeneb,
|
|
6
|
+
VALIDATOR_REGISTRY_LIMIT,
|
|
7
|
+
isForkPostDeneb,
|
|
8
|
+
isForkPostElectra,
|
|
9
|
+
} from "@lodestar/params";
|
|
10
|
+
import {
|
|
11
|
+
Attestation,
|
|
12
|
+
BLSSignature,
|
|
13
|
+
BeaconBlock,
|
|
14
|
+
BlindedBeaconBlock,
|
|
15
|
+
BlockContents,
|
|
16
|
+
CommitteeIndex,
|
|
17
|
+
Epoch,
|
|
18
|
+
ProducedBlockSource,
|
|
19
|
+
Root,
|
|
20
|
+
Slot,
|
|
21
|
+
UintBn64,
|
|
22
|
+
ValidatorIndex,
|
|
23
|
+
altair,
|
|
24
|
+
phase0,
|
|
25
|
+
ssz,
|
|
26
|
+
sszTypesFor,
|
|
27
|
+
stringType,
|
|
28
|
+
} from "@lodestar/types";
|
|
29
|
+
import {fromHex, toHex, toRootHex} from "@lodestar/utils";
|
|
30
|
+
import {
|
|
31
|
+
ArrayOf,
|
|
32
|
+
EmptyMeta,
|
|
33
|
+
EmptyMetaCodec,
|
|
34
|
+
EmptyResponseCodec,
|
|
35
|
+
EmptyResponseData,
|
|
36
|
+
JsonOnlyReq,
|
|
37
|
+
WithVersion,
|
|
38
|
+
} from "../../utils/codecs.js";
|
|
39
|
+
import {getPostBellatrixForkTypes, toForkName} from "../../utils/fork.js";
|
|
40
|
+
import {fromHeaders} from "../../utils/headers.js";
|
|
41
|
+
import {Endpoint, RouteDefinitions, Schema} from "../../utils/index.js";
|
|
42
|
+
import {
|
|
43
|
+
ExecutionOptimisticAndDependentRootCodec,
|
|
44
|
+
ExecutionOptimisticAndDependentRootMeta,
|
|
45
|
+
ExecutionOptimisticCodec,
|
|
46
|
+
ExecutionOptimisticMeta,
|
|
47
|
+
MetaHeader,
|
|
48
|
+
VersionCodec,
|
|
49
|
+
VersionMeta,
|
|
50
|
+
VersionType,
|
|
51
|
+
} from "../../utils/metadata.js";
|
|
52
|
+
import {fromGraffitiHex, toBoolean, toGraffitiHex} from "../../utils/serdes.js";
|
|
53
|
+
import {WireFormat} from "../../utils/wireFormat.js";
|
|
54
|
+
|
|
55
|
+
export enum BuilderSelection {
|
|
56
|
+
Default = "default",
|
|
57
|
+
BuilderAlways = "builderalways",
|
|
58
|
+
ExecutionAlways = "executionalways",
|
|
59
|
+
MaxProfit = "maxprofit",
|
|
60
|
+
/** Only activate builder flow for DVT block proposal protocols */
|
|
61
|
+
BuilderOnly = "builderonly",
|
|
62
|
+
/** Only builds execution block*/
|
|
63
|
+
ExecutionOnly = "executiononly",
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Lodestar-specific (non-standardized) options */
|
|
67
|
+
export type ExtraProduceBlockOpts = {
|
|
68
|
+
feeRecipient?: string;
|
|
69
|
+
builderSelection?: BuilderSelection;
|
|
70
|
+
strictFeeRecipientCheck?: boolean;
|
|
71
|
+
blindedLocal?: boolean;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const ProduceBlockV3MetaType = new ContainerType(
|
|
75
|
+
{
|
|
76
|
+
...VersionType.fields,
|
|
77
|
+
/** Specifies whether the response contains full or blinded block */
|
|
78
|
+
executionPayloadBlinded: ssz.Boolean,
|
|
79
|
+
/** Execution payload value in Wei */
|
|
80
|
+
executionPayloadValue: ssz.UintBn64,
|
|
81
|
+
/** Consensus rewards paid to the proposer for this block, in Wei */
|
|
82
|
+
consensusBlockValue: ssz.UintBn64,
|
|
83
|
+
},
|
|
84
|
+
{jsonCase: "eth2"}
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
export type ProduceBlockV3Meta = ValueOf<typeof ProduceBlockV3MetaType> & {
|
|
88
|
+
/** Lodestar-specific (non-standardized) value */
|
|
89
|
+
executionPayloadSource: ProducedBlockSource;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const AttesterDutyType = new ContainerType(
|
|
93
|
+
{
|
|
94
|
+
/** The validator's public key, uniquely identifying them */
|
|
95
|
+
pubkey: ssz.BLSPubkey,
|
|
96
|
+
/** Index of validator in validator registry */
|
|
97
|
+
validatorIndex: ssz.ValidatorIndex,
|
|
98
|
+
/** Index of the committee */
|
|
99
|
+
committeeIndex: ssz.CommitteeIndex,
|
|
100
|
+
/** Number of validators in committee */
|
|
101
|
+
committeeLength: ssz.UintNum64,
|
|
102
|
+
/** Number of committees at the provided slot */
|
|
103
|
+
committeesAtSlot: ssz.UintNum64,
|
|
104
|
+
/** Index of validator in committee */
|
|
105
|
+
validatorCommitteeIndex: ssz.UintNum64,
|
|
106
|
+
/** The slot at which the validator must attest */
|
|
107
|
+
slot: ssz.Slot,
|
|
108
|
+
},
|
|
109
|
+
{jsonCase: "eth2"}
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
export const ProposerDutyType = new ContainerType(
|
|
113
|
+
{
|
|
114
|
+
slot: ssz.Slot,
|
|
115
|
+
validatorIndex: ssz.ValidatorIndex,
|
|
116
|
+
pubkey: ssz.BLSPubkey,
|
|
117
|
+
},
|
|
118
|
+
{jsonCase: "eth2"}
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* From https://github.com/ethereum/beacon-APIs/pull/134
|
|
123
|
+
*/
|
|
124
|
+
export const SyncDutyType = new ContainerType(
|
|
125
|
+
{
|
|
126
|
+
pubkey: ssz.BLSPubkey,
|
|
127
|
+
/** Index of validator in validator registry. */
|
|
128
|
+
validatorIndex: ssz.ValidatorIndex,
|
|
129
|
+
/** The indices of the validator in the sync committee. */
|
|
130
|
+
validatorSyncCommitteeIndices: ArrayOf(ssz.CommitteeIndex),
|
|
131
|
+
},
|
|
132
|
+
{jsonCase: "eth2"}
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
export const BeaconCommitteeSubscriptionType = new ContainerType(
|
|
136
|
+
{
|
|
137
|
+
validatorIndex: ssz.ValidatorIndex,
|
|
138
|
+
committeeIndex: ssz.CommitteeIndex,
|
|
139
|
+
committeesAtSlot: ssz.Slot,
|
|
140
|
+
slot: ssz.Slot,
|
|
141
|
+
isAggregator: ssz.Boolean,
|
|
142
|
+
},
|
|
143
|
+
{jsonCase: "eth2"}
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* From https://github.com/ethereum/beacon-APIs/pull/136
|
|
148
|
+
*/
|
|
149
|
+
export const SyncCommitteeSubscriptionType = new ContainerType(
|
|
150
|
+
{
|
|
151
|
+
validatorIndex: ssz.ValidatorIndex,
|
|
152
|
+
syncCommitteeIndices: ArrayOf(ssz.CommitteeIndex),
|
|
153
|
+
untilEpoch: ssz.Epoch,
|
|
154
|
+
},
|
|
155
|
+
{jsonCase: "eth2"}
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
export const ProposerPreparationDataType = new ContainerType(
|
|
159
|
+
{
|
|
160
|
+
validatorIndex: ssz.ValidatorIndex,
|
|
161
|
+
feeRecipient: stringType,
|
|
162
|
+
},
|
|
163
|
+
{jsonCase: "eth2"}
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* From https://github.com/ethereum/beacon-APIs/pull/224
|
|
168
|
+
*/
|
|
169
|
+
export const BeaconCommitteeSelectionType = new ContainerType(
|
|
170
|
+
{
|
|
171
|
+
/** Index of the validator */
|
|
172
|
+
validatorIndex: ssz.ValidatorIndex,
|
|
173
|
+
/** The slot at which a validator is assigned to attest */
|
|
174
|
+
slot: ssz.Slot,
|
|
175
|
+
/** The `slot_signature` calculated by the validator for the upcoming attestation slot */
|
|
176
|
+
selectionProof: ssz.BLSSignature,
|
|
177
|
+
},
|
|
178
|
+
{jsonCase: "eth2"}
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* From https://github.com/ethereum/beacon-APIs/pull/224
|
|
183
|
+
*/
|
|
184
|
+
export const SyncCommitteeSelectionType = new ContainerType(
|
|
185
|
+
{
|
|
186
|
+
/** Index of the validator */
|
|
187
|
+
validatorIndex: ssz.ValidatorIndex,
|
|
188
|
+
/** The slot at which validator is assigned to produce a sync committee contribution */
|
|
189
|
+
slot: ssz.Slot,
|
|
190
|
+
/** SubcommitteeIndex to which the validator is assigned */
|
|
191
|
+
subcommitteeIndex: ssz.SubcommitteeIndex,
|
|
192
|
+
/** The `slot_signature` calculated by the validator for the upcoming sync committee slot */
|
|
193
|
+
selectionProof: ssz.BLSSignature,
|
|
194
|
+
},
|
|
195
|
+
{jsonCase: "eth2"}
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
export const LivenessResponseDataType = new ContainerType(
|
|
199
|
+
{
|
|
200
|
+
index: ssz.ValidatorIndex,
|
|
201
|
+
isLive: ssz.Boolean,
|
|
202
|
+
},
|
|
203
|
+
{jsonCase: "eth2"}
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
export const ValidatorIndicesType = ArrayOf(ssz.ValidatorIndex);
|
|
207
|
+
export const AttesterDutyListType = ArrayOf(AttesterDutyType);
|
|
208
|
+
export const ProposerDutyListType = ArrayOf(ProposerDutyType);
|
|
209
|
+
export const SyncDutyListType = ArrayOf(SyncDutyType);
|
|
210
|
+
export const SignedAggregateAndProofListPhase0Type = ArrayOf(ssz.phase0.SignedAggregateAndProof);
|
|
211
|
+
export const SignedAggregateAndProofListElectraType = ArrayOf(ssz.electra.SignedAggregateAndProof);
|
|
212
|
+
export const SignedContributionAndProofListType = ArrayOf(ssz.altair.SignedContributionAndProof);
|
|
213
|
+
export const BeaconCommitteeSubscriptionListType = ArrayOf(BeaconCommitteeSubscriptionType);
|
|
214
|
+
export const SyncCommitteeSubscriptionListType = ArrayOf(SyncCommitteeSubscriptionType);
|
|
215
|
+
export const ProposerPreparationDataListType = ArrayOf(ProposerPreparationDataType);
|
|
216
|
+
export const BeaconCommitteeSelectionListType = ArrayOf(BeaconCommitteeSelectionType);
|
|
217
|
+
export const SyncCommitteeSelectionListType = ArrayOf(SyncCommitteeSelectionType);
|
|
218
|
+
export const LivenessResponseDataListType = ArrayOf(LivenessResponseDataType);
|
|
219
|
+
export const SignedValidatorRegistrationV1ListType = ArrayOf(
|
|
220
|
+
ssz.bellatrix.SignedValidatorRegistrationV1,
|
|
221
|
+
VALIDATOR_REGISTRY_LIMIT
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
export type ValidatorIndices = ValueOf<typeof ValidatorIndicesType>;
|
|
225
|
+
export type AttesterDuty = ValueOf<typeof AttesterDutyType>;
|
|
226
|
+
export type AttesterDutyList = ValueOf<typeof AttesterDutyListType>;
|
|
227
|
+
export type ProposerDuty = ValueOf<typeof ProposerDutyType>;
|
|
228
|
+
export type ProposerDutyList = ValueOf<typeof ProposerDutyListType>;
|
|
229
|
+
export type SyncDuty = ValueOf<typeof SyncDutyType>;
|
|
230
|
+
export type SyncDutyList = ValueOf<typeof SyncDutyListType>;
|
|
231
|
+
export type SignedAggregateAndProofListPhase0 = ValueOf<typeof SignedAggregateAndProofListPhase0Type>;
|
|
232
|
+
export type SignedAggregateAndProofListElectra = ValueOf<typeof SignedAggregateAndProofListElectraType>;
|
|
233
|
+
export type SignedAggregateAndProofList = SignedAggregateAndProofListPhase0 | SignedAggregateAndProofListElectra;
|
|
234
|
+
export type SignedContributionAndProofList = ValueOf<typeof SignedContributionAndProofListType>;
|
|
235
|
+
export type BeaconCommitteeSubscription = ValueOf<typeof BeaconCommitteeSubscriptionType>;
|
|
236
|
+
export type BeaconCommitteeSubscriptionList = ValueOf<typeof BeaconCommitteeSubscriptionListType>;
|
|
237
|
+
export type SyncCommitteeSubscription = ValueOf<typeof SyncCommitteeSubscriptionType>;
|
|
238
|
+
export type SyncCommitteeSubscriptionList = ValueOf<typeof SyncCommitteeSubscriptionListType>;
|
|
239
|
+
export type ProposerPreparationData = ValueOf<typeof ProposerPreparationDataType>;
|
|
240
|
+
export type ProposerPreparationDataList = ValueOf<typeof ProposerPreparationDataListType>;
|
|
241
|
+
export type BeaconCommitteeSelection = ValueOf<typeof BeaconCommitteeSelectionType>;
|
|
242
|
+
export type BeaconCommitteeSelectionList = ValueOf<typeof BeaconCommitteeSelectionListType>;
|
|
243
|
+
export type SyncCommitteeSelection = ValueOf<typeof SyncCommitteeSelectionType>;
|
|
244
|
+
export type SyncCommitteeSelectionList = ValueOf<typeof SyncCommitteeSelectionListType>;
|
|
245
|
+
export type LivenessResponseData = ValueOf<typeof LivenessResponseDataType>;
|
|
246
|
+
export type LivenessResponseDataList = ValueOf<typeof LivenessResponseDataListType>;
|
|
247
|
+
export type SignedValidatorRegistrationV1List = ValueOf<typeof SignedValidatorRegistrationV1ListType>;
|
|
248
|
+
|
|
249
|
+
export type Endpoints = {
|
|
250
|
+
/**
|
|
251
|
+
* Get attester duties
|
|
252
|
+
* Requests the beacon node to provide a set of attestation duties, which should be performed by validators, for a particular epoch.
|
|
253
|
+
* Duties should only need to be checked once per epoch, however a chain reorganization (of > MIN_SEED_LOOKAHEAD epochs) could occur, resulting in a change of duties. For full safety, you should monitor head events and confirm the dependent root in this response matches:
|
|
254
|
+
* - event.previous_duty_dependent_root when `compute_epoch_at_slot(event.slot) == epoch`
|
|
255
|
+
* - event.current_duty_dependent_root when `compute_epoch_at_slot(event.slot) + 1 == epoch`
|
|
256
|
+
* - event.block otherwise
|
|
257
|
+
* The dependent_root value is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch - 1) - 1)` or the genesis block root in the case of underflow.
|
|
258
|
+
*/
|
|
259
|
+
getAttesterDuties: Endpoint<
|
|
260
|
+
"POST",
|
|
261
|
+
{
|
|
262
|
+
/** Should only be allowed 1 epoch ahead */
|
|
263
|
+
epoch: Epoch;
|
|
264
|
+
/** An array of the validator indices for which to obtain the duties */
|
|
265
|
+
indices: ValidatorIndices;
|
|
266
|
+
},
|
|
267
|
+
{params: {epoch: Epoch}; body: unknown},
|
|
268
|
+
AttesterDutyList,
|
|
269
|
+
ExecutionOptimisticAndDependentRootMeta
|
|
270
|
+
>;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Get block proposers duties
|
|
274
|
+
* Request beacon node to provide all validators that are scheduled to propose a block in the given epoch.
|
|
275
|
+
* Duties should only need to be checked once per epoch, however a chain reorganization could occur that results in a change of duties. For full safety, you should monitor head events and confirm the dependent root in this response matches:
|
|
276
|
+
* - event.current_duty_dependent_root when `compute_epoch_at_slot(event.slot) == epoch`
|
|
277
|
+
* - event.block otherwise
|
|
278
|
+
* The dependent_root value is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch) - 1)` or the genesis block root in the case of underflow.
|
|
279
|
+
*/
|
|
280
|
+
getProposerDuties: Endpoint<
|
|
281
|
+
"GET",
|
|
282
|
+
{epoch: Epoch},
|
|
283
|
+
{params: {epoch: Epoch}},
|
|
284
|
+
ProposerDutyList,
|
|
285
|
+
ExecutionOptimisticAndDependentRootMeta
|
|
286
|
+
>;
|
|
287
|
+
|
|
288
|
+
getSyncCommitteeDuties: Endpoint<
|
|
289
|
+
"POST",
|
|
290
|
+
{
|
|
291
|
+
epoch: number;
|
|
292
|
+
indices: ValidatorIndices;
|
|
293
|
+
},
|
|
294
|
+
{params: {epoch: Epoch}; body: unknown},
|
|
295
|
+
SyncDutyList,
|
|
296
|
+
ExecutionOptimisticMeta
|
|
297
|
+
>;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Requests a beacon node to produce a valid block, which can then be signed by a validator.
|
|
301
|
+
* Metadata in the response indicates the type of block produced, and the supported types of block
|
|
302
|
+
* will be added to as forks progress.
|
|
303
|
+
*/
|
|
304
|
+
produceBlockV3: Endpoint<
|
|
305
|
+
"GET",
|
|
306
|
+
{
|
|
307
|
+
/** The slot for which the block should be proposed */
|
|
308
|
+
slot: Slot;
|
|
309
|
+
/** The validator's randao reveal value */
|
|
310
|
+
randaoReveal: BLSSignature;
|
|
311
|
+
/** Arbitrary data validator wants to include in block */
|
|
312
|
+
graffiti?: string;
|
|
313
|
+
skipRandaoVerification?: boolean;
|
|
314
|
+
builderBoostFactor?: UintBn64;
|
|
315
|
+
} & ExtraProduceBlockOpts,
|
|
316
|
+
{
|
|
317
|
+
params: {slot: number};
|
|
318
|
+
query: {
|
|
319
|
+
randao_reveal: string;
|
|
320
|
+
graffiti?: string;
|
|
321
|
+
skip_randao_verification?: string;
|
|
322
|
+
fee_recipient?: string;
|
|
323
|
+
builder_selection?: string;
|
|
324
|
+
builder_boost_factor?: string;
|
|
325
|
+
strict_fee_recipient_check?: boolean;
|
|
326
|
+
blinded_local?: boolean;
|
|
327
|
+
};
|
|
328
|
+
},
|
|
329
|
+
BlockContents | BlindedBeaconBlock,
|
|
330
|
+
ProduceBlockV3Meta
|
|
331
|
+
>;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Produce an attestation data
|
|
335
|
+
* Requests that the beacon node produce an AttestationData.
|
|
336
|
+
*/
|
|
337
|
+
produceAttestationData: Endpoint<
|
|
338
|
+
"GET",
|
|
339
|
+
{
|
|
340
|
+
/** The committee index for which an attestation data should be created */
|
|
341
|
+
committeeIndex?: CommitteeIndex;
|
|
342
|
+
/** The slot for which an attestation data should be created */
|
|
343
|
+
slot: Slot;
|
|
344
|
+
},
|
|
345
|
+
{query: {slot: number; committee_index?: number}},
|
|
346
|
+
phase0.AttestationData,
|
|
347
|
+
EmptyMeta
|
|
348
|
+
>;
|
|
349
|
+
|
|
350
|
+
produceSyncCommitteeContribution: Endpoint<
|
|
351
|
+
"GET",
|
|
352
|
+
{
|
|
353
|
+
slot: Slot;
|
|
354
|
+
subcommitteeIndex: number;
|
|
355
|
+
beaconBlockRoot: Root;
|
|
356
|
+
},
|
|
357
|
+
{query: {slot: number; subcommittee_index: number; beacon_block_root: string}},
|
|
358
|
+
altair.SyncCommitteeContribution,
|
|
359
|
+
EmptyMeta
|
|
360
|
+
>;
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Get aggregated attestation
|
|
364
|
+
* Aggregates all attestations matching given attestation data root and slot
|
|
365
|
+
* Returns an aggregated `Attestation` object with same `AttestationData` root.
|
|
366
|
+
*/
|
|
367
|
+
getAggregatedAttestation: Endpoint<
|
|
368
|
+
"GET",
|
|
369
|
+
{
|
|
370
|
+
/** HashTreeRoot of AttestationData that validator want's aggregated */
|
|
371
|
+
attestationDataRoot: Root;
|
|
372
|
+
slot: Slot;
|
|
373
|
+
},
|
|
374
|
+
{query: {attestation_data_root: string; slot: number}},
|
|
375
|
+
phase0.Attestation,
|
|
376
|
+
EmptyMeta
|
|
377
|
+
>;
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Get aggregated attestation
|
|
381
|
+
* Aggregates all attestations matching given attestation data root, slot and committee index
|
|
382
|
+
* Returns an aggregated `Attestation` object with same `AttestationData` root.
|
|
383
|
+
*/
|
|
384
|
+
getAggregatedAttestationV2: Endpoint<
|
|
385
|
+
"GET",
|
|
386
|
+
{
|
|
387
|
+
/** HashTreeRoot of AttestationData that validator want's aggregated */
|
|
388
|
+
attestationDataRoot: Root;
|
|
389
|
+
slot: Slot;
|
|
390
|
+
committeeIndex: number;
|
|
391
|
+
},
|
|
392
|
+
{query: {attestation_data_root: string; slot: number; committee_index: number}},
|
|
393
|
+
Attestation,
|
|
394
|
+
VersionMeta
|
|
395
|
+
>;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Publish multiple aggregate and proofs
|
|
399
|
+
* Verifies given aggregate and proofs and publishes them on appropriate gossipsub topic.
|
|
400
|
+
*/
|
|
401
|
+
publishAggregateAndProofs: Endpoint<
|
|
402
|
+
"POST",
|
|
403
|
+
{signedAggregateAndProofs: SignedAggregateAndProofListPhase0},
|
|
404
|
+
{body: unknown},
|
|
405
|
+
EmptyResponseData,
|
|
406
|
+
EmptyMeta
|
|
407
|
+
>;
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Publish multiple aggregate and proofs
|
|
411
|
+
* Verifies given aggregate and proofs and publishes them on appropriate gossipsub topic.
|
|
412
|
+
*/
|
|
413
|
+
publishAggregateAndProofsV2: Endpoint<
|
|
414
|
+
"POST",
|
|
415
|
+
{signedAggregateAndProofs: SignedAggregateAndProofList},
|
|
416
|
+
{body: unknown; headers: {[MetaHeader.Version]: string}},
|
|
417
|
+
EmptyResponseData,
|
|
418
|
+
EmptyMeta
|
|
419
|
+
>;
|
|
420
|
+
|
|
421
|
+
publishContributionAndProofs: Endpoint<
|
|
422
|
+
"POST",
|
|
423
|
+
{contributionAndProofs: SignedContributionAndProofList},
|
|
424
|
+
{body: unknown},
|
|
425
|
+
EmptyResponseData,
|
|
426
|
+
EmptyMeta
|
|
427
|
+
>;
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Signal beacon node to prepare for a committee subnet
|
|
431
|
+
* After beacon node receives this request,
|
|
432
|
+
* search using discv5 for peers related to this subnet
|
|
433
|
+
* and replace current peers with those ones if necessary
|
|
434
|
+
* If validator `is_aggregator`, beacon node must:
|
|
435
|
+
* - announce subnet topic subscription on gossipsub
|
|
436
|
+
* - aggregate attestations received on that subnet
|
|
437
|
+
*
|
|
438
|
+
* Returns if slot signature is valid and beacon node has prepared the attestation subnet.
|
|
439
|
+
*
|
|
440
|
+
* Note that we cannot be certain the Beacon node will find peers for that subnet for various reasons.
|
|
441
|
+
*/
|
|
442
|
+
prepareBeaconCommitteeSubnet: Endpoint<
|
|
443
|
+
"POST",
|
|
444
|
+
{subscriptions: BeaconCommitteeSubscriptionList},
|
|
445
|
+
{body: unknown},
|
|
446
|
+
EmptyResponseData,
|
|
447
|
+
EmptyMeta
|
|
448
|
+
>;
|
|
449
|
+
|
|
450
|
+
prepareSyncCommitteeSubnets: Endpoint<
|
|
451
|
+
"POST",
|
|
452
|
+
{subscriptions: SyncCommitteeSubscriptionList},
|
|
453
|
+
{body: unknown},
|
|
454
|
+
EmptyResponseData,
|
|
455
|
+
EmptyMeta
|
|
456
|
+
>;
|
|
457
|
+
|
|
458
|
+
prepareBeaconProposer: Endpoint<
|
|
459
|
+
"POST",
|
|
460
|
+
{proposers: ProposerPreparationDataList},
|
|
461
|
+
{body: unknown},
|
|
462
|
+
EmptyResponseData,
|
|
463
|
+
EmptyMeta
|
|
464
|
+
>;
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Determine if a distributed validator has been selected to aggregate attestations
|
|
468
|
+
*
|
|
469
|
+
* This endpoint is implemented by a distributed validator middleware client to exchange
|
|
470
|
+
* partial beacon committee selection proofs for combined/aggregated selection proofs to allow
|
|
471
|
+
* a validator client to correctly determine if one of its validators has been selected to
|
|
472
|
+
* perform an aggregation duty in this slot.
|
|
473
|
+
*
|
|
474
|
+
* Note that this endpoint is not implemented by the beacon node and will return a 501 error
|
|
475
|
+
*
|
|
476
|
+
* Returns an array of threshold aggregated beacon committee selection proofs
|
|
477
|
+
*/
|
|
478
|
+
submitBeaconCommitteeSelections: Endpoint<
|
|
479
|
+
"POST",
|
|
480
|
+
{
|
|
481
|
+
/** An array of partial beacon committee selection proofs */
|
|
482
|
+
selections: BeaconCommitteeSelectionList;
|
|
483
|
+
},
|
|
484
|
+
{body: unknown},
|
|
485
|
+
BeaconCommitteeSelectionList,
|
|
486
|
+
EmptyMeta
|
|
487
|
+
>;
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Determine if a distributed validator has been selected to make a sync committee contribution
|
|
491
|
+
*
|
|
492
|
+
* This endpoint is implemented by a distributed validator middleware client to exchange
|
|
493
|
+
* partial sync committee selection proofs for combined/aggregated selection proofs to allow
|
|
494
|
+
* a validator client to correctly determine if one of its validators has been selected to
|
|
495
|
+
* perform a sync committee contribution (sync aggregation) duty in this slot.
|
|
496
|
+
*
|
|
497
|
+
* Note that this endpoint is not implemented by the beacon node and will return a 501 error
|
|
498
|
+
*
|
|
499
|
+
* Returns an array of threshold aggregated sync committee selection proofs
|
|
500
|
+
*/
|
|
501
|
+
submitSyncCommitteeSelections: Endpoint<
|
|
502
|
+
"POST",
|
|
503
|
+
{
|
|
504
|
+
/** An array of partial sync committee selection proofs */
|
|
505
|
+
selections: SyncCommitteeSelectionList;
|
|
506
|
+
},
|
|
507
|
+
{body: unknown},
|
|
508
|
+
SyncCommitteeSelectionList,
|
|
509
|
+
EmptyMeta
|
|
510
|
+
>;
|
|
511
|
+
|
|
512
|
+
/** Returns validator indices that have been observed to be active on the network */
|
|
513
|
+
getLiveness: Endpoint<
|
|
514
|
+
"POST",
|
|
515
|
+
{
|
|
516
|
+
epoch: Epoch;
|
|
517
|
+
indices: ValidatorIndex[];
|
|
518
|
+
},
|
|
519
|
+
{params: {epoch: Epoch}; body: unknown},
|
|
520
|
+
LivenessResponseDataList,
|
|
521
|
+
EmptyMeta
|
|
522
|
+
>;
|
|
523
|
+
|
|
524
|
+
registerValidator: Endpoint<
|
|
525
|
+
"POST",
|
|
526
|
+
{registrations: SignedValidatorRegistrationV1List},
|
|
527
|
+
{body: unknown},
|
|
528
|
+
EmptyResponseData,
|
|
529
|
+
EmptyMeta
|
|
530
|
+
>;
|
|
531
|
+
};
|
|
532
|
+
|
|
533
|
+
export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoints> {
|
|
534
|
+
return {
|
|
535
|
+
getAttesterDuties: {
|
|
536
|
+
url: "/eth/v1/validator/duties/attester/{epoch}",
|
|
537
|
+
method: "POST",
|
|
538
|
+
req: {
|
|
539
|
+
writeReqJson: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.toJson(indices)}),
|
|
540
|
+
parseReqJson: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.fromJson(body)}),
|
|
541
|
+
writeReqSsz: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.serialize(indices)}),
|
|
542
|
+
parseReqSsz: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.deserialize(body)}),
|
|
543
|
+
schema: {
|
|
544
|
+
params: {epoch: Schema.UintRequired},
|
|
545
|
+
body: Schema.StringArray,
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
resp: {
|
|
549
|
+
data: AttesterDutyListType,
|
|
550
|
+
meta: ExecutionOptimisticAndDependentRootCodec,
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
getProposerDuties: {
|
|
554
|
+
url: "/eth/v1/validator/duties/proposer/{epoch}",
|
|
555
|
+
method: "GET",
|
|
556
|
+
req: {
|
|
557
|
+
writeReq: ({epoch}) => ({params: {epoch}}),
|
|
558
|
+
parseReq: ({params}) => ({epoch: params.epoch}),
|
|
559
|
+
schema: {
|
|
560
|
+
params: {epoch: Schema.UintRequired},
|
|
561
|
+
},
|
|
562
|
+
},
|
|
563
|
+
resp: {
|
|
564
|
+
data: ProposerDutyListType,
|
|
565
|
+
meta: ExecutionOptimisticAndDependentRootCodec,
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
getSyncCommitteeDuties: {
|
|
569
|
+
url: "/eth/v1/validator/duties/sync/{epoch}",
|
|
570
|
+
method: "POST",
|
|
571
|
+
req: {
|
|
572
|
+
writeReqJson: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.toJson(indices)}),
|
|
573
|
+
parseReqJson: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.fromJson(body)}),
|
|
574
|
+
writeReqSsz: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.serialize(indices)}),
|
|
575
|
+
parseReqSsz: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.deserialize(body)}),
|
|
576
|
+
schema: {
|
|
577
|
+
params: {epoch: Schema.UintRequired},
|
|
578
|
+
body: Schema.StringArray,
|
|
579
|
+
},
|
|
580
|
+
},
|
|
581
|
+
resp: {
|
|
582
|
+
data: SyncDutyListType,
|
|
583
|
+
meta: ExecutionOptimisticCodec,
|
|
584
|
+
},
|
|
585
|
+
},
|
|
586
|
+
produceBlockV3: {
|
|
587
|
+
url: "/eth/v3/validator/blocks/{slot}",
|
|
588
|
+
method: "GET",
|
|
589
|
+
req: {
|
|
590
|
+
writeReq: ({
|
|
591
|
+
slot,
|
|
592
|
+
randaoReveal,
|
|
593
|
+
graffiti,
|
|
594
|
+
skipRandaoVerification,
|
|
595
|
+
feeRecipient,
|
|
596
|
+
builderSelection,
|
|
597
|
+
builderBoostFactor,
|
|
598
|
+
strictFeeRecipientCheck,
|
|
599
|
+
blindedLocal,
|
|
600
|
+
}) => ({
|
|
601
|
+
params: {slot},
|
|
602
|
+
query: {
|
|
603
|
+
randao_reveal: toHex(randaoReveal),
|
|
604
|
+
graffiti: toGraffitiHex(graffiti),
|
|
605
|
+
skip_randao_verification: writeSkipRandaoVerification(skipRandaoVerification),
|
|
606
|
+
fee_recipient: feeRecipient,
|
|
607
|
+
builder_selection: builderSelection,
|
|
608
|
+
builder_boost_factor: builderBoostFactor?.toString(),
|
|
609
|
+
strict_fee_recipient_check: strictFeeRecipientCheck,
|
|
610
|
+
blinded_local: blindedLocal,
|
|
611
|
+
},
|
|
612
|
+
}),
|
|
613
|
+
parseReq: ({params, query}) => ({
|
|
614
|
+
slot: params.slot,
|
|
615
|
+
randaoReveal: fromHex(query.randao_reveal),
|
|
616
|
+
graffiti: fromGraffitiHex(query.graffiti),
|
|
617
|
+
skipRandaoVerification: parseSkipRandaoVerification(query.skip_randao_verification),
|
|
618
|
+
feeRecipient: query.fee_recipient,
|
|
619
|
+
builderSelection: query.builder_selection as BuilderSelection,
|
|
620
|
+
builderBoostFactor: parseBuilderBoostFactor(query.builder_boost_factor),
|
|
621
|
+
strictFeeRecipientCheck: query.strict_fee_recipient_check,
|
|
622
|
+
blindedLocal: query.blinded_local,
|
|
623
|
+
}),
|
|
624
|
+
schema: {
|
|
625
|
+
params: {slot: Schema.UintRequired},
|
|
626
|
+
query: {
|
|
627
|
+
randao_reveal: Schema.StringRequired,
|
|
628
|
+
graffiti: Schema.String,
|
|
629
|
+
skip_randao_verification: Schema.String,
|
|
630
|
+
fee_recipient: Schema.String,
|
|
631
|
+
builder_selection: Schema.String,
|
|
632
|
+
builder_boost_factor: Schema.String,
|
|
633
|
+
strict_fee_recipient_check: Schema.Boolean,
|
|
634
|
+
blinded_local: Schema.Boolean,
|
|
635
|
+
},
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
resp: {
|
|
639
|
+
// The spec defines the response as `preDeneb.BeaconBlock | postDeneb.BlockContents`
|
|
640
|
+
// We represent the response as `{block: preDeneb.BeaconBlock} | postDeneb.BlockContents` (aka BlockContents in our codebase)
|
|
641
|
+
// Due to this discripancy, we require a hand-written codec to handle the transformation.
|
|
642
|
+
data: {
|
|
643
|
+
toJson(data, {executionPayloadBlinded, version}) {
|
|
644
|
+
return executionPayloadBlinded
|
|
645
|
+
? getPostBellatrixForkTypes(version).BlindedBeaconBlock.toJson(data as BlindedBeaconBlock)
|
|
646
|
+
: isForkPostDeneb(version)
|
|
647
|
+
? sszTypesFor(version).BlockContents.toJson(data as BlockContents<ForkPostDeneb>)
|
|
648
|
+
: (ssz[version].BeaconBlock as Type<BeaconBlock<ForkPreDeneb>>).toJson(
|
|
649
|
+
(data as BlockContents).block as BeaconBlock<ForkPreDeneb> // <- tranformation
|
|
650
|
+
);
|
|
651
|
+
},
|
|
652
|
+
fromJson(data, {executionPayloadBlinded, version}) {
|
|
653
|
+
return executionPayloadBlinded
|
|
654
|
+
? getPostBellatrixForkTypes(version).BlindedBeaconBlock.fromJson(data)
|
|
655
|
+
: isForkPostDeneb(version)
|
|
656
|
+
? sszTypesFor(version).BlockContents.fromJson(data)
|
|
657
|
+
: {block: ssz[version].BeaconBlock.fromJson(data)}; // <- tranformation
|
|
658
|
+
},
|
|
659
|
+
serialize(data, {executionPayloadBlinded, version}) {
|
|
660
|
+
return executionPayloadBlinded
|
|
661
|
+
? getPostBellatrixForkTypes(version).BlindedBeaconBlock.serialize(data as BlindedBeaconBlock)
|
|
662
|
+
: isForkPostDeneb(version)
|
|
663
|
+
? sszTypesFor(version).BlockContents.serialize(data as BlockContents<ForkPostDeneb>)
|
|
664
|
+
: (ssz[version].BeaconBlock as Type<BeaconBlock<ForkPreDeneb>>).serialize(
|
|
665
|
+
(data as BlockContents).block as BeaconBlock<ForkPreDeneb> // <- tranformation
|
|
666
|
+
);
|
|
667
|
+
},
|
|
668
|
+
deserialize(data, {executionPayloadBlinded, version}) {
|
|
669
|
+
return executionPayloadBlinded
|
|
670
|
+
? getPostBellatrixForkTypes(version).BlindedBeaconBlock.deserialize(data)
|
|
671
|
+
: isForkPostDeneb(version)
|
|
672
|
+
? sszTypesFor(version).BlockContents.deserialize(data)
|
|
673
|
+
: {block: ssz[version].BeaconBlock.deserialize(data)}; // <- tranformation
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
meta: {
|
|
677
|
+
toJson: (meta) => ({
|
|
678
|
+
...ProduceBlockV3MetaType.toJson(meta),
|
|
679
|
+
execution_payload_source: meta.executionPayloadSource,
|
|
680
|
+
}),
|
|
681
|
+
fromJson: (val) => {
|
|
682
|
+
const {executionPayloadBlinded, ...meta} = ProduceBlockV3MetaType.fromJson(val);
|
|
683
|
+
|
|
684
|
+
// Extract source from the data and assign defaults in the spec compliant manner if not present
|
|
685
|
+
const executionPayloadSource =
|
|
686
|
+
(val as {execution_payload_source: ProducedBlockSource}).execution_payload_source ??
|
|
687
|
+
(executionPayloadBlinded === true ? ProducedBlockSource.builder : ProducedBlockSource.engine);
|
|
688
|
+
|
|
689
|
+
return {...meta, executionPayloadBlinded, executionPayloadSource};
|
|
690
|
+
},
|
|
691
|
+
toHeadersObject: (meta) => ({
|
|
692
|
+
[MetaHeader.Version]: meta.version,
|
|
693
|
+
[MetaHeader.ExecutionPayloadBlinded]: meta.executionPayloadBlinded.toString(),
|
|
694
|
+
[MetaHeader.ExecutionPayloadSource]: meta.executionPayloadSource.toString(),
|
|
695
|
+
[MetaHeader.ExecutionPayloadValue]: meta.executionPayloadValue.toString(),
|
|
696
|
+
[MetaHeader.ConsensusBlockValue]: meta.consensusBlockValue.toString(),
|
|
697
|
+
}),
|
|
698
|
+
fromHeaders: (headers) => {
|
|
699
|
+
const executionPayloadBlinded = toBoolean(headers.getRequired(MetaHeader.ExecutionPayloadBlinded));
|
|
700
|
+
|
|
701
|
+
// Extract source from the headers and assign defaults in a spec compliant manner if not present
|
|
702
|
+
const executionPayloadSource =
|
|
703
|
+
(headers.get(MetaHeader.ExecutionPayloadSource) as ProducedBlockSource) ??
|
|
704
|
+
(executionPayloadBlinded === true ? ProducedBlockSource.builder : ProducedBlockSource.engine);
|
|
705
|
+
|
|
706
|
+
return {
|
|
707
|
+
version: toForkName(headers.getRequired(MetaHeader.Version)),
|
|
708
|
+
executionPayloadBlinded,
|
|
709
|
+
executionPayloadSource,
|
|
710
|
+
executionPayloadValue: BigInt(headers.getRequired(MetaHeader.ExecutionPayloadValue)),
|
|
711
|
+
consensusBlockValue: BigInt(headers.getRequired(MetaHeader.ConsensusBlockValue)),
|
|
712
|
+
};
|
|
713
|
+
},
|
|
714
|
+
},
|
|
715
|
+
},
|
|
716
|
+
},
|
|
717
|
+
produceAttestationData: {
|
|
718
|
+
url: "/eth/v1/validator/attestation_data",
|
|
719
|
+
method: "GET",
|
|
720
|
+
req: {
|
|
721
|
+
writeReq: ({committeeIndex, slot}) => ({query: {slot, committee_index: committeeIndex}}),
|
|
722
|
+
parseReq: ({query}) => ({committeeIndex: query.committee_index, slot: query.slot}),
|
|
723
|
+
schema: {
|
|
724
|
+
query: {slot: Schema.UintRequired, committee_index: Schema.Uint},
|
|
725
|
+
},
|
|
726
|
+
},
|
|
727
|
+
resp: {
|
|
728
|
+
data: ssz.phase0.AttestationData,
|
|
729
|
+
meta: EmptyMetaCodec,
|
|
730
|
+
},
|
|
731
|
+
},
|
|
732
|
+
produceSyncCommitteeContribution: {
|
|
733
|
+
url: "/eth/v1/validator/sync_committee_contribution",
|
|
734
|
+
method: "GET",
|
|
735
|
+
req: {
|
|
736
|
+
writeReq: ({slot, subcommitteeIndex, beaconBlockRoot}) => ({
|
|
737
|
+
query: {slot, subcommittee_index: subcommitteeIndex, beacon_block_root: toRootHex(beaconBlockRoot)},
|
|
738
|
+
}),
|
|
739
|
+
parseReq: ({query}) => ({
|
|
740
|
+
slot: query.slot,
|
|
741
|
+
subcommitteeIndex: query.subcommittee_index,
|
|
742
|
+
beaconBlockRoot: fromHex(query.beacon_block_root),
|
|
743
|
+
}),
|
|
744
|
+
schema: {
|
|
745
|
+
query: {
|
|
746
|
+
slot: Schema.UintRequired,
|
|
747
|
+
subcommittee_index: Schema.UintRequired,
|
|
748
|
+
beacon_block_root: Schema.StringRequired,
|
|
749
|
+
},
|
|
750
|
+
},
|
|
751
|
+
},
|
|
752
|
+
resp: {
|
|
753
|
+
data: ssz.altair.SyncCommitteeContribution,
|
|
754
|
+
meta: EmptyMetaCodec,
|
|
755
|
+
},
|
|
756
|
+
},
|
|
757
|
+
getAggregatedAttestation: {
|
|
758
|
+
url: "/eth/v1/validator/aggregate_attestation",
|
|
759
|
+
method: "GET",
|
|
760
|
+
req: {
|
|
761
|
+
writeReq: ({attestationDataRoot, slot}) => ({
|
|
762
|
+
query: {attestation_data_root: toRootHex(attestationDataRoot), slot},
|
|
763
|
+
}),
|
|
764
|
+
parseReq: ({query}) => ({
|
|
765
|
+
attestationDataRoot: fromHex(query.attestation_data_root),
|
|
766
|
+
slot: query.slot,
|
|
767
|
+
}),
|
|
768
|
+
schema: {
|
|
769
|
+
query: {
|
|
770
|
+
attestation_data_root: Schema.StringRequired,
|
|
771
|
+
slot: Schema.UintRequired,
|
|
772
|
+
},
|
|
773
|
+
},
|
|
774
|
+
},
|
|
775
|
+
resp: {
|
|
776
|
+
data: ssz.phase0.Attestation,
|
|
777
|
+
meta: EmptyMetaCodec,
|
|
778
|
+
},
|
|
779
|
+
},
|
|
780
|
+
getAggregatedAttestationV2: {
|
|
781
|
+
url: "/eth/v2/validator/aggregate_attestation",
|
|
782
|
+
method: "GET",
|
|
783
|
+
req: {
|
|
784
|
+
writeReq: ({attestationDataRoot, slot, committeeIndex}) => ({
|
|
785
|
+
query: {attestation_data_root: toHex(attestationDataRoot), slot, committee_index: committeeIndex},
|
|
786
|
+
}),
|
|
787
|
+
parseReq: ({query}) => ({
|
|
788
|
+
attestationDataRoot: fromHex(query.attestation_data_root),
|
|
789
|
+
slot: query.slot,
|
|
790
|
+
committeeIndex: query.committee_index,
|
|
791
|
+
}),
|
|
792
|
+
schema: {
|
|
793
|
+
query: {
|
|
794
|
+
attestation_data_root: Schema.StringRequired,
|
|
795
|
+
slot: Schema.UintRequired,
|
|
796
|
+
committee_index: Schema.UintRequired,
|
|
797
|
+
},
|
|
798
|
+
},
|
|
799
|
+
},
|
|
800
|
+
resp: {
|
|
801
|
+
data: WithVersion((fork) => (isForkPostElectra(fork) ? ssz.electra.Attestation : ssz.phase0.Attestation)),
|
|
802
|
+
meta: VersionCodec,
|
|
803
|
+
},
|
|
804
|
+
},
|
|
805
|
+
publishAggregateAndProofs: {
|
|
806
|
+
url: "/eth/v1/validator/aggregate_and_proofs",
|
|
807
|
+
method: "POST",
|
|
808
|
+
req: {
|
|
809
|
+
writeReqJson: ({signedAggregateAndProofs}) => ({
|
|
810
|
+
body: SignedAggregateAndProofListPhase0Type.toJson(signedAggregateAndProofs),
|
|
811
|
+
}),
|
|
812
|
+
parseReqJson: ({body}) => ({
|
|
813
|
+
signedAggregateAndProofs: SignedAggregateAndProofListPhase0Type.fromJson(body),
|
|
814
|
+
}),
|
|
815
|
+
writeReqSsz: ({signedAggregateAndProofs}) => ({
|
|
816
|
+
body: SignedAggregateAndProofListPhase0Type.serialize(signedAggregateAndProofs),
|
|
817
|
+
}),
|
|
818
|
+
parseReqSsz: ({body}) => ({
|
|
819
|
+
signedAggregateAndProofs: SignedAggregateAndProofListPhase0Type.deserialize(body),
|
|
820
|
+
}),
|
|
821
|
+
schema: {
|
|
822
|
+
body: Schema.ObjectArray,
|
|
823
|
+
},
|
|
824
|
+
},
|
|
825
|
+
resp: EmptyResponseCodec,
|
|
826
|
+
},
|
|
827
|
+
publishAggregateAndProofsV2: {
|
|
828
|
+
url: "/eth/v2/validator/aggregate_and_proofs",
|
|
829
|
+
method: "POST",
|
|
830
|
+
req: {
|
|
831
|
+
writeReqJson: ({signedAggregateAndProofs}) => {
|
|
832
|
+
const fork = config.getForkName(signedAggregateAndProofs[0]?.message.aggregate.data.slot ?? 0);
|
|
833
|
+
return {
|
|
834
|
+
body: isForkPostElectra(fork)
|
|
835
|
+
? SignedAggregateAndProofListElectraType.toJson(
|
|
836
|
+
signedAggregateAndProofs as SignedAggregateAndProofListElectra
|
|
837
|
+
)
|
|
838
|
+
: SignedAggregateAndProofListPhase0Type.toJson(
|
|
839
|
+
signedAggregateAndProofs as SignedAggregateAndProofListPhase0
|
|
840
|
+
),
|
|
841
|
+
headers: {[MetaHeader.Version]: fork},
|
|
842
|
+
};
|
|
843
|
+
},
|
|
844
|
+
parseReqJson: ({body, headers}) => {
|
|
845
|
+
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
846
|
+
return {
|
|
847
|
+
signedAggregateAndProofs: isForkPostElectra(fork)
|
|
848
|
+
? SignedAggregateAndProofListElectraType.fromJson(body)
|
|
849
|
+
: SignedAggregateAndProofListPhase0Type.fromJson(body),
|
|
850
|
+
};
|
|
851
|
+
},
|
|
852
|
+
writeReqSsz: ({signedAggregateAndProofs}) => {
|
|
853
|
+
const fork = config.getForkName(signedAggregateAndProofs[0]?.message.aggregate.data.slot ?? 0);
|
|
854
|
+
return {
|
|
855
|
+
body: isForkPostElectra(fork)
|
|
856
|
+
? SignedAggregateAndProofListElectraType.serialize(
|
|
857
|
+
signedAggregateAndProofs as SignedAggregateAndProofListElectra
|
|
858
|
+
)
|
|
859
|
+
: SignedAggregateAndProofListPhase0Type.serialize(
|
|
860
|
+
signedAggregateAndProofs as SignedAggregateAndProofListPhase0
|
|
861
|
+
),
|
|
862
|
+
headers: {[MetaHeader.Version]: fork},
|
|
863
|
+
};
|
|
864
|
+
},
|
|
865
|
+
parseReqSsz: ({body, headers}) => {
|
|
866
|
+
const fork = toForkName(fromHeaders(headers, MetaHeader.Version));
|
|
867
|
+
return {
|
|
868
|
+
signedAggregateAndProofs: isForkPostElectra(fork)
|
|
869
|
+
? SignedAggregateAndProofListElectraType.deserialize(body)
|
|
870
|
+
: SignedAggregateAndProofListPhase0Type.deserialize(body),
|
|
871
|
+
};
|
|
872
|
+
},
|
|
873
|
+
schema: {
|
|
874
|
+
body: Schema.ObjectArray,
|
|
875
|
+
headers: {[MetaHeader.Version]: Schema.String},
|
|
876
|
+
},
|
|
877
|
+
},
|
|
878
|
+
resp: EmptyResponseCodec,
|
|
879
|
+
},
|
|
880
|
+
publishContributionAndProofs: {
|
|
881
|
+
url: "/eth/v1/validator/contribution_and_proofs",
|
|
882
|
+
method: "POST",
|
|
883
|
+
req: {
|
|
884
|
+
writeReqJson: ({contributionAndProofs}) => ({
|
|
885
|
+
body: SignedContributionAndProofListType.toJson(contributionAndProofs),
|
|
886
|
+
}),
|
|
887
|
+
parseReqJson: ({body}) => ({contributionAndProofs: SignedContributionAndProofListType.fromJson(body)}),
|
|
888
|
+
writeReqSsz: ({contributionAndProofs}) => ({
|
|
889
|
+
body: SignedContributionAndProofListType.serialize(contributionAndProofs),
|
|
890
|
+
}),
|
|
891
|
+
parseReqSsz: ({body}) => ({contributionAndProofs: SignedContributionAndProofListType.deserialize(body)}),
|
|
892
|
+
schema: {
|
|
893
|
+
body: Schema.ObjectArray,
|
|
894
|
+
},
|
|
895
|
+
},
|
|
896
|
+
resp: EmptyResponseCodec,
|
|
897
|
+
},
|
|
898
|
+
prepareBeaconCommitteeSubnet: {
|
|
899
|
+
url: "/eth/v1/validator/beacon_committee_subscriptions",
|
|
900
|
+
method: "POST",
|
|
901
|
+
req: {
|
|
902
|
+
writeReqJson: ({subscriptions}) => ({body: BeaconCommitteeSubscriptionListType.toJson(subscriptions)}),
|
|
903
|
+
parseReqJson: ({body}) => ({subscriptions: BeaconCommitteeSubscriptionListType.fromJson(body)}),
|
|
904
|
+
writeReqSsz: ({subscriptions}) => ({body: BeaconCommitteeSubscriptionListType.serialize(subscriptions)}),
|
|
905
|
+
parseReqSsz: ({body}) => ({subscriptions: BeaconCommitteeSubscriptionListType.deserialize(body)}),
|
|
906
|
+
schema: {body: Schema.ObjectArray},
|
|
907
|
+
},
|
|
908
|
+
resp: EmptyResponseCodec,
|
|
909
|
+
},
|
|
910
|
+
prepareSyncCommitteeSubnets: {
|
|
911
|
+
url: "/eth/v1/validator/sync_committee_subscriptions",
|
|
912
|
+
method: "POST",
|
|
913
|
+
req: {
|
|
914
|
+
writeReqJson: ({subscriptions}) => ({body: SyncCommitteeSubscriptionListType.toJson(subscriptions)}),
|
|
915
|
+
parseReqJson: ({body}) => ({subscriptions: SyncCommitteeSubscriptionListType.fromJson(body)}),
|
|
916
|
+
writeReqSsz: ({subscriptions}) => ({body: SyncCommitteeSubscriptionListType.serialize(subscriptions)}),
|
|
917
|
+
parseReqSsz: ({body}) => ({subscriptions: SyncCommitteeSubscriptionListType.deserialize(body)}),
|
|
918
|
+
schema: {body: Schema.ObjectArray},
|
|
919
|
+
},
|
|
920
|
+
resp: EmptyResponseCodec,
|
|
921
|
+
},
|
|
922
|
+
prepareBeaconProposer: {
|
|
923
|
+
url: "/eth/v1/validator/prepare_beacon_proposer",
|
|
924
|
+
method: "POST",
|
|
925
|
+
req: JsonOnlyReq({
|
|
926
|
+
writeReqJson: ({proposers}) => ({body: ProposerPreparationDataListType.toJson(proposers)}),
|
|
927
|
+
parseReqJson: ({body}) => ({proposers: ProposerPreparationDataListType.fromJson(body)}),
|
|
928
|
+
schema: {body: Schema.ObjectArray},
|
|
929
|
+
}),
|
|
930
|
+
resp: EmptyResponseCodec,
|
|
931
|
+
},
|
|
932
|
+
submitBeaconCommitteeSelections: {
|
|
933
|
+
url: "/eth/v1/validator/beacon_committee_selections",
|
|
934
|
+
method: "POST",
|
|
935
|
+
req: {
|
|
936
|
+
writeReqJson: ({selections}) => ({body: BeaconCommitteeSelectionListType.toJson(selections)}),
|
|
937
|
+
parseReqJson: ({body}) => ({selections: BeaconCommitteeSelectionListType.fromJson(body)}),
|
|
938
|
+
writeReqSsz: ({selections}) => ({body: BeaconCommitteeSelectionListType.serialize(selections)}),
|
|
939
|
+
parseReqSsz: ({body}) => ({selections: BeaconCommitteeSelectionListType.deserialize(body)}),
|
|
940
|
+
schema: {
|
|
941
|
+
body: Schema.ObjectArray,
|
|
942
|
+
},
|
|
943
|
+
},
|
|
944
|
+
resp: {
|
|
945
|
+
data: BeaconCommitteeSelectionListType,
|
|
946
|
+
meta: EmptyMetaCodec,
|
|
947
|
+
},
|
|
948
|
+
},
|
|
949
|
+
submitSyncCommitteeSelections: {
|
|
950
|
+
url: "/eth/v1/validator/sync_committee_selections",
|
|
951
|
+
method: "POST",
|
|
952
|
+
req: {
|
|
953
|
+
writeReqJson: ({selections}) => ({body: SyncCommitteeSelectionListType.toJson(selections)}),
|
|
954
|
+
parseReqJson: ({body}) => ({selections: SyncCommitteeSelectionListType.fromJson(body)}),
|
|
955
|
+
writeReqSsz: ({selections}) => ({body: SyncCommitteeSelectionListType.serialize(selections)}),
|
|
956
|
+
parseReqSsz: ({body}) => ({selections: SyncCommitteeSelectionListType.deserialize(body)}),
|
|
957
|
+
schema: {
|
|
958
|
+
body: Schema.ObjectArray,
|
|
959
|
+
},
|
|
960
|
+
},
|
|
961
|
+
resp: {
|
|
962
|
+
data: SyncCommitteeSelectionListType,
|
|
963
|
+
meta: EmptyMetaCodec,
|
|
964
|
+
},
|
|
965
|
+
},
|
|
966
|
+
getLiveness: {
|
|
967
|
+
url: "/eth/v1/validator/liveness/{epoch}",
|
|
968
|
+
method: "POST",
|
|
969
|
+
req: {
|
|
970
|
+
writeReqJson: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.toJson(indices)}),
|
|
971
|
+
parseReqJson: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.fromJson(body)}),
|
|
972
|
+
writeReqSsz: ({epoch, indices}) => ({params: {epoch}, body: ValidatorIndicesType.serialize(indices)}),
|
|
973
|
+
parseReqSsz: ({params, body}) => ({epoch: params.epoch, indices: ValidatorIndicesType.deserialize(body)}),
|
|
974
|
+
schema: {
|
|
975
|
+
params: {epoch: Schema.UintRequired},
|
|
976
|
+
body: Schema.StringArray,
|
|
977
|
+
},
|
|
978
|
+
},
|
|
979
|
+
resp: {
|
|
980
|
+
data: LivenessResponseDataListType,
|
|
981
|
+
meta: EmptyMetaCodec,
|
|
982
|
+
},
|
|
983
|
+
},
|
|
984
|
+
registerValidator: {
|
|
985
|
+
url: "/eth/v1/validator/register_validator",
|
|
986
|
+
method: "POST",
|
|
987
|
+
req: {
|
|
988
|
+
writeReqJson: ({registrations}) => ({body: SignedValidatorRegistrationV1ListType.toJson(registrations)}),
|
|
989
|
+
parseReqJson: ({body}) => ({registrations: SignedValidatorRegistrationV1ListType.fromJson(body)}),
|
|
990
|
+
writeReqSsz: ({registrations}) => ({body: SignedValidatorRegistrationV1ListType.serialize(registrations)}),
|
|
991
|
+
parseReqSsz: ({body}) => ({registrations: SignedValidatorRegistrationV1ListType.deserialize(body)}),
|
|
992
|
+
schema: {
|
|
993
|
+
body: Schema.ObjectArray,
|
|
994
|
+
},
|
|
995
|
+
},
|
|
996
|
+
resp: EmptyResponseCodec,
|
|
997
|
+
init: {
|
|
998
|
+
requestWireFormat: WireFormat.ssz,
|
|
999
|
+
},
|
|
1000
|
+
},
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
function parseBuilderBoostFactor(builderBoostFactorInput?: string | number | bigint): bigint | undefined {
|
|
1005
|
+
return builderBoostFactorInput !== undefined ? BigInt(builderBoostFactorInput) : undefined;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
function writeSkipRandaoVerification(skipRandaoVerification?: boolean): string | undefined {
|
|
1009
|
+
return skipRandaoVerification === true ? "" : undefined;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
function parseSkipRandaoVerification(skipRandaoVerification?: string): boolean {
|
|
1013
|
+
return skipRandaoVerification !== undefined && skipRandaoVerification === "";
|
|
1014
|
+
}
|