@obolnetwork/obol-sdk 1.0.16 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/cjs/package.json +11 -6
- package/dist/cjs/src/ajv.js +27 -0
- package/dist/cjs/src/constants.js +8 -4
- package/dist/cjs/src/index.js +10 -9
- package/dist/cjs/src/schema.js +8 -0
- package/dist/cjs/src/utils.js +3 -3
- package/dist/cjs/src/verification/common.js +19 -7
- package/dist/cjs/src/verification/termsAndConditions.js +1 -1
- package/dist/cjs/src/verification/v1.6.0.js +1 -1
- package/dist/cjs/src/verification/v1.7.0.js +3 -3
- package/dist/cjs/src/verification/v1.8.0.js +3 -3
- package/dist/cjs/test/fixtures.js +27 -33
- package/dist/cjs/test/methods.test.js +54 -27
- package/dist/esm/package.json +11 -6
- package/dist/esm/src/ajv.js +27 -0
- package/dist/esm/src/base.js +1 -1
- package/dist/esm/src/constants.js +7 -3
- package/dist/esm/src/index.js +11 -10
- package/dist/esm/src/schema.js +8 -0
- package/dist/esm/src/utils.js +3 -3
- package/dist/esm/src/verification/common.js +27 -15
- package/dist/esm/src/verification/sszTypes.js +1 -1
- package/dist/esm/src/verification/termsAndConditions.js +1 -1
- package/dist/esm/src/verification/v1.6.0.js +5 -5
- package/dist/esm/src/verification/v1.7.0.js +8 -8
- package/dist/esm/src/verification/v1.8.0.js +8 -8
- package/dist/esm/test/fixtures.js +27 -33
- package/dist/esm/test/methods.test.js +55 -28
- package/dist/types/src/constants.d.ts +3 -1
- package/dist/types/src/schema.d.ts +8 -0
- package/dist/types/src/types.d.ts +18 -18
- package/package.json +11 -6
- package/src/ajv.ts +38 -7
- package/src/base.ts +22 -18
- package/src/constants.ts +42 -36
- package/src/errors.ts +4 -4
- package/src/index.ts +85 -75
- package/src/schema.ts +10 -2
- package/src/services.ts +6 -6
- package/src/types.ts +65 -65
- package/src/utils.ts +17 -17
- package/src/verification/common.ts +374 -333
- package/src/verification/sszTypes.ts +60 -51
- package/src/verification/termsAndConditions.ts +16 -14
- package/src/verification/v1.6.0.ts +214 -184
- package/src/verification/v1.7.0.ts +268 -233
- 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.
|
|
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.
|
|
54
|
+
.mockReturnValue(Promise.resolve(fixtures_js_1.clusterLockV1X8.cluster_definition));
|
|
55
55
|
const clusterDefinition = yield clientInstance.acceptClusterDefinition({
|
|
56
|
-
enr: fixtures_js_1.
|
|
57
|
-
version: fixtures_js_1.
|
|
58
|
-
}, fixtures_js_1.
|
|
59
|
-
expect(clusterDefinition).toEqual(fixtures_js_1.
|
|
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.
|
|
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.
|
|
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.
|
|
84
|
-
const clusterDefinition = yield clientInstance.getClusterDefinition(fixtures_js_1.
|
|
85
|
-
expect(clusterDefinition.
|
|
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.
|
|
91
|
-
const clusterLock = yield clientInstance.getClusterLock(fixtures_js_1.
|
|
92
|
-
expect(clusterLock.lock_hash).toEqual(fixtures_js_1.
|
|
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({
|
|
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.
|
|
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.
|
|
134
|
-
version: fixtures_js_1.
|
|
135
|
-
}, fixtures_js_1.
|
|
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.
|
|
145
|
-
const clusterDefinition = yield clientInstance.getClusterDefinition(fixtures_js_1.
|
|
146
|
-
expect(clusterDefinition.config_hash).toEqual(fixtures_js_1.
|
|
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.
|
|
152
|
-
const clusterLock = yield clientInstance.getClusterLock(fixtures_js_1.
|
|
153
|
-
expect(clusterLock.lock_hash).toEqual(fixtures_js_1.
|
|
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([
|
|
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('
|
|
188
|
+
expect(termsAndConditionsHash).toEqual('0xd33721644e8f3afab1495a74abe3523cec12d48b8da6cb760972492ca3f1a273');
|
|
162
189
|
}));
|
|
163
190
|
});
|
package/dist/esm/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obolnetwork/obol-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A package for creating Distributed Validators using the Obol API.",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/obolnetwork/obol-sdk/issues"
|
|
7
7
|
},
|
|
8
|
-
"homepage": "https://docs.obol.
|
|
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,
|
|
24
|
-
"lint-ci": "eslint \"{src,
|
|
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.
|
|
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": "
|
|
81
|
+
"typescript": "~5.3.3"
|
|
77
82
|
},
|
|
78
83
|
"engines": {
|
|
79
84
|
"node": ">= 16"
|
package/dist/esm/src/ajv.js
CHANGED
|
@@ -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) {
|
package/dist/esm/src/base.js
CHANGED
|
@@ -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.
|
|
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 =
|
|
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';
|
package/dist/esm/src/index.js
CHANGED
|
@@ -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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
181
|
+
const lock = yield this.request(`/${DEFAULT_BASE_VERSION}/lock/configHash/${configHash}`, {
|
|
181
182
|
method: 'GET',
|
|
182
183
|
});
|
|
183
184
|
return lock;
|
package/dist/esm/src/schema.js
CHANGED
|
@@ -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
|
};
|
package/dist/esm/src/utils.js
CHANGED
|
@@ -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(
|
|
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(
|
|
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(
|
|
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
|
|
10
|
+
import { fromHexString } from '@chainsafe/ssz';
|
|
11
11
|
import elliptic from 'elliptic';
|
|
12
|
-
import { init
|
|
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' +
|
|
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' +
|
|
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' +
|
|
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(
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 (
|
|
144
|
-
const depositData =
|
|
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;
|