@obolnetwork/obol-sdk 1.0.14 → 1.0.15
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/dist/cjs/package.json +6 -3
- package/dist/cjs/src/base.js +4 -1
- package/dist/cjs/src/constants.js +15 -4
- package/dist/cjs/src/index.js +45 -4
- package/dist/cjs/src/verification/termsAndConditions.js +40 -0
- package/dist/cjs/test/methods.test.js +12 -0
- package/dist/esm/package.json +6 -3
- package/dist/esm/src/base.js +4 -1
- package/dist/esm/src/constants.js +14 -3
- package/dist/esm/src/index.js +46 -5
- package/dist/esm/src/verification/termsAndConditions.js +33 -0
- package/dist/esm/test/methods.test.js +12 -0
- package/dist/types/src/constants.d.ts +9 -1
- package/dist/types/src/index.d.ts +12 -5
- package/dist/types/src/types.d.ts +2 -2
- package/dist/types/src/utils.d.ts +2 -2
- package/dist/types/src/verification/common.d.ts +2 -2
- package/dist/types/src/verification/termsAndConditions.d.ts +1 -0
- package/dist/types/src/verification/v1.6.0.d.ts +2 -2
- package/dist/types/src/verification/v1.7.0.d.ts +2 -2
- package/dist/types/src/verification/v1.8.0.d.ts +2 -2
- package/package.json +6 -3
- package/src/base.ts +4 -2
- package/src/constants.ts +16 -4
- package/src/index.ts +57 -11
- package/src/types.ts +2 -2
- package/src/utils.ts +2 -2
- package/src/verification/common.ts +3 -3
- package/src/verification/termsAndConditions.ts +30 -0
- package/src/verification/v1.6.0.ts +2 -2
- package/src/verification/v1.7.0.ts +2 -2
- package/src/verification/v1.8.0.ts +2 -2
package/dist/cjs/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obolnetwork/obol-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
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"
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"@chainsafe/discv5": "^0.5.1",
|
|
43
43
|
"@chainsafe/ssz": "^0.14.0",
|
|
44
44
|
"@metamask/eth-sig-util": "^7.0.1",
|
|
45
|
+
"@types/pdf-parse": "^1.1.4",
|
|
45
46
|
"ajv": "^8.12.0",
|
|
46
47
|
"cross-fetch": "^3.1.5",
|
|
47
48
|
"elliptic": "^6.5.4",
|
|
@@ -49,9 +50,9 @@
|
|
|
49
50
|
"eslint-plugin-import": "^2.29.1",
|
|
50
51
|
"eslint-plugin-n": "^16.6.2",
|
|
51
52
|
"eslint-plugin-promise": "^6.1.1",
|
|
52
|
-
"ethers": "
|
|
53
|
+
"ethers": "6.4.0",
|
|
53
54
|
"nock": "^13.5.3",
|
|
54
|
-
"
|
|
55
|
+
"pdf-parse": "^1.1.1",
|
|
55
56
|
"semver": "^7.6.0",
|
|
56
57
|
"typescript-eslint": "^7.1.0",
|
|
57
58
|
"uuid": "^9.0.0"
|
|
@@ -61,11 +62,13 @@
|
|
|
61
62
|
"@types/elliptic": "^6.4.18",
|
|
62
63
|
"@types/jest": "^28.1.8",
|
|
63
64
|
"@types/node": "^20.2.5",
|
|
65
|
+
"@types/semver": "^7.5.8",
|
|
64
66
|
"@types/uuid": "^9.0.1",
|
|
65
67
|
"eslint": "^8.57.0",
|
|
66
68
|
"jest": "^28.1.3",
|
|
67
69
|
"msw": "^2.2.1",
|
|
68
70
|
"npm-run-all": "^4.1.5",
|
|
71
|
+
"release-it": "^17.2.1",
|
|
69
72
|
"ts-jest": "^28.0.8",
|
|
70
73
|
"tsup": "^6.7.0",
|
|
71
74
|
"typedoc": "^0.25.7",
|
package/dist/cjs/src/base.js
CHANGED
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.ETHER_TO_GWEI = exports.DEFAULT_CHAIN_ID = exports.DEFAULT_BASE_URL = exports.DefinitionFlow = exports.GENESIS_VALIDATOR_ROOT = exports.DOMAIN_DEPOSIT = exports.DOMAIN_APPLICATION_BUILDER = exports.SDK_VERSION = exports.CONFIG_VERSION = exports.DKG_ALGORITHM = exports.signEnrPayload = exports.signOperatorConfigHashPayload = exports.signCreatorConfigHashPayload = exports.ENRTypedMessage = exports.OperatorTypedMessage = exports.OperatorConfigHashSigningTypes = exports.EnrSigningTypes = exports.CreatorTypedMessage = exports.Domain = exports.CreatorConfigHashSigningTypes = exports.EIP712_DOMAIN_VERSION = exports.EIP712_DOMAIN_NAME = exports.CONFLICT_ERROR_MSG = void 0;
|
|
26
|
+
exports.TERMS_AND_CONDITIONS_URL = exports.TERMS_AND_CONDITIONS_VERSION = exports.ETHER_TO_GWEI = exports.DEFAULT_CHAIN_ID = exports.DEFAULT_BASE_URL = exports.DefinitionFlow = exports.GENESIS_VALIDATOR_ROOT = exports.DOMAIN_DEPOSIT = exports.DOMAIN_APPLICATION_BUILDER = exports.SDK_VERSION = exports.CONFIG_VERSION = exports.DKG_ALGORITHM = exports.signEnrPayload = exports.signOperatorConfigHashPayload = exports.signCreatorConfigHashPayload = exports.ENRTypedMessage = exports.OperatorTypedMessage = exports.OperatorConfigHashSigningTypes = exports.EnrSigningTypes = exports.CreatorTypedMessage = exports.Domain = exports.TermsAndConditionsSigningTypes = exports.CreatorConfigHashSigningTypes = exports.EIP712_DOMAIN_VERSION = exports.EIP712_DOMAIN_NAME = exports.CONFLICT_ERROR_MSG = void 0;
|
|
27
27
|
const pjson = __importStar(require("../package.json"));
|
|
28
28
|
exports.CONFLICT_ERROR_MSG = 'Conflict';
|
|
29
29
|
exports.EIP712_DOMAIN_NAME = 'Obol';
|
|
@@ -31,17 +31,26 @@ exports.EIP712_DOMAIN_VERSION = '1';
|
|
|
31
31
|
exports.CreatorConfigHashSigningTypes = {
|
|
32
32
|
CreatorConfigHash: [{ name: 'creator_config_hash', type: 'string' }],
|
|
33
33
|
};
|
|
34
|
+
exports.TermsAndConditionsSigningTypes = {
|
|
35
|
+
TermsAndConditions: [
|
|
36
|
+
{ name: 'terms_and_conditions_hash', type: 'string' },
|
|
37
|
+
{ name: 'version', type: 'uint256' },
|
|
38
|
+
]
|
|
39
|
+
};
|
|
34
40
|
const EIP712Domain = [
|
|
35
41
|
{ name: 'name', type: 'string' },
|
|
36
42
|
{ name: 'version', type: 'string' },
|
|
37
43
|
{ name: 'chainId', type: 'uint256' },
|
|
38
44
|
];
|
|
39
45
|
const Domain = (chainId) => {
|
|
40
|
-
|
|
46
|
+
const typeDataDomain = {
|
|
41
47
|
name: exports.EIP712_DOMAIN_NAME,
|
|
42
48
|
version: exports.EIP712_DOMAIN_VERSION,
|
|
43
|
-
chainId,
|
|
44
49
|
};
|
|
50
|
+
if (chainId) {
|
|
51
|
+
typeDataDomain.chainId = chainId;
|
|
52
|
+
}
|
|
53
|
+
return typeDataDomain;
|
|
45
54
|
};
|
|
46
55
|
exports.Domain = Domain;
|
|
47
56
|
exports.CreatorTypedMessage = Object.assign({ EIP712Domain }, exports.CreatorConfigHashSigningTypes);
|
|
@@ -99,7 +108,7 @@ exports.SDK_VERSION = pjson.version;
|
|
|
99
108
|
exports.DOMAIN_APPLICATION_BUILDER = '00000001';
|
|
100
109
|
exports.DOMAIN_DEPOSIT = '03000000';
|
|
101
110
|
exports.GENESIS_VALIDATOR_ROOT = '0000000000000000000000000000000000000000000000000000000000000000';
|
|
102
|
-
// Flow used to create
|
|
111
|
+
// Flow used to create definition
|
|
103
112
|
var DefinitionFlow;
|
|
104
113
|
(function (DefinitionFlow) {
|
|
105
114
|
DefinitionFlow["Group"] = "LP-Group";
|
|
@@ -109,3 +118,5 @@ var DefinitionFlow;
|
|
|
109
118
|
exports.DEFAULT_BASE_URL = 'https://api.obol.tech';
|
|
110
119
|
exports.DEFAULT_CHAIN_ID = 17000;
|
|
111
120
|
exports.ETHER_TO_GWEI = 10 ** 9;
|
|
121
|
+
exports.TERMS_AND_CONDITIONS_VERSION = 1;
|
|
122
|
+
exports.TERMS_AND_CONDITIONS_URL = (exports.TERMS_AND_CONDITIONS_VERSION === 1) ? 'https://obol.tech/terms.pdf' : `https://obol.tech/${exports.TERMS_AND_CONDITIONS_VERSION}/terms.pdf`;
|
package/dist/cjs/src/index.js
CHANGED
|
@@ -31,6 +31,7 @@ const errors_js_1 = require("./errors.js");
|
|
|
31
31
|
const common_js_1 = require("./verification/common.js");
|
|
32
32
|
const ajv_js_1 = require("./ajv.js");
|
|
33
33
|
const schema_js_1 = require("./schema.js");
|
|
34
|
+
const termsAndConditions_js_1 = require("./verification/termsAndConditions.js");
|
|
34
35
|
__exportStar(require("./types.js"), exports);
|
|
35
36
|
__exportStar(require("./services.js"), exports);
|
|
36
37
|
/**
|
|
@@ -51,6 +52,46 @@ class Client extends base_js_1.Base {
|
|
|
51
52
|
super(config);
|
|
52
53
|
this.signer = signer;
|
|
53
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Accepts Obol terms and conditions to be able to create or update data.
|
|
57
|
+
* @returns {Promise<string>} terms and conditions acceptance success message.
|
|
58
|
+
* @throws On unverified signature or wrong hash.
|
|
59
|
+
*
|
|
60
|
+
*/
|
|
61
|
+
acceptObolLatestTermsAndConditions() {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
if (!this.signer) {
|
|
64
|
+
throw new Error('Signer is required in acceptObolTermsAndConditions');
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const termsAndConditionsHash = yield (0, termsAndConditions_js_1.hashTermsAndConditions)();
|
|
68
|
+
const address = yield this.signer.getAddress();
|
|
69
|
+
const termsAndConditionsPayload = {
|
|
70
|
+
address,
|
|
71
|
+
version: constants_js_1.TERMS_AND_CONDITIONS_VERSION,
|
|
72
|
+
terms_and_conditions_hash: termsAndConditionsHash
|
|
73
|
+
};
|
|
74
|
+
const termsAndConditionsSignature = yield this.signer.signTypedData((0, constants_js_1.Domain)(), constants_js_1.TermsAndConditionsSigningTypes, {
|
|
75
|
+
terms_and_conditions_hash: termsAndConditionsHash,
|
|
76
|
+
version: constants_js_1.TERMS_AND_CONDITIONS_VERSION,
|
|
77
|
+
});
|
|
78
|
+
const termsAndConditionsResponse = yield this.request('/termsAndConditions', {
|
|
79
|
+
method: 'POST',
|
|
80
|
+
body: JSON.stringify(termsAndConditionsPayload),
|
|
81
|
+
headers: {
|
|
82
|
+
Authorization: `Bearer ${termsAndConditionsSignature}`,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
return termsAndConditionsResponse === null || termsAndConditionsResponse === void 0 ? void 0 : termsAndConditionsResponse.message;
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
if ((err === null || err === void 0 ? void 0 : err.message) === constants_js_1.CONFLICT_ERROR_MSG) {
|
|
89
|
+
throw new errors_js_1.ConflictError();
|
|
90
|
+
}
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
54
95
|
/**
|
|
55
96
|
* Creates a cluster definition which contains cluster configuration.
|
|
56
97
|
* @param {ClusterPayload} newCluster - The new unique cluster.
|
|
@@ -72,7 +113,7 @@ class Client extends base_js_1.Base {
|
|
|
72
113
|
clusterConfig.creator = { address };
|
|
73
114
|
clusterConfig.config_hash = (0, common_js_1.clusterConfigOrDefinitionHash)(clusterConfig, true);
|
|
74
115
|
const creatorConfigSignature = yield this.signer.signTypedData((0, constants_js_1.Domain)(this.chainId), constants_js_1.CreatorConfigHashSigningTypes, { creator_config_hash: clusterConfig.config_hash });
|
|
75
|
-
const clusterDefinition = yield this.request('/
|
|
116
|
+
const clusterDefinition = yield this.request('/v1/definition', {
|
|
76
117
|
method: 'POST',
|
|
77
118
|
body: JSON.stringify(clusterConfig),
|
|
78
119
|
headers: {
|
|
@@ -94,7 +135,7 @@ class Client extends base_js_1.Base {
|
|
|
94
135
|
* Approves joining a cluster with specific configuration.
|
|
95
136
|
* @param {OperatorPayload} operatorPayload - The operator data including signatures.
|
|
96
137
|
* @param {string} configHash - The config hash of the cluster which the operator confirms joining to.
|
|
97
|
-
* @returns {Promise<
|
|
138
|
+
* @returns {Promise<ClusterDefinition>} The cluster definition.
|
|
98
139
|
* @throws On unauthorized, duplicate entries, missing keys, not found cluster or invalid data.
|
|
99
140
|
*
|
|
100
141
|
* An example of how to use acceptClusterDefinition:
|
|
@@ -111,7 +152,7 @@ class Client extends base_js_1.Base {
|
|
|
111
152
|
const operatorConfigSignature = yield this.signer.signTypedData((0, constants_js_1.Domain)(this.chainId), constants_js_1.OperatorConfigHashSigningTypes, { operator_config_hash: configHash });
|
|
112
153
|
const operatorENRSignature = yield this.signer.signTypedData((0, constants_js_1.Domain)(this.chainId), constants_js_1.EnrSigningTypes, { enr: operatorPayload.enr });
|
|
113
154
|
const operatorData = Object.assign(Object.assign({}, operatorPayload), { address, enr_signature: operatorENRSignature, fork_version: this.fork_version });
|
|
114
|
-
const clusterDefinition = yield this.request(`/
|
|
155
|
+
const clusterDefinition = yield this.request(`/v1/definition/${configHash}`, {
|
|
115
156
|
method: 'PUT',
|
|
116
157
|
body: JSON.stringify(operatorData),
|
|
117
158
|
headers: {
|
|
@@ -127,7 +168,7 @@ class Client extends base_js_1.Base {
|
|
|
127
168
|
}
|
|
128
169
|
/**
|
|
129
170
|
* @param configHash - The configuration hash returned in createClusterDefinition
|
|
130
|
-
* @returns {Promise<
|
|
171
|
+
* @returns {Promise<ClusterDefinition>} The cluster definition for config hash
|
|
131
172
|
* @throws On not found config hash.
|
|
132
173
|
*
|
|
133
174
|
* An example of how to use getClusterDefinition:
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.hashTermsAndConditions = void 0;
|
|
16
|
+
const pdf_parse_1 = __importDefault(require("pdf-parse"));
|
|
17
|
+
const ssz_1 = require("@chainsafe/ssz");
|
|
18
|
+
const constants_1 = require("../constants");
|
|
19
|
+
const utils_1 = require("../utils");
|
|
20
|
+
const hashTermsAndConditions = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
+
try {
|
|
22
|
+
// read the pdf
|
|
23
|
+
const response = yield fetch(constants_1.TERMS_AND_CONDITIONS_URL);
|
|
24
|
+
const pdfBuffarrayBuffer = yield response.arrayBuffer();
|
|
25
|
+
const pdfBuffer = Buffer.from(pdfBuffarrayBuffer);
|
|
26
|
+
const data = yield (0, pdf_parse_1.default)(pdfBuffer);
|
|
27
|
+
// ssz hash
|
|
28
|
+
const termsType = new ssz_1.ContainerType({
|
|
29
|
+
terms_and_conditions_hash: new ssz_1.ByteListType(Number.MAX_SAFE_INTEGER),
|
|
30
|
+
});
|
|
31
|
+
const termsHasVal = termsType.defaultValue();
|
|
32
|
+
termsHasVal.terms_and_conditions_hash = (0, utils_1.strToUint8Array)(data === null || data === void 0 ? void 0 : data.text);
|
|
33
|
+
return ('0x' +
|
|
34
|
+
Buffer.from(termsType.hashTreeRoot(termsHasVal).buffer).toString('hex'));
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
exports.hashTermsAndConditions = hashTermsAndConditions;
|
|
@@ -17,6 +17,7 @@ const base_1 = require("../src/base");
|
|
|
17
17
|
const ajv_1 = require("../src/ajv");
|
|
18
18
|
const msw_1 = require("msw");
|
|
19
19
|
const node_1 = require("msw/node");
|
|
20
|
+
const termsAndConditions_1 = require("../src/verification/termsAndConditions");
|
|
20
21
|
/* eslint no-new: 0 */
|
|
21
22
|
describe('Cluster Client', () => {
|
|
22
23
|
var _a, _b;
|
|
@@ -33,6 +34,13 @@ describe('Cluster Client', () => {
|
|
|
33
34
|
// expect(error.message).toBe('Obol-SDK is in Beta phase, mainnet is not yet supported')
|
|
34
35
|
// }
|
|
35
36
|
// })
|
|
37
|
+
test('createTermsAndConditions should return "successful authorization"', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
38
|
+
clientInstance['request'] = jest
|
|
39
|
+
.fn()
|
|
40
|
+
.mockReturnValue(Promise.resolve({ message: 'successful authorization' }));
|
|
41
|
+
const isAuthorized = yield clientInstance.acceptObolLatestTermsAndConditions();
|
|
42
|
+
expect(isAuthorized).toEqual('successful authorization');
|
|
43
|
+
}));
|
|
36
44
|
test('createClusterDefinition should return config_hash', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
45
|
clientInstance['request'] = jest
|
|
38
46
|
.fn()
|
|
@@ -148,4 +156,8 @@ describe('Cluster Client without a signer', () => {
|
|
|
148
156
|
const isValidLock = yield (0, index_1.validateClusterLock)(clusterLock);
|
|
149
157
|
expect(isValidLock).toEqual(true);
|
|
150
158
|
}));
|
|
159
|
+
test('Finds the hash of the latest version of terms and conditions', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
+
const termsAndConditionsHash = yield (0, termsAndConditions_1.hashTermsAndConditions)();
|
|
161
|
+
expect(termsAndConditionsHash).toEqual('0x0015d01710b4d864004320a4826f6846c2db12a7f056a126fa5ae16c0b5e2b65');
|
|
162
|
+
}));
|
|
151
163
|
});
|
package/dist/esm/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obolnetwork/obol-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
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"
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"@chainsafe/discv5": "^0.5.1",
|
|
43
43
|
"@chainsafe/ssz": "^0.14.0",
|
|
44
44
|
"@metamask/eth-sig-util": "^7.0.1",
|
|
45
|
+
"@types/pdf-parse": "^1.1.4",
|
|
45
46
|
"ajv": "^8.12.0",
|
|
46
47
|
"cross-fetch": "^3.1.5",
|
|
47
48
|
"elliptic": "^6.5.4",
|
|
@@ -49,9 +50,9 @@
|
|
|
49
50
|
"eslint-plugin-import": "^2.29.1",
|
|
50
51
|
"eslint-plugin-n": "^16.6.2",
|
|
51
52
|
"eslint-plugin-promise": "^6.1.1",
|
|
52
|
-
"ethers": "
|
|
53
|
+
"ethers": "6.4.0",
|
|
53
54
|
"nock": "^13.5.3",
|
|
54
|
-
"
|
|
55
|
+
"pdf-parse": "^1.1.1",
|
|
55
56
|
"semver": "^7.6.0",
|
|
56
57
|
"typescript-eslint": "^7.1.0",
|
|
57
58
|
"uuid": "^9.0.0"
|
|
@@ -61,11 +62,13 @@
|
|
|
61
62
|
"@types/elliptic": "^6.4.18",
|
|
62
63
|
"@types/jest": "^28.1.8",
|
|
63
64
|
"@types/node": "^20.2.5",
|
|
65
|
+
"@types/semver": "^7.5.8",
|
|
64
66
|
"@types/uuid": "^9.0.1",
|
|
65
67
|
"eslint": "^8.57.0",
|
|
66
68
|
"jest": "^28.1.3",
|
|
67
69
|
"msw": "^2.2.1",
|
|
68
70
|
"npm-run-all": "^4.1.5",
|
|
71
|
+
"release-it": "^17.2.1",
|
|
69
72
|
"ts-jest": "^28.0.8",
|
|
70
73
|
"tsup": "^6.7.0",
|
|
71
74
|
"typedoc": "^0.25.7",
|
package/dist/esm/src/base.js
CHANGED
|
@@ -5,17 +5,26 @@ export const EIP712_DOMAIN_VERSION = '1';
|
|
|
5
5
|
export const CreatorConfigHashSigningTypes = {
|
|
6
6
|
CreatorConfigHash: [{ name: 'creator_config_hash', type: 'string' }],
|
|
7
7
|
};
|
|
8
|
+
export const TermsAndConditionsSigningTypes = {
|
|
9
|
+
TermsAndConditions: [
|
|
10
|
+
{ name: 'terms_and_conditions_hash', type: 'string' },
|
|
11
|
+
{ name: 'version', type: 'uint256' },
|
|
12
|
+
]
|
|
13
|
+
};
|
|
8
14
|
const EIP712Domain = [
|
|
9
15
|
{ name: 'name', type: 'string' },
|
|
10
16
|
{ name: 'version', type: 'string' },
|
|
11
17
|
{ name: 'chainId', type: 'uint256' },
|
|
12
18
|
];
|
|
13
19
|
export const Domain = (chainId) => {
|
|
14
|
-
|
|
20
|
+
const typeDataDomain = {
|
|
15
21
|
name: EIP712_DOMAIN_NAME,
|
|
16
22
|
version: EIP712_DOMAIN_VERSION,
|
|
17
|
-
chainId,
|
|
18
23
|
};
|
|
24
|
+
if (chainId) {
|
|
25
|
+
typeDataDomain.chainId = chainId;
|
|
26
|
+
}
|
|
27
|
+
return typeDataDomain;
|
|
19
28
|
};
|
|
20
29
|
export const CreatorTypedMessage = Object.assign({ EIP712Domain }, CreatorConfigHashSigningTypes);
|
|
21
30
|
// A conflict once updateDefinition is merged
|
|
@@ -69,7 +78,7 @@ export const SDK_VERSION = pjson.version;
|
|
|
69
78
|
export const DOMAIN_APPLICATION_BUILDER = '00000001';
|
|
70
79
|
export const DOMAIN_DEPOSIT = '03000000';
|
|
71
80
|
export const GENESIS_VALIDATOR_ROOT = '0000000000000000000000000000000000000000000000000000000000000000';
|
|
72
|
-
// Flow used to create
|
|
81
|
+
// Flow used to create definition
|
|
73
82
|
export var DefinitionFlow;
|
|
74
83
|
(function (DefinitionFlow) {
|
|
75
84
|
DefinitionFlow["Group"] = "LP-Group";
|
|
@@ -79,3 +88,5 @@ export var DefinitionFlow;
|
|
|
79
88
|
export const DEFAULT_BASE_URL = 'https://api.obol.tech';
|
|
80
89
|
export const DEFAULT_CHAIN_ID = 17000;
|
|
81
90
|
export const ETHER_TO_GWEI = 10 ** 9;
|
|
91
|
+
export const TERMS_AND_CONDITIONS_VERSION = 1;
|
|
92
|
+
export const TERMS_AND_CONDITIONS_URL = (TERMS_AND_CONDITIONS_VERSION === 1) ? 'https://obol.tech/terms.pdf' : `https://obol.tech/${TERMS_AND_CONDITIONS_VERSION}/terms.pdf`;
|
package/dist/esm/src/index.js
CHANGED
|
@@ -9,11 +9,12 @@ 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, } from './constants.js';
|
|
12
|
+
import { CONFLICT_ERROR_MSG, CreatorConfigHashSigningTypes, Domain, DKG_ALGORITHM, CONFIG_VERSION, OperatorConfigHashSigningTypes, EnrSigningTypes, TERMS_AND_CONDITIONS_VERSION, TermsAndConditionsSigningTypes, } 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';
|
|
17
18
|
export * from './types.js';
|
|
18
19
|
export * from './services.js';
|
|
19
20
|
/**
|
|
@@ -34,6 +35,46 @@ export class Client extends Base {
|
|
|
34
35
|
super(config);
|
|
35
36
|
this.signer = signer;
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Accepts Obol terms and conditions to be able to create or update data.
|
|
40
|
+
* @returns {Promise<string>} terms and conditions acceptance success message.
|
|
41
|
+
* @throws On unverified signature or wrong hash.
|
|
42
|
+
*
|
|
43
|
+
*/
|
|
44
|
+
acceptObolLatestTermsAndConditions() {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
if (!this.signer) {
|
|
47
|
+
throw new Error('Signer is required in acceptObolTermsAndConditions');
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const termsAndConditionsHash = yield hashTermsAndConditions();
|
|
51
|
+
const address = yield this.signer.getAddress();
|
|
52
|
+
const termsAndConditionsPayload = {
|
|
53
|
+
address,
|
|
54
|
+
version: TERMS_AND_CONDITIONS_VERSION,
|
|
55
|
+
terms_and_conditions_hash: termsAndConditionsHash
|
|
56
|
+
};
|
|
57
|
+
const termsAndConditionsSignature = yield this.signer.signTypedData(Domain(), TermsAndConditionsSigningTypes, {
|
|
58
|
+
terms_and_conditions_hash: termsAndConditionsHash,
|
|
59
|
+
version: TERMS_AND_CONDITIONS_VERSION,
|
|
60
|
+
});
|
|
61
|
+
const termsAndConditionsResponse = yield this.request('/termsAndConditions', {
|
|
62
|
+
method: 'POST',
|
|
63
|
+
body: JSON.stringify(termsAndConditionsPayload),
|
|
64
|
+
headers: {
|
|
65
|
+
Authorization: `Bearer ${termsAndConditionsSignature}`,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
return termsAndConditionsResponse === null || termsAndConditionsResponse === void 0 ? void 0 : termsAndConditionsResponse.message;
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
if ((err === null || err === void 0 ? void 0 : err.message) === CONFLICT_ERROR_MSG) {
|
|
72
|
+
throw new ConflictError();
|
|
73
|
+
}
|
|
74
|
+
throw err;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
37
78
|
/**
|
|
38
79
|
* Creates a cluster definition which contains cluster configuration.
|
|
39
80
|
* @param {ClusterPayload} newCluster - The new unique cluster.
|
|
@@ -55,7 +96,7 @@ export class Client extends Base {
|
|
|
55
96
|
clusterConfig.creator = { address };
|
|
56
97
|
clusterConfig.config_hash = clusterConfigOrDefinitionHash(clusterConfig, true);
|
|
57
98
|
const creatorConfigSignature = yield this.signer.signTypedData(Domain(this.chainId), CreatorConfigHashSigningTypes, { creator_config_hash: clusterConfig.config_hash });
|
|
58
|
-
const clusterDefinition = yield this.request('/
|
|
99
|
+
const clusterDefinition = yield this.request('/v1/definition', {
|
|
59
100
|
method: 'POST',
|
|
60
101
|
body: JSON.stringify(clusterConfig),
|
|
61
102
|
headers: {
|
|
@@ -77,7 +118,7 @@ export class Client extends Base {
|
|
|
77
118
|
* Approves joining a cluster with specific configuration.
|
|
78
119
|
* @param {OperatorPayload} operatorPayload - The operator data including signatures.
|
|
79
120
|
* @param {string} configHash - The config hash of the cluster which the operator confirms joining to.
|
|
80
|
-
* @returns {Promise<
|
|
121
|
+
* @returns {Promise<ClusterDefinition>} The cluster definition.
|
|
81
122
|
* @throws On unauthorized, duplicate entries, missing keys, not found cluster or invalid data.
|
|
82
123
|
*
|
|
83
124
|
* An example of how to use acceptClusterDefinition:
|
|
@@ -94,7 +135,7 @@ export class Client extends Base {
|
|
|
94
135
|
const operatorConfigSignature = yield this.signer.signTypedData(Domain(this.chainId), OperatorConfigHashSigningTypes, { operator_config_hash: configHash });
|
|
95
136
|
const operatorENRSignature = yield this.signer.signTypedData(Domain(this.chainId), EnrSigningTypes, { enr: operatorPayload.enr });
|
|
96
137
|
const operatorData = Object.assign(Object.assign({}, operatorPayload), { address, enr_signature: operatorENRSignature, fork_version: this.fork_version });
|
|
97
|
-
const clusterDefinition = yield this.request(`/
|
|
138
|
+
const clusterDefinition = yield this.request(`/v1/definition/${configHash}`, {
|
|
98
139
|
method: 'PUT',
|
|
99
140
|
body: JSON.stringify(operatorData),
|
|
100
141
|
headers: {
|
|
@@ -110,7 +151,7 @@ export class Client extends Base {
|
|
|
110
151
|
}
|
|
111
152
|
/**
|
|
112
153
|
* @param configHash - The configuration hash returned in createClusterDefinition
|
|
113
|
-
* @returns {Promise<
|
|
154
|
+
* @returns {Promise<ClusterDefinition>} The cluster definition for config hash
|
|
114
155
|
* @throws On not found config hash.
|
|
115
156
|
*
|
|
116
157
|
* An example of how to use getClusterDefinition:
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import pdf from 'pdf-parse';
|
|
11
|
+
import { ByteListType, ContainerType } from '@chainsafe/ssz';
|
|
12
|
+
import { TERMS_AND_CONDITIONS_URL } from '../constants';
|
|
13
|
+
import { strToUint8Array } from '../utils';
|
|
14
|
+
export const hashTermsAndConditions = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
try {
|
|
16
|
+
// read the pdf
|
|
17
|
+
const response = yield fetch(TERMS_AND_CONDITIONS_URL);
|
|
18
|
+
const pdfBuffarrayBuffer = yield response.arrayBuffer();
|
|
19
|
+
const pdfBuffer = Buffer.from(pdfBuffarrayBuffer);
|
|
20
|
+
const data = yield pdf(pdfBuffer);
|
|
21
|
+
// ssz hash
|
|
22
|
+
const termsType = new ContainerType({
|
|
23
|
+
terms_and_conditions_hash: new ByteListType(Number.MAX_SAFE_INTEGER),
|
|
24
|
+
});
|
|
25
|
+
const termsHasVal = termsType.defaultValue();
|
|
26
|
+
termsHasVal.terms_and_conditions_hash = strToUint8Array(data === null || data === void 0 ? void 0 : data.text);
|
|
27
|
+
return ('0x' +
|
|
28
|
+
Buffer.from(termsType.hashTreeRoot(termsHasVal).buffer).toString('hex'));
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
@@ -15,6 +15,7 @@ import { Base } from '../src/base';
|
|
|
15
15
|
import { validatePayload } from '../src/ajv';
|
|
16
16
|
import { HttpResponse, http } from 'msw';
|
|
17
17
|
import { setupServer } from 'msw/node';
|
|
18
|
+
import { hashTermsAndConditions } from '../src/verification/termsAndConditions';
|
|
18
19
|
/* eslint no-new: 0 */
|
|
19
20
|
describe('Cluster Client', () => {
|
|
20
21
|
var _a, _b;
|
|
@@ -31,6 +32,13 @@ describe('Cluster Client', () => {
|
|
|
31
32
|
// expect(error.message).toBe('Obol-SDK is in Beta phase, mainnet is not yet supported')
|
|
32
33
|
// }
|
|
33
34
|
// })
|
|
35
|
+
test('createTermsAndConditions should return "successful authorization"', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
+
clientInstance['request'] = jest
|
|
37
|
+
.fn()
|
|
38
|
+
.mockReturnValue(Promise.resolve({ message: 'successful authorization' }));
|
|
39
|
+
const isAuthorized = yield clientInstance.acceptObolLatestTermsAndConditions();
|
|
40
|
+
expect(isAuthorized).toEqual('successful authorization');
|
|
41
|
+
}));
|
|
34
42
|
test('createClusterDefinition should return config_hash', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
43
|
clientInstance['request'] = jest
|
|
36
44
|
.fn()
|
|
@@ -146,4 +154,8 @@ describe('Cluster Client without a signer', () => {
|
|
|
146
154
|
const isValidLock = yield validateClusterLock(clusterLock);
|
|
147
155
|
expect(isValidLock).toEqual(true);
|
|
148
156
|
}));
|
|
157
|
+
test('Finds the hash of the latest version of terms and conditions', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
+
const termsAndConditionsHash = yield hashTermsAndConditions();
|
|
159
|
+
expect(termsAndConditionsHash).toEqual('0x0015d01710b4d864004320a4826f6846c2db12a7f056a126fa5ae16c0b5e2b65');
|
|
160
|
+
}));
|
|
149
161
|
});
|
|
@@ -9,7 +9,13 @@ export declare const CreatorConfigHashSigningTypes: {
|
|
|
9
9
|
type: string;
|
|
10
10
|
}[];
|
|
11
11
|
};
|
|
12
|
-
export declare const
|
|
12
|
+
export declare const TermsAndConditionsSigningTypes: {
|
|
13
|
+
TermsAndConditions: {
|
|
14
|
+
name: string;
|
|
15
|
+
type: string;
|
|
16
|
+
}[];
|
|
17
|
+
};
|
|
18
|
+
export declare const Domain: (chainId?: number) => TypedDataDomain;
|
|
13
19
|
export declare const CreatorTypedMessage: {
|
|
14
20
|
CreatorConfigHash: {
|
|
15
21
|
name: string;
|
|
@@ -75,3 +81,5 @@ export declare enum DefinitionFlow {
|
|
|
75
81
|
export declare const DEFAULT_BASE_URL = "https://api.obol.tech";
|
|
76
82
|
export declare const DEFAULT_CHAIN_ID = 17000;
|
|
77
83
|
export declare const ETHER_TO_GWEI: number;
|
|
84
|
+
export declare const TERMS_AND_CONDITIONS_VERSION = 1;
|
|
85
|
+
export declare const TERMS_AND_CONDITIONS_URL: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Signer } from 'ethers';
|
|
2
2
|
import { Base } from './base.js';
|
|
3
|
-
import { type
|
|
3
|
+
import { type ClusterDefinition, type ClusterLock, type ClusterPayload, type OperatorPayload } from './types.js';
|
|
4
4
|
export * from './types.js';
|
|
5
5
|
export * from './services.js';
|
|
6
6
|
/**
|
|
@@ -22,6 +22,13 @@ export declare class Client extends Base {
|
|
|
22
22
|
baseUrl?: string;
|
|
23
23
|
chainId?: number;
|
|
24
24
|
}, signer?: Signer);
|
|
25
|
+
/**
|
|
26
|
+
* Accepts Obol terms and conditions to be able to create or update data.
|
|
27
|
+
* @returns {Promise<string>} terms and conditions acceptance success message.
|
|
28
|
+
* @throws On unverified signature or wrong hash.
|
|
29
|
+
*
|
|
30
|
+
*/
|
|
31
|
+
acceptObolLatestTermsAndConditions(): Promise<string>;
|
|
25
32
|
/**
|
|
26
33
|
* Creates a cluster definition which contains cluster configuration.
|
|
27
34
|
* @param {ClusterPayload} newCluster - The new unique cluster.
|
|
@@ -36,22 +43,22 @@ export declare class Client extends Base {
|
|
|
36
43
|
* Approves joining a cluster with specific configuration.
|
|
37
44
|
* @param {OperatorPayload} operatorPayload - The operator data including signatures.
|
|
38
45
|
* @param {string} configHash - The config hash of the cluster which the operator confirms joining to.
|
|
39
|
-
* @returns {Promise<
|
|
46
|
+
* @returns {Promise<ClusterDefinition>} The cluster definition.
|
|
40
47
|
* @throws On unauthorized, duplicate entries, missing keys, not found cluster or invalid data.
|
|
41
48
|
*
|
|
42
49
|
* An example of how to use acceptClusterDefinition:
|
|
43
50
|
* [acceptClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
|
|
44
51
|
*/
|
|
45
|
-
acceptClusterDefinition(operatorPayload: OperatorPayload, configHash: string): Promise<
|
|
52
|
+
acceptClusterDefinition(operatorPayload: OperatorPayload, configHash: string): Promise<ClusterDefinition>;
|
|
46
53
|
/**
|
|
47
54
|
* @param configHash - The configuration hash returned in createClusterDefinition
|
|
48
|
-
* @returns {Promise<
|
|
55
|
+
* @returns {Promise<ClusterDefinition>} The cluster definition for config hash
|
|
49
56
|
* @throws On not found config hash.
|
|
50
57
|
*
|
|
51
58
|
* An example of how to use getClusterDefinition:
|
|
52
59
|
* [getObolClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
|
|
53
60
|
*/
|
|
54
|
-
getClusterDefinition(configHash: string): Promise<
|
|
61
|
+
getClusterDefinition(configHash: string): Promise<ClusterDefinition>;
|
|
55
62
|
/**
|
|
56
63
|
* @param configHash - The configuration hash in cluster-definition
|
|
57
64
|
* @returns {Promise<ClusterLock>} The matched cluster details (lock) from DB
|
|
@@ -66,7 +66,7 @@ export interface ClusterPayload {
|
|
|
66
66
|
/**
|
|
67
67
|
* Cluster definition data needed for dkg
|
|
68
68
|
*/
|
|
69
|
-
export interface
|
|
69
|
+
export interface ClusterDefinition extends ClusterPayload {
|
|
70
70
|
/** The creator of the cluster. */
|
|
71
71
|
creator: ClusterCreator;
|
|
72
72
|
/** The cluster configuration version. */
|
|
@@ -147,7 +147,7 @@ export interface DistributedValidator {
|
|
|
147
147
|
*/
|
|
148
148
|
export interface ClusterLock {
|
|
149
149
|
/** The cluster definition. */
|
|
150
|
-
cluster_definition:
|
|
150
|
+
cluster_definition: ClusterDefinition;
|
|
151
151
|
/** The cluster distributed validators. */
|
|
152
152
|
distributed_validators: DistributedValidator[];
|
|
153
153
|
/** The cluster bls signature aggregate. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DefinitionFlow } from './constants';
|
|
2
|
-
import { type
|
|
2
|
+
import { type ClusterDefinition } from './types';
|
|
3
3
|
export declare const hexWithout0x: (hex: string) => string;
|
|
4
4
|
export declare const strToUint8Array: (str: string) => Uint8Array;
|
|
5
|
-
export declare const definitionFlow: (clusterDefinition:
|
|
5
|
+
export declare const definitionFlow: (clusterDefinition: ClusterDefinition) => DefinitionFlow | null;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { type
|
|
2
|
+
import { type ClusterDefinition, type ClusterLock, type DepositData, type DistributedValidator } 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
|
|
6
6
|
* @returns The config hash or the definition hash in of the corresponding cluster
|
|
7
7
|
*/
|
|
8
|
-
export declare const clusterConfigOrDefinitionHash: (cluster:
|
|
8
|
+
export declare const clusterConfigOrDefinitionHash: (cluster: ClusterDefinition, configOnly: boolean) => string;
|
|
9
9
|
/**
|
|
10
10
|
* Returns the SSZ cluster lock hash of the given cluster lock object
|
|
11
11
|
* @param cluster The cluster lock whose lock hash needs to be calculated
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const hashTermsAndConditions: () => Promise<string | null>;
|
|
@@ -2,7 +2,7 @@ import { UintNumberType } from '@chainsafe/ssz/lib/type/uint';
|
|
|
2
2
|
import { type creatorAddressWrapperType, type creatorContainerType, type operatorAddressWrapperType, type operatorContainerType, validatorsContainerType } from './sszTypes';
|
|
3
3
|
import { ByteListType, ByteVectorType, ContainerType, ListCompositeType } from '@chainsafe/ssz';
|
|
4
4
|
import { type ValueOfFields } from '@chainsafe/ssz/lib/view/container';
|
|
5
|
-
import { type
|
|
5
|
+
import { type ClusterDefinition, type ClusterLock } from '../types';
|
|
6
6
|
type DefinitionFieldsV1X6 = {
|
|
7
7
|
uuid: ByteListType;
|
|
8
8
|
name: ByteListType;
|
|
@@ -24,7 +24,7 @@ type DefinitionContainerTypeV1X6 = ContainerType<DefinitionFieldsV1X6>;
|
|
|
24
24
|
* @returns SSZ Containerized type of cluster input
|
|
25
25
|
*/
|
|
26
26
|
export declare const clusterDefinitionContainerTypeV1X6: (configOnly: boolean) => DefinitionContainerTypeV1X6;
|
|
27
|
-
export declare const hashClusterDefinitionV1X6: (cluster:
|
|
27
|
+
export declare const hashClusterDefinitionV1X6: (cluster: ClusterDefinition, configOnly: boolean) => ValueOfFields<DefinitionFieldsV1X6>;
|
|
28
28
|
/**
|
|
29
29
|
* @param cluster The published cluster lock
|
|
30
30
|
* @returns The lock hash in of the corresponding cluster
|
|
@@ -2,7 +2,7 @@ import { UintNumberType } from '@chainsafe/ssz/lib/type/uint';
|
|
|
2
2
|
import { type creatorAddressWrapperType, type creatorContainerType, type operatorAddressWrapperType, type operatorContainerType, validatorsContainerType } from './sszTypes';
|
|
3
3
|
import { ByteListType, ByteVectorType, ContainerType, ListCompositeType } from '@chainsafe/ssz';
|
|
4
4
|
import { type ValueOfFields } from '@chainsafe/ssz/lib/view/container';
|
|
5
|
-
import { type
|
|
5
|
+
import { type ClusterDefinition, type ClusterLock } from '../types';
|
|
6
6
|
type DefinitionFieldsV1X7 = {
|
|
7
7
|
uuid: ByteListType;
|
|
8
8
|
name: ByteListType;
|
|
@@ -24,7 +24,7 @@ type DefinitionContainerTypeV1X7 = ContainerType<DefinitionFieldsV1X7>;
|
|
|
24
24
|
* @returns SSZ Containerized type of cluster input
|
|
25
25
|
*/
|
|
26
26
|
export declare const clusterDefinitionContainerTypeV1X7: (configOnly: boolean) => DefinitionContainerTypeV1X7;
|
|
27
|
-
export declare const hashClusterDefinitionV1X7: (cluster:
|
|
27
|
+
export declare const hashClusterDefinitionV1X7: (cluster: ClusterDefinition, configOnly: boolean) => ValueOfFields<DefinitionFieldsV1X7>;
|
|
28
28
|
/**
|
|
29
29
|
* @param cluster The published cluster lock
|
|
30
30
|
* @returns The lock hash in of the corresponding cluster
|
|
@@ -2,7 +2,7 @@ import { UintNumberType } from '@chainsafe/ssz/lib/type/uint';
|
|
|
2
2
|
import { type creatorAddressWrapperType, type creatorContainerType, type operatorAddressWrapperType, type operatorContainerType, validatorsContainerType } from './sszTypes';
|
|
3
3
|
import { ByteListType, ByteVectorType, ContainerType, ListBasicType, ListCompositeType } from '@chainsafe/ssz';
|
|
4
4
|
import { type ValueOfFields } from '@chainsafe/ssz/lib/view/container';
|
|
5
|
-
import { type
|
|
5
|
+
import { type ClusterDefinition, type ClusterLock } from '../types';
|
|
6
6
|
type DefinitionFieldsV1X8 = {
|
|
7
7
|
uuid: ByteListType;
|
|
8
8
|
name: ByteListType;
|
|
@@ -25,7 +25,7 @@ type DefinitionContainerTypeV1X8 = ContainerType<DefinitionFieldsV1X8>;
|
|
|
25
25
|
* @returns SSZ Containerized type of cluster input
|
|
26
26
|
*/
|
|
27
27
|
export declare const clusterDefinitionContainerTypeV1X8: (configOnly: boolean) => DefinitionContainerTypeV1X8;
|
|
28
|
-
export declare const hashClusterDefinitionV1X8: (cluster:
|
|
28
|
+
export declare const hashClusterDefinitionV1X8: (cluster: ClusterDefinition, configOnly: boolean) => ValueOfFields<DefinitionFieldsV1X8>;
|
|
29
29
|
/**
|
|
30
30
|
* @param cluster The published cluster lock
|
|
31
31
|
* @returns The lock hash in of the corresponding cluster
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obolnetwork/obol-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
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"
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"@chainsafe/discv5": "^0.5.1",
|
|
43
43
|
"@chainsafe/ssz": "^0.14.0",
|
|
44
44
|
"@metamask/eth-sig-util": "^7.0.1",
|
|
45
|
+
"@types/pdf-parse": "^1.1.4",
|
|
45
46
|
"ajv": "^8.12.0",
|
|
46
47
|
"cross-fetch": "^3.1.5",
|
|
47
48
|
"elliptic": "^6.5.4",
|
|
@@ -49,9 +50,9 @@
|
|
|
49
50
|
"eslint-plugin-import": "^2.29.1",
|
|
50
51
|
"eslint-plugin-n": "^16.6.2",
|
|
51
52
|
"eslint-plugin-promise": "^6.1.1",
|
|
52
|
-
"ethers": "
|
|
53
|
+
"ethers": "6.4.0",
|
|
53
54
|
"nock": "^13.5.3",
|
|
54
|
-
"
|
|
55
|
+
"pdf-parse": "^1.1.1",
|
|
55
56
|
"semver": "^7.6.0",
|
|
56
57
|
"typescript-eslint": "^7.1.0",
|
|
57
58
|
"uuid": "^9.0.0"
|
|
@@ -61,11 +62,13 @@
|
|
|
61
62
|
"@types/elliptic": "^6.4.18",
|
|
62
63
|
"@types/jest": "^28.1.8",
|
|
63
64
|
"@types/node": "^20.2.5",
|
|
65
|
+
"@types/semver": "^7.5.8",
|
|
64
66
|
"@types/uuid": "^9.0.1",
|
|
65
67
|
"eslint": "^8.57.0",
|
|
66
68
|
"jest": "^28.1.3",
|
|
67
69
|
"msw": "^2.2.1",
|
|
68
70
|
"npm-run-all": "^4.1.5",
|
|
71
|
+
"release-it": "^17.2.1",
|
|
69
72
|
"ts-jest": "^28.0.8",
|
|
70
73
|
"tsup": "^6.7.0",
|
|
71
74
|
"typedoc": "^0.25.7",
|
package/src/base.ts
CHANGED
|
@@ -39,9 +39,11 @@ export abstract class Base {
|
|
|
39
39
|
const response = await fetch(url, config)
|
|
40
40
|
if (response.ok) {
|
|
41
41
|
return await response.json()
|
|
42
|
+
} else {
|
|
43
|
+
const errorResponse = await response.json()
|
|
44
|
+
throw errorResponse
|
|
42
45
|
}
|
|
43
|
-
|
|
44
|
-
} catch (e) {
|
|
46
|
+
} catch (e: any) {
|
|
45
47
|
throw e
|
|
46
48
|
}
|
|
47
49
|
}
|
package/src/constants.ts
CHANGED
|
@@ -9,6 +9,12 @@ export const EIP712_DOMAIN_VERSION = '1'
|
|
|
9
9
|
export const CreatorConfigHashSigningTypes = {
|
|
10
10
|
CreatorConfigHash: [{ name: 'creator_config_hash', type: 'string' }],
|
|
11
11
|
}
|
|
12
|
+
export const TermsAndConditionsSigningTypes = {
|
|
13
|
+
TermsAndConditions: [
|
|
14
|
+
{ name: 'terms_and_conditions_hash', type: 'string' },
|
|
15
|
+
{ name: 'version', type: 'uint256' },
|
|
16
|
+
]
|
|
17
|
+
}
|
|
12
18
|
|
|
13
19
|
const EIP712Domain = [
|
|
14
20
|
{ name: 'name', type: 'string' },
|
|
@@ -16,12 +22,15 @@ const EIP712Domain = [
|
|
|
16
22
|
{ name: 'chainId', type: 'uint256' },
|
|
17
23
|
]
|
|
18
24
|
|
|
19
|
-
export const Domain = (chainId
|
|
20
|
-
|
|
25
|
+
export const Domain = (chainId?: number): TypedDataDomain => {
|
|
26
|
+
const typeDataDomain: any = {
|
|
21
27
|
name: EIP712_DOMAIN_NAME,
|
|
22
28
|
version: EIP712_DOMAIN_VERSION,
|
|
23
|
-
chainId,
|
|
24
29
|
}
|
|
30
|
+
if (chainId) {
|
|
31
|
+
typeDataDomain.chainId = chainId
|
|
32
|
+
}
|
|
33
|
+
return typeDataDomain
|
|
25
34
|
}
|
|
26
35
|
|
|
27
36
|
export const CreatorTypedMessage = {
|
|
@@ -107,7 +116,7 @@ export const DOMAIN_DEPOSIT = '03000000'
|
|
|
107
116
|
export const GENESIS_VALIDATOR_ROOT =
|
|
108
117
|
'0000000000000000000000000000000000000000000000000000000000000000'
|
|
109
118
|
|
|
110
|
-
// Flow used to create
|
|
119
|
+
// Flow used to create definition
|
|
111
120
|
export enum DefinitionFlow {
|
|
112
121
|
Group = 'LP-Group',
|
|
113
122
|
Solo = 'LP-Solo',
|
|
@@ -118,3 +127,6 @@ export const DEFAULT_BASE_URL = 'https://api.obol.tech'
|
|
|
118
127
|
export const DEFAULT_CHAIN_ID = 17000
|
|
119
128
|
|
|
120
129
|
export const ETHER_TO_GWEI = 10 ** 9
|
|
130
|
+
|
|
131
|
+
export const TERMS_AND_CONDITIONS_VERSION = 1
|
|
132
|
+
export const TERMS_AND_CONDITIONS_URL = (TERMS_AND_CONDITIONS_VERSION === 1) ? 'https://obol.tech/terms.pdf' : `https://obol.tech/${TERMS_AND_CONDITIONS_VERSION as number}/terms.pdf`
|
package/src/index.ts
CHANGED
|
@@ -9,10 +9,12 @@ import {
|
|
|
9
9
|
CONFIG_VERSION,
|
|
10
10
|
OperatorConfigHashSigningTypes,
|
|
11
11
|
EnrSigningTypes,
|
|
12
|
+
TERMS_AND_CONDITIONS_VERSION,
|
|
13
|
+
TermsAndConditionsSigningTypes,
|
|
12
14
|
} from './constants.js'
|
|
13
15
|
import { ConflictError } from './errors.js'
|
|
14
16
|
import {
|
|
15
|
-
type
|
|
17
|
+
type ClusterDefinition,
|
|
16
18
|
type ClusterLock,
|
|
17
19
|
type ClusterPayload,
|
|
18
20
|
type OperatorPayload,
|
|
@@ -20,6 +22,7 @@ import {
|
|
|
20
22
|
import { clusterConfigOrDefinitionHash } from './verification/common.js'
|
|
21
23
|
import { validatePayload } from './ajv.js'
|
|
22
24
|
import { definitionSchema, operatorPayloadSchema } from './schema.js'
|
|
25
|
+
import { hashTermsAndConditions } from './verification/termsAndConditions.js'
|
|
23
26
|
export * from './types.js'
|
|
24
27
|
export * from './services.js'
|
|
25
28
|
|
|
@@ -47,6 +50,49 @@ export class Client extends Base {
|
|
|
47
50
|
this.signer = signer
|
|
48
51
|
}
|
|
49
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Accepts Obol terms and conditions to be able to create or update data.
|
|
55
|
+
* @returns {Promise<string>} terms and conditions acceptance success message.
|
|
56
|
+
* @throws On unverified signature or wrong hash.
|
|
57
|
+
*
|
|
58
|
+
*/
|
|
59
|
+
async acceptObolLatestTermsAndConditions (): Promise<string> {
|
|
60
|
+
if (!this.signer) { throw new Error('Signer is required in acceptObolTermsAndConditions') }
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const termsAndConditionsHash = await hashTermsAndConditions()
|
|
64
|
+
const address = await this.signer.getAddress()
|
|
65
|
+
const termsAndConditionsPayload = {
|
|
66
|
+
address,
|
|
67
|
+
version: TERMS_AND_CONDITIONS_VERSION,
|
|
68
|
+
terms_and_conditions_hash: termsAndConditionsHash
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const termsAndConditionsSignature = await this.signer.signTypedData(
|
|
72
|
+
Domain(),
|
|
73
|
+
TermsAndConditionsSigningTypes,
|
|
74
|
+
{
|
|
75
|
+
terms_and_conditions_hash: termsAndConditionsHash,
|
|
76
|
+
version: TERMS_AND_CONDITIONS_VERSION,
|
|
77
|
+
},
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
const termsAndConditionsResponse: { message: string, success: boolean } = await this.request('/termsAndConditions', {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
body: JSON.stringify(termsAndConditionsPayload),
|
|
83
|
+
headers: {
|
|
84
|
+
Authorization: `Bearer ${termsAndConditionsSignature}`,
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
return termsAndConditionsResponse?.message
|
|
88
|
+
} catch (err: any) {
|
|
89
|
+
if (err?.message === CONFLICT_ERROR_MSG) {
|
|
90
|
+
throw new ConflictError()
|
|
91
|
+
}
|
|
92
|
+
throw err
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
50
96
|
/**
|
|
51
97
|
* Creates a cluster definition which contains cluster configuration.
|
|
52
98
|
* @param {ClusterPayload} newCluster - The new unique cluster.
|
|
@@ -61,7 +107,7 @@ export class Client extends Base {
|
|
|
61
107
|
|
|
62
108
|
validatePayload(newCluster, definitionSchema)
|
|
63
109
|
|
|
64
|
-
const clusterConfig: Partial<
|
|
110
|
+
const clusterConfig: Partial<ClusterDefinition> = {
|
|
65
111
|
...newCluster,
|
|
66
112
|
fork_version: this.fork_version,
|
|
67
113
|
dkg_algorithm: DKG_ALGORITHM,
|
|
@@ -77,7 +123,7 @@ export class Client extends Base {
|
|
|
77
123
|
|
|
78
124
|
clusterConfig.creator = { address }
|
|
79
125
|
clusterConfig.config_hash = clusterConfigOrDefinitionHash(
|
|
80
|
-
clusterConfig as
|
|
126
|
+
clusterConfig as ClusterDefinition,
|
|
81
127
|
true,
|
|
82
128
|
)
|
|
83
129
|
|
|
@@ -87,7 +133,7 @@ export class Client extends Base {
|
|
|
87
133
|
{ creator_config_hash: clusterConfig.config_hash },
|
|
88
134
|
)
|
|
89
135
|
|
|
90
|
-
const clusterDefinition:
|
|
136
|
+
const clusterDefinition: ClusterDefinition = await this.request('/v1/definition', {
|
|
91
137
|
method: 'POST',
|
|
92
138
|
body: JSON.stringify(clusterConfig),
|
|
93
139
|
headers: {
|
|
@@ -108,7 +154,7 @@ export class Client extends Base {
|
|
|
108
154
|
* Approves joining a cluster with specific configuration.
|
|
109
155
|
* @param {OperatorPayload} operatorPayload - The operator data including signatures.
|
|
110
156
|
* @param {string} configHash - The config hash of the cluster which the operator confirms joining to.
|
|
111
|
-
* @returns {Promise<
|
|
157
|
+
* @returns {Promise<ClusterDefinition>} The cluster definition.
|
|
112
158
|
* @throws On unauthorized, duplicate entries, missing keys, not found cluster or invalid data.
|
|
113
159
|
*
|
|
114
160
|
* An example of how to use acceptClusterDefinition:
|
|
@@ -117,7 +163,7 @@ export class Client extends Base {
|
|
|
117
163
|
async acceptClusterDefinition (
|
|
118
164
|
operatorPayload: OperatorPayload,
|
|
119
165
|
configHash: string,
|
|
120
|
-
): Promise<
|
|
166
|
+
): Promise<ClusterDefinition> {
|
|
121
167
|
if (!this.signer) { throw new Error('Signer is required in acceptClusterDefinition') }
|
|
122
168
|
|
|
123
169
|
validatePayload(operatorPayload, operatorPayloadSchema)
|
|
@@ -142,8 +188,8 @@ export class Client extends Base {
|
|
|
142
188
|
enr_signature: operatorENRSignature,
|
|
143
189
|
fork_version: this.fork_version,
|
|
144
190
|
}
|
|
145
|
-
const clusterDefinition:
|
|
146
|
-
`/
|
|
191
|
+
const clusterDefinition: ClusterDefinition = await this.request(
|
|
192
|
+
`/v1/definition/${configHash}`,
|
|
147
193
|
{
|
|
148
194
|
method: 'PUT',
|
|
149
195
|
body: JSON.stringify(operatorData),
|
|
@@ -160,14 +206,14 @@ export class Client extends Base {
|
|
|
160
206
|
|
|
161
207
|
/**
|
|
162
208
|
* @param configHash - The configuration hash returned in createClusterDefinition
|
|
163
|
-
* @returns {Promise<
|
|
209
|
+
* @returns {Promise<ClusterDefinition>} The cluster definition for config hash
|
|
164
210
|
* @throws On not found config hash.
|
|
165
211
|
*
|
|
166
212
|
* An example of how to use getClusterDefinition:
|
|
167
213
|
* [getObolClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
|
|
168
214
|
*/
|
|
169
|
-
async getClusterDefinition (configHash: string): Promise<
|
|
170
|
-
const clusterDefinition:
|
|
215
|
+
async getClusterDefinition (configHash: string): Promise<ClusterDefinition> {
|
|
216
|
+
const clusterDefinition: ClusterDefinition = await this.request(
|
|
171
217
|
`/dv/${configHash}`,
|
|
172
218
|
{
|
|
173
219
|
method: 'GET',
|
package/src/types.ts
CHANGED
|
@@ -85,7 +85,7 @@ export interface ClusterPayload {
|
|
|
85
85
|
/**
|
|
86
86
|
* Cluster definition data needed for dkg
|
|
87
87
|
*/
|
|
88
|
-
export interface
|
|
88
|
+
export interface ClusterDefinition extends ClusterPayload {
|
|
89
89
|
/** The creator of the cluster. */
|
|
90
90
|
creator: ClusterCreator
|
|
91
91
|
|
|
@@ -193,7 +193,7 @@ export interface DistributedValidator {
|
|
|
193
193
|
*/
|
|
194
194
|
export interface ClusterLock {
|
|
195
195
|
/** The cluster definition. */
|
|
196
|
-
cluster_definition:
|
|
196
|
+
cluster_definition: ClusterDefinition
|
|
197
197
|
|
|
198
198
|
/** The cluster distributed validators. */
|
|
199
199
|
distributed_validators: DistributedValidator[]
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DefinitionFlow } from './constants'
|
|
2
|
-
import { type
|
|
2
|
+
import { type ClusterDefinition } from './types'
|
|
3
3
|
|
|
4
4
|
export const hexWithout0x = (hex: string): string => {
|
|
5
5
|
return hex.slice(2, hex.length)
|
|
@@ -10,7 +10,7 @@ export const strToUint8Array = (str: string): Uint8Array => {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export const definitionFlow = (
|
|
13
|
-
clusterDefinition:
|
|
13
|
+
clusterDefinition: ClusterDefinition,
|
|
14
14
|
): DefinitionFlow | null => {
|
|
15
15
|
if (
|
|
16
16
|
clusterDefinition.creator.address &&
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
init,
|
|
7
7
|
} from '@chainsafe/bls'
|
|
8
8
|
|
|
9
|
-
import { FORK_MAPPING, type
|
|
9
|
+
import { FORK_MAPPING, type ClusterDefinition, type ClusterLock, type DepositData, type BuilderRegistrationMessage, type DistributedValidator } from '../types.js'
|
|
10
10
|
import * as semver from 'semver'
|
|
11
11
|
import { clusterDefinitionContainerTypeV1X6, hashClusterDefinitionV1X6, hashClusterLockV1X6, verifyDVV1X6 } from './v1.6.0.js'
|
|
12
12
|
import { clusterDefinitionContainerTypeV1X7, hashClusterDefinitionV1X7, hashClusterLockV1X7, verifyDVV1X7 } from './v1.7.0.js'
|
|
@@ -26,7 +26,7 @@ import { clusterDefinitionContainerTypeV1X8, hashClusterDefinitionV1X8, hashClus
|
|
|
26
26
|
* @returns The config hash or the definition hash in of the corresponding cluster
|
|
27
27
|
*/
|
|
28
28
|
export const clusterConfigOrDefinitionHash = (
|
|
29
|
-
cluster:
|
|
29
|
+
cluster: ClusterDefinition,
|
|
30
30
|
configOnly: boolean,
|
|
31
31
|
): string => {
|
|
32
32
|
let definitionType, val
|
|
@@ -142,7 +142,7 @@ const getEnrSigner = (
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
const verifyDefinitionSignatures = (
|
|
145
|
-
clusterDefinition:
|
|
145
|
+
clusterDefinition: ClusterDefinition,
|
|
146
146
|
definitionType: DefinitionFlow,
|
|
147
147
|
): boolean => {
|
|
148
148
|
if (definitionType === DefinitionFlow.Charon) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import pdf from 'pdf-parse'
|
|
2
|
+
import { ByteListType, ContainerType } from '@chainsafe/ssz'
|
|
3
|
+
import { TERMS_AND_CONDITIONS_URL } from '../constants'
|
|
4
|
+
import { strToUint8Array } from '../utils'
|
|
5
|
+
|
|
6
|
+
export const hashTermsAndConditions = async (): Promise<string | null> => {
|
|
7
|
+
try {
|
|
8
|
+
// read the pdf
|
|
9
|
+
const response = await fetch(TERMS_AND_CONDITIONS_URL)
|
|
10
|
+
const pdfBuffarrayBuffer = await response.arrayBuffer()
|
|
11
|
+
const pdfBuffer = Buffer.from(pdfBuffarrayBuffer)
|
|
12
|
+
const data = await pdf(pdfBuffer)
|
|
13
|
+
|
|
14
|
+
// ssz hash
|
|
15
|
+
const termsType = new ContainerType({
|
|
16
|
+
terms_and_conditions_hash: new ByteListType(Number.MAX_SAFE_INTEGER),
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const termsHasVal = termsType.defaultValue()
|
|
20
|
+
|
|
21
|
+
termsHasVal.terms_and_conditions_hash = strToUint8Array(data?.text)
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
'0x' +
|
|
25
|
+
Buffer.from(termsType.hashTreeRoot(termsHasVal).buffer).toString('hex')
|
|
26
|
+
)
|
|
27
|
+
} catch (err) {
|
|
28
|
+
return null
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -3,7 +3,7 @@ import { strToUint8Array } from '../utils'
|
|
|
3
3
|
import { type creatorAddressWrapperType, type creatorContainerType, newCreatorContainerType, newOperatorContainerType, type operatorAddressWrapperType, type operatorContainerType, validatorsContainerType } from './sszTypes'
|
|
4
4
|
import { ByteListType, ByteVectorType, ContainerType, ListCompositeType, fromHexString } from '@chainsafe/ssz'
|
|
5
5
|
import { type ValueOfFields } from '@chainsafe/ssz/lib/view/container'
|
|
6
|
-
import { type
|
|
6
|
+
import { type ClusterDefinition, type ClusterLock, type DepositData } from '../types'
|
|
7
7
|
import { verifyDepositData } from './common'
|
|
8
8
|
import { aggregateSignatures, verifyAggregate, verifyMultiple } from '@chainsafe/bls'
|
|
9
9
|
|
|
@@ -61,7 +61,7 @@ export const clusterDefinitionContainerTypeV1X6 = (
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export const hashClusterDefinitionV1X6 = (
|
|
64
|
-
cluster:
|
|
64
|
+
cluster: ClusterDefinition,
|
|
65
65
|
configOnly: boolean,
|
|
66
66
|
): ValueOfFields<DefinitionFieldsV1X6> => {
|
|
67
67
|
const definitionType = clusterDefinitionContainerTypeV1X6(configOnly)
|
|
@@ -3,7 +3,7 @@ import { strToUint8Array } from '../utils'
|
|
|
3
3
|
import { builderRegistrationContainer, type creatorAddressWrapperType, type creatorContainerType, depositDataContainer, newCreatorContainerType, newOperatorContainerType, type operatorAddressWrapperType, type operatorContainerType, validatorsContainerType } from './sszTypes'
|
|
4
4
|
import { ByteListType, ByteVectorType, ContainerType, ListCompositeType, fromHexString } from '@chainsafe/ssz'
|
|
5
5
|
import { type ValueOfFields } from '@chainsafe/ssz/lib/view/container'
|
|
6
|
-
import { type
|
|
6
|
+
import { type ClusterDefinition, type ClusterLock, type DepositData } from '../types'
|
|
7
7
|
import { verifyBuilderRegistration, verifyDepositData, verifyNodeSignatures } from './common'
|
|
8
8
|
import { aggregateSignatures, verifyAggregate, verifyMultiple } from '@chainsafe/bls'
|
|
9
9
|
|
|
@@ -61,7 +61,7 @@ export const clusterDefinitionContainerTypeV1X7 = (
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export const hashClusterDefinitionV1X7 = (
|
|
64
|
-
cluster:
|
|
64
|
+
cluster: ClusterDefinition,
|
|
65
65
|
configOnly: boolean,
|
|
66
66
|
): ValueOfFields<DefinitionFieldsV1X7> => {
|
|
67
67
|
const definitionType = clusterDefinitionContainerTypeV1X7(configOnly)
|
|
@@ -3,7 +3,7 @@ import { strToUint8Array } from '../utils'
|
|
|
3
3
|
import { builderRegistrationContainer, type creatorAddressWrapperType, type creatorContainerType, depositDataContainer, newCreatorContainerType, newOperatorContainerType, type operatorAddressWrapperType, type operatorContainerType, validatorsContainerType } from './sszTypes'
|
|
4
4
|
import { ByteListType, ByteVectorType, ContainerType, ListBasicType, ListCompositeType, fromHexString } from '@chainsafe/ssz'
|
|
5
5
|
import { type ValueOfFields } from '@chainsafe/ssz/lib/view/container'
|
|
6
|
-
import { type
|
|
6
|
+
import { type ClusterDefinition, type ClusterLock, type DepositData } from '../types'
|
|
7
7
|
import { verifyBuilderRegistration, verifyDepositData, verifyNodeSignatures } from './common'
|
|
8
8
|
import { aggregateSignatures, verifyAggregate, verifyMultiple } from '@chainsafe/bls'
|
|
9
9
|
|
|
@@ -65,7 +65,7 @@ export const clusterDefinitionContainerTypeV1X8 = (
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
export const hashClusterDefinitionV1X8 = (
|
|
68
|
-
cluster:
|
|
68
|
+
cluster: ClusterDefinition,
|
|
69
69
|
configOnly: boolean,
|
|
70
70
|
): ValueOfFields<DefinitionFieldsV1X8> => {
|
|
71
71
|
const definitionType = clusterDefinitionContainerTypeV1X8(configOnly)
|