@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,588 @@
|
|
|
1
|
+
import {ContainerType, ValueOf} from "@chainsafe/ssz";
|
|
2
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
+
import {MAX_VALIDATORS_PER_COMMITTEE} from "@lodestar/params";
|
|
4
|
+
import {
|
|
5
|
+
CommitteeIndex,
|
|
6
|
+
Epoch,
|
|
7
|
+
RootHex,
|
|
8
|
+
Slot,
|
|
9
|
+
StringType,
|
|
10
|
+
ValidatorStatus,
|
|
11
|
+
electra,
|
|
12
|
+
fulu,
|
|
13
|
+
phase0,
|
|
14
|
+
ssz,
|
|
15
|
+
} from "@lodestar/types";
|
|
16
|
+
import {ArrayOf, JsonOnlyReq} from "../../../utils/codecs.js";
|
|
17
|
+
import {Endpoint, RequestCodec, RouteDefinitions, Schema} from "../../../utils/index.js";
|
|
18
|
+
import {
|
|
19
|
+
ExecutionOptimisticAndFinalizedCodec,
|
|
20
|
+
ExecutionOptimisticAndFinalizedMeta,
|
|
21
|
+
ExecutionOptimisticFinalizedAndVersionCodec,
|
|
22
|
+
ExecutionOptimisticFinalizedAndVersionMeta,
|
|
23
|
+
} from "../../../utils/metadata.js";
|
|
24
|
+
import {fromValidatorIdsStr, toValidatorIdsStr} from "../../../utils/serdes.js";
|
|
25
|
+
import {WireFormat} from "../../../utils/wireFormat.js";
|
|
26
|
+
import {RootResponse, RootResponseType} from "./block.js";
|
|
27
|
+
|
|
28
|
+
export type StateId = RootHex | Slot | "head" | "genesis" | "finalized" | "justified";
|
|
29
|
+
|
|
30
|
+
export type StateArgs = {
|
|
31
|
+
/**
|
|
32
|
+
* State identifier.
|
|
33
|
+
* Can be one of: "head" (canonical head in node's view), "genesis", "finalized", "justified", \<slot\>, \<hex encoded stateRoot with 0x prefix\>.
|
|
34
|
+
*/
|
|
35
|
+
stateId: StateId;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type ValidatorId = string | number;
|
|
39
|
+
|
|
40
|
+
export type {ValidatorStatus};
|
|
41
|
+
|
|
42
|
+
export const RandaoResponseType = new ContainerType({
|
|
43
|
+
randao: ssz.Root,
|
|
44
|
+
});
|
|
45
|
+
export const FinalityCheckpointsType = new ContainerType(
|
|
46
|
+
{
|
|
47
|
+
previousJustified: ssz.phase0.Checkpoint,
|
|
48
|
+
currentJustified: ssz.phase0.Checkpoint,
|
|
49
|
+
finalized: ssz.phase0.Checkpoint,
|
|
50
|
+
},
|
|
51
|
+
{jsonCase: "eth2"}
|
|
52
|
+
);
|
|
53
|
+
export const ValidatorResponseType = new ContainerType({
|
|
54
|
+
index: ssz.ValidatorIndex,
|
|
55
|
+
balance: ssz.UintNum64,
|
|
56
|
+
status: new StringType<ValidatorStatus>(),
|
|
57
|
+
validator: ssz.phase0.Validator,
|
|
58
|
+
});
|
|
59
|
+
export const ValidatorIdentityType = new ContainerType(
|
|
60
|
+
{
|
|
61
|
+
index: ssz.ValidatorIndex,
|
|
62
|
+
pubkey: ssz.BLSPubkey,
|
|
63
|
+
activationEpoch: ssz.UintNum64,
|
|
64
|
+
},
|
|
65
|
+
{jsonCase: "eth2"}
|
|
66
|
+
);
|
|
67
|
+
export const EpochCommitteeResponseType = new ContainerType({
|
|
68
|
+
index: ssz.CommitteeIndex,
|
|
69
|
+
slot: ssz.Slot,
|
|
70
|
+
validators: ArrayOf(ssz.ValidatorIndex, MAX_VALIDATORS_PER_COMMITTEE),
|
|
71
|
+
});
|
|
72
|
+
export const ValidatorBalanceType = new ContainerType({
|
|
73
|
+
index: ssz.ValidatorIndex,
|
|
74
|
+
balance: ssz.UintNum64,
|
|
75
|
+
});
|
|
76
|
+
export const EpochSyncCommitteeResponseType = new ContainerType(
|
|
77
|
+
{
|
|
78
|
+
/** All of the validator indices in the current sync committee */
|
|
79
|
+
validators: ArrayOf(ssz.ValidatorIndex),
|
|
80
|
+
/** Subcommittee slices of the current sync committee */
|
|
81
|
+
validatorAggregates: ArrayOf(ArrayOf(ssz.ValidatorIndex)),
|
|
82
|
+
},
|
|
83
|
+
{jsonCase: "eth2"}
|
|
84
|
+
);
|
|
85
|
+
export const ValidatorResponseListType = ArrayOf(ValidatorResponseType);
|
|
86
|
+
export const ValidatorIdentitiesType = ArrayOf(ValidatorIdentityType);
|
|
87
|
+
export const EpochCommitteeResponseListType = ArrayOf(EpochCommitteeResponseType);
|
|
88
|
+
export const ValidatorBalanceListType = ArrayOf(ValidatorBalanceType);
|
|
89
|
+
|
|
90
|
+
export type RandaoResponse = ValueOf<typeof RandaoResponseType>;
|
|
91
|
+
export type FinalityCheckpoints = ValueOf<typeof FinalityCheckpointsType>;
|
|
92
|
+
export type ValidatorResponse = ValueOf<typeof ValidatorResponseType>;
|
|
93
|
+
export type EpochCommitteeResponse = ValueOf<typeof EpochCommitteeResponseType>;
|
|
94
|
+
export type ValidatorBalance = ValueOf<typeof ValidatorBalanceType>;
|
|
95
|
+
export type EpochSyncCommitteeResponse = ValueOf<typeof EpochSyncCommitteeResponseType>;
|
|
96
|
+
|
|
97
|
+
export type ValidatorResponseList = ValueOf<typeof ValidatorResponseListType>;
|
|
98
|
+
export type ValidatorIdentities = ValueOf<typeof ValidatorIdentitiesType>;
|
|
99
|
+
export type EpochCommitteeResponseList = ValueOf<typeof EpochCommitteeResponseListType>;
|
|
100
|
+
export type ValidatorBalanceList = ValueOf<typeof ValidatorBalanceListType>;
|
|
101
|
+
|
|
102
|
+
export type Endpoints = {
|
|
103
|
+
/**
|
|
104
|
+
* Get state SSZ HashTreeRoot
|
|
105
|
+
* Calculates HashTreeRoot for state with given 'stateId'. If stateId is root, same value will be returned.
|
|
106
|
+
*/
|
|
107
|
+
getStateRoot: Endpoint<
|
|
108
|
+
"GET",
|
|
109
|
+
StateArgs,
|
|
110
|
+
{params: {state_id: string}},
|
|
111
|
+
RootResponse,
|
|
112
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
113
|
+
>;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get Fork object for requested state
|
|
117
|
+
* Returns [Fork](https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/beacon-chain.md#fork) object for state with given 'stateId'.
|
|
118
|
+
*/
|
|
119
|
+
getStateFork: Endpoint<
|
|
120
|
+
"GET",
|
|
121
|
+
StateArgs,
|
|
122
|
+
{params: {state_id: string}},
|
|
123
|
+
phase0.Fork,
|
|
124
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
125
|
+
>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Fetch the RANDAO mix for the requested epoch from the state identified by 'stateId'.
|
|
129
|
+
*/
|
|
130
|
+
getStateRandao: Endpoint<
|
|
131
|
+
"GET",
|
|
132
|
+
StateArgs & {
|
|
133
|
+
/**
|
|
134
|
+
* Fetch randao mix for the given epoch. If an epoch is not specified
|
|
135
|
+
* then the RANDAO mix for the state's current epoch will be returned.
|
|
136
|
+
*/
|
|
137
|
+
epoch?: Epoch;
|
|
138
|
+
},
|
|
139
|
+
{params: {state_id: string}; query: {epoch?: number}},
|
|
140
|
+
RandaoResponse,
|
|
141
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
142
|
+
>;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get state finality checkpoints
|
|
146
|
+
* Returns finality checkpoints for state with given 'stateId'.
|
|
147
|
+
* In case finality is not yet achieved, checkpoint should return epoch 0 and ZERO_HASH as root.
|
|
148
|
+
*/
|
|
149
|
+
getStateFinalityCheckpoints: Endpoint<
|
|
150
|
+
"GET",
|
|
151
|
+
StateArgs,
|
|
152
|
+
{params: {state_id: string}},
|
|
153
|
+
FinalityCheckpoints,
|
|
154
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
155
|
+
>;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get validator from state by id
|
|
159
|
+
* Returns validator specified by state and id or public key along with status and balance.
|
|
160
|
+
*/
|
|
161
|
+
getStateValidator: Endpoint<
|
|
162
|
+
"GET",
|
|
163
|
+
StateArgs & {
|
|
164
|
+
/** Either hex encoded public key (with 0x prefix) or validator index */
|
|
165
|
+
validatorId: ValidatorId;
|
|
166
|
+
},
|
|
167
|
+
{params: {state_id: string; validator_id: ValidatorId}},
|
|
168
|
+
ValidatorResponse,
|
|
169
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
170
|
+
>;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get validators from state
|
|
174
|
+
* Returns filterable list of validators with their balance, status and index.
|
|
175
|
+
*/
|
|
176
|
+
getStateValidators: Endpoint<
|
|
177
|
+
"GET",
|
|
178
|
+
StateArgs & {
|
|
179
|
+
/** Either hex encoded public key (with 0x prefix) or validator index */
|
|
180
|
+
validatorIds?: ValidatorId[];
|
|
181
|
+
/** [Validator status specification](https://hackmd.io/ofFJ5gOmQpu1jjHilHbdQQ) */
|
|
182
|
+
statuses?: ValidatorStatus[];
|
|
183
|
+
},
|
|
184
|
+
{params: {state_id: string}; query: {id?: ValidatorId[]; status?: ValidatorStatus[]}},
|
|
185
|
+
ValidatorResponseList,
|
|
186
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
187
|
+
>;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Get validators from state
|
|
191
|
+
* Returns filterable list of validators with their balance, status and index.
|
|
192
|
+
*/
|
|
193
|
+
postStateValidators: Endpoint<
|
|
194
|
+
"POST",
|
|
195
|
+
StateArgs & {
|
|
196
|
+
/** Either hex encoded public key (with 0x prefix) or validator index */
|
|
197
|
+
validatorIds?: ValidatorId[];
|
|
198
|
+
/** [Validator status specification](https://hackmd.io/ofFJ5gOmQpu1jjHilHbdQQ) */
|
|
199
|
+
statuses?: ValidatorStatus[];
|
|
200
|
+
},
|
|
201
|
+
{params: {state_id: string}; body: {ids?: string[]; statuses?: ValidatorStatus[]}},
|
|
202
|
+
ValidatorResponseList,
|
|
203
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
204
|
+
>;
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Get validator identities from state
|
|
208
|
+
*
|
|
209
|
+
* Returns filterable list of validators identities.
|
|
210
|
+
*
|
|
211
|
+
* Identities will be returned for all indices or public keys that match known validators. If an index or public key does not
|
|
212
|
+
* match any known validator, no identity will be returned but this will not cause an error. There are no guarantees for the
|
|
213
|
+
* returned data in terms of ordering.
|
|
214
|
+
*/
|
|
215
|
+
postStateValidatorIdentities: Endpoint<
|
|
216
|
+
"POST",
|
|
217
|
+
StateArgs & {
|
|
218
|
+
/** An array of values, with each value either a hex encoded public key (any bytes48 with 0x prefix) or a validator index */
|
|
219
|
+
validatorIds?: ValidatorId[];
|
|
220
|
+
},
|
|
221
|
+
{params: {state_id: string}; body: string[]},
|
|
222
|
+
ValidatorIdentities,
|
|
223
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
224
|
+
>;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Get validator balances from state
|
|
228
|
+
* Returns filterable list of validator balances.
|
|
229
|
+
*/
|
|
230
|
+
getStateValidatorBalances: Endpoint<
|
|
231
|
+
"GET",
|
|
232
|
+
StateArgs & {
|
|
233
|
+
/** Either hex encoded public key (with 0x prefix) or validator index */
|
|
234
|
+
validatorIds?: ValidatorId[];
|
|
235
|
+
},
|
|
236
|
+
{params: {state_id: string}; query: {id?: ValidatorId[]}},
|
|
237
|
+
ValidatorBalanceList,
|
|
238
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
239
|
+
>;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Get validator balances from state
|
|
243
|
+
* Returns filterable list of validator balances.
|
|
244
|
+
*/
|
|
245
|
+
postStateValidatorBalances: Endpoint<
|
|
246
|
+
"POST",
|
|
247
|
+
StateArgs & {
|
|
248
|
+
/** Either hex encoded public key (with 0x prefix) or validator index */
|
|
249
|
+
validatorIds?: ValidatorId[];
|
|
250
|
+
},
|
|
251
|
+
{params: {state_id: string}; body: string[]},
|
|
252
|
+
ValidatorBalanceList,
|
|
253
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
254
|
+
>;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Get all committees for a state.
|
|
258
|
+
* Retrieves the committees for the given state.
|
|
259
|
+
*/
|
|
260
|
+
getEpochCommittees: Endpoint<
|
|
261
|
+
"GET",
|
|
262
|
+
StateArgs & {
|
|
263
|
+
/** Fetch committees for the given epoch. If not present then the committees for the epoch of the state will be obtained. */
|
|
264
|
+
epoch?: Epoch;
|
|
265
|
+
/** Restrict returned values to those matching the supplied committee index. */
|
|
266
|
+
index?: CommitteeIndex;
|
|
267
|
+
/** Restrict returned values to those matching the supplied slot. */
|
|
268
|
+
slot?: Slot;
|
|
269
|
+
},
|
|
270
|
+
{params: {state_id: string}; query: {slot?: number; epoch?: number; index?: number}},
|
|
271
|
+
EpochCommitteeResponseList,
|
|
272
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
273
|
+
>;
|
|
274
|
+
|
|
275
|
+
getEpochSyncCommittees: Endpoint<
|
|
276
|
+
"GET",
|
|
277
|
+
StateArgs & {epoch?: Epoch},
|
|
278
|
+
{params: {state_id: string}; query: {epoch?: number}},
|
|
279
|
+
EpochSyncCommitteeResponse,
|
|
280
|
+
ExecutionOptimisticAndFinalizedMeta
|
|
281
|
+
>;
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Get State Pending Deposits
|
|
285
|
+
*
|
|
286
|
+
* Returns pending deposits for state with given 'stateId'.
|
|
287
|
+
*/
|
|
288
|
+
getPendingDeposits: Endpoint<
|
|
289
|
+
"GET",
|
|
290
|
+
StateArgs,
|
|
291
|
+
{params: {state_id: string}},
|
|
292
|
+
electra.PendingDeposits,
|
|
293
|
+
ExecutionOptimisticFinalizedAndVersionMeta
|
|
294
|
+
>;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Get State Pending Partial Withdrawals
|
|
298
|
+
*
|
|
299
|
+
* Returns pending partial withdrawals for state with given 'stateId'.
|
|
300
|
+
*/
|
|
301
|
+
getPendingPartialWithdrawals: Endpoint<
|
|
302
|
+
"GET",
|
|
303
|
+
StateArgs,
|
|
304
|
+
{params: {state_id: string}},
|
|
305
|
+
electra.PendingPartialWithdrawals,
|
|
306
|
+
ExecutionOptimisticFinalizedAndVersionMeta
|
|
307
|
+
>;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Get State Pending Consolidations
|
|
311
|
+
*
|
|
312
|
+
* Returns pending consolidations for state with given 'stateId'.
|
|
313
|
+
*/
|
|
314
|
+
getPendingConsolidations: Endpoint<
|
|
315
|
+
"GET",
|
|
316
|
+
StateArgs,
|
|
317
|
+
{params: {state_id: string}},
|
|
318
|
+
electra.PendingConsolidations,
|
|
319
|
+
ExecutionOptimisticFinalizedAndVersionMeta
|
|
320
|
+
>;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Get State Proposer Lookahead
|
|
324
|
+
*
|
|
325
|
+
* Returns proposer lookahead for state with given 'stateId'.
|
|
326
|
+
*/
|
|
327
|
+
getProposerLookahead: Endpoint<
|
|
328
|
+
"GET",
|
|
329
|
+
StateArgs,
|
|
330
|
+
{params: {state_id: string}},
|
|
331
|
+
fulu.ProposerLookahead,
|
|
332
|
+
ExecutionOptimisticFinalizedAndVersionMeta
|
|
333
|
+
>;
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// biome-ignore lint/suspicious/noExplicitAny: We need to use `any` type here
|
|
337
|
+
const stateIdOnlyReq: RequestCodec<Endpoint<"GET", {stateId: StateId}, {params: {state_id: string}}, any, any>> = {
|
|
338
|
+
writeReq: ({stateId}) => ({params: {state_id: stateId.toString()}}),
|
|
339
|
+
parseReq: ({params}) => ({stateId: params.state_id}),
|
|
340
|
+
schema: {params: {state_id: Schema.StringRequired}},
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpoints> {
|
|
344
|
+
return {
|
|
345
|
+
getEpochCommittees: {
|
|
346
|
+
url: "/eth/v1/beacon/states/{state_id}/committees",
|
|
347
|
+
method: "GET",
|
|
348
|
+
req: {
|
|
349
|
+
writeReq: ({stateId, epoch, index, slot}) => ({
|
|
350
|
+
params: {state_id: stateId.toString()},
|
|
351
|
+
query: {epoch, index, slot},
|
|
352
|
+
}),
|
|
353
|
+
parseReq: ({params, query}) => ({
|
|
354
|
+
stateId: params.state_id,
|
|
355
|
+
epoch: query.epoch,
|
|
356
|
+
index: query.index,
|
|
357
|
+
slot: query.slot,
|
|
358
|
+
}),
|
|
359
|
+
schema: {
|
|
360
|
+
params: {state_id: Schema.StringRequired},
|
|
361
|
+
query: {slot: Schema.Uint, epoch: Schema.Uint, index: Schema.Uint},
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
resp: {
|
|
365
|
+
data: EpochCommitteeResponseListType,
|
|
366
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
getEpochSyncCommittees: {
|
|
370
|
+
url: "/eth/v1/beacon/states/{state_id}/sync_committees",
|
|
371
|
+
method: "GET",
|
|
372
|
+
req: {
|
|
373
|
+
writeReq: ({stateId, epoch}) => ({params: {state_id: stateId.toString()}, query: {epoch}}),
|
|
374
|
+
parseReq: ({params, query}) => ({stateId: params.state_id, epoch: query.epoch}),
|
|
375
|
+
schema: {
|
|
376
|
+
params: {state_id: Schema.StringRequired},
|
|
377
|
+
query: {epoch: Schema.Uint},
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
resp: {
|
|
381
|
+
data: EpochSyncCommitteeResponseType,
|
|
382
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
383
|
+
},
|
|
384
|
+
},
|
|
385
|
+
getStateFinalityCheckpoints: {
|
|
386
|
+
url: "/eth/v1/beacon/states/{state_id}/finality_checkpoints",
|
|
387
|
+
method: "GET",
|
|
388
|
+
req: stateIdOnlyReq,
|
|
389
|
+
resp: {
|
|
390
|
+
data: FinalityCheckpointsType,
|
|
391
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
getStateFork: {
|
|
395
|
+
url: "/eth/v1/beacon/states/{state_id}/fork",
|
|
396
|
+
method: "GET",
|
|
397
|
+
req: stateIdOnlyReq,
|
|
398
|
+
resp: {
|
|
399
|
+
data: ssz.phase0.Fork,
|
|
400
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
getStateRoot: {
|
|
404
|
+
url: "/eth/v1/beacon/states/{state_id}/root",
|
|
405
|
+
method: "GET",
|
|
406
|
+
req: stateIdOnlyReq,
|
|
407
|
+
resp: {
|
|
408
|
+
data: RootResponseType,
|
|
409
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
getStateRandao: {
|
|
413
|
+
url: "/eth/v1/beacon/states/{state_id}/randao",
|
|
414
|
+
method: "GET",
|
|
415
|
+
req: {
|
|
416
|
+
writeReq: ({stateId, epoch}) => ({params: {state_id: stateId.toString()}, query: {epoch}}),
|
|
417
|
+
parseReq: ({params, query}) => ({stateId: params.state_id, epoch: query.epoch}),
|
|
418
|
+
schema: {
|
|
419
|
+
params: {state_id: Schema.StringRequired},
|
|
420
|
+
query: {epoch: Schema.Uint},
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
resp: {
|
|
424
|
+
data: RandaoResponseType,
|
|
425
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
getStateValidator: {
|
|
429
|
+
url: "/eth/v1/beacon/states/{state_id}/validators/{validator_id}",
|
|
430
|
+
method: "GET",
|
|
431
|
+
req: {
|
|
432
|
+
writeReq: ({stateId, validatorId}) => ({params: {state_id: stateId.toString(), validator_id: validatorId}}),
|
|
433
|
+
parseReq: ({params}) => ({stateId: params.state_id, validatorId: params.validator_id}),
|
|
434
|
+
schema: {
|
|
435
|
+
params: {state_id: Schema.StringRequired, validator_id: Schema.StringRequired},
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
resp: {
|
|
439
|
+
onlySupport: WireFormat.json,
|
|
440
|
+
data: ValidatorResponseType,
|
|
441
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
getStateValidators: {
|
|
445
|
+
url: "/eth/v1/beacon/states/{state_id}/validators",
|
|
446
|
+
method: "GET",
|
|
447
|
+
req: {
|
|
448
|
+
writeReq: ({stateId, validatorIds: id, statuses}) => ({
|
|
449
|
+
params: {state_id: stateId.toString()},
|
|
450
|
+
query: {id, status: statuses},
|
|
451
|
+
}),
|
|
452
|
+
parseReq: ({params, query}) => ({stateId: params.state_id, validatorIds: query.id, statuses: query.status}),
|
|
453
|
+
schema: {
|
|
454
|
+
params: {state_id: Schema.StringRequired},
|
|
455
|
+
query: {id: Schema.UintOrStringArray, status: Schema.StringArray},
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
resp: {
|
|
459
|
+
onlySupport: WireFormat.json,
|
|
460
|
+
data: ValidatorResponseListType,
|
|
461
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
postStateValidators: {
|
|
465
|
+
url: "/eth/v1/beacon/states/{state_id}/validators",
|
|
466
|
+
method: "POST",
|
|
467
|
+
req: JsonOnlyReq({
|
|
468
|
+
writeReqJson: ({stateId, validatorIds, statuses}) => ({
|
|
469
|
+
params: {state_id: stateId.toString()},
|
|
470
|
+
body: {
|
|
471
|
+
ids: toValidatorIdsStr(validatorIds),
|
|
472
|
+
statuses,
|
|
473
|
+
},
|
|
474
|
+
}),
|
|
475
|
+
parseReqJson: ({params, body = {}}) => ({
|
|
476
|
+
stateId: params.state_id,
|
|
477
|
+
validatorIds: fromValidatorIdsStr(body.ids),
|
|
478
|
+
statuses: body.statuses ?? undefined,
|
|
479
|
+
}),
|
|
480
|
+
schema: {
|
|
481
|
+
params: {state_id: Schema.StringRequired},
|
|
482
|
+
body: Schema.Object,
|
|
483
|
+
},
|
|
484
|
+
}),
|
|
485
|
+
resp: {
|
|
486
|
+
onlySupport: WireFormat.json,
|
|
487
|
+
data: ValidatorResponseListType,
|
|
488
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
489
|
+
},
|
|
490
|
+
},
|
|
491
|
+
postStateValidatorIdentities: {
|
|
492
|
+
url: "/eth/v1/beacon/states/{state_id}/validator_identities",
|
|
493
|
+
method: "POST",
|
|
494
|
+
req: JsonOnlyReq({
|
|
495
|
+
writeReqJson: ({stateId, validatorIds}) => ({
|
|
496
|
+
params: {state_id: stateId.toString()},
|
|
497
|
+
body: toValidatorIdsStr(validatorIds) || [],
|
|
498
|
+
}),
|
|
499
|
+
parseReqJson: ({params, body = []}) => ({
|
|
500
|
+
stateId: params.state_id,
|
|
501
|
+
validatorIds: fromValidatorIdsStr(body),
|
|
502
|
+
}),
|
|
503
|
+
schema: {
|
|
504
|
+
params: {state_id: Schema.StringRequired},
|
|
505
|
+
body: Schema.UintOrStringArray,
|
|
506
|
+
},
|
|
507
|
+
}),
|
|
508
|
+
resp: {
|
|
509
|
+
data: ValidatorIdentitiesType,
|
|
510
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
511
|
+
},
|
|
512
|
+
},
|
|
513
|
+
getStateValidatorBalances: {
|
|
514
|
+
url: "/eth/v1/beacon/states/{state_id}/validator_balances",
|
|
515
|
+
method: "GET",
|
|
516
|
+
req: {
|
|
517
|
+
writeReq: ({stateId, validatorIds}) => ({params: {state_id: stateId.toString()}, query: {id: validatorIds}}),
|
|
518
|
+
parseReq: ({params, query}) => ({stateId: params.state_id, validatorIds: query.id}),
|
|
519
|
+
schema: {
|
|
520
|
+
params: {state_id: Schema.StringRequired},
|
|
521
|
+
query: {id: Schema.UintOrStringArray},
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
resp: {
|
|
525
|
+
data: ValidatorBalanceListType,
|
|
526
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
postStateValidatorBalances: {
|
|
530
|
+
url: "/eth/v1/beacon/states/{state_id}/validator_balances",
|
|
531
|
+
method: "POST",
|
|
532
|
+
req: JsonOnlyReq({
|
|
533
|
+
writeReqJson: ({stateId, validatorIds}) => ({
|
|
534
|
+
params: {state_id: stateId.toString()},
|
|
535
|
+
body: toValidatorIdsStr(validatorIds) || [],
|
|
536
|
+
}),
|
|
537
|
+
parseReqJson: ({params, body = []}) => ({
|
|
538
|
+
stateId: params.state_id,
|
|
539
|
+
validatorIds: fromValidatorIdsStr(body),
|
|
540
|
+
}),
|
|
541
|
+
schema: {
|
|
542
|
+
params: {state_id: Schema.StringRequired},
|
|
543
|
+
body: Schema.UintOrStringArray,
|
|
544
|
+
},
|
|
545
|
+
}),
|
|
546
|
+
resp: {
|
|
547
|
+
data: ValidatorBalanceListType,
|
|
548
|
+
meta: ExecutionOptimisticAndFinalizedCodec,
|
|
549
|
+
},
|
|
550
|
+
},
|
|
551
|
+
getPendingDeposits: {
|
|
552
|
+
url: "/eth/v1/beacon/states/{state_id}/pending_deposits",
|
|
553
|
+
method: "GET",
|
|
554
|
+
req: stateIdOnlyReq,
|
|
555
|
+
resp: {
|
|
556
|
+
data: ssz.electra.PendingDeposits,
|
|
557
|
+
meta: ExecutionOptimisticFinalizedAndVersionCodec,
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
getPendingPartialWithdrawals: {
|
|
561
|
+
url: "/eth/v1/beacon/states/{state_id}/pending_partial_withdrawals",
|
|
562
|
+
method: "GET",
|
|
563
|
+
req: stateIdOnlyReq,
|
|
564
|
+
resp: {
|
|
565
|
+
data: ssz.electra.PendingPartialWithdrawals,
|
|
566
|
+
meta: ExecutionOptimisticFinalizedAndVersionCodec,
|
|
567
|
+
},
|
|
568
|
+
},
|
|
569
|
+
getPendingConsolidations: {
|
|
570
|
+
url: "/eth/v1/beacon/states/{state_id}/pending_consolidations",
|
|
571
|
+
method: "GET",
|
|
572
|
+
req: stateIdOnlyReq,
|
|
573
|
+
resp: {
|
|
574
|
+
data: ssz.electra.PendingConsolidations,
|
|
575
|
+
meta: ExecutionOptimisticFinalizedAndVersionCodec,
|
|
576
|
+
},
|
|
577
|
+
},
|
|
578
|
+
getProposerLookahead: {
|
|
579
|
+
url: "/eth/v1/beacon/states/{state_id}/proposer_lookahead",
|
|
580
|
+
method: "GET",
|
|
581
|
+
req: stateIdOnlyReq,
|
|
582
|
+
resp: {
|
|
583
|
+
data: ssz.fulu.ProposerLookahead,
|
|
584
|
+
meta: ExecutionOptimisticFinalizedAndVersionCodec,
|
|
585
|
+
},
|
|
586
|
+
},
|
|
587
|
+
};
|
|
588
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import {ContainerType, ValueOf} from "@chainsafe/ssz";
|
|
2
|
+
import {ChainForkConfig, SpecJson} from "@lodestar/config";
|
|
3
|
+
import {ssz} from "@lodestar/types";
|
|
4
|
+
import {
|
|
5
|
+
ArrayOf,
|
|
6
|
+
EmptyArgs,
|
|
7
|
+
EmptyMeta,
|
|
8
|
+
EmptyMetaCodec,
|
|
9
|
+
EmptyRequest,
|
|
10
|
+
EmptyRequestCodec,
|
|
11
|
+
JsonOnlyResp,
|
|
12
|
+
} from "../../utils/codecs.js";
|
|
13
|
+
import {Endpoint, RouteDefinitions} from "../../utils/index.js";
|
|
14
|
+
|
|
15
|
+
export const DepositContractType = new ContainerType(
|
|
16
|
+
{
|
|
17
|
+
chainId: ssz.UintNum64,
|
|
18
|
+
address: ssz.ExecutionAddress,
|
|
19
|
+
},
|
|
20
|
+
{jsonCase: "eth2"}
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export const ForkListType = ArrayOf(ssz.phase0.Fork);
|
|
24
|
+
|
|
25
|
+
export type DepositContract = ValueOf<typeof DepositContractType>;
|
|
26
|
+
export type ForkList = ValueOf<typeof ForkListType>;
|
|
27
|
+
export type Spec = SpecJson;
|
|
28
|
+
|
|
29
|
+
export type Endpoints = {
|
|
30
|
+
/**
|
|
31
|
+
* Get deposit contract address.
|
|
32
|
+
* Retrieve Eth1 deposit contract address and chain ID.
|
|
33
|
+
*/
|
|
34
|
+
getDepositContract: Endpoint<
|
|
35
|
+
// ⏎
|
|
36
|
+
"GET",
|
|
37
|
+
EmptyArgs,
|
|
38
|
+
EmptyRequest,
|
|
39
|
+
DepositContract,
|
|
40
|
+
EmptyMeta
|
|
41
|
+
>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get scheduled upcoming forks.
|
|
45
|
+
* Retrieve all scheduled upcoming forks this node is aware of.
|
|
46
|
+
*/
|
|
47
|
+
getForkSchedule: Endpoint<
|
|
48
|
+
// ⏎
|
|
49
|
+
"GET",
|
|
50
|
+
EmptyArgs,
|
|
51
|
+
EmptyRequest,
|
|
52
|
+
ForkList,
|
|
53
|
+
EmptyMeta
|
|
54
|
+
>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Retrieve specification configuration used on this node. The configuration should include:
|
|
58
|
+
* - Constants for all hard forks known by the beacon node, for example the [phase 0](https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/beacon-chain.md#constants) and [altair](https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/beacon-chain.md#constants) values
|
|
59
|
+
* - Presets for all hard forks supplied to the beacon node, for example the [phase 0](https://github.com/ethereum/consensus-specs/blob/v1.1.10/presets/mainnet/phase0.yaml) and [altair](https://github.com/ethereum/consensus-specs/blob/v1.1.10/presets/mainnet/altair.yaml) values
|
|
60
|
+
* - Configuration for the beacon node, for example the [mainnet](https://github.com/ethereum/consensus-specs/blob/v1.1.10/configs/mainnet.yaml) values
|
|
61
|
+
*
|
|
62
|
+
* Values are returned with following format:
|
|
63
|
+
* - any value starting with 0x in the spec is returned as a hex string
|
|
64
|
+
* - numeric values are returned as a quoted integer
|
|
65
|
+
*/
|
|
66
|
+
getSpec: Endpoint<
|
|
67
|
+
// ⏎
|
|
68
|
+
"GET",
|
|
69
|
+
EmptyArgs,
|
|
70
|
+
EmptyRequest,
|
|
71
|
+
Spec,
|
|
72
|
+
EmptyMeta
|
|
73
|
+
>;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpoints> {
|
|
77
|
+
return {
|
|
78
|
+
getDepositContract: {
|
|
79
|
+
url: "/eth/v1/config/deposit_contract",
|
|
80
|
+
method: "GET",
|
|
81
|
+
req: EmptyRequestCodec,
|
|
82
|
+
resp: {
|
|
83
|
+
data: DepositContractType,
|
|
84
|
+
meta: EmptyMetaCodec,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
getForkSchedule: {
|
|
88
|
+
url: "/eth/v1/config/fork_schedule",
|
|
89
|
+
method: "GET",
|
|
90
|
+
req: EmptyRequestCodec,
|
|
91
|
+
resp: {
|
|
92
|
+
data: ForkListType,
|
|
93
|
+
meta: EmptyMetaCodec,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
getSpec: {
|
|
97
|
+
url: "/eth/v1/config/spec",
|
|
98
|
+
method: "GET",
|
|
99
|
+
req: EmptyRequestCodec,
|
|
100
|
+
resp: JsonOnlyResp({
|
|
101
|
+
data: {
|
|
102
|
+
toJson: (data) => data,
|
|
103
|
+
fromJson: (data) => {
|
|
104
|
+
if (typeof data !== "object" || data === null) {
|
|
105
|
+
throw Error("JSON must be of type object");
|
|
106
|
+
}
|
|
107
|
+
return data as Spec;
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
meta: EmptyMetaCodec,
|
|
111
|
+
}),
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|