@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.
- package/README.md +1 -1
- package/dist/cjs/package.json +4 -2
- package/dist/cjs/src/ajv.js +67 -41
- package/dist/cjs/src/constants.js +1 -1
- package/dist/cjs/src/incentiveHelpers.js +2 -4
- package/dist/cjs/src/incentives.js +1 -1
- package/dist/cjs/src/index.js +25 -27
- package/dist/cjs/src/schema.js +50 -23
- package/dist/cjs/src/services.js +3 -2
- package/dist/cjs/src/utils.js +4 -4
- package/dist/cjs/src/verification/common.js +12 -9
- package/dist/cjs/src/verification/signature-validator.js +6 -5
- package/dist/cjs/src/verification/v1.8.0.js +18 -0
- package/dist/cjs/test/fixtures.js +125 -17
- package/dist/cjs/test/incentives.test.js +2 -2
- package/dist/cjs/test/methods.test.js +47 -42
- package/dist/esm/package.json +4 -2
- package/dist/esm/src/ajv.js +66 -40
- package/dist/esm/src/constants.js +1 -1
- package/dist/esm/src/incentiveHelpers.js +2 -4
- package/dist/esm/src/incentives.js +1 -1
- package/dist/esm/src/index.js +26 -28
- package/dist/esm/src/schema.js +50 -23
- package/dist/esm/src/services.js +3 -2
- package/dist/esm/src/utils.js +4 -4
- package/dist/esm/src/verification/common.js +12 -9
- package/dist/esm/src/verification/signature-validator.js +6 -5
- package/dist/esm/src/verification/v1.8.0.js +18 -0
- package/dist/esm/test/fixtures.js +124 -16
- package/dist/esm/test/incentives.test.js +2 -2
- package/dist/esm/test/methods.test.js +48 -43
- package/dist/types/src/ajv.d.ts +3 -2
- package/dist/types/src/constants.d.ts +1 -1
- package/dist/types/src/incentiveHelpers.d.ts +1 -1
- package/dist/types/src/incentives.d.ts +2 -2
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/schema.d.ts +40 -8
- package/dist/types/src/services.d.ts +3 -2
- package/dist/types/src/types.d.ts +16 -6
- package/dist/types/src/utils.d.ts +1 -1
- package/dist/types/src/verification/common.d.ts +2 -2
- package/dist/types/src/verification/signature-validator.d.ts +5 -2
- package/dist/types/test/fixtures.d.ts +78 -11
- package/package.json +4 -2
- package/src/ajv.ts +91 -52
- package/src/constants.ts +1 -1
- package/src/incentiveHelpers.ts +1 -5
- package/src/incentives.ts +3 -4
- package/src/index.ts +37 -35
- package/src/schema.ts +45 -22
- package/src/services.ts +4 -2
- package/src/types.ts +20 -5
- package/src/utils.ts +7 -4
- package/src/verification/common.ts +13 -1
- package/src/verification/signature-validator.ts +10 -3
- 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,
|
|
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(
|
|
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(
|
|
48
|
+
.mockReturnValue(Promise.resolve(clusterLockV1X10.cluster_definition));
|
|
50
49
|
const clusterDefinition = yield clientInstance.acceptClusterDefinition({
|
|
51
|
-
enr:
|
|
52
|
-
version:
|
|
53
|
-
},
|
|
54
|
-
expect(clusterDefinition).toEqual(
|
|
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({},
|
|
60
|
+
yield clientInstance.createClusterDefinition(Object.assign(Object.assign({}, clusterConfigV1X10), { operators: [] }));
|
|
62
61
|
}
|
|
63
62
|
catch (error) {
|
|
64
|
-
expect(error.message).toEqual("
|
|
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
|
|
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('
|
|
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(
|
|
99
|
-
const clusterDefinition = yield clientInstance.getClusterDefinition(
|
|
100
|
-
expect(
|
|
101
|
-
expect(clusterDefinition.config_hash).toEqual(
|
|
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(
|
|
107
|
-
const clusterLock = yield clientInstance.getClusterLock(
|
|
108
|
-
expect(clusterLock.lock_hash).toEqual(
|
|
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(
|
|
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:
|
|
155
|
-
version:
|
|
156
|
-
},
|
|
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(
|
|
166
|
-
const clusterDefinition = yield clientInstance.getClusterDefinition(
|
|
167
|
-
expect(clusterDefinition.config_hash).toEqual(
|
|
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(
|
|
173
|
-
const clusterLock = yield clientInstance.getClusterLock(
|
|
174
|
-
expect(clusterLock.lock_hash).toEqual(
|
|
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('
|
|
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("
|
|
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('
|
|
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("
|
|
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.
|
|
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({
|
package/dist/types/src/ajv.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
export declare
|
|
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.
|
|
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: (
|
|
12
|
+
export declare const isClaimedFromMerkleDistributor: (contractAddress: ETH_ADDRESS, index: number, provider: ProviderType | undefined | null) => Promise<boolean>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
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<
|
|
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
|
-
|
|
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
|
|
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
|
|
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 recipient
|
|
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
|
-
|
|
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.
|
|
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.
|
|
61
|
+
"ethers": "^6.13.5",
|
|
60
62
|
"nock": "^13.5.3",
|
|
61
63
|
"pdf-parse": "^1.1.1",
|
|
62
64
|
"semver": "^7.6.0",
|