@obolnetwork/obol-sdk 2.4.5 → 2.5.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 (56) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/package.json +4 -2
  3. package/dist/cjs/src/ajv.js +67 -41
  4. package/dist/cjs/src/constants.js +1 -1
  5. package/dist/cjs/src/incentiveHelpers.js +2 -4
  6. package/dist/cjs/src/incentives.js +1 -1
  7. package/dist/cjs/src/index.js +25 -27
  8. package/dist/cjs/src/schema.js +50 -23
  9. package/dist/cjs/src/services.js +3 -2
  10. package/dist/cjs/src/utils.js +4 -4
  11. package/dist/cjs/src/verification/common.js +12 -9
  12. package/dist/cjs/src/verification/signature-validator.js +6 -5
  13. package/dist/cjs/src/verification/v1.8.0.js +18 -0
  14. package/dist/cjs/test/fixtures.js +125 -17
  15. package/dist/cjs/test/incentives.test.js +2 -2
  16. package/dist/cjs/test/methods.test.js +47 -42
  17. package/dist/esm/package.json +4 -2
  18. package/dist/esm/src/ajv.js +66 -40
  19. package/dist/esm/src/constants.js +1 -1
  20. package/dist/esm/src/incentiveHelpers.js +2 -4
  21. package/dist/esm/src/incentives.js +1 -1
  22. package/dist/esm/src/index.js +26 -28
  23. package/dist/esm/src/schema.js +50 -23
  24. package/dist/esm/src/services.js +3 -2
  25. package/dist/esm/src/utils.js +4 -4
  26. package/dist/esm/src/verification/common.js +12 -9
  27. package/dist/esm/src/verification/signature-validator.js +6 -5
  28. package/dist/esm/src/verification/v1.8.0.js +18 -0
  29. package/dist/esm/test/fixtures.js +124 -16
  30. package/dist/esm/test/incentives.test.js +2 -2
  31. package/dist/esm/test/methods.test.js +48 -43
  32. package/dist/types/src/ajv.d.ts +3 -2
  33. package/dist/types/src/constants.d.ts +1 -1
  34. package/dist/types/src/incentiveHelpers.d.ts +1 -1
  35. package/dist/types/src/incentives.d.ts +2 -2
  36. package/dist/types/src/index.d.ts +1 -0
  37. package/dist/types/src/schema.d.ts +40 -8
  38. package/dist/types/src/services.d.ts +3 -2
  39. package/dist/types/src/types.d.ts +16 -6
  40. package/dist/types/src/utils.d.ts +1 -1
  41. package/dist/types/src/verification/common.d.ts +2 -2
  42. package/dist/types/src/verification/signature-validator.d.ts +5 -2
  43. package/dist/types/test/fixtures.d.ts +78 -11
  44. package/package.json +4 -2
  45. package/src/ajv.ts +91 -52
  46. package/src/constants.ts +1 -1
  47. package/src/incentiveHelpers.ts +1 -5
  48. package/src/incentives.ts +3 -4
  49. package/src/index.ts +37 -35
  50. package/src/schema.ts +45 -22
  51. package/src/services.ts +4 -2
  52. package/src/types.ts +20 -5
  53. package/src/utils.ts +7 -4
  54. package/src/verification/common.ts +13 -1
  55. package/src/verification/signature-validator.ts +10 -3
  56. package/src/verification/v1.8.0.ts +24 -0
@@ -10,10 +10,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  var _a, _b;
11
11
  import { ethers, JsonRpcProvider } from 'ethers';
12
12
  import { Client, validateClusterLock } from '../src/index';
13
- import { clusterConfigV1X7, clusterConfigV1X8, clusterLockV1X10, clusterLockV1X6, clusterLockV1X7, clusterLockV1X8, clusterLockWithCompoundingWithdrawals, clusterLockWithSafe, nullDepositAmountsClusterLockV1X8, } from './fixtures.js';
13
+ import { clusterConfigV1X7, clusterConfigV1X10, clusterLockV1X10, clusterLockV1X6, clusterLockV1X7, clusterLockV1X8, clusterLockWithCompoundingWithdrawals, clusterLockWithSafe, nullDepositAmountsClusterLockV1X8, } from './fixtures.js';
14
14
  import { SDK_VERSION } from '../src/constants';
15
15
  import { Base } from '../src/base';
16
- import { validatePayload } from '../src/ajv';
17
16
  import { HttpResponse, http } from 'msw';
18
17
  import { setupServer } from 'msw/node';
19
18
  import { hashTermsAndConditions } from '../src/verification/termsAndConditions';
@@ -40,31 +39,31 @@ describe('Cluster Client', () => {
40
39
  clientInstance['request'] = jest
41
40
  .fn()
42
41
  .mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
43
- const configHash = yield clientInstance.createClusterDefinition(clusterConfigV1X8);
42
+ const configHash = yield clientInstance.createClusterDefinition(clusterConfigV1X10);
44
43
  expect(configHash).toEqual(mockConfigHash);
45
44
  }));
46
45
  test('acceptClusterDefinition should return cluster definition', () => __awaiter(void 0, void 0, void 0, function* () {
47
46
  clientInstance['request'] = jest
48
47
  .fn()
49
- .mockReturnValue(Promise.resolve(clusterLockV1X8.cluster_definition));
48
+ .mockReturnValue(Promise.resolve(clusterLockV1X10.cluster_definition));
50
49
  const clusterDefinition = yield clientInstance.acceptClusterDefinition({
51
- enr: clusterLockV1X8.cluster_definition.operators[0].enr,
52
- version: clusterLockV1X8.cluster_definition.version,
53
- }, clusterLockV1X8.cluster_definition.config_hash);
54
- expect(clusterDefinition).toEqual(clusterLockV1X8.cluster_definition);
50
+ enr: clusterLockV1X10.cluster_definition.operators[0].enr,
51
+ version: clusterLockV1X10.cluster_definition.version,
52
+ }, clusterLockV1X10.cluster_definition.config_hash);
53
+ expect(clusterDefinition).toEqual(clusterLockV1X10.cluster_definition);
55
54
  }));
56
55
  test('createClusterDefinition should throw an error on invalid operators', () => __awaiter(void 0, void 0, void 0, function* () {
57
56
  clientInstance['request'] = jest
58
57
  .fn()
59
58
  .mockReturnValue(Promise.resolve({ config_hash: mockConfigHash }));
60
59
  try {
61
- yield clientInstance.createClusterDefinition(Object.assign(Object.assign({}, clusterConfigV1X8), { operators: [] }));
60
+ yield clientInstance.createClusterDefinition(Object.assign(Object.assign({}, clusterConfigV1X10), { operators: [] }));
62
61
  }
63
62
  catch (error) {
64
- expect(error.message).toEqual("Schema compilation errors', must NOT have fewer than 4 items");
63
+ expect(error.message).toEqual('Validation failed: /operators must pass "validateUniqueAddresses" keyword validation, /operators must NOT have fewer than 4 items');
65
64
  }
66
65
  }));
67
- // cause we default to 32000000000
66
+ // cause we default to null
68
67
  test('createClusterDefinition should accept a configuration without deposit_amounts', () => __awaiter(void 0, void 0, void 0, function* () {
69
68
  clientInstance['request'] = jest
70
69
  .fn()
@@ -80,32 +79,27 @@ describe('Cluster Client', () => {
80
79
  yield clientInstance.createClusterDefinition(Object.assign(Object.assign({}, clusterConfigV1X7), { deposit_amounts: ['34000000'] }));
81
80
  }
82
81
  catch (error) {
83
- expect(error.message).toEqual('Schema compilation errors\', must pass "validDepositAmounts" keyword validation');
84
- }
85
- }));
86
- test('validatePayload should throw an error on empty schema', () => __awaiter(void 0, void 0, void 0, function* () {
87
- try {
88
- validatePayload(Object.assign(Object.assign({}, clusterConfigV1X8), { operators: [] }), '');
89
- }
90
- catch (error) {
91
- expect(error.message).toEqual('schema must be object or boolean');
82
+ expect(error.message).toEqual('Validation failed: /deposit_amounts/0 must be equal to one of the allowed values, /deposit_amounts must match "then" schema');
92
83
  }
93
84
  }));
94
85
  test('getClusterdefinition should return cluster definition if config hash exist', () => __awaiter(void 0, void 0, void 0, function* () {
95
- var _a;
96
86
  clientInstance['request'] = jest
97
87
  .fn()
98
- .mockReturnValue(Promise.resolve(clusterLockV1X8.cluster_definition));
99
- const clusterDefinition = yield clientInstance.getClusterDefinition(clusterLockV1X8.cluster_definition.config_hash);
100
- expect((_a = clusterDefinition.deposit_amounts) === null || _a === void 0 ? void 0 : _a.length).toEqual(clusterLockV1X8.cluster_definition.deposit_amounts.length);
101
- expect(clusterDefinition.config_hash).toEqual(clusterLockV1X8.cluster_definition.config_hash);
88
+ .mockReturnValue(Promise.resolve(clusterLockV1X10.cluster_definition));
89
+ const clusterDefinition = yield clientInstance.getClusterDefinition(clusterLockV1X10.cluster_definition.config_hash);
90
+ expect(clusterDefinition.deposit_amounts).toBeDefined();
91
+ expect(clusterDefinition.config_hash).toEqual(clusterLockV1X10.cluster_definition.config_hash);
92
+ // Test for new fields
93
+ expect(clusterDefinition.compounding).toBeDefined();
94
+ expect(clusterDefinition.target_gas_limit).toBeDefined();
95
+ expect(clusterDefinition.consensus_protocol).toBeDefined();
102
96
  }));
103
97
  test('getClusterLock should return lockFile if exist', () => __awaiter(void 0, void 0, void 0, function* () {
104
98
  clientInstance['request'] = jest
105
99
  .fn()
106
- .mockReturnValue(Promise.resolve(clusterLockV1X8));
107
- const clusterLock = yield clientInstance.getClusterLock(clusterLockV1X8.cluster_definition.config_hash);
108
- expect(clusterLock.lock_hash).toEqual(clusterLockV1X8.lock_hash);
100
+ .mockReturnValue(Promise.resolve(clusterLockV1X10));
101
+ const clusterLock = yield clientInstance.getClusterLock(clusterLockV1X10.cluster_definition.config_hash);
102
+ expect(clusterLock.lock_hash).toEqual(clusterLockV1X10.lock_hash);
109
103
  }));
110
104
  test('request method should set user agent header', () => __awaiter(void 0, void 0, void 0, function* () {
111
105
  const server = setupServer(http.get('http://testexample.com/test', ({ request }) => {
@@ -140,9 +134,12 @@ describe('Cluster Client without a signer', () => {
140
134
  beforeAll(() => {
141
135
  jest.restoreAllMocks();
142
136
  });
137
+ beforeEach(() => {
138
+ jest.resetModules();
139
+ });
143
140
  test('createClusterDefinition should throw an error without signer', () => __awaiter(void 0, void 0, void 0, function* () {
144
141
  try {
145
- yield clientInstance.createClusterDefinition(clusterConfigV1X8);
142
+ yield clientInstance.createClusterDefinition(clusterConfigV1X10);
146
143
  }
147
144
  catch (err) {
148
145
  expect(err.message).toEqual('Signer is required in createClusterDefinition');
@@ -151,9 +148,9 @@ describe('Cluster Client without a signer', () => {
151
148
  test('acceptClusterDefinition should throw an error without signer', () => __awaiter(void 0, void 0, void 0, function* () {
152
149
  try {
153
150
  yield clientInstance.acceptClusterDefinition({
154
- enr: clusterLockV1X8.cluster_definition.operators[0].enr,
155
- version: clusterLockV1X8.cluster_definition.version,
156
- }, clusterLockV1X8.cluster_definition.config_hash);
151
+ enr: clusterLockV1X10.cluster_definition.operators[0].enr,
152
+ version: clusterLockV1X10.cluster_definition.version,
153
+ }, clusterLockV1X10.cluster_definition.config_hash);
157
154
  }
158
155
  catch (err) {
159
156
  expect(err.message).toEqual('Signer is required in acceptClusterDefinition');
@@ -162,16 +159,16 @@ describe('Cluster Client without a signer', () => {
162
159
  test('getClusterdefinition should return cluster definition if config hash exist', () => __awaiter(void 0, void 0, void 0, function* () {
163
160
  clientInstance['request'] = jest
164
161
  .fn()
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);
162
+ .mockReturnValue(Promise.resolve(clusterLockV1X10.cluster_definition));
163
+ const clusterDefinition = yield clientInstance.getClusterDefinition(clusterLockV1X10.cluster_definition.config_hash);
164
+ expect(clusterDefinition.config_hash).toEqual(clusterLockV1X10.cluster_definition.config_hash);
168
165
  }));
169
166
  test('getClusterLock should return lockFile if exist', () => __awaiter(void 0, void 0, void 0, function* () {
170
167
  clientInstance['request'] = jest
171
168
  .fn()
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);
169
+ .mockReturnValue(Promise.resolve(clusterLockV1X10));
170
+ const clusterLock = yield clientInstance.getClusterLock(clusterLockV1X10.cluster_definition.config_hash);
171
+ expect(clusterLock.lock_hash).toEqual(clusterLockV1X10.lock_hash);
175
172
  }));
176
173
  test.each([
177
174
  { version: 'v1.6.0', clusterLock: clusterLockV1X6 },
@@ -194,6 +191,14 @@ describe('Cluster Client without a signer', () => {
194
191
  const isValidLock = yield validateClusterLock(clusterLock);
195
192
  expect(isValidLock).toEqual(true);
196
193
  }));
194
+ test('should return true on verified cluster lock with Safe wallet and safe rpc url', () => __awaiter(void 0, void 0, void 0, function* () {
195
+ process.env.RPC_HOLESKY = undefined;
196
+ /* eslint-disable @typescript-eslint/no-var-requires */
197
+ const { validateClusterLock: validateLockWithRpcUrl, } = require('../src/index');
198
+ const safeRpcUrl = 'https://ethereum-holesky-rpc.publicnode.com';
199
+ const isValidLock = yield validateLockWithRpcUrl(clusterLockWithSafe, safeRpcUrl);
200
+ expect(isValidLock).toEqual(true);
201
+ }));
197
202
  test('validateCluster should return false for cluster with null deposit_amounts and incorrect partial_deposits', () => __awaiter(void 0, void 0, void 0, function* () {
198
203
  const partialDeposit = nullDepositAmountsClusterLockV1X8.distributed_validators[0]
199
204
  .partial_deposit_data[0];
@@ -270,7 +275,7 @@ describe('createObolRewardsSplit', () => {
270
275
  });
271
276
  }
272
277
  catch (error) {
273
- expect(error.message).toEqual('Schema compilation errors\', must pass "validateSplitRecipients" keyword validation');
278
+ expect(error.message).toEqual('Validation failed: must pass "validateRewardsSplitRecipients" keyword validation');
274
279
  }
275
280
  }));
276
281
  test('should throw an error if ObolRAFSplit is less than 1', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -283,7 +288,7 @@ describe('createObolRewardsSplit', () => {
283
288
  });
284
289
  }
285
290
  catch (error) {
286
- expect(error.message).toEqual("Schema compilation errors', must be >= 1");
291
+ expect(error.message).toEqual('Validation failed: must pass "validateRewardsSplitRecipients" keyword validation, /ObolRAFSplit must be >= 1');
287
292
  }
288
293
  }));
289
294
  it('should return the correct withdrawal and fee recipient addresses', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -350,7 +355,7 @@ describe('createObolTotalSplit', () => {
350
355
  });
351
356
  }
352
357
  catch (error) {
353
- expect(error.message).toEqual('Schema compilation errors\', must pass "validateSplitRecipients" keyword validation');
358
+ expect(error.message).toEqual('Validation failed: must pass "validateTotalSplitRecipients" keyword validation');
354
359
  }
355
360
  }));
356
361
  test('should throw an error if ObolRAFSplit is less than 0.1', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -361,13 +366,13 @@ describe('createObolTotalSplit', () => {
361
366
  });
362
367
  }
363
368
  catch (error) {
364
- expect(error.message).toEqual("Schema compilation errors', must be >= 0.1");
369
+ expect(error.message).toEqual('Validation failed: must pass "validateTotalSplitRecipients" keyword validation, /ObolRAFSplit must be >= 0.1');
365
370
  }
366
371
  }));
367
372
  it('should return the correct withdrawal and fee recipient addresses and ObolRAFSplit', () => __awaiter(void 0, void 0, void 0, function* () {
368
373
  const result = yield clientInstance.createObolTotalSplit({
369
374
  splitRecipients: mockSplitRecipients,
370
- ObolRAFSplit: 0.5,
375
+ ObolRAFSplit: 0.1,
371
376
  });
372
377
  // 0xPredictedAddress and not 0xSplitterAddress since were mocking isContractAvailable response to be true
373
378
  expect(result).toEqual({
@@ -1,2 +1,3 @@
1
- import { type ErrorObject } from 'ajv';
2
- export declare function validatePayload(data: any, schema: any): ErrorObject[] | undefined | null | boolean;
1
+ export declare const VALID_DEPOSIT_AMOUNTS: string[];
2
+ export declare const VALID_NON_COMPOUNDING_AMOUNTS: string[];
3
+ export declare function validatePayload<T>(data: unknown, schema: object): T;
@@ -69,7 +69,7 @@ export declare const signEnrPayload: (payload: {
69
69
  enr: string;
70
70
  }, chainId: number) => TypedMessage<typeof ENRTypedMessage>;
71
71
  export declare const DKG_ALGORITHM = "default";
72
- export declare const CONFIG_VERSION = "v1.8.0";
72
+ export declare const CONFIG_VERSION = "v1.10.0";
73
73
  export declare const SDK_VERSION: string;
74
74
  export declare const DOMAIN_APPLICATION_BUILDER = "00000001";
75
75
  export declare const DOMAIN_DEPOSIT = "03000000";
@@ -9,4 +9,4 @@ export declare const claimIncentivesFromMerkleDistributor: (incentivesData: {
9
9
  }) => Promise<{
10
10
  txHash: string;
11
11
  }>;
12
- export declare const isClaimedFromMerkleDistributor: (chainId: number, contractAddress: ETH_ADDRESS, index: number, provider: ProviderType | undefined | null) => Promise<boolean>;
12
+ export declare const isClaimedFromMerkleDistributor: (contractAddress: ETH_ADDRESS, index: number, provider: ProviderType | undefined | null) => Promise<boolean>;
@@ -1,4 +1,4 @@
1
- import { type Incentives as IncentivesType, type ETH_ADDRESS, type ProviderType, type SignerType, type ClaimIncentivesResponse } from './types';
1
+ import { type ClaimableIncentives, type ETH_ADDRESS, type ProviderType, type SignerType, type ClaimIncentivesResponse } from './types';
2
2
  /**
3
3
  * Incentives can be used for fetching and claiming Obol incentives.
4
4
  * @class
@@ -53,5 +53,5 @@ export declare class Incentives {
53
53
  * An example of how to use getIncentivesByAddress:
54
54
  * [obolClient](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L250)
55
55
  */
56
- getIncentivesByAddress(address: string): Promise<IncentivesType>;
56
+ getIncentivesByAddress(address: string): Promise<ClaimableIncentives>;
57
57
  }
@@ -5,6 +5,7 @@ export * from './types.js';
5
5
  export * from './services.js';
6
6
  export * from './verification/signature-validator.js';
7
7
  export * from './verification/common.js';
8
+ export * from './constants.js';
8
9
  export { Incentives } from './incentives.js';
9
10
  /**
10
11
  * Obol sdk Client can be used for creating, managing and activating distributed validators.
@@ -19,18 +19,16 @@ export declare const definitionSchema: {
19
19
  operators: {
20
20
  type: string;
21
21
  minItems: number;
22
- uniqueItems: boolean;
23
22
  items: {
24
23
  type: string;
25
24
  properties: {
26
25
  address: {
27
26
  type: string;
28
- minLength: number;
29
- maxLength: number;
30
27
  };
31
28
  };
32
29
  required: string[];
33
30
  };
31
+ validateUniqueAddresses: boolean;
34
32
  };
35
33
  validators: {
36
34
  type: string;
@@ -51,12 +49,39 @@ export declare const definitionSchema: {
51
49
  };
52
50
  };
53
51
  deposit_amounts: {
54
- type: string;
52
+ type: string[];
55
53
  items: {
56
54
  type: string;
57
55
  pattern: string;
58
56
  };
59
- validDepositAmounts: boolean;
57
+ if: {
58
+ $data: string;
59
+ };
60
+ then: {
61
+ items: {
62
+ enum: string[];
63
+ };
64
+ };
65
+ else: {
66
+ items: {
67
+ enum: string[];
68
+ };
69
+ };
70
+ default: null;
71
+ };
72
+ compounding: {
73
+ type: string;
74
+ default: boolean;
75
+ };
76
+ target_gas_limit: {
77
+ type: string;
78
+ minimum: number;
79
+ default: number;
80
+ };
81
+ consensus_protocol: {
82
+ type: string;
83
+ enum: string[];
84
+ default: string;
60
85
  };
61
86
  };
62
87
  required: string[];
@@ -83,29 +108,35 @@ export declare const totalSplitterPayloadSchema: {
83
108
  ObolRAFSplit: {
84
109
  type: string;
85
110
  minimum: number;
111
+ default: number;
86
112
  };
87
113
  distributorFee: {
88
114
  type: string;
89
115
  maximum: number;
90
116
  multipleOf: number;
117
+ default: number;
91
118
  };
92
119
  controllerAddress: {
93
120
  type: string;
94
121
  pattern: string;
122
+ default: string;
95
123
  };
96
- validateSplitRecipients: boolean;
97
124
  };
125
+ validateTotalSplitRecipients: boolean;
98
126
  required: string[];
99
127
  };
100
128
  export declare const rewardsSplitterPayloadSchema: {
129
+ type: string;
101
130
  properties: {
102
131
  ObolRAFSplit: {
103
132
  type: string;
104
133
  minimum: number;
134
+ default: number;
105
135
  };
106
136
  recoveryAddress: {
107
137
  type: string;
108
138
  pattern: string;
139
+ default: string;
109
140
  };
110
141
  etherAmount: {
111
142
  type: string;
@@ -134,13 +165,14 @@ export declare const rewardsSplitterPayloadSchema: {
134
165
  type: string;
135
166
  maximum: number;
136
167
  multipleOf: number;
168
+ default: number;
137
169
  };
138
170
  controllerAddress: {
139
171
  type: string;
140
172
  pattern: string;
173
+ default: string;
141
174
  };
142
- validateSplitRecipients: boolean;
143
175
  };
176
+ validateRewardsSplitRecipients: boolean;
144
177
  required: string[];
145
- type: string;
146
178
  };
@@ -1,11 +1,12 @@
1
- import { type ClusterLock } from './types.js';
1
+ import { type SafeRpcUrl, type ClusterLock } from './types.js';
2
2
  /**
3
3
  * Verifies Cluster Lock's validity.
4
4
  * @param lock - cluster lock
5
+ * @param safeRpcUrl - optional safeRpcUrl for safe wallet verification
5
6
  * @returns {Promise<{ result: boolean }> } boolean result to indicate if lock is valid
6
7
  * @throws on missing keys or values.
7
8
  *
8
9
  * An example of how to use validateClusterLock:
9
10
  * [validateClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L127)
10
11
  */
11
- export declare const validateClusterLock: (lock: ClusterLock) => Promise<boolean>;
12
+ export declare const validateClusterLock: (lock: ClusterLock, safeRpcUrl?: SafeRpcUrl) => Promise<boolean>;
@@ -1,4 +1,4 @@
1
- import { type ethers, type JsonRpcApiProvider, type JsonRpcProvider, type JsonRpcSigner, type Provider, type Signer } from 'ethers';
1
+ import { type Wallet, type ethers, type JsonRpcApiProvider, type JsonRpcProvider, type JsonRpcSigner, type Provider, type Signer } from 'ethers';
2
2
  /**
3
3
  * Permitted ChainID's
4
4
  */
@@ -68,6 +68,12 @@ export type ClusterPayload = {
68
68
  validators: ClusterValidator[];
69
69
  /** The cluster partial deposits in gwei or 32000000000. */
70
70
  deposit_amounts?: string[] | null;
71
+ /** A withdrawal mechanism with 0x02 withdrawal credentials. */
72
+ compounding?: boolean;
73
+ /** The target gas limit where default is 36M. */
74
+ target_gas_limit?: number;
75
+ /** The consensus protocol e.g qbft. */
76
+ consensus_protocol?: string;
71
77
  };
72
78
  /**
73
79
  * Cluster definition data needed for dkg
@@ -95,7 +101,7 @@ export interface ClusterDefinition extends ClusterPayload {
95
101
  definition_hash?: string;
96
102
  /** The consensus protocol e.g qbft. */
97
103
  consensus_protocol?: string;
98
- /** The target gas limit where default is 30M. */
104
+ /** The target gas limit where default is 36M. */
99
105
  target_gas_limit?: number;
100
106
  /** A withdrawal mechanism with 0x02 withdrawal credentials. */
101
107
  compounding?: boolean;
@@ -212,14 +218,14 @@ export type ClusterLock = {
212
218
  node_signatures?: string[];
213
219
  };
214
220
  /**
215
- * Incentives
221
+ * Claimable Obol Incentives
216
222
  */
217
- export type Incentives = {
223
+ export type ClaimableIncentives = {
218
224
  /** Operator Address. */
219
225
  operator_address: string;
220
226
  /** The amount the recipient is entitled to. */
221
227
  amount: string;
222
- /** The recipients index in the Merkle tree. */
228
+ /** The recipient's index in the Merkle tree. */
223
229
  index: number;
224
230
  /** The Merkle proof (an array of hashes) generated for the recipient. */
225
231
  merkle_proof: string[];
@@ -234,10 +240,14 @@ export type ETH_ADDRESS = string;
234
240
  * Provider Types
235
241
  */
236
242
  export type ProviderType = Provider | JsonRpcProvider | JsonRpcApiProvider | ethers.BrowserProvider;
243
+ /**
244
+ * Safe Wallet Provider Types
245
+ */
246
+ export type SafeRpcUrl = string;
237
247
  /**
238
248
  * Signer Types
239
249
  */
240
- export type SignerType = Signer | JsonRpcSigner;
250
+ export type SignerType = Signer | JsonRpcSigner | Wallet;
241
251
  /**
242
252
  * claimIncentives Response
243
253
  */
@@ -6,4 +6,4 @@ export declare const strToUint8Array: (str: string) => Uint8Array;
6
6
  export declare const definitionFlow: (clusterDefinition: ClusterDefinition) => DefinitionFlow | null;
7
7
  export declare const findDeployedBytecode: (contractAddress: string, provider: ProviderType) => Promise<string>;
8
8
  export declare const isContractAvailable: (contractAddress: string, provider: ProviderType, bytecode?: string) => Promise<boolean>;
9
- export declare const getProvider: (chainId: number) => ethers.JsonRpcProvider;
9
+ export declare const getProvider: (chainId: number, rpcUrl?: string) => ethers.JsonRpcProvider;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- import { type ClusterDefinition, type ClusterLock, type DepositData, type DistributedValidator } from '../types.js';
2
+ import { type ClusterDefinition, type ClusterLock, type DepositData, type DistributedValidator, type SafeRpcUrl } from '../types.js';
3
3
  /**
4
4
  * @param cluster The cluster configuration or the cluster definition
5
5
  * @param configOnly a boolean to indicate config hash or definition hash
@@ -29,4 +29,4 @@ export declare const verifyBuilderRegistration: (validator: DistributedValidator
29
29
  };
30
30
  export declare const verifyNodeSignatures: (clusterLock: ClusterLock) => boolean;
31
31
  export declare const signingRoot: (domain: Uint8Array, messageBuffer: Buffer) => Uint8Array;
32
- export declare const isValidClusterLock: (clusterLock: ClusterLock) => Promise<boolean>;
32
+ export declare const isValidClusterLock: (clusterLock: ClusterLock, safeRpcUrl?: SafeRpcUrl) => Promise<boolean>;
@@ -1,19 +1,22 @@
1
1
  import { type TypedMessage } from '@metamask/eth-sig-util';
2
2
  import { type EIP712TypedData } from '@safe-global/safe-core-sdk-types';
3
- export declare const validateAddressSignature: ({ address, token, data, chainId, }: {
3
+ import { type SafeRpcUrl } from '../types';
4
+ export declare const validateAddressSignature: ({ address, token, data, chainId, safeRpcUrl, }: {
4
5
  address: string;
5
6
  token: string;
6
7
  data: TypedMessage<any>;
7
8
  chainId: number;
9
+ safeRpcUrl?: string | undefined;
8
10
  }) => Promise<boolean>;
9
11
  export declare const validateEOASignature: ({ token, data, address, }: {
10
12
  token: string;
11
13
  data: TypedMessage<any>;
12
14
  address: string;
13
15
  }) => boolean;
14
- export declare const validateSmartContractSignature: ({ token, data, address, chainId, }: {
16
+ export declare const validateSmartContractSignature: ({ token, data, address, chainId, safeRpcUrl, }: {
15
17
  token: string;
16
18
  data: EIP712TypedData;
17
19
  address: string;
18
20
  chainId: number;
21
+ safeRpcUrl?: string | undefined;
19
22
  }) => Promise<boolean>;
@@ -99,17 +99,6 @@ export declare const clusterLockV1X7: {
99
99
  lock_hash: string;
100
100
  node_signatures: string[];
101
101
  };
102
- export declare const clusterConfigV1X8: {
103
- name: string;
104
- operators: {
105
- address: string;
106
- }[];
107
- validators: {
108
- fee_recipient_address: string;
109
- withdrawal_address: string;
110
- }[];
111
- deposit_amounts: string[];
112
- };
113
102
  export declare const clusterLockV1X8: {
114
103
  cluster_definition: {
115
104
  name: string;
@@ -263,6 +252,30 @@ export declare const clusterLockWithSafe: {
263
252
  lock_hash: string;
264
253
  node_signatures: string[];
265
254
  };
255
+ export declare const clusterConfigV1X10: {
256
+ name: string;
257
+ operators: {
258
+ address: string;
259
+ }[];
260
+ validators: {
261
+ fee_recipient_address: string;
262
+ withdrawal_address: string;
263
+ }[];
264
+ deposit_amounts: string[];
265
+ compounding: boolean;
266
+ target_gas_limit: number;
267
+ consensus_protocol: string;
268
+ };
269
+ export declare const soloClusterConfigV1X10: {
270
+ name: string;
271
+ operators: {
272
+ address: string;
273
+ }[];
274
+ validators: {
275
+ fee_recipient_address: string;
276
+ withdrawal_address: string;
277
+ }[];
278
+ };
266
279
  export declare const clusterLockV1X10: {
267
280
  cluster_definition: {
268
281
  name: string;
@@ -371,3 +384,57 @@ export declare const clusterLockWithCompoundingWithdrawals: {
371
384
  lock_hash: string;
372
385
  node_signatures: string[];
373
386
  };
387
+ export declare const clusterLockWithCompoundingWithdrawalss: {
388
+ cluster_definition: {
389
+ name: string;
390
+ creator: {
391
+ address: string;
392
+ config_signature: string;
393
+ };
394
+ operators: {
395
+ address: string;
396
+ enr: string;
397
+ config_signature: string;
398
+ enr_signature: string;
399
+ }[];
400
+ uuid: string;
401
+ version: string;
402
+ timestamp: string;
403
+ num_validators: number;
404
+ threshold: number;
405
+ validators: {
406
+ fee_recipient_address: string;
407
+ withdrawal_address: string;
408
+ }[];
409
+ dkg_algorithm: string;
410
+ fork_version: string;
411
+ deposit_amounts: string[];
412
+ consensus_protocol: string;
413
+ target_gas_limit: number;
414
+ compounding: boolean;
415
+ config_hash: string;
416
+ definition_hash: string;
417
+ };
418
+ distributed_validators: {
419
+ distributed_public_key: string;
420
+ public_shares: string[];
421
+ builder_registration: {
422
+ message: {
423
+ fee_recipient: string;
424
+ gas_limit: number;
425
+ timestamp: number;
426
+ pubkey: string;
427
+ };
428
+ signature: string;
429
+ };
430
+ partial_deposit_data: {
431
+ pubkey: string;
432
+ withdrawal_credentials: string;
433
+ amount: string;
434
+ signature: string;
435
+ }[];
436
+ }[];
437
+ signature_aggregate: string;
438
+ lock_hash: string;
439
+ node_signatures: string[];
440
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obolnetwork/obol-sdk",
3
- "version": "2.4.5",
3
+ "version": "2.5.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"
@@ -49,6 +49,8 @@
49
49
  "@safe-global/safe-core-sdk-types": "5.1.0",
50
50
  "@types/pdf-parse": "^1.1.4",
51
51
  "ajv": "^8.12.0",
52
+ "ajv-formats": "^3.0.1",
53
+ "ajv-keywords": "^5.1.0",
52
54
  "cross-fetch": "^3.1.5",
53
55
  "dotenv": "^16.4.7",
54
56
  "elliptic": "^6.5.4",
@@ -56,7 +58,7 @@
56
58
  "eslint-plugin-import": "^2.29.1",
57
59
  "eslint-plugin-n": "^16.6.2",
58
60
  "eslint-plugin-promise": "^6.1.1",
59
- "ethers": "6.4.0",
61
+ "ethers": "^6.13.5",
60
62
  "nock": "^13.5.3",
61
63
  "pdf-parse": "^1.1.1",
62
64
  "semver": "^7.6.0",