@obolnetwork/obol-sdk 1.0.16 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/cjs/package.json +11 -6
- package/dist/cjs/src/ajv.js +27 -0
- package/dist/cjs/src/constants.js +8 -4
- package/dist/cjs/src/index.js +10 -9
- package/dist/cjs/src/schema.js +8 -0
- package/dist/cjs/src/utils.js +3 -3
- package/dist/cjs/src/verification/common.js +19 -7
- package/dist/cjs/src/verification/termsAndConditions.js +1 -1
- package/dist/cjs/src/verification/v1.6.0.js +1 -1
- package/dist/cjs/src/verification/v1.7.0.js +3 -3
- package/dist/cjs/src/verification/v1.8.0.js +3 -3
- package/dist/cjs/test/fixtures.js +27 -33
- package/dist/cjs/test/methods.test.js +54 -27
- package/dist/esm/package.json +11 -6
- package/dist/esm/src/ajv.js +27 -0
- package/dist/esm/src/base.js +1 -1
- package/dist/esm/src/constants.js +7 -3
- package/dist/esm/src/index.js +11 -10
- package/dist/esm/src/schema.js +8 -0
- package/dist/esm/src/utils.js +3 -3
- package/dist/esm/src/verification/common.js +27 -15
- package/dist/esm/src/verification/sszTypes.js +1 -1
- package/dist/esm/src/verification/termsAndConditions.js +1 -1
- package/dist/esm/src/verification/v1.6.0.js +5 -5
- package/dist/esm/src/verification/v1.7.0.js +8 -8
- package/dist/esm/src/verification/v1.8.0.js +8 -8
- package/dist/esm/test/fixtures.js +27 -33
- package/dist/esm/test/methods.test.js +55 -28
- package/dist/types/src/constants.d.ts +3 -1
- package/dist/types/src/schema.d.ts +8 -0
- package/dist/types/src/types.d.ts +18 -18
- package/package.json +11 -6
- package/src/ajv.ts +38 -7
- package/src/base.ts +22 -18
- package/src/constants.ts +42 -36
- package/src/errors.ts +4 -4
- package/src/index.ts +85 -75
- package/src/schema.ts +10 -2
- package/src/services.ts +6 -6
- package/src/types.ts +65 -65
- package/src/utils.ts +17 -17
- package/src/verification/common.ts +374 -333
- package/src/verification/sszTypes.ts +60 -51
- package/src/verification/termsAndConditions.ts +16 -14
- package/src/verification/v1.6.0.ts +214 -184
- package/src/verification/v1.7.0.ts +268 -233
- package/src/verification/v1.8.0.ts +266 -225
|
@@ -184,44 +184,40 @@ export const clusterConfigV1X8 = {
|
|
|
184
184
|
withdrawal_address: '0xE0C5ceA4D3869F156717C66E188Ae81C80914a6e',
|
|
185
185
|
},
|
|
186
186
|
],
|
|
187
|
-
deposit_amounts: [
|
|
188
|
-
'8000000000',
|
|
189
|
-
'16000000000',
|
|
190
|
-
'8000000000'
|
|
191
|
-
],
|
|
187
|
+
deposit_amounts: ['8000000000', '16000000000', '8000000000'],
|
|
192
188
|
};
|
|
193
189
|
export const clusterLockV1X8 = {
|
|
194
190
|
cluster_definition: {
|
|
195
191
|
name: 'xxxx',
|
|
196
192
|
creator: {
|
|
197
193
|
address: '0x86B8145c98e5BD25BA722645b15eD65f024a87EC',
|
|
198
|
-
config_signature: '0xd30b182fadbc2c5b2bb3f3f6ed6ac2588f297ceb610ed5509bf3e5a25a9b30c70f8a09ef1d2c8e1dbe5ff441299fe66ec677734cc08beec87e94b7effcb089701b'
|
|
194
|
+
config_signature: '0xd30b182fadbc2c5b2bb3f3f6ed6ac2588f297ceb610ed5509bf3e5a25a9b30c70f8a09ef1d2c8e1dbe5ff441299fe66ec677734cc08beec87e94b7effcb089701b',
|
|
199
195
|
},
|
|
200
196
|
operators: [
|
|
201
197
|
{
|
|
202
198
|
address: '0x86B8145c98e5BD25BA722645b15eD65f024a87EC',
|
|
203
199
|
enr: 'enr:-HW4QLlrtMjFLGkFT1bwdGbvZQlH8hLi0M2g44JAxEYP3BZmYpcsy9Q56HPPD87fMucjvLv4-obEFacpsg0ehRilbHeAgmlkgnY0iXNlY3AyNTZrMaEDRaa5o2aSgqyFq_ERZcQTztrOij1mFtXX1bJuVI6ieak',
|
|
204
200
|
config_signature: '0x3df771ecfc9ae2d01da9249dc636a42893e48759c0fa5c51f5e5e14f3ea4513233d1e3bbdd0e11d4b67c8a907201fd08225a75a1e2d6f510a439d6b15f0c36341c',
|
|
205
|
-
enr_signature: '0x3fe2a124dabe3d517e4c274074b3529d36d9528ca6fa8a4e74ef356f86a07c1462fe72a5336421c2647be7babc4ce1835c2101133e0779cf81d4a8d8cb9fe5591c'
|
|
201
|
+
enr_signature: '0x3fe2a124dabe3d517e4c274074b3529d36d9528ca6fa8a4e74ef356f86a07c1462fe72a5336421c2647be7babc4ce1835c2101133e0779cf81d4a8d8cb9fe5591c',
|
|
206
202
|
},
|
|
207
203
|
{
|
|
208
204
|
address: '0xC35CfCd67b9C27345a54EDEcC1033F2284148c81',
|
|
209
205
|
enr: 'enr:-Iu4QNbiUUUwT18LynBbVPJhNxvzQsaSpUr40mQTWscnZaqKb6vAlvV8j-eDDR3E0wjMQumGRbGm2IAb5_k4bVWJiVGAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQPOiodUji0ohgJb5sNK1hgv8g6xO5_znZz3NkkBkyYyKIN0Y3CCDhqDdWRwgg4u',
|
|
210
206
|
config_signature: '0x12d19d6fc4c1a5d9e7be09f47c2f2357dd89f47aba8ae0185f5345e08bcc3adc324bdd51e68a12c3ca34c604d786cfde5f0798aa928dac496edb16c70e7086551b',
|
|
211
|
-
enr_signature: '0xa3d49832dfaf0ad87c5796f9bc151009343da70b91fd53bee3645baa63d001d3207662da8f67b3a20f2ee30c9cacb24a5719a78dc24e030c8ac93e7b3b46bf881b'
|
|
207
|
+
enr_signature: '0xa3d49832dfaf0ad87c5796f9bc151009343da70b91fd53bee3645baa63d001d3207662da8f67b3a20f2ee30c9cacb24a5719a78dc24e030c8ac93e7b3b46bf881b',
|
|
212
208
|
},
|
|
213
209
|
{
|
|
214
210
|
address: '0x33807D6F1DCe44b9C599fFE03640762A6F08C496',
|
|
215
211
|
enr: 'enr:-Iu4QJyserRukhG0Vgi2csu7GjpHYUGufNEbZ8Q7ZBrcZUb0KqpL5QzHonkh1xxHlxatTxrIcX_IS5J3SEWR_sa0ptGAgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQMAUgEqczOjevyculnUIofhCj0DkgJudErM7qCYIvIkzIN0Y3CCDhqDdWRwgg4u',
|
|
216
212
|
config_signature: '0x665d287c46921aad0dde389291b982f24dbbeb4b7ce5ee7bbc4a7d1fb55134f7136889eb3ce70208a7f276b9d4aefb1fbc6159476934567e5bf11765b2c9649b1b',
|
|
217
|
-
enr_signature: '0xc32d5ea29569b01354d48ddaf56df1481a5ae618ffb47602ef40e0e77357de5f23a5258923be5fa06ecce20f5692847860c25c38b97a4e306c94decd99c0519a1b'
|
|
213
|
+
enr_signature: '0xc32d5ea29569b01354d48ddaf56df1481a5ae618ffb47602ef40e0e77357de5f23a5258923be5fa06ecce20f5692847860c25c38b97a4e306c94decd99c0519a1b',
|
|
218
214
|
},
|
|
219
215
|
{
|
|
220
216
|
address: '0xc6e76F72Ea672FAe05C357157CfC37720F0aF26f',
|
|
221
217
|
enr: 'enr:-HW4QKJTwXC6Chw6zbnA3HFZi6Jo0DkIgjKy4eUBpsSOGnAeWE6ChEjEyk_6R6Qrm7jI-iqfs3_HYxiKde8vFgvHHrCAgmlkgnY0iXNlY3AyNTZrMaECfFKQH4spdZCHqrKVz1Q02xYla6J_RQECDNNYBRWdzv8',
|
|
222
218
|
config_signature: '0x610f7be9c7c38878cde1cb391de08eee2f86e62f31f450843b4e37164e738fc8769046e53ad1f018f54ddaf858ff372d22169702c60d68bda19c96fdd20150b61c',
|
|
223
|
-
enr_signature: '0xe2977c79f63b8fe6cb6551efec0cf69041c7f4aaa8ea338997a397450ee946023b03ccb70ad3cc97b1319e1eea9f7472a2ca161bc8b33acdcde689d84c7e771c1b'
|
|
224
|
-
}
|
|
219
|
+
enr_signature: '0xe2977c79f63b8fe6cb6551efec0cf69041c7f4aaa8ea338997a397450ee946023b03ccb70ad3cc97b1319e1eea9f7472a2ca161bc8b33acdcde689d84c7e771c1b',
|
|
220
|
+
},
|
|
225
221
|
],
|
|
226
222
|
uuid: 'bc2fec0c-0b8b-4415-bf48-1e96b07f50eb',
|
|
227
223
|
version: 'v1.8.0',
|
|
@@ -231,20 +227,18 @@ export const clusterLockV1X8 = {
|
|
|
231
227
|
validators: [
|
|
232
228
|
{
|
|
233
229
|
fee_recipient_address: '0x7aC193bF9a9C6e6DD6302969E8Ea6EdF6df490d8',
|
|
234
|
-
withdrawal_address: '0x9e0AC0078F10d28E875577bb3A4A9EDAB60c03EC'
|
|
230
|
+
withdrawal_address: '0x9e0AC0078F10d28E875577bb3A4A9EDAB60c03EC',
|
|
235
231
|
},
|
|
236
232
|
{
|
|
237
233
|
fee_recipient_address: '0x7aC193bF9a9C6e6DD6302969E8Ea6EdF6df490d8',
|
|
238
|
-
withdrawal_address: '0x9e0AC0078F10d28E875577bb3A4A9EDAB60c03EC'
|
|
239
|
-
}
|
|
234
|
+
withdrawal_address: '0x9e0AC0078F10d28E875577bb3A4A9EDAB60c03EC',
|
|
235
|
+
},
|
|
240
236
|
],
|
|
241
237
|
dkg_algorithm: 'default',
|
|
242
238
|
fork_version: '0x01017000',
|
|
243
|
-
deposit_amounts: [
|
|
244
|
-
'32000000000'
|
|
245
|
-
],
|
|
239
|
+
deposit_amounts: ['32000000000'],
|
|
246
240
|
config_hash: '0xb2601f51d277f699acb8ea3b9fb4fc68087c0f1f2c6ae83d00fdd853a6cddb31',
|
|
247
|
-
definition_hash: '0x2a9d52b1dd13fd91661d81e3786512ffdcc3689e2ec97105add153f543c642b4'
|
|
241
|
+
definition_hash: '0x2a9d52b1dd13fd91661d81e3786512ffdcc3689e2ec97105add153f543c642b4',
|
|
248
242
|
},
|
|
249
243
|
distributed_validators: [
|
|
250
244
|
{
|
|
@@ -253,25 +247,25 @@ export const clusterLockV1X8 = {
|
|
|
253
247
|
'0x849db297f690a26e76d5930f99eac9e3f95d9232256d6e39124fe071745b43c8b5418c733b06683aa240a2a0e44b9b8f',
|
|
254
248
|
'0xa1051bf5692153d5bc418946763bb5c82780a05e97bd5b258ea7abe6705047628edd8277366f6b5d0469abfee18988d9',
|
|
255
249
|
'0x87d0342e5dc49a0a0c8f08ec011da3bd859a333bfc46ddd0a194485aa5aa954b7c18d05a2c1ae148d4dc45331101f496',
|
|
256
|
-
'0xa4fa0e971e1a5e38ebe89c6457bc9316b3dd0933660b17e1c717ac148f8340a5db20d867c7a24758c701f6b6bec4d552'
|
|
250
|
+
'0xa4fa0e971e1a5e38ebe89c6457bc9316b3dd0933660b17e1c717ac148f8340a5db20d867c7a24758c701f6b6bec4d552',
|
|
257
251
|
],
|
|
258
252
|
builder_registration: {
|
|
259
253
|
message: {
|
|
260
254
|
fee_recipient: '0x7ac193bf9a9c6e6dd6302969e8ea6edf6df490d8',
|
|
261
255
|
gas_limit: 30000000,
|
|
262
256
|
timestamp: 1696000704,
|
|
263
|
-
pubkey: '0xa33ae80f967a669d8df3ae769acc114577fab185d53e10154b0b50cc0cf9b9f35e466a318f174e8cecdc12173d95cb27'
|
|
257
|
+
pubkey: '0xa33ae80f967a669d8df3ae769acc114577fab185d53e10154b0b50cc0cf9b9f35e466a318f174e8cecdc12173d95cb27',
|
|
264
258
|
},
|
|
265
|
-
signature: '0xb39977fe7c45bab28cfd1bcf356a71b0557187a75e0dfa0facaf5eddba05988c0da85800a4b4528704df44f280913ebc125eb3f9c091d6dd220c92dfcc3c80bc7a9ed2f1b96bffaeaa1053cf117b02b48eb755139c5623b6e61dd92c27d15813'
|
|
259
|
+
signature: '0xb39977fe7c45bab28cfd1bcf356a71b0557187a75e0dfa0facaf5eddba05988c0da85800a4b4528704df44f280913ebc125eb3f9c091d6dd220c92dfcc3c80bc7a9ed2f1b96bffaeaa1053cf117b02b48eb755139c5623b6e61dd92c27d15813',
|
|
266
260
|
},
|
|
267
261
|
partial_deposit_data: [
|
|
268
262
|
{
|
|
269
263
|
pubkey: '0xa33ae80f967a669d8df3ae769acc114577fab185d53e10154b0b50cc0cf9b9f35e466a318f174e8cecdc12173d95cb27',
|
|
270
264
|
withdrawal_credentials: '0x0100000000000000000000009e0ac0078f10d28e875577bb3a4a9edab60c03ec',
|
|
271
265
|
amount: '32000000000',
|
|
272
|
-
signature: '0x9861022ca71cf18aad49a201b023356b8c5ca090086614b681cb84a54327caeff53c0a71c5f55f49976114bb86de2ad6052d174d7948e6c8a924d9bfbbbc2181fad967d818454c6c4f7cffb7bb93dc2c4f4c87fc5598cb4582fa08eff0c7bc08'
|
|
273
|
-
}
|
|
274
|
-
]
|
|
266
|
+
signature: '0x9861022ca71cf18aad49a201b023356b8c5ca090086614b681cb84a54327caeff53c0a71c5f55f49976114bb86de2ad6052d174d7948e6c8a924d9bfbbbc2181fad967d818454c6c4f7cffb7bb93dc2c4f4c87fc5598cb4582fa08eff0c7bc08',
|
|
267
|
+
},
|
|
268
|
+
],
|
|
275
269
|
},
|
|
276
270
|
{
|
|
277
271
|
distributed_public_key: '0xaa888bf805bec7da7ac18dea3afefbf5b8510cbf76367229dab830b3ecdd4533b9d50fb9fcb454df5cbe08e4b31e8479',
|
|
@@ -279,26 +273,26 @@ export const clusterLockV1X8 = {
|
|
|
279
273
|
'0x8279ae646839d946a622d096296ffcccd289e8c49ea2308560bbb731c63d4b49ea46db817a955e47634edbded4919d82',
|
|
280
274
|
'0xa8a12b5b645b015c55515b3220395e015fc051c58bf243e1b638770652c67f863852f9190e3e182aa86b99823b4cf28d',
|
|
281
275
|
'0xb0c557f812060bb1c409e5324c7b54f35fee8f1180c714e60784f7df6a58e3ba3da6cc8b3cebc01975f9f41efcd777cb',
|
|
282
|
-
'0xa7a8576c3b21221f2a6adefc41b4c1f979ee0761e9a7ff50d30434d1a0c4e7fc505b308636801925e698286b802de421'
|
|
276
|
+
'0xa7a8576c3b21221f2a6adefc41b4c1f979ee0761e9a7ff50d30434d1a0c4e7fc505b308636801925e698286b802de421',
|
|
283
277
|
],
|
|
284
278
|
builder_registration: {
|
|
285
279
|
message: {
|
|
286
280
|
fee_recipient: '0x7ac193bf9a9c6e6dd6302969e8ea6edf6df490d8',
|
|
287
281
|
gas_limit: 30000000,
|
|
288
282
|
timestamp: 1696000704,
|
|
289
|
-
pubkey: '0xaa888bf805bec7da7ac18dea3afefbf5b8510cbf76367229dab830b3ecdd4533b9d50fb9fcb454df5cbe08e4b31e8479'
|
|
283
|
+
pubkey: '0xaa888bf805bec7da7ac18dea3afefbf5b8510cbf76367229dab830b3ecdd4533b9d50fb9fcb454df5cbe08e4b31e8479',
|
|
290
284
|
},
|
|
291
|
-
signature: '0x8dcb54028adb8f5601b6ab20ded381dabb6739b3e506df795a279043997908c7d38a68b8e8dda27516165f18e437a84603935bfefc1a83befbd1a90ac43fcc7fb0eed81122852a2ee71fef414aa8879198da239527036b0eaebcdc88d6eca3d1'
|
|
285
|
+
signature: '0x8dcb54028adb8f5601b6ab20ded381dabb6739b3e506df795a279043997908c7d38a68b8e8dda27516165f18e437a84603935bfefc1a83befbd1a90ac43fcc7fb0eed81122852a2ee71fef414aa8879198da239527036b0eaebcdc88d6eca3d1',
|
|
292
286
|
},
|
|
293
287
|
partial_deposit_data: [
|
|
294
288
|
{
|
|
295
289
|
pubkey: '0xaa888bf805bec7da7ac18dea3afefbf5b8510cbf76367229dab830b3ecdd4533b9d50fb9fcb454df5cbe08e4b31e8479',
|
|
296
290
|
withdrawal_credentials: '0x0100000000000000000000009e0ac0078f10d28e875577bb3a4a9edab60c03ec',
|
|
297
291
|
amount: '32000000000',
|
|
298
|
-
signature: '0x95ee68e5191d34e10f567ab0f565cd927211b29be9ab830d39bf74d0486aee7bff78d8fe12d455cb40ec707378eea1040a9d80806f82afa58295de9d4db2dccc48cfaf3c98e9020c6b5c8a9aacf5bbfc7e316871f505000304d9d39b7ad5c5d8'
|
|
299
|
-
}
|
|
300
|
-
]
|
|
301
|
-
}
|
|
292
|
+
signature: '0x95ee68e5191d34e10f567ab0f565cd927211b29be9ab830d39bf74d0486aee7bff78d8fe12d455cb40ec707378eea1040a9d80806f82afa58295de9d4db2dccc48cfaf3c98e9020c6b5c8a9aacf5bbfc7e316871f505000304d9d39b7ad5c5d8',
|
|
293
|
+
},
|
|
294
|
+
],
|
|
295
|
+
},
|
|
302
296
|
],
|
|
303
297
|
signature_aggregate: '0x81ab6319191e3b9065f14231a71fe480b4a45e5e5db4a064faa19a31d04b9cb55fa88b8aa3c966b054b97ae7db2233ee060ae333c5ca3a55ed16b9a3de1894087901cb2d3a177de1cd40030c93301c23ca3edd28dfd1ad04e210b7e2c7625f89',
|
|
304
298
|
lock_hash: '0x186e7e61fb49373d9034d101f2f08429cb379bfcc2f7fa5e9598e8a14ae13ed7',
|
|
@@ -306,6 +300,6 @@ export const clusterLockV1X8 = {
|
|
|
306
300
|
'0xd4b1b6f7b363015b9d1c1c4f199fffc3f9238b7326fdfc5059b175519b05c90a022a18bf2e3eae7d7b0e833384131c2e7be17cc78f6ca23644ae345904dc2d2601',
|
|
307
301
|
'0xc186f930d8d281ab3999fb0ff62b5d96045a4e2330d9d8b300d5d1014f6b4bd925d9c2fedbb53047a49d4008f82600f46e1131b981222c5e423c12b1c9fd544900',
|
|
308
302
|
'0xbc0831fa82b1a70e17eb4fe6f79249a8f5aab1d1f196dd07e32766eb27e72354757d7146b64fca4ad4efa554f7a5d4e7ef835aab6348e9afa37c9eeab069ff4e01',
|
|
309
|
-
'0x0135f307831fa58ff64f9af46e00b92e2375162646af88f6991ba6f98a8c262f2c41846af59da68eadb8ff9c94db42ee8005bd4236e5897635573db2911460aa00'
|
|
310
|
-
]
|
|
303
|
+
'0x0135f307831fa58ff64f9af46e00b92e2375162646af88f6991ba6f98a8c262f2c41846af59da68eadb8ff9c94db42ee8005bd4236e5897635573db2911460aa00',
|
|
304
|
+
],
|
|
311
305
|
};
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { ethers } from 'ethers';
|
|
11
11
|
import { Client, validateClusterLock } from '../src/index';
|
|
12
|
-
import { clusterConfigV1X7, clusterLockV1X6, clusterLockV1X7, clusterLockV1X8 } from './fixtures.js';
|
|
12
|
+
import { clusterConfigV1X7, clusterConfigV1X8, clusterLockV1X6, clusterLockV1X7, clusterLockV1X8, } from './fixtures.js';
|
|
13
13
|
import { SDK_VERSION } from '../src/constants';
|
|
14
14
|
import { Base } from '../src/base';
|
|
15
15
|
import { validatePayload } from '../src/ajv';
|
|
@@ -43,51 +43,72 @@ describe('Cluster Client', () => {
|
|
|
43
43
|
clientInstance['request'] = jest
|
|
44
44
|
.fn()
|
|
45
45
|
.mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
|
|
46
|
-
const configHash = yield clientInstance.createClusterDefinition(
|
|
46
|
+
const configHash = yield clientInstance.createClusterDefinition(clusterConfigV1X8);
|
|
47
47
|
expect(configHash).toEqual(mockConfigHash);
|
|
48
48
|
}));
|
|
49
49
|
test('acceptClusterDefinition should return cluster definition', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
50
|
clientInstance['request'] = jest
|
|
51
51
|
.fn()
|
|
52
|
-
.mockReturnValue(Promise.resolve(
|
|
52
|
+
.mockReturnValue(Promise.resolve(clusterLockV1X8.cluster_definition));
|
|
53
53
|
const clusterDefinition = yield clientInstance.acceptClusterDefinition({
|
|
54
|
-
enr:
|
|
55
|
-
version:
|
|
56
|
-
},
|
|
57
|
-
expect(clusterDefinition).toEqual(
|
|
54
|
+
enr: clusterLockV1X8.cluster_definition.operators[0].enr,
|
|
55
|
+
version: clusterLockV1X8.cluster_definition.version,
|
|
56
|
+
}, clusterLockV1X8.cluster_definition.config_hash);
|
|
57
|
+
expect(clusterDefinition).toEqual(clusterLockV1X8.cluster_definition);
|
|
58
58
|
}));
|
|
59
59
|
test('createClusterDefinition should throw an error on invalid operators', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
60
|
clientInstance['request'] = jest
|
|
61
61
|
.fn()
|
|
62
62
|
.mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
|
|
63
63
|
try {
|
|
64
|
-
yield clientInstance.createClusterDefinition(Object.assign(Object.assign({},
|
|
64
|
+
yield clientInstance.createClusterDefinition(Object.assign(Object.assign({}, clusterConfigV1X8), { operators: [] }));
|
|
65
65
|
}
|
|
66
66
|
catch (error) {
|
|
67
67
|
expect(error.message).toEqual("Schema compilation errors', must NOT have fewer than 4 items");
|
|
68
68
|
}
|
|
69
69
|
}));
|
|
70
|
+
// cause we default to 32000000000
|
|
71
|
+
test('createClusterDefinition should accept a configuration without deposit_amounts', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
+
clientInstance['request'] = jest
|
|
73
|
+
.fn()
|
|
74
|
+
.mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
|
|
75
|
+
const configHash = yield clientInstance.createClusterDefinition(Object.assign({}, clusterConfigV1X7));
|
|
76
|
+
expect(configHash).toEqual(mockConfigHash);
|
|
77
|
+
}));
|
|
78
|
+
test('createClusterDefinition should throw on not valid deposit_amounts ', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
79
|
+
clientInstance['request'] = jest
|
|
80
|
+
.fn()
|
|
81
|
+
.mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
|
|
82
|
+
try {
|
|
83
|
+
yield clientInstance.createClusterDefinition(Object.assign(Object.assign({}, clusterConfigV1X7), { deposit_amounts: ['34000000'] }));
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
expect(error.message).toEqual('Schema compilation errors\', must pass "validDepositAmounts" keyword validation');
|
|
87
|
+
}
|
|
88
|
+
}));
|
|
70
89
|
test('validatePayload should throw an error on empty schema', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
90
|
try {
|
|
72
|
-
validatePayload(Object.assign(Object.assign({},
|
|
91
|
+
validatePayload(Object.assign(Object.assign({}, clusterConfigV1X8), { operators: [] }), '');
|
|
73
92
|
}
|
|
74
93
|
catch (error) {
|
|
75
94
|
expect(error.message).toEqual('schema must be object or boolean');
|
|
76
95
|
}
|
|
77
96
|
}));
|
|
78
97
|
test('getClusterdefinition should return cluster definition if config hash exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
98
|
+
var _c;
|
|
79
99
|
clientInstance['request'] = jest
|
|
80
100
|
.fn()
|
|
81
|
-
.mockReturnValue(Promise.resolve(
|
|
82
|
-
const clusterDefinition = yield clientInstance.getClusterDefinition(
|
|
83
|
-
expect(clusterDefinition.
|
|
101
|
+
.mockReturnValue(Promise.resolve(clusterLockV1X8.cluster_definition));
|
|
102
|
+
const clusterDefinition = yield clientInstance.getClusterDefinition(clusterLockV1X8.cluster_definition.config_hash);
|
|
103
|
+
expect((_c = clusterDefinition.deposit_amounts) === null || _c === void 0 ? void 0 : _c.length).toEqual(clusterLockV1X8.cluster_definition.deposit_amounts.length);
|
|
104
|
+
expect(clusterDefinition.config_hash).toEqual(clusterLockV1X8.cluster_definition.config_hash);
|
|
84
105
|
}));
|
|
85
106
|
test('getClusterLock should return lockFile if exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
86
107
|
clientInstance['request'] = jest
|
|
87
108
|
.fn()
|
|
88
|
-
.mockReturnValue(Promise.resolve(
|
|
89
|
-
const clusterLock = yield clientInstance.getClusterLock(
|
|
90
|
-
expect(clusterLock.lock_hash).toEqual(
|
|
109
|
+
.mockReturnValue(Promise.resolve(clusterLockV1X8));
|
|
110
|
+
const clusterLock = yield clientInstance.getClusterLock(clusterLockV1X8.cluster_definition.config_hash);
|
|
111
|
+
expect(clusterLock.lock_hash).toEqual(clusterLockV1X8.lock_hash);
|
|
91
112
|
}));
|
|
92
113
|
test('request method should set user agent header', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
93
114
|
const server = setupServer(http.get('http://testexample.com/test', ({ request }) => {
|
|
@@ -104,7 +125,9 @@ describe('Cluster Client', () => {
|
|
|
104
125
|
});
|
|
105
126
|
}
|
|
106
127
|
}
|
|
107
|
-
const testBaseInstance = new TestBase({
|
|
128
|
+
const testBaseInstance = new TestBase({
|
|
129
|
+
baseUrl: 'http://testExample.com',
|
|
130
|
+
});
|
|
108
131
|
const result = yield testBaseInstance.callProtectedRequest('/test', {
|
|
109
132
|
method: 'GET',
|
|
110
133
|
});
|
|
@@ -119,7 +142,7 @@ describe('Cluster Client without a signer', () => {
|
|
|
119
142
|
});
|
|
120
143
|
test('createClusterDefinition should throw an error without signer', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
121
144
|
try {
|
|
122
|
-
yield clientInstance.createClusterDefinition(
|
|
145
|
+
yield clientInstance.createClusterDefinition(clusterConfigV1X8);
|
|
123
146
|
}
|
|
124
147
|
catch (err) {
|
|
125
148
|
expect(err.message).toEqual('Signer is required in createClusterDefinition');
|
|
@@ -128,9 +151,9 @@ describe('Cluster Client without a signer', () => {
|
|
|
128
151
|
test('acceptClusterDefinition should throw an error without signer', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
129
152
|
try {
|
|
130
153
|
yield clientInstance.acceptClusterDefinition({
|
|
131
|
-
enr:
|
|
132
|
-
version:
|
|
133
|
-
},
|
|
154
|
+
enr: clusterLockV1X8.cluster_definition.operators[0].enr,
|
|
155
|
+
version: clusterLockV1X8.cluster_definition.version,
|
|
156
|
+
}, clusterLockV1X8.cluster_definition.config_hash);
|
|
134
157
|
}
|
|
135
158
|
catch (err) {
|
|
136
159
|
expect(err.message).toEqual('Signer is required in acceptClusterDefinition');
|
|
@@ -139,23 +162,27 @@ describe('Cluster Client without a signer', () => {
|
|
|
139
162
|
test('getClusterdefinition should return cluster definition if config hash exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
140
163
|
clientInstance['request'] = jest
|
|
141
164
|
.fn()
|
|
142
|
-
.mockReturnValue(Promise.resolve(
|
|
143
|
-
const clusterDefinition = yield clientInstance.getClusterDefinition(
|
|
144
|
-
expect(clusterDefinition.config_hash).toEqual(
|
|
165
|
+
.mockReturnValue(Promise.resolve(clusterLockV1X8.cluster_definition));
|
|
166
|
+
const clusterDefinition = yield clientInstance.getClusterDefinition(clusterLockV1X8.cluster_definition.config_hash);
|
|
167
|
+
expect(clusterDefinition.config_hash).toEqual(clusterLockV1X8.cluster_definition.config_hash);
|
|
145
168
|
}));
|
|
146
169
|
test('getClusterLock should return lockFile if exist', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
147
170
|
clientInstance['request'] = jest
|
|
148
171
|
.fn()
|
|
149
|
-
.mockReturnValue(Promise.resolve(
|
|
150
|
-
const clusterLock = yield clientInstance.getClusterLock(
|
|
151
|
-
expect(clusterLock.lock_hash).toEqual(
|
|
172
|
+
.mockReturnValue(Promise.resolve(clusterLockV1X8));
|
|
173
|
+
const clusterLock = yield clientInstance.getClusterLock(clusterLockV1X8.cluster_definition.config_hash);
|
|
174
|
+
expect(clusterLock.lock_hash).toEqual(clusterLockV1X8.lock_hash);
|
|
152
175
|
}));
|
|
153
|
-
test.each([
|
|
176
|
+
test.each([
|
|
177
|
+
{ version: 'v1.6.0', clusterLock: clusterLockV1X6 },
|
|
178
|
+
{ version: 'v1.7.0', clusterLock: clusterLockV1X7 },
|
|
179
|
+
{ version: 'v1.8.0', clusterLock: clusterLockV1X8 },
|
|
180
|
+
])("$version: 'should return true on verified cluster lock'", ({ clusterLock }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
154
181
|
const isValidLock = yield validateClusterLock(clusterLock);
|
|
155
182
|
expect(isValidLock).toEqual(true);
|
|
156
183
|
}));
|
|
157
184
|
test('Finds the hash of the latest version of terms and conditions', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
185
|
const termsAndConditionsHash = yield hashTermsAndConditions();
|
|
159
|
-
expect(termsAndConditionsHash).toEqual('
|
|
186
|
+
expect(termsAndConditionsHash).toEqual('0xd33721644e8f3afab1495a74abe3523cec12d48b8da6cb760972492ca3f1a273');
|
|
160
187
|
}));
|
|
161
188
|
});
|
|
@@ -68,7 +68,7 @@ export declare const signEnrPayload: (payload: {
|
|
|
68
68
|
enr: string;
|
|
69
69
|
}, chainId: number) => TypedMessage<typeof ENRTypedMessage>;
|
|
70
70
|
export declare const DKG_ALGORITHM = "default";
|
|
71
|
-
export declare const CONFIG_VERSION = "v1.
|
|
71
|
+
export declare const CONFIG_VERSION = "v1.8.0";
|
|
72
72
|
export declare const SDK_VERSION: string;
|
|
73
73
|
export declare const DOMAIN_APPLICATION_BUILDER = "00000001";
|
|
74
74
|
export declare const DOMAIN_DEPOSIT = "03000000";
|
|
@@ -79,7 +79,9 @@ export declare enum DefinitionFlow {
|
|
|
79
79
|
Charon = "Charon-Command"
|
|
80
80
|
}
|
|
81
81
|
export declare const DEFAULT_BASE_URL = "https://api.obol.tech";
|
|
82
|
+
export declare const DEFAULT_BASE_VERSION = "v1";
|
|
82
83
|
export declare const DEFAULT_CHAIN_ID = 17000;
|
|
83
84
|
export declare const ETHER_TO_GWEI: number;
|
|
84
85
|
export declare const TERMS_AND_CONDITIONS_VERSION = 1;
|
|
85
86
|
export declare const TERMS_AND_CONDITIONS_URL: string;
|
|
87
|
+
export declare const TERMS_AND_CONDITIONS_HASH = "0xd33721644e8f3afab1495a74abe3523cec12d48b8da6cb760972492ca3f1a273";
|
|
@@ -14,7 +14,7 @@ export declare enum FORK_MAPPING {
|
|
|
14
14
|
/**
|
|
15
15
|
* Node operator data
|
|
16
16
|
*/
|
|
17
|
-
export
|
|
17
|
+
export type ClusterOperator = {
|
|
18
18
|
/** The operator address. */
|
|
19
19
|
address: string;
|
|
20
20
|
/** The operator ethereum node record. */
|
|
@@ -27,7 +27,7 @@ export interface ClusterOperator {
|
|
|
27
27
|
enr_signature?: string;
|
|
28
28
|
/** The operator configuration signature. */
|
|
29
29
|
config_signature?: string;
|
|
30
|
-
}
|
|
30
|
+
};
|
|
31
31
|
/**
|
|
32
32
|
* A partial view of `ClusterOperator` with `enr` and `version` as required properties.
|
|
33
33
|
*/
|
|
@@ -35,25 +35,25 @@ export type OperatorPayload = Partial<ClusterOperator> & Required<Pick<ClusterOp
|
|
|
35
35
|
/**
|
|
36
36
|
* Cluster creator data
|
|
37
37
|
*/
|
|
38
|
-
export
|
|
38
|
+
export type ClusterCreator = {
|
|
39
39
|
/** The creator address. */
|
|
40
40
|
address: string;
|
|
41
41
|
/** The cluster configuration signature. */
|
|
42
42
|
config_signature?: string;
|
|
43
|
-
}
|
|
43
|
+
};
|
|
44
44
|
/**
|
|
45
45
|
* Validator withdrawal configuration
|
|
46
46
|
*/
|
|
47
|
-
export
|
|
47
|
+
export type ClusterValidator = {
|
|
48
48
|
/** The validator fee recipient address. */
|
|
49
49
|
fee_recipient_address: string;
|
|
50
50
|
/** The validator reward address. */
|
|
51
51
|
withdrawal_address: string;
|
|
52
|
-
}
|
|
52
|
+
};
|
|
53
53
|
/**
|
|
54
54
|
* Cluster configuration
|
|
55
55
|
*/
|
|
56
|
-
export
|
|
56
|
+
export type ClusterPayload = {
|
|
57
57
|
/** The cluster name. */
|
|
58
58
|
name: string;
|
|
59
59
|
/** The cluster nodes operators addresses. */
|
|
@@ -62,7 +62,7 @@ export interface ClusterPayload {
|
|
|
62
62
|
validators: ClusterValidator[];
|
|
63
63
|
/** The cluster partial deposits in gwei or 32000000000. */
|
|
64
64
|
deposit_amounts?: string[];
|
|
65
|
-
}
|
|
65
|
+
};
|
|
66
66
|
/**
|
|
67
67
|
* Cluster definition data needed for dkg
|
|
68
68
|
*/
|
|
@@ -93,7 +93,7 @@ export interface ClusterDefinition extends ClusterPayload {
|
|
|
93
93
|
/**
|
|
94
94
|
* Unsigned DV Builder Registration Message
|
|
95
95
|
*/
|
|
96
|
-
export
|
|
96
|
+
export type BuilderRegistrationMessage = {
|
|
97
97
|
/** The DV fee recipient. */
|
|
98
98
|
fee_recipient: string;
|
|
99
99
|
/** Default is 30000000. */
|
|
@@ -102,20 +102,20 @@ export interface BuilderRegistrationMessage {
|
|
|
102
102
|
timestamp: number;
|
|
103
103
|
/** The public key of the DV. */
|
|
104
104
|
pubkey: string;
|
|
105
|
-
}
|
|
105
|
+
};
|
|
106
106
|
/**
|
|
107
107
|
* Pre-generated Signed Validator Builder Registration
|
|
108
108
|
*/
|
|
109
|
-
export
|
|
109
|
+
export type BuilderRegistration = {
|
|
110
110
|
/** Builder registration message. */
|
|
111
111
|
message: BuilderRegistrationMessage;
|
|
112
112
|
/** BLS signature of the builder registration message. */
|
|
113
113
|
signature: string;
|
|
114
|
-
}
|
|
114
|
+
};
|
|
115
115
|
/**
|
|
116
116
|
* Required deposit data for validator activation
|
|
117
117
|
*/
|
|
118
|
-
export
|
|
118
|
+
export type DepositData = {
|
|
119
119
|
/** The public key of the distributed validator. */
|
|
120
120
|
pubkey: string;
|
|
121
121
|
/** The 0x01 withdrawal address of the DV. */
|
|
@@ -126,11 +126,11 @@ export interface DepositData {
|
|
|
126
126
|
deposit_data_root: string;
|
|
127
127
|
/** BLS signature of the deposit message. */
|
|
128
128
|
signature: string;
|
|
129
|
-
}
|
|
129
|
+
};
|
|
130
130
|
/**
|
|
131
131
|
* Required deposit data for validator activation
|
|
132
132
|
*/
|
|
133
|
-
export
|
|
133
|
+
export type DistributedValidator = {
|
|
134
134
|
/** The public key of the distributed validator. */
|
|
135
135
|
distributed_public_key: string;
|
|
136
136
|
/** The public key of the node distributed validator share. */
|
|
@@ -141,11 +141,11 @@ export interface DistributedValidator {
|
|
|
141
141
|
partial_deposit_data?: Array<Partial<DepositData>>;
|
|
142
142
|
/** pre-generated signed validator builder registration to be sent to builder network. */
|
|
143
143
|
builder_registration?: BuilderRegistration;
|
|
144
|
-
}
|
|
144
|
+
};
|
|
145
145
|
/**
|
|
146
146
|
* Cluster Details after DKG is complete
|
|
147
147
|
*/
|
|
148
|
-
export
|
|
148
|
+
export type ClusterLock = {
|
|
149
149
|
/** The cluster definition. */
|
|
150
150
|
cluster_definition: ClusterDefinition;
|
|
151
151
|
/** The cluster distributed validators. */
|
|
@@ -156,4 +156,4 @@ export interface ClusterLock {
|
|
|
156
156
|
lock_hash: string;
|
|
157
157
|
/** Node Signature for the lock hash by the node secp256k1 key. */
|
|
158
158
|
node_signatures?: string[];
|
|
159
|
-
}
|
|
159
|
+
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obolnetwork/obol-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A package for creating Distributed Validators using the Obol API.",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/obolnetwork/obol-sdk/issues"
|
|
7
7
|
},
|
|
8
|
-
"homepage": "https://docs.obol.
|
|
8
|
+
"homepage": "https://docs.obol.org/",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"Obol",
|
|
11
11
|
"Distributed Validators",
|
|
@@ -20,13 +20,15 @@
|
|
|
20
20
|
"npm:publish": "npm publish --tag latest",
|
|
21
21
|
"release": "release-it",
|
|
22
22
|
"release:dry": "release-it --dry-run --no-npm",
|
|
23
|
-
"lint": "eslint \"{src,
|
|
24
|
-
"lint-ci": "eslint \"{src,
|
|
23
|
+
"lint": "eslint \"{src,test}/**/*.{js,ts}\" --fix",
|
|
24
|
+
"lint-ci": "eslint \"{src,test}/**/*.{js,ts}\"",
|
|
25
|
+
"prettier-ci": "prettier --check \"{src,test}/**/*.{js,ts}\"",
|
|
26
|
+
"prettier": "prettier --write \"{src,test}/**/*.{js,ts}\""
|
|
25
27
|
},
|
|
26
28
|
"main": "./dist/cjs/src/index.js",
|
|
27
29
|
"module": "./dist/esm/src/index.js",
|
|
28
30
|
"typings": "./dist/types/src/index.d.ts",
|
|
29
|
-
"author": "Obol Labs (https://obol.
|
|
31
|
+
"author": "Obol Labs (https://obol.org)",
|
|
30
32
|
"repository": {
|
|
31
33
|
"type": "git",
|
|
32
34
|
"url": "git+https://github.com/obolnetwork/obol-sdk.git"
|
|
@@ -65,15 +67,18 @@
|
|
|
65
67
|
"@types/semver": "^7.5.8",
|
|
66
68
|
"@types/uuid": "^9.0.1",
|
|
67
69
|
"eslint": "^8.57.0",
|
|
70
|
+
"husky": "^9.0.11",
|
|
68
71
|
"jest": "^28.1.3",
|
|
72
|
+
"lint-staged": "^15.2.2",
|
|
69
73
|
"msw": "^2.2.1",
|
|
70
74
|
"npm-run-all": "^4.1.5",
|
|
75
|
+
"prettier": "^3.2.5",
|
|
71
76
|
"release-it": "^17.2.1",
|
|
72
77
|
"ts-jest": "^28.0.8",
|
|
73
78
|
"tsup": "^6.7.0",
|
|
74
79
|
"typedoc": "^0.25.7",
|
|
75
80
|
"typedoc-plugin-markdown": "^4.0.0-next.50",
|
|
76
|
-
"typescript": "
|
|
81
|
+
"typescript": "~5.3.3"
|
|
77
82
|
},
|
|
78
83
|
"engines": {
|
|
79
84
|
"node": ">= 16"
|
package/src/ajv.ts
CHANGED
|
@@ -1,16 +1,47 @@
|
|
|
1
|
-
import Ajv, { type ErrorObject } from 'ajv'
|
|
1
|
+
import Ajv, { type ErrorObject } from 'ajv';
|
|
2
|
+
import { parseUnits } from 'ethers';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
function validDepositAmounts(data: boolean, deposits: string[]): boolean {
|
|
5
|
+
let sum = 0;
|
|
6
|
+
// from ether togwei is same as from gwei to wei
|
|
7
|
+
const maxDeposit = Number(parseUnits('32', 'gwei'));
|
|
8
|
+
const minDeposit = Number(parseUnits('1', 'gwei'));
|
|
9
|
+
|
|
10
|
+
for (const element of deposits) {
|
|
11
|
+
const amountInGWei = Number(element);
|
|
12
|
+
|
|
13
|
+
if (
|
|
14
|
+
!Number.isInteger(amountInGWei) ||
|
|
15
|
+
amountInGWei > maxDeposit ||
|
|
16
|
+
amountInGWei < minDeposit
|
|
17
|
+
) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
sum += amountInGWei;
|
|
21
|
+
}
|
|
22
|
+
if (sum / minDeposit !== 32) {
|
|
23
|
+
return false;
|
|
24
|
+
} else {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function validatePayload(
|
|
4
30
|
data: any,
|
|
5
31
|
schema: any,
|
|
6
32
|
): ErrorObject[] | undefined | null | boolean {
|
|
7
|
-
const ajv = new Ajv()
|
|
8
|
-
|
|
9
|
-
|
|
33
|
+
const ajv = new Ajv();
|
|
34
|
+
ajv.addKeyword({
|
|
35
|
+
keyword: 'validDepositAmounts',
|
|
36
|
+
validate: validDepositAmounts,
|
|
37
|
+
errors: true,
|
|
38
|
+
});
|
|
39
|
+
const validate = ajv.compile(schema);
|
|
40
|
+
const isValid = validate(data);
|
|
10
41
|
if (!isValid) {
|
|
11
42
|
throw new Error(
|
|
12
43
|
`Schema compilation errors', ${validate.errors?.[0].message}`,
|
|
13
|
-
)
|
|
44
|
+
);
|
|
14
45
|
}
|
|
15
|
-
return isValid
|
|
46
|
+
return isValid;
|
|
16
47
|
}
|