@obolnetwork/obol-sdk 1.0.15 → 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 (52) 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 +21 -18
  6. package/dist/cjs/src/schema.js +8 -0
  7. package/dist/cjs/src/services.js +1 -1
  8. package/dist/cjs/src/utils.js +3 -3
  9. package/dist/cjs/src/verification/common.js +19 -7
  10. package/dist/cjs/src/verification/termsAndConditions.js +1 -1
  11. package/dist/cjs/src/verification/v1.6.0.js +1 -1
  12. package/dist/cjs/src/verification/v1.7.0.js +3 -3
  13. package/dist/cjs/src/verification/v1.8.0.js +3 -3
  14. package/dist/cjs/test/fixtures.js +71 -82
  15. package/dist/cjs/test/methods.test.js +54 -27
  16. package/dist/esm/package.json +11 -6
  17. package/dist/esm/src/ajv.js +27 -0
  18. package/dist/esm/src/base.js +1 -1
  19. package/dist/esm/src/constants.js +7 -3
  20. package/dist/esm/src/index.js +22 -19
  21. package/dist/esm/src/schema.js +8 -0
  22. package/dist/esm/src/services.js +1 -1
  23. package/dist/esm/src/utils.js +3 -3
  24. package/dist/esm/src/verification/common.js +27 -15
  25. package/dist/esm/src/verification/sszTypes.js +1 -1
  26. package/dist/esm/src/verification/termsAndConditions.js +1 -1
  27. package/dist/esm/src/verification/v1.6.0.js +5 -5
  28. package/dist/esm/src/verification/v1.7.0.js +8 -8
  29. package/dist/esm/src/verification/v1.8.0.js +8 -8
  30. package/dist/esm/test/fixtures.js +71 -82
  31. package/dist/esm/test/methods.test.js +55 -28
  32. package/dist/types/src/constants.d.ts +3 -1
  33. package/dist/types/src/index.d.ts +11 -9
  34. package/dist/types/src/schema.d.ts +8 -0
  35. package/dist/types/src/services.d.ts +1 -1
  36. package/dist/types/src/types.d.ts +18 -18
  37. package/package.json +12 -7
  38. package/src/ajv.ts +38 -7
  39. package/src/base.ts +22 -18
  40. package/src/constants.ts +42 -36
  41. package/src/errors.ts +4 -4
  42. package/src/index.ts +96 -84
  43. package/src/schema.ts +10 -2
  44. package/src/services.ts +7 -7
  45. package/src/types.ts +65 -65
  46. package/src/utils.ts +17 -17
  47. package/src/verification/common.ts +374 -333
  48. package/src/verification/sszTypes.ts +60 -51
  49. package/src/verification/termsAndConditions.ts +16 -14
  50. package/src/verification/v1.6.0.ts +214 -184
  51. package/src/verification/v1.7.0.ts +268 -233
  52. package/src/verification/v1.8.0.ts +266 -225
@@ -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";
@@ -23,11 +23,13 @@ export declare class Client extends Base {
23
23
  chainId?: number;
24
24
  }, signer?: Signer);
25
25
  /**
26
- * Accepts Obol terms and conditions to be able to create or update data.
27
- * @returns {Promise<string>} terms and conditions acceptance success message.
28
- * @throws On unverified signature or wrong hash.
29
- *
30
- */
26
+ * Accepts Obol terms and conditions to be able to create or update data.
27
+ * @returns {Promise<string>} terms and conditions acceptance success message.
28
+ * @throws On unverified signature or wrong hash.
29
+ *
30
+ * An example of how to use acceptObolLatestTermsAndConditions:
31
+ * [acceptObolLatestTermsAndConditions](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L44)
32
+ */
31
33
  acceptObolLatestTermsAndConditions(): Promise<string>;
32
34
  /**
33
35
  * Creates a cluster definition which contains cluster configuration.
@@ -36,7 +38,7 @@ export declare class Client extends Base {
36
38
  * @throws On duplicate entries, missing or wrong cluster keys.
37
39
  *
38
40
  * An example of how to use createClusterDefinition:
39
- * [createObolCluster](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
41
+ * [createObolCluster](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L59)
40
42
  */
41
43
  createClusterDefinition(newCluster: ClusterPayload): Promise<string>;
42
44
  /**
@@ -47,7 +49,7 @@ export declare class Client extends Base {
47
49
  * @throws On unauthorized, duplicate entries, missing keys, not found cluster or invalid data.
48
50
  *
49
51
  * An example of how to use acceptClusterDefinition:
50
- * [acceptClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
52
+ * [acceptClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L106)
51
53
  */
52
54
  acceptClusterDefinition(operatorPayload: OperatorPayload, configHash: string): Promise<ClusterDefinition>;
53
55
  /**
@@ -56,7 +58,7 @@ export declare class Client extends Base {
56
58
  * @throws On not found config hash.
57
59
  *
58
60
  * An example of how to use getClusterDefinition:
59
- * [getObolClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
61
+ * [getObolClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L74)
60
62
  */
61
63
  getClusterDefinition(configHash: string): Promise<ClusterDefinition>;
62
64
  /**
@@ -65,7 +67,7 @@ export declare class Client extends Base {
65
67
  * @throws On not found cluster definition or lock.
66
68
  *
67
69
  * An example of how to use getClusterLock:
68
- * [getObolClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
70
+ * [getObolClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L89)
69
71
  */
70
72
  getClusterLock(configHash: string): Promise<ClusterLock>;
71
73
  }
@@ -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
  };
@@ -6,6 +6,6 @@ import { type ClusterLock } from './types.js';
6
6
  * @throws on missing keys or values.
7
7
  *
8
8
  * An example of how to use validateClusterLock:
9
- * [validateClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
9
+ * [validateClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L127)
10
10
  */
11
11
  export declare const validateClusterLock: (lock: ClusterLock) => Promise<boolean>;
@@ -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.15",
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"
@@ -128,4 +133,4 @@
128
133
  ".ts"
129
134
  ]
130
135
  }
131
- }
136
+ }
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
  }
package/src/base.ts CHANGED
@@ -1,31 +1,35 @@
1
1
  // src/resources/base.ts
2
- import { DEFAULT_BASE_URL, DEFAULT_CHAIN_ID, SDK_VERSION } from './constants.js'
3
- import { FORK_MAPPING } from './types.js'
2
+ import {
3
+ DEFAULT_BASE_URL,
4
+ DEFAULT_CHAIN_ID,
5
+ SDK_VERSION,
6
+ } from './constants.js';
7
+ import { FORK_MAPPING } from './types.js';
4
8
 
5
9
  interface Config {
6
- baseUrl?: string
7
- chainId?: FORK_MAPPING
10
+ baseUrl?: string;
11
+ chainId?: FORK_MAPPING;
8
12
  }
9
13
 
10
14
  export abstract class Base {
11
- baseUrl: string
12
- chainId: number
13
- fork_version: string
15
+ baseUrl: string;
16
+ chainId: number;
17
+ fork_version: string;
14
18
 
15
- constructor ({
19
+ constructor({
16
20
  baseUrl = DEFAULT_BASE_URL,
17
21
  chainId = DEFAULT_CHAIN_ID,
18
22
  }: Config) {
19
- this.baseUrl = baseUrl
20
- this.chainId = chainId
21
- this.fork_version = FORK_MAPPING[this.chainId]
23
+ this.baseUrl = baseUrl;
24
+ this.chainId = chainId;
25
+ this.fork_version = FORK_MAPPING[this.chainId];
22
26
  }
23
27
 
24
28
  protected async request<T>(
25
29
  endpoint: string,
26
30
  options?: RequestInit,
27
31
  ): Promise<T> {
28
- const url = `${this.baseUrl}${endpoint}`
32
+ const url = `${this.baseUrl}${endpoint}`;
29
33
  const config = {
30
34
  ...options,
31
35
  headers: {
@@ -33,18 +37,18 @@ export abstract class Base {
33
37
  'User-Agent': `Obol-SDK/${SDK_VERSION}`,
34
38
  ...options?.headers,
35
39
  },
36
- }
40
+ };
37
41
 
38
42
  try {
39
- const response = await fetch(url, config)
43
+ const response = await fetch(url, config);
40
44
  if (response.ok) {
41
- return await response.json()
45
+ return await response.json();
42
46
  } else {
43
- const errorResponse = await response.json()
44
- throw errorResponse
47
+ const errorResponse = await response.json();
48
+ throw errorResponse;
45
49
  }
46
50
  } catch (e: any) {
47
- throw e
51
+ throw e;
48
52
  }
49
53
  }
50
54
  }