@obolnetwork/obol-sdk 1.0.14 → 1.0.16

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 (40) hide show
  1. package/dist/cjs/package.json +6 -3
  2. package/dist/cjs/src/base.js +4 -1
  3. package/dist/cjs/src/constants.js +15 -4
  4. package/dist/cjs/src/index.js +51 -8
  5. package/dist/cjs/src/services.js +1 -1
  6. package/dist/cjs/src/verification/termsAndConditions.js +40 -0
  7. package/dist/cjs/src/verification/v1.8.0.js +1 -1
  8. package/dist/cjs/test/fixtures.js +64 -69
  9. package/dist/cjs/test/methods.test.js +12 -0
  10. package/dist/esm/package.json +6 -3
  11. package/dist/esm/src/base.js +4 -1
  12. package/dist/esm/src/constants.js +14 -3
  13. package/dist/esm/src/index.js +52 -9
  14. package/dist/esm/src/services.js +1 -1
  15. package/dist/esm/src/verification/termsAndConditions.js +33 -0
  16. package/dist/esm/src/verification/v1.8.0.js +1 -1
  17. package/dist/esm/test/fixtures.js +64 -69
  18. package/dist/esm/test/methods.test.js +12 -0
  19. package/dist/types/src/constants.d.ts +9 -1
  20. package/dist/types/src/index.d.ts +18 -9
  21. package/dist/types/src/services.d.ts +1 -1
  22. package/dist/types/src/types.d.ts +2 -2
  23. package/dist/types/src/utils.d.ts +2 -2
  24. package/dist/types/src/verification/common.d.ts +2 -2
  25. package/dist/types/src/verification/termsAndConditions.d.ts +1 -0
  26. package/dist/types/src/verification/v1.6.0.d.ts +2 -2
  27. package/dist/types/src/verification/v1.7.0.d.ts +2 -2
  28. package/dist/types/src/verification/v1.8.0.d.ts +2 -2
  29. package/package.json +6 -3
  30. package/src/base.ts +4 -2
  31. package/src/constants.ts +16 -4
  32. package/src/index.ts +63 -15
  33. package/src/services.ts +1 -1
  34. package/src/types.ts +2 -2
  35. package/src/utils.ts +2 -2
  36. package/src/verification/common.ts +3 -3
  37. package/src/verification/termsAndConditions.ts +30 -0
  38. package/src/verification/v1.6.0.ts +2 -2
  39. package/src/verification/v1.7.0.ts +2 -2
  40. package/src/verification/v1.8.0.ts +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obolnetwork/obol-sdk",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
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": "^6.4.0",
53
+ "ethers": "6.4.0",
53
54
  "nock": "^13.5.3",
54
- "release-it": "^17.1.1",
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
- throw new Error(response.statusText)
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: number): TypedDataDomain => {
20
- return {
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 defintion
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 ClusterDefintion,
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,51 @@ 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
+ * An example of how to use acceptObolLatestTermsAndConditions:
59
+ * [acceptObolLatestTermsAndConditions](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L44)
60
+ */
61
+ async acceptObolLatestTermsAndConditions (): Promise<string> {
62
+ if (!this.signer) { throw new Error('Signer is required in acceptObolTermsAndConditions') }
63
+
64
+ try {
65
+ const termsAndConditionsHash = await hashTermsAndConditions()
66
+ const address = await this.signer.getAddress()
67
+ const termsAndConditionsPayload = {
68
+ address,
69
+ version: TERMS_AND_CONDITIONS_VERSION,
70
+ terms_and_conditions_hash: termsAndConditionsHash
71
+ }
72
+
73
+ const termsAndConditionsSignature = await this.signer.signTypedData(
74
+ Domain(),
75
+ TermsAndConditionsSigningTypes,
76
+ {
77
+ terms_and_conditions_hash: termsAndConditionsHash,
78
+ version: TERMS_AND_CONDITIONS_VERSION,
79
+ },
80
+ )
81
+
82
+ const termsAndConditionsResponse: { message: string, success: boolean } = await this.request('/termsAndConditions', {
83
+ method: 'POST',
84
+ body: JSON.stringify(termsAndConditionsPayload),
85
+ headers: {
86
+ Authorization: `Bearer ${termsAndConditionsSignature}`,
87
+ },
88
+ })
89
+ return termsAndConditionsResponse?.message
90
+ } catch (err: any) {
91
+ if (err?.message === CONFLICT_ERROR_MSG) {
92
+ throw new ConflictError()
93
+ }
94
+ throw err
95
+ }
96
+ }
97
+
50
98
  /**
51
99
  * Creates a cluster definition which contains cluster configuration.
52
100
  * @param {ClusterPayload} newCluster - The new unique cluster.
@@ -54,14 +102,14 @@ export class Client extends Base {
54
102
  * @throws On duplicate entries, missing or wrong cluster keys.
55
103
  *
56
104
  * An example of how to use createClusterDefinition:
57
- * [createObolCluster](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
105
+ * [createObolCluster](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L59)
58
106
  */
59
107
  async createClusterDefinition (newCluster: ClusterPayload): Promise<string> {
60
108
  if (!this.signer) { throw new Error('Signer is required in createClusterDefinition') }
61
109
 
62
110
  validatePayload(newCluster, definitionSchema)
63
111
 
64
- const clusterConfig: Partial<ClusterDefintion> = {
112
+ const clusterConfig: Partial<ClusterDefinition> = {
65
113
  ...newCluster,
66
114
  fork_version: this.fork_version,
67
115
  dkg_algorithm: DKG_ALGORITHM,
@@ -77,7 +125,7 @@ export class Client extends Base {
77
125
 
78
126
  clusterConfig.creator = { address }
79
127
  clusterConfig.config_hash = clusterConfigOrDefinitionHash(
80
- clusterConfig as ClusterDefintion,
128
+ clusterConfig as ClusterDefinition,
81
129
  true,
82
130
  )
83
131
 
@@ -87,7 +135,7 @@ export class Client extends Base {
87
135
  { creator_config_hash: clusterConfig.config_hash },
88
136
  )
89
137
 
90
- const clusterDefinition: ClusterDefintion = await this.request('/dv', {
138
+ const clusterDefinition: ClusterDefinition = await this.request('/v1/definition', {
91
139
  method: 'POST',
92
140
  body: JSON.stringify(clusterConfig),
93
141
  headers: {
@@ -108,16 +156,16 @@ export class Client extends Base {
108
156
  * Approves joining a cluster with specific configuration.
109
157
  * @param {OperatorPayload} operatorPayload - The operator data including signatures.
110
158
  * @param {string} configHash - The config hash of the cluster which the operator confirms joining to.
111
- * @returns {Promise<ClusterDefintion>} The cluster definition.
159
+ * @returns {Promise<ClusterDefinition>} The cluster definition.
112
160
  * @throws On unauthorized, duplicate entries, missing keys, not found cluster or invalid data.
113
161
  *
114
162
  * An example of how to use acceptClusterDefinition:
115
- * [acceptClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
163
+ * [acceptClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L106)
116
164
  */
117
165
  async acceptClusterDefinition (
118
166
  operatorPayload: OperatorPayload,
119
167
  configHash: string,
120
- ): Promise<ClusterDefintion> {
168
+ ): Promise<ClusterDefinition> {
121
169
  if (!this.signer) { throw new Error('Signer is required in acceptClusterDefinition') }
122
170
 
123
171
  validatePayload(operatorPayload, operatorPayloadSchema)
@@ -142,8 +190,8 @@ export class Client extends Base {
142
190
  enr_signature: operatorENRSignature,
143
191
  fork_version: this.fork_version,
144
192
  }
145
- const clusterDefinition: ClusterDefintion = await this.request(
146
- `/dv/${configHash}`,
193
+ const clusterDefinition: ClusterDefinition = await this.request(
194
+ `/v1/definition/${configHash}`,
147
195
  {
148
196
  method: 'PUT',
149
197
  body: JSON.stringify(operatorData),
@@ -160,14 +208,14 @@ export class Client extends Base {
160
208
 
161
209
  /**
162
210
  * @param configHash - The configuration hash returned in createClusterDefinition
163
- * @returns {Promise<ClusterDefintion>} The cluster definition for config hash
211
+ * @returns {Promise<ClusterDefinition>} The cluster definition for config hash
164
212
  * @throws On not found config hash.
165
213
  *
166
214
  * An example of how to use getClusterDefinition:
167
- * [getObolClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
215
+ * [getObolClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L74)
168
216
  */
169
- async getClusterDefinition (configHash: string): Promise<ClusterDefintion> {
170
- const clusterDefinition: ClusterDefintion = await this.request(
217
+ async getClusterDefinition (configHash: string): Promise<ClusterDefinition> {
218
+ const clusterDefinition: ClusterDefinition = await this.request(
171
219
  `/dv/${configHash}`,
172
220
  {
173
221
  method: 'GET',
@@ -183,7 +231,7 @@ export class Client extends Base {
183
231
  * @throws On not found cluster definition or lock.
184
232
  *
185
233
  * An example of how to use getClusterLock:
186
- * [getObolClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
234
+ * [getObolClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L89)
187
235
  */
188
236
  async getClusterLock (configHash: string): Promise<ClusterLock> {
189
237
  const lock: ClusterLock = await this.request(
package/src/services.ts CHANGED
@@ -8,7 +8,7 @@ import { isValidClusterLock } from './verification/common.js'
8
8
  * @throws on missing keys or values.
9
9
  *
10
10
  * An example of how to use validateClusterLock:
11
- * [validateClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
11
+ * [validateClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L127)
12
12
  */
13
13
  export const validateClusterLock = async (
14
14
  lock: ClusterLock,
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 ClusterDefintion extends ClusterPayload {
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: ClusterDefintion
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 ClusterDefintion } from './types'
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: ClusterDefintion,
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 ClusterDefintion, type ClusterLock, type DepositData, type BuilderRegistrationMessage, type DistributedValidator } from '../types.js'
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: ClusterDefintion,
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: ClusterDefintion,
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 ClusterDefintion, type ClusterLock, type DepositData } from '../types'
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: ClusterDefintion,
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 ClusterDefintion, type ClusterLock, type DepositData } from '../types'
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: ClusterDefintion,
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 ClusterDefintion, type ClusterLock, type DepositData } from '../types'
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: ClusterDefintion,
68
+ cluster: ClusterDefinition,
69
69
  configOnly: boolean,
70
70
  ): ValueOfFields<DefinitionFieldsV1X8> => {
71
71
  const definitionType = clusterDefinitionContainerTypeV1X8(configOnly)
@@ -205,7 +205,7 @@ export const verifyDVV1X8 = (clusterLock: ClusterLock): boolean => {
205
205
 
206
206
  // Deposit Data Verification
207
207
  for (let j = 0; j < (validator.partial_deposit_data as DepositData[]).length; j++) {
208
- const depositData = (validator.partial_deposit_data as DepositData[])[i]
208
+ const depositData = (validator.partial_deposit_data as DepositData[])[j]
209
209
  const { isValidDepositData, depositDataMsg } = verifyDepositData(
210
210
  distributedPublicKey,
211
211
  depositData as Partial<DepositData>,