@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.
Files changed (48) hide show
  1. package/README.md +6 -3
  2. package/dist/cjs/package.json +11 -6
  3. package/dist/cjs/src/ajv.js +27 -0
  4. package/dist/cjs/src/constants.js +8 -4
  5. package/dist/cjs/src/index.js +10 -9
  6. package/dist/cjs/src/schema.js +8 -0
  7. package/dist/cjs/src/utils.js +3 -3
  8. package/dist/cjs/src/verification/common.js +19 -7
  9. package/dist/cjs/src/verification/termsAndConditions.js +1 -1
  10. package/dist/cjs/src/verification/v1.6.0.js +1 -1
  11. package/dist/cjs/src/verification/v1.7.0.js +3 -3
  12. package/dist/cjs/src/verification/v1.8.0.js +3 -3
  13. package/dist/cjs/test/fixtures.js +27 -33
  14. package/dist/cjs/test/methods.test.js +54 -27
  15. package/dist/esm/package.json +11 -6
  16. package/dist/esm/src/ajv.js +27 -0
  17. package/dist/esm/src/base.js +1 -1
  18. package/dist/esm/src/constants.js +7 -3
  19. package/dist/esm/src/index.js +11 -10
  20. package/dist/esm/src/schema.js +8 -0
  21. package/dist/esm/src/utils.js +3 -3
  22. package/dist/esm/src/verification/common.js +27 -15
  23. package/dist/esm/src/verification/sszTypes.js +1 -1
  24. package/dist/esm/src/verification/termsAndConditions.js +1 -1
  25. package/dist/esm/src/verification/v1.6.0.js +5 -5
  26. package/dist/esm/src/verification/v1.7.0.js +8 -8
  27. package/dist/esm/src/verification/v1.8.0.js +8 -8
  28. package/dist/esm/test/fixtures.js +27 -33
  29. package/dist/esm/test/methods.test.js +55 -28
  30. package/dist/types/src/constants.d.ts +3 -1
  31. package/dist/types/src/schema.d.ts +8 -0
  32. package/dist/types/src/types.d.ts +18 -18
  33. package/package.json +11 -6
  34. package/src/ajv.ts +38 -7
  35. package/src/base.ts +22 -18
  36. package/src/constants.ts +42 -36
  37. package/src/errors.ts +4 -4
  38. package/src/index.ts +85 -75
  39. package/src/schema.ts +10 -2
  40. package/src/services.ts +6 -6
  41. package/src/types.ts +65 -65
  42. package/src/utils.ts +17 -17
  43. package/src/verification/common.ts +374 -333
  44. package/src/verification/sszTypes.ts +60 -51
  45. package/src/verification/termsAndConditions.ts +16 -14
  46. package/src/verification/v1.6.0.ts +214 -184
  47. package/src/verification/v1.7.0.ts +268 -233
  48. 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(clusterConfigV1X7);
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(clusterLockV1X7.cluster_definition));
52
+ .mockReturnValue(Promise.resolve(clusterLockV1X8.cluster_definition));
53
53
  const clusterDefinition = yield clientInstance.acceptClusterDefinition({
54
- enr: clusterLockV1X7.cluster_definition.operators[0].enr,
55
- version: clusterLockV1X7.cluster_definition.version,
56
- }, clusterLockV1X7.cluster_definition.config_hash);
57
- expect(clusterDefinition).toEqual(clusterLockV1X7.cluster_definition);
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({}, clusterConfigV1X7), { operators: [] }));
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({}, clusterConfigV1X7), { operators: [] }), '');
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(clusterLockV1X7.cluster_definition));
82
- const clusterDefinition = yield clientInstance.getClusterDefinition(clusterLockV1X7.cluster_definition.config_hash);
83
- expect(clusterDefinition.config_hash).toEqual(clusterLockV1X7.cluster_definition.config_hash);
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(clusterLockV1X7));
89
- const clusterLock = yield clientInstance.getClusterLock(clusterLockV1X7.cluster_definition.config_hash);
90
- expect(clusterLock.lock_hash).toEqual(clusterLockV1X7.lock_hash);
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({ baseUrl: 'http://testExample.com' });
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(clusterConfigV1X7);
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: clusterLockV1X7.cluster_definition.operators[0].enr,
132
- version: clusterLockV1X7.cluster_definition.version,
133
- }, clusterLockV1X7.cluster_definition.config_hash);
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(clusterLockV1X7.cluster_definition));
143
- const clusterDefinition = yield clientInstance.getClusterDefinition(clusterLockV1X7.cluster_definition.config_hash);
144
- expect(clusterDefinition.config_hash).toEqual(clusterLockV1X7.cluster_definition.config_hash);
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(clusterLockV1X7));
150
- const clusterLock = yield clientInstance.getClusterLock(clusterLockV1X7.cluster_definition.config_hash);
151
- expect(clusterLock.lock_hash).toEqual(clusterLockV1X7.lock_hash);
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([{ version: 'v1.6.0', clusterLock: clusterLockV1X6 }, { version: 'v1.7.0', clusterLock: clusterLockV1X7 }, { version: 'v1.8.0', clusterLock: clusterLockV1X8 }])('$version: \'should return true on verified cluster lock\'', (_a) => __awaiter(void 0, [_a], void 0, function* ({ clusterLock }) {
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('0x0015d01710b4d864004320a4826f6846c2db12a7f056a126fa5ae16c0b5e2b65');
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.7.0";
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";
@@ -52,6 +52,14 @@ export declare const definitionSchema: {
52
52
  required: string[];
53
53
  };
54
54
  };
55
+ deposit_amounts: {
56
+ type: string;
57
+ items: {
58
+ type: string;
59
+ pattern: string;
60
+ };
61
+ validDepositAmounts: boolean;
62
+ };
55
63
  };
56
64
  required: string[];
57
65
  };
@@ -14,7 +14,7 @@ export declare enum FORK_MAPPING {
14
14
  /**
15
15
  * Node operator data
16
16
  */
17
- export interface ClusterOperator {
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 interface ClusterCreator {
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 interface ClusterValidator {
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 interface ClusterPayload {
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 interface BuilderRegistrationMessage {
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 interface BuilderRegistration {
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 interface DepositData {
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 interface DistributedValidator {
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 interface ClusterLock {
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": "1.0.16",
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.tech/",
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,apps,libs,test}/**/*.ts\" --fix",
24
- "lint-ci": "eslint \"{src,apps,libs,test}/**/*.ts\""
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.tech)",
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": "^5.3.3"
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
- export function validatePayload (
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
- const validate = ajv.compile(schema)
9
- const isValid = validate(data)
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
  }