@obolnetwork/obol-sdk 1.0.12 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/LICENCE +21 -0
  2. package/README.md +33 -3
  3. package/dist/cjs/package.json +128 -0
  4. package/dist/cjs/src/ajv.js +2 -1
  5. package/dist/cjs/src/base.js +2 -2
  6. package/dist/cjs/src/constants.js +38 -13
  7. package/dist/cjs/src/errors.js +1 -1
  8. package/dist/cjs/src/index.js +24 -21
  9. package/dist/cjs/src/schema.js +24 -36
  10. package/dist/cjs/src/services.js +2 -2
  11. package/dist/cjs/src/types.js +0 -1
  12. package/dist/cjs/src/utils.js +36 -1
  13. package/dist/cjs/src/{verify.js → verification/common.js} +128 -155
  14. package/dist/cjs/src/verification/sszTypes.js +69 -0
  15. package/dist/cjs/src/verification/v1.6.0.js +149 -0
  16. package/dist/cjs/src/verification/v1.7.0.js +173 -0
  17. package/dist/cjs/src/verification/v1.8.0.js +183 -0
  18. package/dist/cjs/test/fixtures.js +281 -63
  19. package/dist/cjs/test/methods.test.js +58 -35
  20. package/dist/esm/package.json +128 -0
  21. package/dist/esm/src/ajv.js +2 -1
  22. package/dist/esm/src/base.js +2 -2
  23. package/dist/esm/src/constants.js +14 -12
  24. package/dist/esm/src/errors.js +1 -1
  25. package/dist/esm/src/index.js +27 -24
  26. package/dist/esm/src/schema.js +24 -36
  27. package/dist/esm/src/services.js +1 -1
  28. package/dist/esm/src/types.js +0 -1
  29. package/dist/esm/src/utils.js +34 -0
  30. package/dist/esm/src/{verify.js → verification/common.js} +114 -146
  31. package/dist/esm/src/verification/sszTypes.js +64 -0
  32. package/dist/esm/src/verification/v1.6.0.js +142 -0
  33. package/dist/esm/src/verification/v1.7.0.js +166 -0
  34. package/dist/esm/src/verification/v1.8.0.js +176 -0
  35. package/dist/esm/test/fixtures.js +280 -62
  36. package/dist/esm/test/methods.test.js +59 -36
  37. package/dist/types/src/ajv.d.ts +1 -1
  38. package/dist/types/src/base.d.ts +3 -3
  39. package/dist/types/src/constants.d.ts +8 -10
  40. package/dist/types/src/index.d.ts +16 -16
  41. package/dist/types/src/services.d.ts +1 -1
  42. package/dist/types/src/types.d.ts +33 -27
  43. package/dist/types/src/utils.d.ts +3 -0
  44. package/dist/types/src/verification/common.d.ts +32 -0
  45. package/dist/types/src/verification/sszTypes.d.ts +63 -0
  46. package/dist/types/src/verification/v1.6.0.d.ts +34 -0
  47. package/dist/types/src/verification/v1.7.0.d.ts +34 -0
  48. package/dist/types/src/verification/v1.8.0.d.ts +35 -0
  49. package/dist/types/test/fixtures.d.ts +104 -2
  50. package/package.json +42 -8
  51. package/src/ajv.ts +15 -10
  52. package/src/base.ts +25 -21
  53. package/src/constants.ts +80 -78
  54. package/src/errors.ts +6 -9
  55. package/src/index.ts +118 -81
  56. package/src/schema.ts +24 -36
  57. package/src/services.ts +15 -13
  58. package/src/types.ts +72 -74
  59. package/src/utils.ts +53 -4
  60. package/src/verification/common.ts +420 -0
  61. package/src/verification/sszTypes.ts +79 -0
  62. package/src/verification/v1.6.0.ts +226 -0
  63. package/src/verification/v1.7.0.ts +274 -0
  64. package/src/verification/v1.8.0.ts +281 -0
  65. package/dist/cjs/src/hash.js +0 -172
  66. package/dist/esm/src/hash.js +0 -165
  67. package/dist/types/src/hash.d.ts +0 -56
  68. package/dist/types/src/verify.d.ts +0 -4
  69. package/src/hash.ts +0 -250
  70. package/src/verify.ts +0 -479
@@ -0,0 +1,128 @@
1
+ {
2
+ "name": "@obolnetwork/obol-sdk",
3
+ "version": "1.0.13",
4
+ "description": "A package for creating Distributed Validators using the Obol API.",
5
+ "bugs": {
6
+ "url": "https://github.com/obolnetwork/obol-sdk/issues"
7
+ },
8
+ "homepage": "https://docs.obol.tech/",
9
+ "keywords": [
10
+ "Obol",
11
+ "Distributed Validators",
12
+ "Ethereum"
13
+ ],
14
+ "scripts": {
15
+ "compile": "tsc -b ./tsconfig.cjs.json ./tsconfig.esm.json ./tsconfig.types.json",
16
+ "build:clean": "rm -rf ./dist",
17
+ "build": "npm-run-all build:clean compile",
18
+ "test": "jest ./test/methods.test.ts",
19
+ "generate-typedoc": "typedoc",
20
+ "npm:publish": "npm publish --tag latest",
21
+ "release": "release-it",
22
+ "release:dry": "release-it --dry-run --no-npm",
23
+ "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
24
+ "lint-ci": "eslint \"{src,apps,libs,test}/**/*.ts\""
25
+ },
26
+ "main": "./dist/cjs/src/index.js",
27
+ "module": "./dist/esm/src/index.js",
28
+ "typings": "./dist/types/src/index.d.ts",
29
+ "author": "Obol Labs (https://obol.tech)",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/obolnetwork/obol-sdk.git"
33
+ },
34
+ "license": "ISC",
35
+ "publishConfig": {
36
+ "registry": "https://registry.npmjs.org/",
37
+ "access": "public"
38
+ },
39
+ "dependencies": {
40
+ "@chainsafe/bls": "6.0.3",
41
+ "@chainsafe/blst": "^0.2.9",
42
+ "@chainsafe/discv5": "^0.5.1",
43
+ "@chainsafe/ssz": "^0.14.0",
44
+ "@metamask/eth-sig-util": "^7.0.1",
45
+ "ajv": "^8.12.0",
46
+ "cross-fetch": "^3.1.5",
47
+ "elliptic": "^6.5.4",
48
+ "eslint-config-standard-with-typescript": "^43.0.1",
49
+ "eslint-plugin-import": "^2.29.1",
50
+ "eslint-plugin-n": "^16.6.2",
51
+ "eslint-plugin-promise": "^6.1.1",
52
+ "ethers": "^6.4.0",
53
+ "nock": "^13.5.3",
54
+ "release-it": "^17.1.1",
55
+ "semver": "^7.6.0",
56
+ "typescript-eslint": "^7.1.0",
57
+ "uuid": "^9.0.0"
58
+ },
59
+ "devDependencies": {
60
+ "@release-it/conventional-changelog": "^8.0.1",
61
+ "@types/elliptic": "^6.4.18",
62
+ "@types/jest": "^28.1.8",
63
+ "@types/node": "^20.2.5",
64
+ "@types/uuid": "^9.0.1",
65
+ "eslint": "^8.57.0",
66
+ "jest": "^28.1.3",
67
+ "msw": "^2.2.1",
68
+ "npm-run-all": "^4.1.5",
69
+ "ts-jest": "^28.0.8",
70
+ "tsup": "^6.7.0",
71
+ "typedoc": "^0.25.7",
72
+ "typedoc-plugin-markdown": "^4.0.0-next.50",
73
+ "typescript": "^5.3.3"
74
+ },
75
+ "engines": {
76
+ "node": ">= 16"
77
+ },
78
+ "files": [
79
+ "package.json",
80
+ "README.md",
81
+ "dist",
82
+ "src"
83
+ ],
84
+ "release-it": {
85
+ "git": {
86
+ "commitMessage": "chore(release): v${version}",
87
+ "push": true,
88
+ "commit": true,
89
+ "tag": true,
90
+ "requireCommits": false,
91
+ "requireCleanWorkingDir": false
92
+ },
93
+ "github": {
94
+ "release": true,
95
+ "draft": true
96
+ },
97
+ "npm": {
98
+ "publish": false,
99
+ "ignoreVersion": false
100
+ },
101
+ "plugins": {
102
+ "@release-it/conventional-changelog": {
103
+ "preset": "angular",
104
+ "infile": "CHANGELOG.md",
105
+ "header": "# Changelog"
106
+ }
107
+ }
108
+ },
109
+ "jest": {
110
+ "transform": {
111
+ "\\.[jt]sx?$": "ts-jest"
112
+ },
113
+ "globals": {
114
+ "ts-jest": {
115
+ "useESM": true
116
+ }
117
+ },
118
+ "moduleNameMapper": {
119
+ "^bn.js$": "<rootDir>/node_modules/bn.js",
120
+ "^asn1.js$": "<rootDir>/node_modules/asn1.js",
121
+ "^hash.js$": "<rootDir>/node_modules/hash.js",
122
+ "(.+)\\.js": "$1"
123
+ },
124
+ "extensionsToTreatAsEsm": [
125
+ ".ts"
126
+ ]
127
+ }
128
+ }
@@ -1,10 +1,11 @@
1
1
  import Ajv from 'ajv';
2
2
  export function validatePayload(data, schema) {
3
+ var _a;
3
4
  const ajv = new Ajv();
4
5
  const validate = ajv.compile(schema);
5
6
  const isValid = validate(data);
6
7
  if (!isValid) {
7
- throw new Error(`Schema compilation errors', ${validate.errors && validate.errors[0].message}`);
8
+ throw new Error(`Schema compilation errors', ${(_a = validate.errors) === null || _a === void 0 ? void 0 : _a[0].message}`);
8
9
  }
9
10
  return isValid;
10
11
  }
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
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
- constructor({ baseUrl = DEFAULT_BASE_URL, chainId = DEFAULT_CHAIN_ID }) {
14
+ constructor({ baseUrl = DEFAULT_BASE_URL, chainId = DEFAULT_CHAIN_ID, }) {
15
15
  this.baseUrl = baseUrl;
16
16
  this.chainId = chainId;
17
17
  this.fork_version = FORK_MAPPING[this.chainId];
@@ -23,7 +23,7 @@ export class Base {
23
23
  try {
24
24
  const response = yield fetch(url, config);
25
25
  if (response.ok) {
26
- return (yield response.json());
26
+ return yield response.json();
27
27
  }
28
28
  throw new Error(response.statusText);
29
29
  }
@@ -1,8 +1,9 @@
1
- export const CONFLICT_ERROR_MSG = "Conflict";
2
- export const EIP712_DOMAIN_NAME = "Obol";
3
- export const EIP712_DOMAIN_VERSION = "1";
1
+ import * as pjson from '../package.json';
2
+ export const CONFLICT_ERROR_MSG = 'Conflict';
3
+ export const EIP712_DOMAIN_NAME = 'Obol';
4
+ export const EIP712_DOMAIN_VERSION = '1';
4
5
  export const CreatorConfigHashSigningTypes = {
5
- CreatorConfigHash: [{ name: "creator_config_hash", type: "string" }],
6
+ CreatorConfigHash: [{ name: 'creator_config_hash', type: 'string' }],
6
7
  };
7
8
  const EIP712Domain = [
8
9
  { name: 'name', type: 'string' },
@@ -17,12 +18,12 @@ export const Domain = (chainId) => {
17
18
  };
18
19
  };
19
20
  export const CreatorTypedMessage = Object.assign({ EIP712Domain }, CreatorConfigHashSigningTypes);
20
- //A conflict once updateDefinition is merged
21
+ // A conflict once updateDefinition is merged
21
22
  export const EnrSigningTypes = {
22
- ENR: [{ name: "enr", type: "string" }],
23
+ ENR: [{ name: 'enr', type: 'string' }],
23
24
  };
24
25
  export const OperatorConfigHashSigningTypes = {
25
- OperatorConfigHash: [{ name: "operator_config_hash", type: "string" }],
26
+ OperatorConfigHash: [{ name: 'operator_config_hash', type: 'string' }],
26
27
  };
27
28
  export const OperatorTypedMessage = Object.assign({ EIP712Domain }, OperatorConfigHashSigningTypes);
28
29
  export const ENRTypedMessage = Object.assign({ EIP712Domain }, EnrSigningTypes);
@@ -62,9 +63,9 @@ export const signEnrPayload = (payload, chainId) => {
62
63
  message: payload,
63
64
  };
64
65
  };
65
- export const dkg_algorithm = "default";
66
- export const config_version = "v1.7.0";
67
- export const SDK_VERSION = "1.0.7";
66
+ export const DKG_ALGORITHM = 'default';
67
+ export const CONFIG_VERSION = 'v1.7.0';
68
+ export const SDK_VERSION = pjson.version;
68
69
  export const DOMAIN_APPLICATION_BUILDER = '00000001';
69
70
  export const DOMAIN_DEPOSIT = '03000000';
70
71
  export const GENESIS_VALIDATOR_ROOT = '0000000000000000000000000000000000000000000000000000000000000000';
@@ -75,5 +76,6 @@ export var DefinitionFlow;
75
76
  DefinitionFlow["Solo"] = "LP-Solo";
76
77
  DefinitionFlow["Charon"] = "Charon-Command";
77
78
  })(DefinitionFlow || (DefinitionFlow = {}));
78
- export const DEFAULT_BASE_URL = "https://api.obol.tech";
79
- export const DEFAULT_CHAIN_ID = 1;
79
+ export const DEFAULT_BASE_URL = 'https://api.obol.tech';
80
+ export const DEFAULT_CHAIN_ID = 17000;
81
+ export const ETHER_TO_GWEI = 10 ** 9;
@@ -1,6 +1,6 @@
1
1
  export class ConflictError extends Error {
2
2
  constructor() {
3
- super(`This Cluster has been already posted.`);
3
+ super('This Cluster has been already posted.');
4
4
  this.name = 'ConflictError';
5
5
  Object.setPrototypeOf(this, ConflictError.prototype);
6
6
  }
@@ -7,15 +7,15 @@ 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 { v4 as uuidv4 } from "uuid";
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, } from './constants.js';
13
13
  import { ConflictError } from './errors.js';
14
- import { clusterConfigOrDefinitionHash } from './hash.js';
14
+ import { clusterConfigOrDefinitionHash } from './verification/common.js';
15
15
  import { validatePayload } from './ajv.js';
16
16
  import { definitionSchema, operatorPayloadSchema } from './schema.js';
17
- export * from "./types.js";
18
- export * from "./services.js";
17
+ export * from './types.js';
18
+ export * from './services.js';
19
19
  /**
20
20
  * Obol sdk Client can be used for creating, managing and activating distributed validators.
21
21
  */
@@ -45,46 +45,49 @@ export class Client extends Base {
45
45
  */
46
46
  createClusterDefinition(newCluster) {
47
47
  return __awaiter(this, void 0, void 0, function* () {
48
- if (!this.signer)
49
- throw "Signer is required in createClusterDefinition";
48
+ if (!this.signer) {
49
+ throw new Error('Signer is required in createClusterDefinition');
50
+ }
50
51
  validatePayload(newCluster, definitionSchema);
51
- 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 });
52
+ 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 });
52
53
  try {
53
54
  const address = yield this.signer.getAddress();
54
55
  clusterConfig.creator = { address };
55
56
  clusterConfig.config_hash = clusterConfigOrDefinitionHash(clusterConfig, true);
56
57
  const creatorConfigSignature = yield this.signer.signTypedData(Domain(this.chainId), CreatorConfigHashSigningTypes, { creator_config_hash: clusterConfig.config_hash });
57
- const clusterDefinition = yield this.request(`/dv`, {
58
+ const clusterDefinition = yield this.request('/dv', {
58
59
  method: 'POST',
59
60
  body: JSON.stringify(clusterConfig),
60
61
  headers: {
61
62
  Authorization: `Bearer ${creatorConfigSignature}`,
62
- "fork-version": this.fork_version,
63
- }
63
+ 'fork-version': this.fork_version,
64
+ },
64
65
  });
65
66
  return clusterDefinition === null || clusterDefinition === void 0 ? void 0 : clusterDefinition.config_hash;
66
67
  }
67
68
  catch (err) {
68
- if ((err === null || err === void 0 ? void 0 : err.message) == CONFLICT_ERROR_MSG)
69
+ if ((err === null || err === void 0 ? void 0 : err.message) === CONFLICT_ERROR_MSG) {
69
70
  throw new ConflictError();
71
+ }
70
72
  throw err;
71
73
  }
72
74
  });
73
75
  }
74
76
  /**
75
- * Approves joining a cluster with specific configuration.
76
- * @param {OperatorPayload} operatorPayload - The operator data including signatures.
77
- * @param {string} configHash - The config hash of the cluster which the operator confirms joining to.
78
- * @returns {Promise<ClusterDefintion>} The cluster definition.
79
- * @throws On unauthorized, duplicate entries, missing keys, not found cluster or invalid data.
80
- *
81
- * An example of how to use acceptClusterDefinition:
82
- * [acceptClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
83
- */
77
+ * Approves joining a cluster with specific configuration.
78
+ * @param {OperatorPayload} operatorPayload - The operator data including signatures.
79
+ * @param {string} configHash - The config hash of the cluster which the operator confirms joining to.
80
+ * @returns {Promise<ClusterDefintion>} The cluster definition.
81
+ * @throws On unauthorized, duplicate entries, missing keys, not found cluster or invalid data.
82
+ *
83
+ * An example of how to use acceptClusterDefinition:
84
+ * [acceptClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
85
+ */
84
86
  acceptClusterDefinition(operatorPayload, configHash) {
85
87
  return __awaiter(this, void 0, void 0, function* () {
86
- if (!this.signer)
87
- throw "Signer is required in acceptClusterDefinition";
88
+ if (!this.signer) {
89
+ throw new Error('Signer is required in acceptClusterDefinition');
90
+ }
88
91
  validatePayload(operatorPayload, operatorPayloadSchema);
89
92
  try {
90
93
  const address = yield this.signer.getAddress();
@@ -96,7 +99,7 @@ export class Client extends Base {
96
99
  body: JSON.stringify(operatorData),
97
100
  headers: {
98
101
  Authorization: `Bearer ${operatorConfigSignature}`,
99
- }
102
+ },
100
103
  });
101
104
  return clusterDefinition;
102
105
  }
@@ -1,69 +1,57 @@
1
1
  export const operatorPayloadSchema = {
2
- type: "object",
2
+ type: 'object',
3
3
  properties: {
4
4
  version: {
5
- type: "string"
5
+ type: 'string',
6
6
  },
7
7
  enr: {
8
- type: "string"
8
+ type: 'string',
9
9
  },
10
10
  },
11
- required: [
12
- "version",
13
- "enr",
14
- ]
11
+ required: ['version', 'enr'],
15
12
  };
16
13
  export const definitionSchema = {
17
- type: "object",
14
+ type: 'object',
18
15
  properties: {
19
16
  name: {
20
- type: "string"
17
+ type: 'string',
21
18
  },
22
19
  operators: {
23
- type: "array",
20
+ type: 'array',
24
21
  minItems: 4,
25
22
  uniqueItems: true,
26
23
  items: {
27
- type: "object",
24
+ type: 'object',
28
25
  properties: {
29
26
  address: {
30
- type: "string",
27
+ type: 'string',
31
28
  minLength: 42,
32
- maxLength: 42
33
- }
29
+ maxLength: 42,
30
+ },
34
31
  },
35
- required: [
36
- "address"
37
- ]
38
- }
32
+ required: ['address'],
33
+ },
39
34
  },
40
35
  validators: {
41
- type: "array",
36
+ type: 'array',
42
37
  minItems: 1,
43
38
  items: {
44
- type: "object",
39
+ type: 'object',
45
40
  properties: {
46
41
  fee_recipient_address: {
47
- type: "string",
42
+ type: 'string',
48
43
  minLength: 42,
49
- maxLength: 42
44
+ maxLength: 42,
50
45
  },
51
46
  withdrawal_address: {
52
- type: "string",
47
+ type: 'string',
53
48
  minLength: 42,
54
- maxLength: 42
55
- }
49
+ maxLength: 42,
50
+ },
56
51
  },
57
- required: [
58
- "fee_recipient_address",
59
- "withdrawal_address"
60
- ]
61
- }
62
- }
52
+ required: ['fee_recipient_address', 'withdrawal_address'],
53
+ },
54
+ },
63
55
  },
64
- required: [
65
- "name",
66
- "operators",
67
- "validators"
68
- ]
56
+ required: ['name', 'operators', 'validators'],
69
57
  };
@@ -7,7 +7,7 @@ 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 { isValidClusterLock } from "./verify.js";
10
+ import { isValidClusterLock } from './verification/common.js';
11
11
  /**
12
12
  * Verifies Cluster Lock's validity.
13
13
  * @param lock - cluster lock
@@ -12,4 +12,3 @@ export var FORK_MAPPING;
12
12
  /** Holesky. */
13
13
  FORK_MAPPING[FORK_MAPPING["0x01017000"] = 17000] = "0x01017000";
14
14
  })(FORK_MAPPING || (FORK_MAPPING = {}));
15
- ;
@@ -1,6 +1,40 @@
1
+ import { DefinitionFlow } from './constants';
1
2
  export const hexWithout0x = (hex) => {
2
3
  return hex.slice(2, hex.length);
3
4
  };
4
5
  export const strToUint8Array = (str) => {
5
6
  return new TextEncoder().encode(str);
6
7
  };
8
+ export const definitionFlow = (clusterDefinition) => {
9
+ if (clusterDefinition.creator.address &&
10
+ clusterDefinition.creator.config_signature &&
11
+ clusterDefinition.operators.every((operator) => {
12
+ return (operator.address &&
13
+ operator.config_signature &&
14
+ operator.enr &&
15
+ operator.enr_signature);
16
+ })) {
17
+ return DefinitionFlow.Group;
18
+ }
19
+ else if (clusterDefinition.creator.address &&
20
+ clusterDefinition.creator.config_signature &&
21
+ clusterDefinition.operators.every((operator) => {
22
+ return (!operator.address &&
23
+ !operator.config_signature &&
24
+ operator.enr &&
25
+ !operator.enr_signature);
26
+ })) {
27
+ return DefinitionFlow.Solo;
28
+ }
29
+ else if (!clusterDefinition.creator.address &&
30
+ !clusterDefinition.creator.config_signature &&
31
+ clusterDefinition.operators.every((operator) => {
32
+ return (!operator.address &&
33
+ !operator.config_signature &&
34
+ operator.enr &&
35
+ !operator.enr_signature);
36
+ })) {
37
+ return DefinitionFlow.Charon;
38
+ }
39
+ return null;
40
+ };