@obolnetwork/obol-sdk 1.0.12 → 1.0.13

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.
Files changed (70) hide show
  1. package/LICENCE +21 -0
  2. package/README.md +33 -3
  3. package/dist/cjs/package.json +128 -0
  4. package/dist/cjs/src/ajv.js +2 -1
  5. package/dist/cjs/src/base.js +2 -2
  6. package/dist/cjs/src/constants.js +38 -13
  7. package/dist/cjs/src/errors.js +1 -1
  8. package/dist/cjs/src/index.js +24 -21
  9. package/dist/cjs/src/schema.js +24 -36
  10. package/dist/cjs/src/services.js +2 -2
  11. package/dist/cjs/src/types.js +0 -1
  12. package/dist/cjs/src/utils.js +36 -1
  13. package/dist/cjs/src/{verify.js → verification/common.js} +128 -155
  14. package/dist/cjs/src/verification/sszTypes.js +69 -0
  15. package/dist/cjs/src/verification/v1.6.0.js +149 -0
  16. package/dist/cjs/src/verification/v1.7.0.js +173 -0
  17. package/dist/cjs/src/verification/v1.8.0.js +183 -0
  18. package/dist/cjs/test/fixtures.js +281 -63
  19. package/dist/cjs/test/methods.test.js +58 -35
  20. package/dist/esm/package.json +128 -0
  21. package/dist/esm/src/ajv.js +2 -1
  22. package/dist/esm/src/base.js +2 -2
  23. package/dist/esm/src/constants.js +14 -12
  24. package/dist/esm/src/errors.js +1 -1
  25. package/dist/esm/src/index.js +27 -24
  26. package/dist/esm/src/schema.js +24 -36
  27. package/dist/esm/src/services.js +1 -1
  28. package/dist/esm/src/types.js +0 -1
  29. package/dist/esm/src/utils.js +34 -0
  30. package/dist/esm/src/{verify.js → verification/common.js} +114 -146
  31. package/dist/esm/src/verification/sszTypes.js +64 -0
  32. package/dist/esm/src/verification/v1.6.0.js +142 -0
  33. package/dist/esm/src/verification/v1.7.0.js +166 -0
  34. package/dist/esm/src/verification/v1.8.0.js +176 -0
  35. package/dist/esm/test/fixtures.js +280 -62
  36. package/dist/esm/test/methods.test.js +59 -36
  37. package/dist/types/src/ajv.d.ts +1 -1
  38. package/dist/types/src/base.d.ts +3 -3
  39. package/dist/types/src/constants.d.ts +8 -10
  40. package/dist/types/src/index.d.ts +16 -16
  41. package/dist/types/src/services.d.ts +1 -1
  42. package/dist/types/src/types.d.ts +33 -27
  43. package/dist/types/src/utils.d.ts +3 -0
  44. package/dist/types/src/verification/common.d.ts +32 -0
  45. package/dist/types/src/verification/sszTypes.d.ts +63 -0
  46. package/dist/types/src/verification/v1.6.0.d.ts +34 -0
  47. package/dist/types/src/verification/v1.7.0.d.ts +34 -0
  48. package/dist/types/src/verification/v1.8.0.d.ts +35 -0
  49. package/dist/types/test/fixtures.d.ts +104 -2
  50. package/package.json +42 -8
  51. package/src/ajv.ts +15 -10
  52. package/src/base.ts +25 -21
  53. package/src/constants.ts +80 -78
  54. package/src/errors.ts +6 -9
  55. package/src/index.ts +118 -81
  56. package/src/schema.ts +24 -36
  57. package/src/services.ts +15 -13
  58. package/src/types.ts +72 -74
  59. package/src/utils.ts +53 -4
  60. package/src/verification/common.ts +420 -0
  61. package/src/verification/sszTypes.ts +79 -0
  62. package/src/verification/v1.6.0.ts +226 -0
  63. package/src/verification/v1.7.0.ts +274 -0
  64. package/src/verification/v1.8.0.ts +281 -0
  65. package/dist/cjs/src/hash.js +0 -172
  66. package/dist/esm/src/hash.js +0 -165
  67. package/dist/types/src/hash.d.ts +0 -56
  68. package/dist/types/src/verify.d.ts +0 -4
  69. package/src/hash.ts +0 -250
  70. package/src/verify.ts +0 -479
@@ -0,0 +1,281 @@
1
+ import { type UintNumberByteLen, UintNumberType } from '@chainsafe/ssz/lib/type/uint'
2
+ import { strToUint8Array } from '../utils'
3
+ import { builderRegistrationContainer, type creatorAddressWrapperType, type creatorContainerType, depositDataContainer, newCreatorContainerType, newOperatorContainerType, type operatorAddressWrapperType, type operatorContainerType, validatorsContainerType } from './sszTypes'
4
+ import { ByteListType, ByteVectorType, ContainerType, ListBasicType, ListCompositeType, fromHexString } from '@chainsafe/ssz'
5
+ import { type ValueOfFields } from '@chainsafe/ssz/lib/view/container'
6
+ import { type ClusterDefintion, type ClusterLock, type DepositData } from '../types'
7
+ import { verifyBuilderRegistration, verifyDepositData, verifyNodeSignatures } from './common'
8
+ import { aggregateSignatures, verifyAggregate, verifyMultiple } from '@chainsafe/bls'
9
+
10
+ // cluster defintion
11
+ type DefinitionFieldsV1X8 = {
12
+ uuid: ByteListType
13
+ name: ByteListType
14
+ version: ByteListType
15
+ timestamp: ByteListType
16
+ num_validators: UintNumberType
17
+ threshold: UintNumberType
18
+ dkg_algorithm: ByteListType
19
+ fork_version: ByteVectorType
20
+ operators: ListCompositeType<
21
+ typeof operatorContainerType | typeof operatorAddressWrapperType
22
+ >
23
+ creator: typeof creatorContainerType | typeof creatorAddressWrapperType
24
+ validators: ListCompositeType<typeof validatorsContainerType>
25
+ deposit_amounts: ListBasicType<UintNumberType>
26
+ config_hash?: ByteVectorType
27
+ }
28
+
29
+ type DefinitionContainerTypeV1X8 = ContainerType<DefinitionFieldsV1X8>
30
+
31
+ /**
32
+ * Returns the containerized cluster definition
33
+ * @param cluster ClusterDefinition to calculate the type from
34
+ * @returns SSZ Containerized type of cluster input
35
+ */
36
+ export const clusterDefinitionContainerTypeV1X8 = (
37
+ configOnly: boolean,
38
+ ): DefinitionContainerTypeV1X8 => {
39
+ let returnedContainerType: any = {
40
+ uuid: new ByteListType(64),
41
+ name: new ByteListType(256),
42
+ version: new ByteListType(16),
43
+ timestamp: new ByteListType(32),
44
+ num_validators: new UintNumberType(8 as UintNumberByteLen),
45
+ threshold: new UintNumberType(8 as UintNumberByteLen),
46
+ dkg_algorithm: new ByteListType(32),
47
+ fork_version: new ByteVectorType(4),
48
+ operators: new ListCompositeType(newOperatorContainerType(configOnly), 256),
49
+ creator: newCreatorContainerType(configOnly),
50
+ validators: new ListCompositeType(validatorsContainerType, 65536),
51
+ deposit_amounts: new ListBasicType(
52
+ new UintNumberType(8 as UintNumberByteLen),
53
+ 256,
54
+ ),
55
+ }
56
+
57
+ if (!configOnly) {
58
+ returnedContainerType = {
59
+ ...returnedContainerType,
60
+ config_hash: new ByteVectorType(32),
61
+ }
62
+ }
63
+
64
+ return new ContainerType(returnedContainerType)
65
+ }
66
+
67
+ export const hashClusterDefinitionV1X8 = (
68
+ cluster: ClusterDefintion,
69
+ configOnly: boolean,
70
+ ): ValueOfFields<DefinitionFieldsV1X8> => {
71
+ const definitionType = clusterDefinitionContainerTypeV1X8(configOnly)
72
+
73
+ const val = definitionType.defaultValue()
74
+
75
+ // order should be same as charon https://github.com/ObolNetwork/charon/blob/main/cluster/ssz.go#L276
76
+ val.uuid = strToUint8Array(cluster.uuid)
77
+ val.name = strToUint8Array(cluster.name)
78
+ val.version = strToUint8Array(cluster.version)
79
+ val.timestamp = strToUint8Array(cluster.timestamp)
80
+ val.num_validators = cluster.num_validators
81
+ val.threshold = cluster.threshold
82
+ val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm)
83
+ val.fork_version = fromHexString(cluster.fork_version)
84
+ val.operators = cluster.operators.map(operator => {
85
+ return configOnly
86
+ ? { address: fromHexString(operator.address) }
87
+ : {
88
+ address: fromHexString(operator.address),
89
+ enr: strToUint8Array(operator.enr as string),
90
+ config_signature: fromHexString(operator.config_signature as string),
91
+ enr_signature: fromHexString(operator.enr_signature as string),
92
+ }
93
+ })
94
+ val.creator = configOnly
95
+ ? { address: fromHexString(cluster.creator.address) }
96
+ : {
97
+ address: fromHexString(cluster.creator.address),
98
+ config_signature: fromHexString(cluster.creator.config_signature as string),
99
+ }
100
+ val.validators = cluster.validators.map((validator) => {
101
+ return {
102
+ fee_recipient_address: fromHexString(validator.fee_recipient_address),
103
+ withdrawal_address: fromHexString(validator.withdrawal_address),
104
+ }
105
+ })
106
+ val.deposit_amounts = (cluster.deposit_amounts as string[]).map((amount: string) => {
107
+ return parseInt(amount)
108
+ })
109
+
110
+ if (!configOnly) {
111
+ val.config_hash = fromHexString(cluster.config_hash)
112
+ }
113
+ return val
114
+ }
115
+
116
+ // cluster lock
117
+
118
+ const dvContainerTypeV1X8 = new ContainerType({
119
+ distributed_public_key: new ByteVectorType(48),
120
+ public_shares: new ListCompositeType(new ByteVectorType(48), 256),
121
+ partial_deposit_data: new ListCompositeType(depositDataContainer, 256),
122
+ builder_registration: builderRegistrationContainer,
123
+ })
124
+
125
+ type LockContainerTypeV1X8 = ContainerType<{
126
+ cluster_definition: DefinitionContainerTypeV1X8
127
+ distributed_validators: ListCompositeType<typeof dvContainerTypeV1X8>
128
+ }>
129
+
130
+ /**
131
+ * @returns SSZ Containerized type of cluster lock
132
+ */
133
+ const clusterLockContainerTypeV1X8 = (): LockContainerTypeV1X8 => {
134
+ return new ContainerType({
135
+ cluster_definition: clusterDefinitionContainerTypeV1X8(false),
136
+ distributed_validators: new ListCompositeType(dvContainerTypeV1X8, 65536),
137
+ })
138
+ }
139
+
140
+ /**
141
+ * @param cluster The published cluster lock
142
+ * @returns The lock hash in of the corresponding cluster
143
+ */
144
+ export const hashClusterLockV1X8 = (cluster: ClusterLock): string => {
145
+ const lockType = clusterLockContainerTypeV1X8()
146
+
147
+ const val = lockType.defaultValue()
148
+
149
+ // Check if we can replace with definition_hash
150
+ val.cluster_definition = hashClusterDefinitionV1X8(
151
+ cluster.cluster_definition,
152
+ false,
153
+ )
154
+ val.distributed_validators = cluster.distributed_validators.map(dValidator => {
155
+ return {
156
+ distributed_public_key: fromHexString(dValidator.distributed_public_key),
157
+ public_shares: dValidator.public_shares.map(publicShare =>
158
+ fromHexString(publicShare),
159
+ ),
160
+ // should be fixed
161
+ partial_deposit_data: (dValidator.partial_deposit_data as DepositData[]).map(depositData => {
162
+ return {
163
+ pubkey: fromHexString(depositData.pubkey),
164
+ withdrawal_credentials: fromHexString(
165
+ depositData.withdrawal_credentials,
166
+ ),
167
+ amount: parseInt(depositData.amount),
168
+ signature: fromHexString(depositData.signature),
169
+ }
170
+ }),
171
+ builder_registration: {
172
+ message: {
173
+ fee_recipient: fromHexString(
174
+ dValidator.builder_registration?.message.fee_recipient as string,
175
+ ),
176
+ gas_limit: dValidator.builder_registration?.message.gas_limit as number,
177
+ timestamp: dValidator.builder_registration?.message.timestamp as number,
178
+ pubkey: fromHexString(dValidator.builder_registration?.message.pubkey as string),
179
+ },
180
+ signature: fromHexString(dValidator.builder_registration?.signature as string),
181
+ },
182
+ }
183
+ })
184
+
185
+ return '0x' + Buffer.from(lockType.hashTreeRoot(val).buffer).toString('hex')
186
+ }
187
+
188
+ // DV verification
189
+ export const verifyDVV1X8 = (clusterLock: ClusterLock): boolean => {
190
+ const validators = clusterLock.distributed_validators
191
+ const pubShares = []
192
+ const pubKeys = []
193
+ const builderRegistrationAndDepositDataMessages = []
194
+ const blsSignatures = []
195
+
196
+ for (let i = 0; i < validators.length; i++) {
197
+ const validator = validators[i]
198
+ const validatorPublicShares = validator.public_shares
199
+ const distributedPublicKey = validator.distributed_public_key
200
+
201
+ // Needed in signature_aggregate verification
202
+ for (const element of validatorPublicShares) {
203
+ pubShares.push(fromHexString(element))
204
+ }
205
+
206
+ // Deposit Data Verification
207
+ for (let j = 0; j < (validator.partial_deposit_data as DepositData[]).length; j++) {
208
+ const depositData = (validator.partial_deposit_data as DepositData[])[i]
209
+ const { isValidDepositData, depositDataMsg } = verifyDepositData(
210
+ distributedPublicKey,
211
+ depositData as Partial<DepositData>,
212
+ clusterLock.cluster_definition.validators[i].withdrawal_address,
213
+ clusterLock.cluster_definition.fork_version
214
+ )
215
+
216
+ if (
217
+ !isValidDepositData
218
+ ) {
219
+ return false
220
+ }
221
+
222
+ pubKeys.push(fromHexString(distributedPublicKey))
223
+ builderRegistrationAndDepositDataMessages.push(depositDataMsg)
224
+ blsSignatures.push(fromHexString(depositData?.signature))
225
+ }
226
+
227
+ // Builder Registration Verification
228
+ const { isValidBuilderRegistration, builderRegistrationMsg } = verifyBuilderRegistration(
229
+ validator,
230
+ clusterLock.cluster_definition.validators[i].fee_recipient_address,
231
+ clusterLock.cluster_definition.fork_version
232
+ )
233
+
234
+ if (
235
+ !isValidBuilderRegistration
236
+ ) {
237
+ return false
238
+ }
239
+
240
+ pubKeys.push(fromHexString(distributedPublicKey))
241
+ builderRegistrationAndDepositDataMessages.push(builderRegistrationMsg)
242
+ blsSignatures.push(
243
+ fromHexString(validator.builder_registration?.signature as string),
244
+ )
245
+ }
246
+
247
+ // BLS signatures verification
248
+ const aggregateBLSSignature = aggregateSignatures(blsSignatures)
249
+
250
+ if (
251
+ !verifyMultiple(
252
+ pubKeys,
253
+ builderRegistrationAndDepositDataMessages,
254
+ aggregateBLSSignature,
255
+ )
256
+ ) {
257
+ return false
258
+ }
259
+
260
+ // Node Signatures verification
261
+ if (
262
+ !verifyNodeSignatures(
263
+ clusterLock
264
+ )
265
+ ) {
266
+ return false
267
+ }
268
+
269
+ // signature_aggregate verification
270
+ if (
271
+ !verifyAggregate(
272
+ pubShares,
273
+ fromHexString(clusterLock.lock_hash),
274
+ fromHexString(clusterLock.signature_aggregate),
275
+ )
276
+ ) {
277
+ return false
278
+ }
279
+
280
+ return true
281
+ }
@@ -1,172 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.clusterLockHash = exports.clusterDefinitionContainerType = exports.validatorsContainerType = exports.creatorContainerType = exports.operatorContainerType = exports.hashClusterDefinition = exports.clusterConfigOrDefinitionHash = void 0;
4
- const ssz_1 = require("@chainsafe/ssz");
5
- const utils_js_1 = require("./utils.js");
6
- //cluster-definition
7
- /**
8
- * @param cluster The cluster configuration or the cluster definition
9
- * @param configOnly a boolean to indicate config hash or definition hash
10
- * @returns The config hash or the definition hash in of the corresponding cluster
11
- */
12
- const clusterConfigOrDefinitionHash = (cluster, configOnly) => {
13
- const definitionType = (0, exports.clusterDefinitionContainerType)(configOnly);
14
- const val = (0, exports.hashClusterDefinition)(cluster, configOnly);
15
- return ('0x' + Buffer.from(definitionType.hashTreeRoot(val).buffer).toString('hex'));
16
- };
17
- exports.clusterConfigOrDefinitionHash = clusterConfigOrDefinitionHash;
18
- const hashClusterDefinition = (cluster, configOnly) => {
19
- const definitionType = (0, exports.clusterDefinitionContainerType)(configOnly);
20
- const val = definitionType.defaultValue();
21
- //order should be same as charon https://github.com/ObolNetwork/charon/blob/d00b31e6465a260a43ce40f15c47fb5a5b009042/cluster/ssz.go#L285
22
- val.uuid = (0, utils_js_1.strToUint8Array)(cluster.uuid);
23
- val.name = (0, utils_js_1.strToUint8Array)(cluster.name);
24
- val.version = (0, utils_js_1.strToUint8Array)(cluster.version);
25
- val.timestamp = (0, utils_js_1.strToUint8Array)(cluster.timestamp);
26
- val.num_validators = cluster.num_validators;
27
- val.threshold = cluster.threshold;
28
- val.dkg_algorithm = (0, utils_js_1.strToUint8Array)(cluster.dkg_algorithm);
29
- val.fork_version = (0, ssz_1.fromHexString)(cluster.fork_version);
30
- val.operators = cluster.operators.map((operator) => {
31
- return configOnly
32
- ? { address: (0, ssz_1.fromHexString)(operator.address) }
33
- : {
34
- address: (0, ssz_1.fromHexString)(operator.address),
35
- enr: (0, utils_js_1.strToUint8Array)(operator.enr),
36
- config_signature: (0, ssz_1.fromHexString)(operator.config_signature),
37
- enr_signature: (0, ssz_1.fromHexString)(operator.enr_signature),
38
- };
39
- });
40
- val.creator = configOnly
41
- ? { address: (0, ssz_1.fromHexString)(cluster.creator.address) }
42
- : {
43
- address: (0, ssz_1.fromHexString)(cluster.creator.address),
44
- config_signature: (0, ssz_1.fromHexString)(cluster.creator.config_signature),
45
- };
46
- val.validators = cluster.validators.map((validator) => {
47
- return {
48
- fee_recipient_address: (0, ssz_1.fromHexString)(validator.fee_recipient_address),
49
- withdrawal_address: (0, ssz_1.fromHexString)(validator.withdrawal_address),
50
- };
51
- });
52
- if (!configOnly) {
53
- val.config_hash = (0, ssz_1.fromHexString)(cluster.config_hash);
54
- }
55
- return val;
56
- };
57
- exports.hashClusterDefinition = hashClusterDefinition;
58
- const operatorAddressWrapperType = new ssz_1.ContainerType({
59
- address: new ssz_1.ByteVectorType(20),
60
- });
61
- const creatorAddressWrapperType = new ssz_1.ContainerType({
62
- address: new ssz_1.ByteVectorType(20),
63
- });
64
- exports.operatorContainerType = new ssz_1.ContainerType({
65
- address: new ssz_1.ByteVectorType(20),
66
- enr: new ssz_1.ByteListType(1024), // This needs to be dynamic, since ENRs do not have a fixed length.
67
- config_signature: new ssz_1.ByteVectorType(65),
68
- enr_signature: new ssz_1.ByteVectorType(65),
69
- });
70
- exports.creatorContainerType = new ssz_1.ContainerType({
71
- address: new ssz_1.ByteVectorType(20),
72
- config_signature: new ssz_1.ByteVectorType(65),
73
- });
74
- exports.validatorsContainerType = new ssz_1.ContainerType({
75
- fee_recipient_address: new ssz_1.ByteVectorType(20),
76
- withdrawal_address: new ssz_1.ByteVectorType(20),
77
- });
78
- const newCreatorContainerType = (configOnly) => {
79
- return configOnly ? creatorAddressWrapperType : exports.creatorContainerType;
80
- };
81
- const newOperatorContainerType = (configOnly) => {
82
- return configOnly ? operatorAddressWrapperType : exports.operatorContainerType;
83
- };
84
- /**
85
- * @param configOnly a boolean to indicate config hash or definition hash
86
- * @returns SSZ Containerized type of cluster definition
87
- */
88
- const clusterDefinitionContainerType = (configOnly) => {
89
- let returnedContainerType = {
90
- uuid: new ssz_1.ByteListType(64),
91
- name: new ssz_1.ByteListType(256),
92
- version: new ssz_1.ByteListType(16),
93
- timestamp: new ssz_1.ByteListType(32),
94
- num_validators: new ssz_1.UintNumberType(8),
95
- threshold: new ssz_1.UintNumberType(8),
96
- dkg_algorithm: new ssz_1.ByteListType(32),
97
- fork_version: new ssz_1.ByteVectorType(4),
98
- operators: new ssz_1.ListCompositeType(newOperatorContainerType(configOnly), 256),
99
- creator: newCreatorContainerType(configOnly),
100
- validators: new ssz_1.ListCompositeType(exports.validatorsContainerType, 65536),
101
- };
102
- if (!configOnly) {
103
- returnedContainerType = Object.assign(Object.assign({}, returnedContainerType), { config_hash: new ssz_1.ByteVectorType(32) });
104
- }
105
- return new ssz_1.ContainerType(returnedContainerType);
106
- };
107
- exports.clusterDefinitionContainerType = clusterDefinitionContainerType;
108
- //cluster-lock
109
- /**
110
- * @param cluster The published cluster lock
111
- * @returns The lock hash in of the corresponding cluster
112
- */
113
- const clusterLockHash = (cluster) => {
114
- const lockType = clusterLockContainerType();
115
- const val = lockType.defaultValue();
116
- //Check if we can replace with definition_hash
117
- val.cluster_definition = (0, exports.hashClusterDefinition)(cluster.cluster_definition, false);
118
- val.distributed_validators = cluster.distributed_validators.map(dVaidator => {
119
- return {
120
- distributed_public_key: (0, ssz_1.fromHexString)(dVaidator.distributed_public_key),
121
- public_shares: dVaidator.public_shares.map(publicShare => (0, ssz_1.fromHexString)(publicShare)),
122
- deposit_data: {
123
- pubkey: (0, ssz_1.fromHexString)(dVaidator.deposit_data.pubkey),
124
- withdrawal_credentials: (0, ssz_1.fromHexString)(dVaidator.deposit_data.withdrawal_credentials),
125
- amount: parseInt(dVaidator.deposit_data.amount),
126
- signature: (0, ssz_1.fromHexString)(dVaidator.deposit_data.signature),
127
- },
128
- builder_registration: {
129
- message: {
130
- fee_recipient: (0, ssz_1.fromHexString)(dVaidator.builder_registration.message.fee_recipient),
131
- gas_limit: dVaidator.builder_registration.message.gas_limit,
132
- timestamp: dVaidator.builder_registration.message.timestamp,
133
- pubkey: (0, ssz_1.fromHexString)(dVaidator.builder_registration.message.pubkey),
134
- },
135
- signature: (0, ssz_1.fromHexString)(dVaidator.builder_registration.signature),
136
- },
137
- };
138
- });
139
- return '0x' + Buffer.from(lockType.hashTreeRoot(val).buffer).toString('hex');
140
- };
141
- exports.clusterLockHash = clusterLockHash;
142
- const depositDataContainer = new ssz_1.ContainerType({
143
- pubkey: new ssz_1.ByteVectorType(48),
144
- withdrawal_credentials: new ssz_1.ByteVectorType(32),
145
- amount: new ssz_1.UintNumberType(8),
146
- signature: new ssz_1.ByteVectorType(96),
147
- });
148
- const builderRegistrationMessageContainer = new ssz_1.ContainerType({
149
- fee_recipient: new ssz_1.ByteVectorType(20),
150
- gas_limit: new ssz_1.UintNumberType(8),
151
- timestamp: new ssz_1.UintNumberType(8),
152
- pubkey: new ssz_1.ByteVectorType(48),
153
- });
154
- const builderRegistrationContainer = new ssz_1.ContainerType({
155
- message: builderRegistrationMessageContainer,
156
- signature: new ssz_1.ByteVectorType(96),
157
- });
158
- const dvContainerType = new ssz_1.ContainerType({
159
- distributed_public_key: new ssz_1.ByteVectorType(48),
160
- public_shares: new ssz_1.ListCompositeType(new ssz_1.ByteVectorType(48), 256),
161
- deposit_data: depositDataContainer,
162
- builder_registration: builderRegistrationContainer,
163
- });
164
- /**
165
- * @returns SSZ Containerized type of cluster lock
166
- */
167
- const clusterLockContainerType = () => {
168
- return new ssz_1.ContainerType({
169
- cluster_definition: (0, exports.clusterDefinitionContainerType)(false),
170
- distributed_validators: new ssz_1.ListCompositeType(dvContainerType, 65536),
171
- });
172
- };
@@ -1,165 +0,0 @@
1
- import { ContainerType, ByteVectorType, UintNumberType, ListCompositeType, ByteListType, fromHexString, } from '@chainsafe/ssz';
2
- import { strToUint8Array } from './utils.js';
3
- //cluster-definition
4
- /**
5
- * @param cluster The cluster configuration or the cluster definition
6
- * @param configOnly a boolean to indicate config hash or definition hash
7
- * @returns The config hash or the definition hash in of the corresponding cluster
8
- */
9
- export const clusterConfigOrDefinitionHash = (cluster, configOnly) => {
10
- const definitionType = clusterDefinitionContainerType(configOnly);
11
- const val = hashClusterDefinition(cluster, configOnly);
12
- return ('0x' + Buffer.from(definitionType.hashTreeRoot(val).buffer).toString('hex'));
13
- };
14
- export const hashClusterDefinition = (cluster, configOnly) => {
15
- const definitionType = clusterDefinitionContainerType(configOnly);
16
- const val = definitionType.defaultValue();
17
- //order should be same as charon https://github.com/ObolNetwork/charon/blob/d00b31e6465a260a43ce40f15c47fb5a5b009042/cluster/ssz.go#L285
18
- val.uuid = strToUint8Array(cluster.uuid);
19
- val.name = strToUint8Array(cluster.name);
20
- val.version = strToUint8Array(cluster.version);
21
- val.timestamp = strToUint8Array(cluster.timestamp);
22
- val.num_validators = cluster.num_validators;
23
- val.threshold = cluster.threshold;
24
- val.dkg_algorithm = strToUint8Array(cluster.dkg_algorithm);
25
- val.fork_version = fromHexString(cluster.fork_version);
26
- val.operators = cluster.operators.map((operator) => {
27
- return configOnly
28
- ? { address: fromHexString(operator.address) }
29
- : {
30
- address: fromHexString(operator.address),
31
- enr: strToUint8Array(operator.enr),
32
- config_signature: fromHexString(operator.config_signature),
33
- enr_signature: fromHexString(operator.enr_signature),
34
- };
35
- });
36
- val.creator = configOnly
37
- ? { address: fromHexString(cluster.creator.address) }
38
- : {
39
- address: fromHexString(cluster.creator.address),
40
- config_signature: fromHexString(cluster.creator.config_signature),
41
- };
42
- val.validators = cluster.validators.map((validator) => {
43
- return {
44
- fee_recipient_address: fromHexString(validator.fee_recipient_address),
45
- withdrawal_address: fromHexString(validator.withdrawal_address),
46
- };
47
- });
48
- if (!configOnly) {
49
- val.config_hash = fromHexString(cluster.config_hash);
50
- }
51
- return val;
52
- };
53
- const operatorAddressWrapperType = new ContainerType({
54
- address: new ByteVectorType(20),
55
- });
56
- const creatorAddressWrapperType = new ContainerType({
57
- address: new ByteVectorType(20),
58
- });
59
- export const operatorContainerType = new ContainerType({
60
- address: new ByteVectorType(20),
61
- enr: new ByteListType(1024), // This needs to be dynamic, since ENRs do not have a fixed length.
62
- config_signature: new ByteVectorType(65),
63
- enr_signature: new ByteVectorType(65),
64
- });
65
- export const creatorContainerType = new ContainerType({
66
- address: new ByteVectorType(20),
67
- config_signature: new ByteVectorType(65),
68
- });
69
- export const validatorsContainerType = new ContainerType({
70
- fee_recipient_address: new ByteVectorType(20),
71
- withdrawal_address: new ByteVectorType(20),
72
- });
73
- const newCreatorContainerType = (configOnly) => {
74
- return configOnly ? creatorAddressWrapperType : creatorContainerType;
75
- };
76
- const newOperatorContainerType = (configOnly) => {
77
- return configOnly ? operatorAddressWrapperType : operatorContainerType;
78
- };
79
- /**
80
- * @param configOnly a boolean to indicate config hash or definition hash
81
- * @returns SSZ Containerized type of cluster definition
82
- */
83
- export const clusterDefinitionContainerType = (configOnly) => {
84
- let returnedContainerType = {
85
- uuid: new ByteListType(64),
86
- name: new ByteListType(256),
87
- version: new ByteListType(16),
88
- timestamp: new ByteListType(32),
89
- num_validators: new UintNumberType(8),
90
- threshold: new UintNumberType(8),
91
- dkg_algorithm: new ByteListType(32),
92
- fork_version: new ByteVectorType(4),
93
- operators: new ListCompositeType(newOperatorContainerType(configOnly), 256),
94
- creator: newCreatorContainerType(configOnly),
95
- validators: new ListCompositeType(validatorsContainerType, 65536),
96
- };
97
- if (!configOnly) {
98
- returnedContainerType = Object.assign(Object.assign({}, returnedContainerType), { config_hash: new ByteVectorType(32) });
99
- }
100
- return new ContainerType(returnedContainerType);
101
- };
102
- //cluster-lock
103
- /**
104
- * @param cluster The published cluster lock
105
- * @returns The lock hash in of the corresponding cluster
106
- */
107
- export const clusterLockHash = (cluster) => {
108
- const lockType = clusterLockContainerType();
109
- const val = lockType.defaultValue();
110
- //Check if we can replace with definition_hash
111
- val.cluster_definition = hashClusterDefinition(cluster.cluster_definition, false);
112
- val.distributed_validators = cluster.distributed_validators.map(dVaidator => {
113
- return {
114
- distributed_public_key: fromHexString(dVaidator.distributed_public_key),
115
- public_shares: dVaidator.public_shares.map(publicShare => fromHexString(publicShare)),
116
- deposit_data: {
117
- pubkey: fromHexString(dVaidator.deposit_data.pubkey),
118
- withdrawal_credentials: fromHexString(dVaidator.deposit_data.withdrawal_credentials),
119
- amount: parseInt(dVaidator.deposit_data.amount),
120
- signature: fromHexString(dVaidator.deposit_data.signature),
121
- },
122
- builder_registration: {
123
- message: {
124
- fee_recipient: fromHexString(dVaidator.builder_registration.message.fee_recipient),
125
- gas_limit: dVaidator.builder_registration.message.gas_limit,
126
- timestamp: dVaidator.builder_registration.message.timestamp,
127
- pubkey: fromHexString(dVaidator.builder_registration.message.pubkey),
128
- },
129
- signature: fromHexString(dVaidator.builder_registration.signature),
130
- },
131
- };
132
- });
133
- return '0x' + Buffer.from(lockType.hashTreeRoot(val).buffer).toString('hex');
134
- };
135
- const depositDataContainer = new ContainerType({
136
- pubkey: new ByteVectorType(48),
137
- withdrawal_credentials: new ByteVectorType(32),
138
- amount: new UintNumberType(8),
139
- signature: new ByteVectorType(96),
140
- });
141
- const builderRegistrationMessageContainer = new ContainerType({
142
- fee_recipient: new ByteVectorType(20),
143
- gas_limit: new UintNumberType(8),
144
- timestamp: new UintNumberType(8),
145
- pubkey: new ByteVectorType(48),
146
- });
147
- const builderRegistrationContainer = new ContainerType({
148
- message: builderRegistrationMessageContainer,
149
- signature: new ByteVectorType(96),
150
- });
151
- const dvContainerType = new ContainerType({
152
- distributed_public_key: new ByteVectorType(48),
153
- public_shares: new ListCompositeType(new ByteVectorType(48), 256),
154
- deposit_data: depositDataContainer,
155
- builder_registration: builderRegistrationContainer,
156
- });
157
- /**
158
- * @returns SSZ Containerized type of cluster lock
159
- */
160
- const clusterLockContainerType = () => {
161
- return new ContainerType({
162
- cluster_definition: clusterDefinitionContainerType(false),
163
- distributed_validators: new ListCompositeType(dvContainerType, 65536),
164
- });
165
- };
@@ -1,56 +0,0 @@
1
- import { ContainerType, ByteVectorType, UintNumberType, ListCompositeType, ByteListType } from '@chainsafe/ssz';
2
- import { ValueOfFields } from '@chainsafe/ssz/lib/view/container.js';
3
- import { ClusterDefintion, ClusterLock } from './types.js';
4
- /**
5
- * @param cluster The cluster configuration or the cluster definition
6
- * @param configOnly a boolean to indicate config hash or definition hash
7
- * @returns The config hash or the definition hash in of the corresponding cluster
8
- */
9
- export declare const clusterConfigOrDefinitionHash: (cluster: ClusterDefintion, configOnly: boolean) => string;
10
- export declare const hashClusterDefinition: (cluster: ClusterDefintion, configOnly: boolean) => ValueOfFields<DefinitionFields>;
11
- declare const operatorAddressWrapperType: ContainerType<{
12
- address: ByteVectorType;
13
- }>;
14
- declare const creatorAddressWrapperType: ContainerType<{
15
- address: ByteVectorType;
16
- }>;
17
- export declare const operatorContainerType: ContainerType<{
18
- address: ByteVectorType;
19
- enr: ByteListType;
20
- config_signature: ByteVectorType;
21
- enr_signature: ByteVectorType;
22
- }>;
23
- export declare const creatorContainerType: ContainerType<{
24
- address: ByteVectorType;
25
- config_signature: ByteVectorType;
26
- }>;
27
- export declare const validatorsContainerType: ContainerType<{
28
- fee_recipient_address: ByteVectorType;
29
- withdrawal_address: ByteVectorType;
30
- }>;
31
- type DefinitionFields = {
32
- uuid: ByteListType;
33
- name: ByteListType;
34
- version: ByteListType;
35
- timestamp: ByteListType;
36
- num_validators: UintNumberType;
37
- threshold: UintNumberType;
38
- dkg_algorithm: ByteListType;
39
- fork_version: ByteVectorType;
40
- operators: ListCompositeType<typeof operatorContainerType | typeof operatorAddressWrapperType>;
41
- creator: typeof creatorContainerType | typeof creatorAddressWrapperType;
42
- validators: ListCompositeType<typeof validatorsContainerType>;
43
- config_hash?: ByteVectorType;
44
- };
45
- export type DefinitionContainerType = ContainerType<DefinitionFields>;
46
- /**
47
- * @param configOnly a boolean to indicate config hash or definition hash
48
- * @returns SSZ Containerized type of cluster definition
49
- */
50
- export declare const clusterDefinitionContainerType: (configOnly: boolean) => DefinitionContainerType;
51
- /**
52
- * @param cluster The published cluster lock
53
- * @returns The lock hash in of the corresponding cluster
54
- */
55
- export declare const clusterLockHash: (cluster: ClusterLock) => string;
56
- export {};
@@ -1,4 +0,0 @@
1
- /// <reference types="node" />
2
- import { ClusterLock } from "./types.js";
3
- export declare const signingRoot: (domain: Uint8Array, messageBuffer: Buffer) => Uint8Array;
4
- export declare const isValidClusterLock: (clusterLock: ClusterLock) => Promise<boolean>;