@obolnetwork/obol-sdk 1.0.16 → 1.0.17

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 +12 -7
  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
@@ -45,51 +45,72 @@ describe('Cluster Client', () => {
45
45
  clientInstance['request'] = jest
46
46
  .fn()
47
47
  .mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
48
- const configHash = yield clientInstance.createClusterDefinition(fixtures_js_1.clusterConfigV1X7);
48
+ const configHash = yield clientInstance.createClusterDefinition(fixtures_js_1.clusterConfigV1X8);
49
49
  expect(configHash).toEqual(mockConfigHash);
50
50
  }));
51
51
  test('acceptClusterDefinition should return cluster definition', () => __awaiter(void 0, void 0, void 0, function* () {
52
52
  clientInstance['request'] = jest
53
53
  .fn()
54
- .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X7.cluster_definition));
54
+ .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X8.cluster_definition));
55
55
  const clusterDefinition = yield clientInstance.acceptClusterDefinition({
56
- enr: fixtures_js_1.clusterLockV1X7.cluster_definition.operators[0].enr,
57
- version: fixtures_js_1.clusterLockV1X7.cluster_definition.version,
58
- }, fixtures_js_1.clusterLockV1X7.cluster_definition.config_hash);
59
- expect(clusterDefinition).toEqual(fixtures_js_1.clusterLockV1X7.cluster_definition);
56
+ enr: fixtures_js_1.clusterLockV1X8.cluster_definition.operators[0].enr,
57
+ version: fixtures_js_1.clusterLockV1X8.cluster_definition.version,
58
+ }, fixtures_js_1.clusterLockV1X8.cluster_definition.config_hash);
59
+ expect(clusterDefinition).toEqual(fixtures_js_1.clusterLockV1X8.cluster_definition);
60
60
  }));
61
61
  test('createClusterDefinition should throw an error on invalid operators', () => __awaiter(void 0, void 0, void 0, function* () {
62
62
  clientInstance['request'] = jest
63
63
  .fn()
64
64
  .mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
65
65
  try {
66
- yield clientInstance.createClusterDefinition(Object.assign(Object.assign({}, fixtures_js_1.clusterConfigV1X7), { operators: [] }));
66
+ yield clientInstance.createClusterDefinition(Object.assign(Object.assign({}, fixtures_js_1.clusterConfigV1X8), { operators: [] }));
67
67
  }
68
68
  catch (error) {
69
69
  expect(error.message).toEqual("Schema compilation errors', must NOT have fewer than 4 items");
70
70
  }
71
71
  }));
72
+ // cause we default to 32000000000
73
+ test('createClusterDefinition should accept a configuration without deposit_amounts', () => __awaiter(void 0, void 0, void 0, function* () {
74
+ clientInstance['request'] = jest
75
+ .fn()
76
+ .mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
77
+ const configHash = yield clientInstance.createClusterDefinition(Object.assign({}, fixtures_js_1.clusterConfigV1X7));
78
+ expect(configHash).toEqual(mockConfigHash);
79
+ }));
80
+ test('createClusterDefinition should throw on not valid deposit_amounts ', () => __awaiter(void 0, void 0, void 0, function* () {
81
+ clientInstance['request'] = jest
82
+ .fn()
83
+ .mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
84
+ try {
85
+ yield clientInstance.createClusterDefinition(Object.assign(Object.assign({}, fixtures_js_1.clusterConfigV1X7), { deposit_amounts: ['34000000'] }));
86
+ }
87
+ catch (error) {
88
+ expect(error.message).toEqual('Schema compilation errors\', must pass "validDepositAmounts" keyword validation');
89
+ }
90
+ }));
72
91
  test('validatePayload should throw an error on empty schema', () => __awaiter(void 0, void 0, void 0, function* () {
73
92
  try {
74
- (0, ajv_1.validatePayload)(Object.assign(Object.assign({}, fixtures_js_1.clusterConfigV1X7), { operators: [] }), '');
93
+ (0, ajv_1.validatePayload)(Object.assign(Object.assign({}, fixtures_js_1.clusterConfigV1X8), { operators: [] }), '');
75
94
  }
76
95
  catch (error) {
77
96
  expect(error.message).toEqual('schema must be object or boolean');
78
97
  }
79
98
  }));
80
99
  test('getClusterdefinition should return cluster definition if config hash exist', () => __awaiter(void 0, void 0, void 0, function* () {
100
+ var _c;
81
101
  clientInstance['request'] = jest
82
102
  .fn()
83
- .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X7.cluster_definition));
84
- const clusterDefinition = yield clientInstance.getClusterDefinition(fixtures_js_1.clusterLockV1X7.cluster_definition.config_hash);
85
- expect(clusterDefinition.config_hash).toEqual(fixtures_js_1.clusterLockV1X7.cluster_definition.config_hash);
103
+ .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X8.cluster_definition));
104
+ const clusterDefinition = yield clientInstance.getClusterDefinition(fixtures_js_1.clusterLockV1X8.cluster_definition.config_hash);
105
+ expect((_c = clusterDefinition.deposit_amounts) === null || _c === void 0 ? void 0 : _c.length).toEqual(fixtures_js_1.clusterLockV1X8.cluster_definition.deposit_amounts.length);
106
+ expect(clusterDefinition.config_hash).toEqual(fixtures_js_1.clusterLockV1X8.cluster_definition.config_hash);
86
107
  }));
87
108
  test('getClusterLock should return lockFile if exist', () => __awaiter(void 0, void 0, void 0, function* () {
88
109
  clientInstance['request'] = jest
89
110
  .fn()
90
- .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X7));
91
- const clusterLock = yield clientInstance.getClusterLock(fixtures_js_1.clusterLockV1X7.cluster_definition.config_hash);
92
- expect(clusterLock.lock_hash).toEqual(fixtures_js_1.clusterLockV1X7.lock_hash);
111
+ .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X8));
112
+ const clusterLock = yield clientInstance.getClusterLock(fixtures_js_1.clusterLockV1X8.cluster_definition.config_hash);
113
+ expect(clusterLock.lock_hash).toEqual(fixtures_js_1.clusterLockV1X8.lock_hash);
93
114
  }));
94
115
  test('request method should set user agent header', () => __awaiter(void 0, void 0, void 0, function* () {
95
116
  const server = (0, node_1.setupServer)(msw_1.http.get('http://testexample.com/test', ({ request }) => {
@@ -106,7 +127,9 @@ describe('Cluster Client', () => {
106
127
  });
107
128
  }
108
129
  }
109
- const testBaseInstance = new TestBase({ baseUrl: 'http://testExample.com' });
130
+ const testBaseInstance = new TestBase({
131
+ baseUrl: 'http://testExample.com',
132
+ });
110
133
  const result = yield testBaseInstance.callProtectedRequest('/test', {
111
134
  method: 'GET',
112
135
  });
@@ -121,7 +144,7 @@ describe('Cluster Client without a signer', () => {
121
144
  });
122
145
  test('createClusterDefinition should throw an error without signer', () => __awaiter(void 0, void 0, void 0, function* () {
123
146
  try {
124
- yield clientInstance.createClusterDefinition(fixtures_js_1.clusterConfigV1X7);
147
+ yield clientInstance.createClusterDefinition(fixtures_js_1.clusterConfigV1X8);
125
148
  }
126
149
  catch (err) {
127
150
  expect(err.message).toEqual('Signer is required in createClusterDefinition');
@@ -130,9 +153,9 @@ describe('Cluster Client without a signer', () => {
130
153
  test('acceptClusterDefinition should throw an error without signer', () => __awaiter(void 0, void 0, void 0, function* () {
131
154
  try {
132
155
  yield clientInstance.acceptClusterDefinition({
133
- enr: fixtures_js_1.clusterLockV1X7.cluster_definition.operators[0].enr,
134
- version: fixtures_js_1.clusterLockV1X7.cluster_definition.version,
135
- }, fixtures_js_1.clusterLockV1X7.cluster_definition.config_hash);
156
+ enr: fixtures_js_1.clusterLockV1X8.cluster_definition.operators[0].enr,
157
+ version: fixtures_js_1.clusterLockV1X8.cluster_definition.version,
158
+ }, fixtures_js_1.clusterLockV1X8.cluster_definition.config_hash);
136
159
  }
137
160
  catch (err) {
138
161
  expect(err.message).toEqual('Signer is required in acceptClusterDefinition');
@@ -141,23 +164,27 @@ describe('Cluster Client without a signer', () => {
141
164
  test('getClusterdefinition should return cluster definition if config hash exist', () => __awaiter(void 0, void 0, void 0, function* () {
142
165
  clientInstance['request'] = jest
143
166
  .fn()
144
- .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X7.cluster_definition));
145
- const clusterDefinition = yield clientInstance.getClusterDefinition(fixtures_js_1.clusterLockV1X7.cluster_definition.config_hash);
146
- expect(clusterDefinition.config_hash).toEqual(fixtures_js_1.clusterLockV1X7.cluster_definition.config_hash);
167
+ .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X8.cluster_definition));
168
+ const clusterDefinition = yield clientInstance.getClusterDefinition(fixtures_js_1.clusterLockV1X8.cluster_definition.config_hash);
169
+ expect(clusterDefinition.config_hash).toEqual(fixtures_js_1.clusterLockV1X8.cluster_definition.config_hash);
147
170
  }));
148
171
  test('getClusterLock should return lockFile if exist', () => __awaiter(void 0, void 0, void 0, function* () {
149
172
  clientInstance['request'] = jest
150
173
  .fn()
151
- .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X7));
152
- const clusterLock = yield clientInstance.getClusterLock(fixtures_js_1.clusterLockV1X7.cluster_definition.config_hash);
153
- expect(clusterLock.lock_hash).toEqual(fixtures_js_1.clusterLockV1X7.lock_hash);
174
+ .mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X8));
175
+ const clusterLock = yield clientInstance.getClusterLock(fixtures_js_1.clusterLockV1X8.cluster_definition.config_hash);
176
+ expect(clusterLock.lock_hash).toEqual(fixtures_js_1.clusterLockV1X8.lock_hash);
154
177
  }));
155
- test.each([{ version: 'v1.6.0', clusterLock: fixtures_js_1.clusterLockV1X6 }, { version: 'v1.7.0', clusterLock: fixtures_js_1.clusterLockV1X7 }, { version: 'v1.8.0', clusterLock: fixtures_js_1.clusterLockV1X8 }])('$version: \'should return true on verified cluster lock\'', (_a) => __awaiter(void 0, [_a], void 0, function* ({ clusterLock }) {
178
+ test.each([
179
+ { version: 'v1.6.0', clusterLock: fixtures_js_1.clusterLockV1X6 },
180
+ { version: 'v1.7.0', clusterLock: fixtures_js_1.clusterLockV1X7 },
181
+ { version: 'v1.8.0', clusterLock: fixtures_js_1.clusterLockV1X8 },
182
+ ])("$version: 'should return true on verified cluster lock'", ({ clusterLock }) => __awaiter(void 0, void 0, void 0, function* () {
156
183
  const isValidLock = yield (0, index_1.validateClusterLock)(clusterLock);
157
184
  expect(isValidLock).toEqual(true);
158
185
  }));
159
186
  test('Finds the hash of the latest version of terms and conditions', () => __awaiter(void 0, void 0, void 0, function* () {
160
187
  const termsAndConditionsHash = yield (0, termsAndConditions_1.hashTermsAndConditions)();
161
- expect(termsAndConditionsHash).toEqual('0x0015d01710b4d864004320a4826f6846c2db12a7f056a126fa5ae16c0b5e2b65');
188
+ expect(termsAndConditionsHash).toEqual('0xd33721644e8f3afab1495a74abe3523cec12d48b8da6cb760972492ca3f1a273');
162
189
  }));
163
190
  });
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@obolnetwork/obol-sdk",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
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"
@@ -1,7 +1,34 @@
1
1
  import Ajv from 'ajv';
2
+ import { parseUnits } from 'ethers';
3
+ function validDepositAmounts(data, deposits) {
4
+ let sum = 0;
5
+ // from ether togwei is same as from gwei to wei
6
+ const maxDeposit = Number(parseUnits('32', 'gwei'));
7
+ const minDeposit = Number(parseUnits('1', 'gwei'));
8
+ for (const element of deposits) {
9
+ const amountInGWei = Number(element);
10
+ if (!Number.isInteger(amountInGWei) ||
11
+ amountInGWei > maxDeposit ||
12
+ amountInGWei < minDeposit) {
13
+ return false;
14
+ }
15
+ sum += amountInGWei;
16
+ }
17
+ if (sum / minDeposit !== 32) {
18
+ return false;
19
+ }
20
+ else {
21
+ return true;
22
+ }
23
+ }
2
24
  export function validatePayload(data, schema) {
3
25
  var _a;
4
26
  const ajv = new Ajv();
27
+ ajv.addKeyword({
28
+ keyword: 'validDepositAmounts',
29
+ validate: validDepositAmounts,
30
+ errors: true,
31
+ });
5
32
  const validate = ajv.compile(schema);
6
33
  const isValid = validate(data);
7
34
  if (!isValid) {
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  // src/resources/base.ts
11
- import { DEFAULT_BASE_URL, DEFAULT_CHAIN_ID, SDK_VERSION } from './constants.js';
11
+ import { DEFAULT_BASE_URL, DEFAULT_CHAIN_ID, SDK_VERSION, } from './constants.js';
12
12
  import { FORK_MAPPING } from './types.js';
13
13
  export class Base {
14
14
  constructor({ baseUrl = DEFAULT_BASE_URL, chainId = DEFAULT_CHAIN_ID, }) {
@@ -9,7 +9,7 @@ export const TermsAndConditionsSigningTypes = {
9
9
  TermsAndConditions: [
10
10
  { name: 'terms_and_conditions_hash', type: 'string' },
11
11
  { name: 'version', type: 'uint256' },
12
- ]
12
+ ],
13
13
  };
14
14
  const EIP712Domain = [
15
15
  { name: 'name', type: 'string' },
@@ -73,7 +73,7 @@ export const signEnrPayload = (payload, chainId) => {
73
73
  };
74
74
  };
75
75
  export const DKG_ALGORITHM = 'default';
76
- export const CONFIG_VERSION = 'v1.7.0';
76
+ export const CONFIG_VERSION = 'v1.8.0';
77
77
  export const SDK_VERSION = pjson.version;
78
78
  export const DOMAIN_APPLICATION_BUILDER = '00000001';
79
79
  export const DOMAIN_DEPOSIT = '03000000';
@@ -86,7 +86,11 @@ export var DefinitionFlow;
86
86
  DefinitionFlow["Charon"] = "Charon-Command";
87
87
  })(DefinitionFlow || (DefinitionFlow = {}));
88
88
  export const DEFAULT_BASE_URL = 'https://api.obol.tech';
89
+ export const DEFAULT_BASE_VERSION = 'v1';
89
90
  export const DEFAULT_CHAIN_ID = 17000;
90
91
  export const ETHER_TO_GWEI = 10 ** 9;
91
92
  export const TERMS_AND_CONDITIONS_VERSION = 1;
92
- export const TERMS_AND_CONDITIONS_URL = (TERMS_AND_CONDITIONS_VERSION === 1) ? 'https://obol.tech/terms.pdf' : `https://obol.tech/${TERMS_AND_CONDITIONS_VERSION}/terms.pdf`;
93
+ export const TERMS_AND_CONDITIONS_URL = TERMS_AND_CONDITIONS_VERSION === 1
94
+ ? 'https://obol.org/terms.pdf'
95
+ : `https://obol.org/${TERMS_AND_CONDITIONS_VERSION}/terms.pdf`;
96
+ export const TERMS_AND_CONDITIONS_HASH = '0xd33721644e8f3afab1495a74abe3523cec12d48b8da6cb760972492ca3f1a273';
@@ -9,12 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { v4 as uuidv4 } from 'uuid';
11
11
  import { Base } from './base.js';
12
- import { CONFLICT_ERROR_MSG, CreatorConfigHashSigningTypes, Domain, DKG_ALGORITHM, CONFIG_VERSION, OperatorConfigHashSigningTypes, EnrSigningTypes, TERMS_AND_CONDITIONS_VERSION, TermsAndConditionsSigningTypes, } from './constants.js';
12
+ import { CONFLICT_ERROR_MSG, CreatorConfigHashSigningTypes, Domain, DKG_ALGORITHM, CONFIG_VERSION, OperatorConfigHashSigningTypes, EnrSigningTypes, TERMS_AND_CONDITIONS_VERSION, TermsAndConditionsSigningTypes, DEFAULT_BASE_VERSION, TERMS_AND_CONDITIONS_HASH, } from './constants.js';
13
13
  import { ConflictError } from './errors.js';
14
14
  import { clusterConfigOrDefinitionHash } from './verification/common.js';
15
15
  import { validatePayload } from './ajv.js';
16
16
  import { definitionSchema, operatorPayloadSchema } from './schema.js';
17
- import { hashTermsAndConditions } from './verification/termsAndConditions.js';
18
17
  export * from './types.js';
19
18
  export * from './services.js';
20
19
  /**
@@ -49,18 +48,18 @@ export class Client extends Base {
49
48
  throw new Error('Signer is required in acceptObolTermsAndConditions');
50
49
  }
51
50
  try {
52
- const termsAndConditionsHash = yield hashTermsAndConditions();
51
+ const termsAndConditionsHash = TERMS_AND_CONDITIONS_HASH;
53
52
  const address = yield this.signer.getAddress();
54
53
  const termsAndConditionsPayload = {
55
54
  address,
56
55
  version: TERMS_AND_CONDITIONS_VERSION,
57
- terms_and_conditions_hash: termsAndConditionsHash
56
+ terms_and_conditions_hash: termsAndConditionsHash,
58
57
  };
59
58
  const termsAndConditionsSignature = yield this.signer.signTypedData(Domain(), TermsAndConditionsSigningTypes, {
60
59
  terms_and_conditions_hash: termsAndConditionsHash,
61
60
  version: TERMS_AND_CONDITIONS_VERSION,
62
61
  });
63
- const termsAndConditionsResponse = yield this.request('/termsAndConditions', {
62
+ const termsAndConditionsResponse = yield this.request(`/${DEFAULT_BASE_VERSION}/termsAndConditions`, {
64
63
  method: 'POST',
65
64
  body: JSON.stringify(termsAndConditionsPayload),
66
65
  headers: {
@@ -92,13 +91,15 @@ export class Client extends Base {
92
91
  throw new Error('Signer is required in createClusterDefinition');
93
92
  }
94
93
  validatePayload(newCluster, definitionSchema);
95
- const clusterConfig = Object.assign(Object.assign({}, newCluster), { fork_version: this.fork_version, dkg_algorithm: DKG_ALGORITHM, version: CONFIG_VERSION, uuid: uuidv4(), timestamp: new Date().toISOString(), threshold: Math.ceil((2 * newCluster.operators.length) / 3), num_validators: newCluster.validators.length });
94
+ const clusterConfig = Object.assign(Object.assign({}, newCluster), { fork_version: this.fork_version, dkg_algorithm: DKG_ALGORITHM, version: CONFIG_VERSION, uuid: uuidv4(), timestamp: new Date().toISOString(), threshold: Math.ceil((2 * newCluster.operators.length) / 3), num_validators: newCluster.validators.length, deposit_amounts: newCluster.deposit_amounts
95
+ ? newCluster.deposit_amounts
96
+ : ['32000000000'] });
96
97
  try {
97
98
  const address = yield this.signer.getAddress();
98
99
  clusterConfig.creator = { address };
99
100
  clusterConfig.config_hash = clusterConfigOrDefinitionHash(clusterConfig, true);
100
101
  const creatorConfigSignature = yield this.signer.signTypedData(Domain(this.chainId), CreatorConfigHashSigningTypes, { creator_config_hash: clusterConfig.config_hash });
101
- const clusterDefinition = yield this.request('/v1/definition', {
102
+ const clusterDefinition = yield this.request(`/${DEFAULT_BASE_VERSION}/definition`, {
102
103
  method: 'POST',
103
104
  body: JSON.stringify(clusterConfig),
104
105
  headers: {
@@ -137,7 +138,7 @@ export class Client extends Base {
137
138
  const operatorConfigSignature = yield this.signer.signTypedData(Domain(this.chainId), OperatorConfigHashSigningTypes, { operator_config_hash: configHash });
138
139
  const operatorENRSignature = yield this.signer.signTypedData(Domain(this.chainId), EnrSigningTypes, { enr: operatorPayload.enr });
139
140
  const operatorData = Object.assign(Object.assign({}, operatorPayload), { address, enr_signature: operatorENRSignature, fork_version: this.fork_version });
140
- const clusterDefinition = yield this.request(`/v1/definition/${configHash}`, {
141
+ const clusterDefinition = yield this.request(`/${DEFAULT_BASE_VERSION}/definition/${configHash}`, {
141
142
  method: 'PUT',
142
143
  body: JSON.stringify(operatorData),
143
144
  headers: {
@@ -161,7 +162,7 @@ export class Client extends Base {
161
162
  */
162
163
  getClusterDefinition(configHash) {
163
164
  return __awaiter(this, void 0, void 0, function* () {
164
- const clusterDefinition = yield this.request(`/dv/${configHash}`, {
165
+ const clusterDefinition = yield this.request(`/${DEFAULT_BASE_VERSION}/definition/${configHash}`, {
165
166
  method: 'GET',
166
167
  });
167
168
  return clusterDefinition;
@@ -177,7 +178,7 @@ export class Client extends Base {
177
178
  */
178
179
  getClusterLock(configHash) {
179
180
  return __awaiter(this, void 0, void 0, function* () {
180
- const lock = yield this.request(`/lock/configHash/${configHash}`, {
181
+ const lock = yield this.request(`/${DEFAULT_BASE_VERSION}/lock/configHash/${configHash}`, {
181
182
  method: 'GET',
182
183
  });
183
184
  return lock;
@@ -52,6 +52,14 @@ export const definitionSchema = {
52
52
  required: ['fee_recipient_address', 'withdrawal_address'],
53
53
  },
54
54
  },
55
+ deposit_amounts: {
56
+ type: 'array',
57
+ items: {
58
+ type: 'string',
59
+ pattern: '^[0-9]+$',
60
+ },
61
+ validDepositAmounts: true,
62
+ },
55
63
  },
56
64
  required: ['name', 'operators', 'validators'],
57
65
  };
@@ -8,7 +8,7 @@ export const strToUint8Array = (str) => {
8
8
  export const definitionFlow = (clusterDefinition) => {
9
9
  if (clusterDefinition.creator.address &&
10
10
  clusterDefinition.creator.config_signature &&
11
- clusterDefinition.operators.every((operator) => {
11
+ clusterDefinition.operators.every(operator => {
12
12
  return (operator.address &&
13
13
  operator.config_signature &&
14
14
  operator.enr &&
@@ -18,7 +18,7 @@ export const definitionFlow = (clusterDefinition) => {
18
18
  }
19
19
  else if (clusterDefinition.creator.address &&
20
20
  clusterDefinition.creator.config_signature &&
21
- clusterDefinition.operators.every((operator) => {
21
+ clusterDefinition.operators.every(operator => {
22
22
  return (!operator.address &&
23
23
  !operator.config_signature &&
24
24
  operator.enr &&
@@ -28,7 +28,7 @@ export const definitionFlow = (clusterDefinition) => {
28
28
  }
29
29
  else if (!clusterDefinition.creator.address &&
30
30
  !clusterDefinition.creator.config_signature &&
31
- clusterDefinition.operators.every((operator) => {
31
+ clusterDefinition.operators.every(operator => {
32
32
  return (!operator.address &&
33
33
  !operator.config_signature &&
34
34
  operator.enr &&
@@ -7,20 +7,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { fromHexString, } from '@chainsafe/ssz';
10
+ import { fromHexString } from '@chainsafe/ssz';
11
11
  import elliptic from 'elliptic';
12
- import { init, } from '@chainsafe/bls';
13
- import { FORK_MAPPING } from '../types.js';
12
+ import { init } from '@chainsafe/bls';
13
+ import { FORK_MAPPING, } from '../types.js';
14
14
  import * as semver from 'semver';
15
- import { clusterDefinitionContainerTypeV1X6, hashClusterDefinitionV1X6, hashClusterLockV1X6, verifyDVV1X6 } from './v1.6.0.js';
16
- import { clusterDefinitionContainerTypeV1X7, hashClusterDefinitionV1X7, hashClusterLockV1X7, verifyDVV1X7 } from './v1.7.0.js';
15
+ import { clusterDefinitionContainerTypeV1X6, hashClusterDefinitionV1X6, hashClusterLockV1X6, verifyDVV1X6, } from './v1.6.0.js';
16
+ import { clusterDefinitionContainerTypeV1X7, hashClusterDefinitionV1X7, hashClusterLockV1X7, verifyDVV1X7, } from './v1.7.0.js';
17
17
  import { ethers } from 'ethers';
18
- import { DOMAIN_APPLICATION_BUILDER, DOMAIN_DEPOSIT, DefinitionFlow, GENESIS_VALIDATOR_ROOT, signCreatorConfigHashPayload, signEnrPayload, signOperatorConfigHashPayload } from '../constants.js';
18
+ import { DOMAIN_APPLICATION_BUILDER, DOMAIN_DEPOSIT, DefinitionFlow, GENESIS_VALIDATOR_ROOT, signCreatorConfigHashPayload, signEnrPayload, signOperatorConfigHashPayload, } from '../constants.js';
19
19
  import { SignTypedDataVersion, TypedDataUtils } from '@metamask/eth-sig-util';
20
- import { builderRegistrationMessageType, depositMessageType, forkDataType, signingRootType } from './sszTypes.js';
20
+ import { builderRegistrationMessageType, depositMessageType, forkDataType, signingRootType, } from './sszTypes.js';
21
21
  import { definitionFlow, hexWithout0x } from '../utils.js';
22
22
  import { ENR } from '@chainsafe/discv5';
23
- import { clusterDefinitionContainerTypeV1X8, hashClusterDefinitionV1X8, hashClusterLockV1X8, verifyDVV1X8 } from './v1.8.0.js';
23
+ import { clusterDefinitionContainerTypeV1X8, hashClusterDefinitionV1X8, hashClusterLockV1X8, verifyDVV1X8, } from './v1.8.0.js';
24
24
  // cluster-definition hash
25
25
  /**
26
26
  * @param cluster The cluster configuration or the cluster definition
@@ -32,17 +32,20 @@ export const clusterConfigOrDefinitionHash = (cluster, configOnly) => {
32
32
  if (semver.eq(cluster.version, 'v1.6.0')) {
33
33
  definitionType = clusterDefinitionContainerTypeV1X6(configOnly);
34
34
  val = hashClusterDefinitionV1X6(cluster, configOnly);
35
- return ('0x' + Buffer.from(definitionType.hashTreeRoot(val).buffer).toString('hex'));
35
+ return ('0x' +
36
+ Buffer.from(definitionType.hashTreeRoot(val).buffer).toString('hex'));
36
37
  }
37
38
  if (semver.eq(cluster.version, 'v1.7.0')) {
38
39
  definitionType = clusterDefinitionContainerTypeV1X7(configOnly);
39
40
  val = hashClusterDefinitionV1X7(cluster, configOnly);
40
- return ('0x' + Buffer.from(definitionType.hashTreeRoot(val).buffer).toString('hex'));
41
+ return ('0x' +
42
+ Buffer.from(definitionType.hashTreeRoot(val).buffer).toString('hex'));
41
43
  }
42
44
  if (semver.eq(cluster.version, 'v1.8.0')) {
43
45
  definitionType = clusterDefinitionContainerTypeV1X8(configOnly);
44
46
  val = hashClusterDefinitionV1X8(cluster, configOnly);
45
- return ('0x' + Buffer.from(definitionType.hashTreeRoot(val).buffer).toString('hex'));
47
+ return ('0x' +
48
+ Buffer.from(definitionType.hashTreeRoot(val).buffer).toString('hex'));
46
49
  }
47
50
  throw new Error('unsupported version');
48
51
  };
@@ -112,7 +115,7 @@ const verifyDefinitionSignatures = (clusterDefinition, definitionType) => {
112
115
  if (definitionType === DefinitionFlow.Solo) {
113
116
  return true;
114
117
  }
115
- return clusterDefinition.operators.every((operator) => {
118
+ return clusterDefinition.operators.every(operator => {
116
119
  const configSigner = getPUTConfigHashSigner(operator.config_signature, clusterDefinition.config_hash, FORK_MAPPING[clusterDefinition.fork_version]);
117
120
  const enrSigner = getEnrSigner(operator.enr_signature, operator.enr, FORK_MAPPING[clusterDefinition.fork_version]);
118
121
  if (configSigner !== operator.address.toLowerCase() ||
@@ -188,15 +191,24 @@ export const verifyBuilderRegistration = (validator, feeRecipientAddress, forkVe
188
191
  const builderDomain = computeDomain(fromHexString(DOMAIN_APPLICATION_BUILDER), forkVersion);
189
192
  if (validator.distributed_public_key !==
190
193
  ((_a = validator.builder_registration) === null || _a === void 0 ? void 0 : _a.message.pubkey)) {
191
- return { isValidBuilderRegistration: false, builderRegistrationMsg: new Uint8Array(0) };
194
+ return {
195
+ isValidBuilderRegistration: false,
196
+ builderRegistrationMsg: new Uint8Array(0),
197
+ };
192
198
  }
193
199
  if (feeRecipientAddress.toLowerCase() !==
194
200
  validator.builder_registration.message.fee_recipient.toLowerCase()) {
195
- return { isValidBuilderRegistration: false, builderRegistrationMsg: new Uint8Array(0) };
201
+ return {
202
+ isValidBuilderRegistration: false,
203
+ builderRegistrationMsg: new Uint8Array(0),
204
+ };
196
205
  }
197
206
  const builderRegistrationMessageBuffer = computebuilderRegistrationMsgRoot(validator.builder_registration.message);
198
207
  const builderRegistrationMessage = signingRoot(builderDomain, builderRegistrationMessageBuffer);
199
- return { isValidBuilderRegistration: true, builderRegistrationMsg: builderRegistrationMessage };
208
+ return {
209
+ isValidBuilderRegistration: true,
210
+ builderRegistrationMsg: builderRegistrationMessage,
211
+ };
200
212
  };
201
213
  export const verifyNodeSignatures = (clusterLock) => {
202
214
  const ec = new elliptic.ec('secp256k1');
@@ -1,4 +1,4 @@
1
- import { ByteListType, ByteVectorType, ContainerType, UintNumberType } from '@chainsafe/ssz';
1
+ import { ByteListType, ByteVectorType, ContainerType, UintNumberType, } from '@chainsafe/ssz';
2
2
  export const operatorAddressWrapperType = new ContainerType({
3
3
  address: new ByteVectorType(20),
4
4
  });
@@ -23,7 +23,7 @@ export const hashTermsAndConditions = () => __awaiter(void 0, void 0, void 0, fu
23
23
  terms_and_conditions_hash: new ByteListType(Number.MAX_SAFE_INTEGER),
24
24
  });
25
25
  const termsHasVal = termsType.defaultValue();
26
- termsHasVal.terms_and_conditions_hash = strToUint8Array(data === null || data === void 0 ? void 0 : data.text);
26
+ termsHasVal.terms_and_conditions_hash = strToUint8Array(data === null || data === void 0 ? void 0 : data.text.replace(/[^a-zA-Z0-9]/g, ''));
27
27
  return ('0x' +
28
28
  Buffer.from(termsType.hashTreeRoot(termsHasVal).buffer).toString('hex'));
29
29
  }
@@ -1,9 +1,9 @@
1
- import { UintNumberType } from '@chainsafe/ssz/lib/type/uint';
1
+ import { UintNumberType, } from '@chainsafe/ssz/lib/type/uint';
2
2
  import { strToUint8Array } from '../utils';
3
- import { newCreatorContainerType, newOperatorContainerType, validatorsContainerType } from './sszTypes';
4
- import { ByteListType, ByteVectorType, ContainerType, ListCompositeType, fromHexString } from '@chainsafe/ssz';
3
+ import { newCreatorContainerType, newOperatorContainerType, validatorsContainerType, } from './sszTypes';
4
+ import { ByteListType, ByteVectorType, ContainerType, ListCompositeType, fromHexString, } from '@chainsafe/ssz';
5
5
  import { verifyDepositData } from './common';
6
- import { aggregateSignatures, verifyAggregate, verifyMultiple } from '@chainsafe/bls';
6
+ import { aggregateSignatures, verifyAggregate, verifyMultiple, } from '@chainsafe/bls';
7
7
  /**
8
8
  * Returns the containerized cluster definition
9
9
  * @param cluster ClusterDefinition to calculate the type from
@@ -56,7 +56,7 @@ export const hashClusterDefinitionV1X6 = (cluster, configOnly) => {
56
56
  address: fromHexString(cluster.creator.address),
57
57
  config_signature: fromHexString(cluster.creator.config_signature),
58
58
  };
59
- val.validators = cluster.validators.map((validator) => {
59
+ val.validators = cluster.validators.map(validator => {
60
60
  return {
61
61
  fee_recipient_address: fromHexString(validator.fee_recipient_address),
62
62
  withdrawal_address: fromHexString(validator.withdrawal_address),
@@ -1,9 +1,9 @@
1
- import { UintNumberType } from '@chainsafe/ssz/lib/type/uint';
1
+ import { UintNumberType, } from '@chainsafe/ssz/lib/type/uint';
2
2
  import { strToUint8Array } from '../utils';
3
- import { builderRegistrationContainer, depositDataContainer, newCreatorContainerType, newOperatorContainerType, validatorsContainerType } from './sszTypes';
4
- import { ByteListType, ByteVectorType, ContainerType, ListCompositeType, fromHexString } from '@chainsafe/ssz';
5
- import { verifyBuilderRegistration, verifyDepositData, verifyNodeSignatures } from './common';
6
- import { aggregateSignatures, verifyAggregate, verifyMultiple } from '@chainsafe/bls';
3
+ import { builderRegistrationContainer, depositDataContainer, newCreatorContainerType, newOperatorContainerType, validatorsContainerType, } from './sszTypes';
4
+ import { ByteListType, ByteVectorType, ContainerType, ListCompositeType, fromHexString, } from '@chainsafe/ssz';
5
+ import { verifyBuilderRegistration, verifyDepositData, verifyNodeSignatures, } from './common';
6
+ import { aggregateSignatures, verifyAggregate, verifyMultiple, } from '@chainsafe/bls';
7
7
  /**
8
8
  * Returns the containerized cluster definition
9
9
  * @param cluster ClusterDefinition to calculate the type from
@@ -56,7 +56,7 @@ export const hashClusterDefinitionV1X7 = (cluster, configOnly) => {
56
56
  address: fromHexString(cluster.creator.address),
57
57
  config_signature: fromHexString(cluster.creator.config_signature),
58
58
  };
59
- val.validators = cluster.validators.map((validator) => {
59
+ val.validators = cluster.validators.map(validator => {
60
60
  return {
61
61
  fee_recipient_address: fromHexString(validator.fee_recipient_address),
62
62
  withdrawal_address: fromHexString(validator.withdrawal_address),
@@ -92,11 +92,11 @@ export const hashClusterLockV1X7 = (cluster) => {
92
92
  const val = lockType.defaultValue();
93
93
  // Check if we can replace with definition_hash
94
94
  val.cluster_definition = hashClusterDefinitionV1X7(cluster.cluster_definition, false);
95
- val.distributed_validators = cluster.distributed_validators.map((dValidator) => {
95
+ val.distributed_validators = cluster.distributed_validators.map(dValidator => {
96
96
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
97
97
  return {
98
98
  distributed_public_key: fromHexString(dValidator.distributed_public_key),
99
- public_shares: dValidator.public_shares.map((publicShare) => fromHexString(publicShare)),
99
+ public_shares: dValidator.public_shares.map(publicShare => fromHexString(publicShare)),
100
100
  deposit_data: {
101
101
  pubkey: fromHexString((_a = dValidator.deposit_data) === null || _a === void 0 ? void 0 : _a.pubkey),
102
102
  withdrawal_credentials: fromHexString((_b = dValidator.deposit_data) === null || _b === void 0 ? void 0 : _b.withdrawal_credentials),
@@ -1,9 +1,9 @@
1
- import { UintNumberType } from '@chainsafe/ssz/lib/type/uint';
1
+ import { UintNumberType, } from '@chainsafe/ssz/lib/type/uint';
2
2
  import { strToUint8Array } from '../utils';
3
- import { builderRegistrationContainer, depositDataContainer, newCreatorContainerType, newOperatorContainerType, validatorsContainerType } from './sszTypes';
4
- import { ByteListType, ByteVectorType, ContainerType, ListBasicType, ListCompositeType, fromHexString } from '@chainsafe/ssz';
5
- import { verifyBuilderRegistration, verifyDepositData, verifyNodeSignatures } from './common';
6
- import { aggregateSignatures, verifyAggregate, verifyMultiple } from '@chainsafe/bls';
3
+ import { builderRegistrationContainer, depositDataContainer, newCreatorContainerType, newOperatorContainerType, validatorsContainerType, } from './sszTypes';
4
+ import { ByteListType, ByteVectorType, ContainerType, ListBasicType, ListCompositeType, fromHexString, } from '@chainsafe/ssz';
5
+ import { verifyBuilderRegistration, verifyDepositData, verifyNodeSignatures, } from './common';
6
+ import { aggregateSignatures, verifyAggregate, verifyMultiple, } from '@chainsafe/bls';
7
7
  /**
8
8
  * Returns the containerized cluster definition
9
9
  * @param cluster ClusterDefinition to calculate the type from
@@ -57,7 +57,7 @@ export const hashClusterDefinitionV1X8 = (cluster, configOnly) => {
57
57
  address: fromHexString(cluster.creator.address),
58
58
  config_signature: fromHexString(cluster.creator.config_signature),
59
59
  };
60
- val.validators = cluster.validators.map((validator) => {
60
+ val.validators = cluster.validators.map(validator => {
61
61
  return {
62
62
  fee_recipient_address: fromHexString(validator.fee_recipient_address),
63
63
  withdrawal_address: fromHexString(validator.withdrawal_address),
@@ -140,8 +140,8 @@ export const verifyDVV1X8 = (clusterLock) => {
140
140
  pubShares.push(fromHexString(element));
141
141
  }
142
142
  // Deposit Data Verification
143
- for (let j = 0; j < validator.partial_deposit_data.length; j++) {
144
- const depositData = validator.partial_deposit_data[j];
143
+ for (const element of validator.partial_deposit_data) {
144
+ const depositData = element;
145
145
  const { isValidDepositData, depositDataMsg } = verifyDepositData(distributedPublicKey, depositData, clusterLock.cluster_definition.validators[i].withdrawal_address, clusterLock.cluster_definition.fork_version);
146
146
  if (!isValidDepositData) {
147
147
  return false;