@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.
- package/LICENCE +21 -0
- package/README.md +33 -3
- package/dist/cjs/package.json +128 -0
- package/dist/cjs/src/ajv.js +2 -1
- package/dist/cjs/src/base.js +2 -2
- package/dist/cjs/src/constants.js +38 -13
- package/dist/cjs/src/errors.js +1 -1
- package/dist/cjs/src/index.js +24 -21
- package/dist/cjs/src/schema.js +24 -36
- package/dist/cjs/src/services.js +2 -2
- package/dist/cjs/src/types.js +0 -1
- package/dist/cjs/src/utils.js +36 -1
- package/dist/cjs/src/{verify.js → verification/common.js} +128 -155
- package/dist/cjs/src/verification/sszTypes.js +69 -0
- package/dist/cjs/src/verification/v1.6.0.js +149 -0
- package/dist/cjs/src/verification/v1.7.0.js +173 -0
- package/dist/cjs/src/verification/v1.8.0.js +183 -0
- package/dist/cjs/test/fixtures.js +281 -63
- package/dist/cjs/test/methods.test.js +58 -35
- package/dist/esm/package.json +128 -0
- package/dist/esm/src/ajv.js +2 -1
- package/dist/esm/src/base.js +2 -2
- package/dist/esm/src/constants.js +14 -12
- package/dist/esm/src/errors.js +1 -1
- package/dist/esm/src/index.js +27 -24
- package/dist/esm/src/schema.js +24 -36
- package/dist/esm/src/services.js +1 -1
- package/dist/esm/src/types.js +0 -1
- package/dist/esm/src/utils.js +34 -0
- package/dist/esm/src/{verify.js → verification/common.js} +114 -146
- package/dist/esm/src/verification/sszTypes.js +64 -0
- package/dist/esm/src/verification/v1.6.0.js +142 -0
- package/dist/esm/src/verification/v1.7.0.js +166 -0
- package/dist/esm/src/verification/v1.8.0.js +176 -0
- package/dist/esm/test/fixtures.js +280 -62
- package/dist/esm/test/methods.test.js +59 -36
- package/dist/types/src/ajv.d.ts +1 -1
- package/dist/types/src/base.d.ts +3 -3
- package/dist/types/src/constants.d.ts +8 -10
- package/dist/types/src/index.d.ts +16 -16
- package/dist/types/src/services.d.ts +1 -1
- package/dist/types/src/types.d.ts +33 -27
- package/dist/types/src/utils.d.ts +3 -0
- package/dist/types/src/verification/common.d.ts +32 -0
- package/dist/types/src/verification/sszTypes.d.ts +63 -0
- package/dist/types/src/verification/v1.6.0.d.ts +34 -0
- package/dist/types/src/verification/v1.7.0.d.ts +34 -0
- package/dist/types/src/verification/v1.8.0.d.ts +35 -0
- package/dist/types/test/fixtures.d.ts +104 -2
- package/package.json +42 -8
- package/src/ajv.ts +15 -10
- package/src/base.ts +25 -21
- package/src/constants.ts +80 -78
- package/src/errors.ts +6 -9
- package/src/index.ts +118 -81
- package/src/schema.ts +24 -36
- package/src/services.ts +15 -13
- package/src/types.ts +72 -74
- package/src/utils.ts +53 -4
- package/src/verification/common.ts +420 -0
- package/src/verification/sszTypes.ts +79 -0
- package/src/verification/v1.6.0.ts +226 -0
- package/src/verification/v1.7.0.ts +274 -0
- package/src/verification/v1.8.0.ts +281 -0
- package/dist/cjs/src/hash.js +0 -172
- package/dist/esm/src/hash.js +0 -165
- package/dist/types/src/hash.d.ts +0 -56
- package/dist/types/src/verify.d.ts +0 -4
- package/src/hash.ts +0 -250
- package/src/verify.ts +0 -479
package/src/ajv.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import Ajv, { ErrorObject } from 'ajv'
|
|
1
|
+
import Ajv, { type ErrorObject } from 'ajv'
|
|
2
2
|
|
|
3
|
-
export function validatePayload(
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
export function validatePayload (
|
|
4
|
+
data: any,
|
|
5
|
+
schema: any,
|
|
6
|
+
): ErrorObject[] | undefined | null | boolean {
|
|
7
|
+
const ajv = new Ajv()
|
|
8
|
+
const validate = ajv.compile(schema)
|
|
9
|
+
const isValid = validate(data)
|
|
10
|
+
if (!isValid) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`Schema compilation errors', ${validate.errors?.[0].message}`,
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
return isValid
|
|
16
|
+
}
|
package/src/base.ts
CHANGED
|
@@ -1,42 +1,46 @@
|
|
|
1
1
|
// src/resources/base.ts
|
|
2
|
-
import { DEFAULT_BASE_URL, DEFAULT_CHAIN_ID, SDK_VERSION } from './constants.js'
|
|
3
|
-
import { FORK_MAPPING } from './types.js'
|
|
2
|
+
import { DEFAULT_BASE_URL, DEFAULT_CHAIN_ID, SDK_VERSION } from './constants.js'
|
|
3
|
+
import { FORK_MAPPING } from './types.js'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
baseUrl?: string
|
|
7
|
-
chainId?: FORK_MAPPING
|
|
8
|
-
}
|
|
5
|
+
interface Config {
|
|
6
|
+
baseUrl?: string
|
|
7
|
+
chainId?: FORK_MAPPING
|
|
8
|
+
}
|
|
9
9
|
|
|
10
10
|
export abstract class Base {
|
|
11
|
-
baseUrl: string
|
|
12
|
-
chainId: number
|
|
13
|
-
fork_version: string
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
baseUrl: string
|
|
12
|
+
chainId: number
|
|
13
|
+
fork_version: string
|
|
16
14
|
|
|
17
|
-
constructor({
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
constructor ({
|
|
16
|
+
baseUrl = DEFAULT_BASE_URL,
|
|
17
|
+
chainId = DEFAULT_CHAIN_ID,
|
|
18
|
+
}: Config) {
|
|
19
|
+
this.baseUrl = baseUrl
|
|
20
|
+
this.chainId = chainId
|
|
20
21
|
this.fork_version = FORK_MAPPING[this.chainId]
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
protected async request<T>(
|
|
24
|
+
protected async request<T>(
|
|
25
|
+
endpoint: string,
|
|
26
|
+
options?: RequestInit,
|
|
27
|
+
): Promise<T> {
|
|
24
28
|
const url = `${this.baseUrl}${endpoint}`
|
|
25
29
|
const config = {
|
|
26
30
|
...options,
|
|
27
31
|
headers: {
|
|
28
32
|
'Content-Type': 'application/json',
|
|
29
33
|
'User-Agent': `Obol-SDK/${SDK_VERSION}`,
|
|
30
|
-
...options?.headers
|
|
31
|
-
}
|
|
32
|
-
}
|
|
34
|
+
...options?.headers,
|
|
35
|
+
},
|
|
36
|
+
}
|
|
33
37
|
|
|
34
38
|
try {
|
|
35
|
-
const response = await fetch(url, config)
|
|
39
|
+
const response = await fetch(url, config)
|
|
36
40
|
if (response.ok) {
|
|
37
|
-
|
|
41
|
+
return await response.json()
|
|
38
42
|
}
|
|
39
|
-
throw new Error(response.statusText)
|
|
43
|
+
throw new Error(response.statusText)
|
|
40
44
|
} catch (e) {
|
|
41
45
|
throw e
|
|
42
46
|
}
|
package/src/constants.ts
CHANGED
|
@@ -1,118 +1,120 @@
|
|
|
1
|
-
import { TypedMessage } from
|
|
1
|
+
import { type TypedMessage } from '@metamask/eth-sig-util'
|
|
2
|
+
import { type TypedDataDomain } from 'ethers'
|
|
3
|
+
import * as pjson from '../package.json'
|
|
2
4
|
|
|
3
|
-
export const CONFLICT_ERROR_MSG =
|
|
5
|
+
export const CONFLICT_ERROR_MSG = 'Conflict'
|
|
4
6
|
|
|
5
|
-
export const EIP712_DOMAIN_NAME =
|
|
6
|
-
export const EIP712_DOMAIN_VERSION =
|
|
7
|
+
export const EIP712_DOMAIN_NAME = 'Obol'
|
|
8
|
+
export const EIP712_DOMAIN_VERSION = '1'
|
|
7
9
|
export const CreatorConfigHashSigningTypes = {
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
+
CreatorConfigHash: [{ name: 'creator_config_hash', type: 'string' }],
|
|
11
|
+
}
|
|
10
12
|
|
|
11
13
|
const EIP712Domain = [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
{ name: 'name', type: 'string' },
|
|
15
|
+
{ name: 'version', type: 'string' },
|
|
16
|
+
{ name: 'chainId', type: 'uint256' },
|
|
15
17
|
]
|
|
16
18
|
|
|
17
|
-
export const Domain = (chainId: number) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
export const Domain = (chainId: number): TypedDataDomain => {
|
|
20
|
+
return {
|
|
21
|
+
name: EIP712_DOMAIN_NAME,
|
|
22
|
+
version: EIP712_DOMAIN_VERSION,
|
|
23
|
+
chainId,
|
|
24
|
+
}
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export const CreatorTypedMessage = {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
28
|
+
EIP712Domain,
|
|
29
|
+
...CreatorConfigHashSigningTypes,
|
|
30
|
+
}
|
|
29
31
|
|
|
30
|
-
//A conflict once updateDefinition is merged
|
|
32
|
+
// A conflict once updateDefinition is merged
|
|
31
33
|
export const EnrSigningTypes = {
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
+
ENR: [{ name: 'enr', type: 'string' }],
|
|
35
|
+
}
|
|
34
36
|
|
|
35
37
|
export const OperatorConfigHashSigningTypes = {
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
+
OperatorConfigHash: [{ name: 'operator_config_hash', type: 'string' }],
|
|
39
|
+
}
|
|
38
40
|
|
|
39
41
|
export const OperatorTypedMessage = {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
42
|
+
EIP712Domain,
|
|
43
|
+
...OperatorConfigHashSigningTypes,
|
|
44
|
+
}
|
|
43
45
|
|
|
44
46
|
export const ENRTypedMessage = {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
47
|
+
EIP712Domain,
|
|
48
|
+
...EnrSigningTypes,
|
|
49
|
+
}
|
|
48
50
|
|
|
49
51
|
export const signCreatorConfigHashPayload = (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
payload: { creator_config_hash: string },
|
|
53
|
+
chainId: number,
|
|
52
54
|
): TypedMessage<typeof CreatorTypedMessage> => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
55
|
+
return {
|
|
56
|
+
types: CreatorTypedMessage,
|
|
57
|
+
primaryType: 'CreatorConfigHash',
|
|
58
|
+
domain: {
|
|
59
|
+
name: EIP712_DOMAIN_NAME,
|
|
60
|
+
version: EIP712_DOMAIN_VERSION,
|
|
61
|
+
chainId,
|
|
62
|
+
},
|
|
63
|
+
message: payload,
|
|
64
|
+
}
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
export const signOperatorConfigHashPayload = (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
payload: { operator_config_hash: string },
|
|
69
|
+
chainId: number,
|
|
68
70
|
): TypedMessage<typeof OperatorTypedMessage> => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
71
|
+
return {
|
|
72
|
+
types: OperatorTypedMessage,
|
|
73
|
+
primaryType: 'OperatorConfigHash',
|
|
74
|
+
domain: {
|
|
75
|
+
name: EIP712_DOMAIN_NAME,
|
|
76
|
+
version: EIP712_DOMAIN_VERSION,
|
|
77
|
+
chainId,
|
|
78
|
+
},
|
|
79
|
+
message: payload,
|
|
80
|
+
}
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
export const signEnrPayload = (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
payload: { enr: string },
|
|
85
|
+
chainId: number,
|
|
84
86
|
): TypedMessage<typeof ENRTypedMessage> => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
return {
|
|
88
|
+
types: ENRTypedMessage,
|
|
89
|
+
primaryType: 'ENR',
|
|
90
|
+
domain: {
|
|
91
|
+
name: EIP712_DOMAIN_NAME,
|
|
92
|
+
version: EIP712_DOMAIN_VERSION,
|
|
93
|
+
chainId,
|
|
94
|
+
},
|
|
95
|
+
message: payload,
|
|
96
|
+
}
|
|
95
97
|
}
|
|
96
98
|
|
|
99
|
+
export const DKG_ALGORITHM = 'default'
|
|
97
100
|
|
|
98
|
-
export const
|
|
99
|
-
|
|
100
|
-
export const config_version = "v1.7.0";
|
|
101
|
+
export const CONFIG_VERSION = 'v1.7.0'
|
|
101
102
|
|
|
102
|
-
export const SDK_VERSION =
|
|
103
|
+
export const SDK_VERSION = pjson.version
|
|
103
104
|
|
|
104
|
-
export const DOMAIN_APPLICATION_BUILDER = '00000001'
|
|
105
|
-
export const DOMAIN_DEPOSIT = '03000000'
|
|
105
|
+
export const DOMAIN_APPLICATION_BUILDER = '00000001'
|
|
106
|
+
export const DOMAIN_DEPOSIT = '03000000'
|
|
106
107
|
export const GENESIS_VALIDATOR_ROOT =
|
|
107
|
-
|
|
108
|
+
'0000000000000000000000000000000000000000000000000000000000000000'
|
|
108
109
|
|
|
109
110
|
// Flow used to create defintion
|
|
110
111
|
export enum DefinitionFlow {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
Group = 'LP-Group',
|
|
113
|
+
Solo = 'LP-Solo',
|
|
114
|
+
Charon = 'Charon-Command',
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
export const DEFAULT_BASE_URL =
|
|
118
|
-
export const DEFAULT_CHAIN_ID =
|
|
117
|
+
export const DEFAULT_BASE_URL = 'https://api.obol.tech'
|
|
118
|
+
export const DEFAULT_CHAIN_ID = 17000
|
|
119
|
+
|
|
120
|
+
export const ETHER_TO_GWEI = 10 ** 9
|
package/src/errors.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
export class ConflictError extends Error {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
)
|
|
8
|
-
Object.setPrototypeOf(this, ConflictError.prototype)
|
|
9
|
-
}
|
|
2
|
+
name = 'ConflictError'
|
|
3
|
+
|
|
4
|
+
constructor () {
|
|
5
|
+
super('This Cluster has been already posted.')
|
|
6
|
+
Object.setPrototypeOf(this, ConflictError.prototype)
|
|
10
7
|
}
|
|
11
|
-
|
|
8
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,34 +1,48 @@
|
|
|
1
|
-
import { Signer } from
|
|
2
|
-
import { v4 as uuidv4 } from
|
|
3
|
-
import { Base } from './base.js'
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { type Signer } from 'ethers'
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid'
|
|
3
|
+
import { Base } from './base.js'
|
|
4
|
+
import {
|
|
5
|
+
CONFLICT_ERROR_MSG,
|
|
6
|
+
CreatorConfigHashSigningTypes,
|
|
7
|
+
Domain,
|
|
8
|
+
DKG_ALGORITHM,
|
|
9
|
+
CONFIG_VERSION,
|
|
10
|
+
OperatorConfigHashSigningTypes,
|
|
11
|
+
EnrSigningTypes,
|
|
12
|
+
} from './constants.js'
|
|
13
|
+
import { ConflictError } from './errors.js'
|
|
14
|
+
import {
|
|
15
|
+
type ClusterDefintion,
|
|
16
|
+
type ClusterLock,
|
|
17
|
+
type ClusterPayload,
|
|
18
|
+
type OperatorPayload,
|
|
19
|
+
} from './types.js'
|
|
20
|
+
import { clusterConfigOrDefinitionHash } from './verification/common.js'
|
|
21
|
+
import { validatePayload } from './ajv.js'
|
|
22
|
+
import { definitionSchema, operatorPayloadSchema } from './schema.js'
|
|
23
|
+
export * from './types.js'
|
|
24
|
+
export * from './services.js'
|
|
13
25
|
|
|
14
26
|
/**
|
|
15
27
|
* Obol sdk Client can be used for creating, managing and activating distributed validators.
|
|
16
28
|
*/
|
|
17
29
|
export class Client extends Base {
|
|
18
|
-
private signer: Signer | undefined
|
|
30
|
+
private readonly signer: Signer | undefined
|
|
19
31
|
|
|
20
32
|
/**
|
|
21
33
|
* @param config - Client configurations
|
|
22
34
|
* @param config.baseUrl - obol-api url
|
|
23
35
|
* @param config.chainId - Blockchain network ID
|
|
24
|
-
* @param signer - ethersJS Signer
|
|
36
|
+
* @param signer - ethersJS Signer
|
|
25
37
|
* @returns Obol-SDK Client instance
|
|
26
|
-
*
|
|
38
|
+
*
|
|
27
39
|
* An example of how to instantiate obol-sdk Client:
|
|
28
40
|
* [obolClient](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L29)
|
|
29
41
|
*/
|
|
30
|
-
constructor(
|
|
31
|
-
|
|
42
|
+
constructor (
|
|
43
|
+
config: { baseUrl?: string, chainId?: number },
|
|
44
|
+
signer?: Signer,
|
|
45
|
+
) {
|
|
32
46
|
super(config)
|
|
33
47
|
this.signer = signer
|
|
34
48
|
}
|
|
@@ -38,123 +52,146 @@ export class Client extends Base {
|
|
|
38
52
|
* @param {ClusterPayload} newCluster - The new unique cluster.
|
|
39
53
|
* @returns {Promise<string>} config_hash.
|
|
40
54
|
* @throws On duplicate entries, missing or wrong cluster keys.
|
|
41
|
-
*
|
|
55
|
+
*
|
|
42
56
|
* An example of how to use createClusterDefinition:
|
|
43
57
|
* [createObolCluster](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
|
|
44
58
|
*/
|
|
45
|
-
async createClusterDefinition(newCluster: ClusterPayload): Promise<string> {
|
|
46
|
-
if (!this.signer) throw
|
|
59
|
+
async createClusterDefinition (newCluster: ClusterPayload): Promise<string> {
|
|
60
|
+
if (!this.signer) { throw new Error('Signer is required in createClusterDefinition') }
|
|
47
61
|
|
|
48
|
-
validatePayload(newCluster, definitionSchema)
|
|
62
|
+
validatePayload(newCluster, definitionSchema)
|
|
49
63
|
|
|
50
64
|
const clusterConfig: Partial<ClusterDefintion> = {
|
|
51
65
|
...newCluster,
|
|
52
66
|
fork_version: this.fork_version,
|
|
53
|
-
dkg_algorithm:
|
|
54
|
-
version:
|
|
67
|
+
dkg_algorithm: DKG_ALGORITHM,
|
|
68
|
+
version: CONFIG_VERSION,
|
|
55
69
|
uuid: uuidv4(),
|
|
56
70
|
timestamp: new Date().toISOString(),
|
|
57
71
|
threshold: Math.ceil((2 * newCluster.operators.length) / 3),
|
|
58
|
-
num_validators: newCluster.validators.length
|
|
72
|
+
num_validators: newCluster.validators.length,
|
|
59
73
|
}
|
|
60
74
|
|
|
61
75
|
try {
|
|
62
|
-
const address = await this.signer.getAddress()
|
|
76
|
+
const address = await this.signer.getAddress()
|
|
63
77
|
|
|
64
|
-
clusterConfig.creator = { address }
|
|
65
|
-
clusterConfig.config_hash = clusterConfigOrDefinitionHash(
|
|
78
|
+
clusterConfig.creator = { address }
|
|
79
|
+
clusterConfig.config_hash = clusterConfigOrDefinitionHash(
|
|
80
|
+
clusterConfig as ClusterDefintion,
|
|
81
|
+
true,
|
|
82
|
+
)
|
|
66
83
|
|
|
67
|
-
const creatorConfigSignature = await this.signer.signTypedData(
|
|
84
|
+
const creatorConfigSignature = await this.signer.signTypedData(
|
|
85
|
+
Domain(this.chainId),
|
|
86
|
+
CreatorConfigHashSigningTypes,
|
|
87
|
+
{ creator_config_hash: clusterConfig.config_hash },
|
|
88
|
+
)
|
|
68
89
|
|
|
69
|
-
const clusterDefinition: ClusterDefintion = await this.request(
|
|
90
|
+
const clusterDefinition: ClusterDefintion = await this.request('/dv', {
|
|
70
91
|
method: 'POST',
|
|
71
92
|
body: JSON.stringify(clusterConfig),
|
|
72
93
|
headers: {
|
|
73
94
|
Authorization: `Bearer ${creatorConfigSignature}`,
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return clusterDefinition?.config_hash;
|
|
95
|
+
'fork-version': this.fork_version,
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
return clusterDefinition?.config_hash
|
|
79
99
|
} catch (err: any) {
|
|
80
|
-
if (err?.message
|
|
81
|
-
throw new ConflictError()
|
|
82
|
-
|
|
100
|
+
if (err?.message === CONFLICT_ERROR_MSG) {
|
|
101
|
+
throw new ConflictError()
|
|
102
|
+
}
|
|
103
|
+
throw err
|
|
83
104
|
}
|
|
84
105
|
}
|
|
85
106
|
|
|
86
107
|
/**
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
async acceptClusterDefinition(
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
108
|
+
* Approves joining a cluster with specific configuration.
|
|
109
|
+
* @param {OperatorPayload} operatorPayload - The operator data including signatures.
|
|
110
|
+
* @param {string} configHash - The config hash of the cluster which the operator confirms joining to.
|
|
111
|
+
* @returns {Promise<ClusterDefintion>} The cluster definition.
|
|
112
|
+
* @throws On unauthorized, duplicate entries, missing keys, not found cluster or invalid data.
|
|
113
|
+
*
|
|
114
|
+
* An example of how to use acceptClusterDefinition:
|
|
115
|
+
* [acceptClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
|
|
116
|
+
*/
|
|
117
|
+
async acceptClusterDefinition (
|
|
118
|
+
operatorPayload: OperatorPayload,
|
|
119
|
+
configHash: string,
|
|
120
|
+
): Promise<ClusterDefintion> {
|
|
121
|
+
if (!this.signer) { throw new Error('Signer is required in acceptClusterDefinition') }
|
|
100
122
|
|
|
101
|
-
|
|
102
|
-
const address = await this.signer.getAddress();
|
|
123
|
+
validatePayload(operatorPayload, operatorPayloadSchema)
|
|
103
124
|
|
|
104
|
-
|
|
105
|
-
const
|
|
125
|
+
try {
|
|
126
|
+
const address = await this.signer.getAddress()
|
|
127
|
+
|
|
128
|
+
const operatorConfigSignature = await this.signer.signTypedData(
|
|
129
|
+
Domain(this.chainId),
|
|
130
|
+
OperatorConfigHashSigningTypes,
|
|
131
|
+
{ operator_config_hash: configHash },
|
|
132
|
+
)
|
|
133
|
+
const operatorENRSignature = await this.signer.signTypedData(
|
|
134
|
+
Domain(this.chainId),
|
|
135
|
+
EnrSigningTypes,
|
|
136
|
+
{ enr: operatorPayload.enr },
|
|
137
|
+
)
|
|
106
138
|
|
|
107
139
|
const operatorData: OperatorPayload = {
|
|
108
140
|
...operatorPayload,
|
|
109
141
|
address,
|
|
110
142
|
enr_signature: operatorENRSignature,
|
|
111
|
-
fork_version: this.fork_version
|
|
143
|
+
fork_version: this.fork_version,
|
|
112
144
|
}
|
|
113
|
-
const clusterDefinition: ClusterDefintion = await this.request(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
145
|
+
const clusterDefinition: ClusterDefintion = await this.request(
|
|
146
|
+
`/dv/${configHash}`,
|
|
147
|
+
{
|
|
148
|
+
method: 'PUT',
|
|
149
|
+
body: JSON.stringify(operatorData),
|
|
150
|
+
headers: {
|
|
151
|
+
Authorization: `Bearer ${operatorConfigSignature}`,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
)
|
|
155
|
+
return clusterDefinition
|
|
122
156
|
} catch (err: any) {
|
|
123
|
-
throw err
|
|
157
|
+
throw err
|
|
124
158
|
}
|
|
125
159
|
}
|
|
126
160
|
|
|
127
|
-
|
|
128
|
-
/**
|
|
161
|
+
/**
|
|
129
162
|
* @param configHash - The configuration hash returned in createClusterDefinition
|
|
130
163
|
* @returns {Promise<ClusterDefintion>} The cluster definition for config hash
|
|
131
164
|
* @throws On not found config hash.
|
|
132
|
-
*
|
|
165
|
+
*
|
|
133
166
|
* An example of how to use getClusterDefinition:
|
|
134
167
|
* [getObolClusterDefinition](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
|
|
135
168
|
*/
|
|
136
|
-
async getClusterDefinition(configHash: string): Promise<ClusterDefintion> {
|
|
137
|
-
|
|
169
|
+
async getClusterDefinition (configHash: string): Promise<ClusterDefintion> {
|
|
170
|
+
const clusterDefinition: ClusterDefintion = await this.request(
|
|
171
|
+
`/dv/${configHash}`,
|
|
172
|
+
{
|
|
138
173
|
method: 'GET',
|
|
139
|
-
}
|
|
174
|
+
},
|
|
175
|
+
)
|
|
140
176
|
|
|
141
|
-
|
|
177
|
+
return clusterDefinition
|
|
142
178
|
}
|
|
143
179
|
|
|
144
|
-
/**
|
|
145
|
-
* @param configHash - The configuration hash in cluster-definition
|
|
180
|
+
/**
|
|
181
|
+
* @param configHash - The configuration hash in cluster-definition
|
|
146
182
|
* @returns {Promise<ClusterLock>} The matched cluster details (lock) from DB
|
|
147
183
|
* @throws On not found cluster definition or lock.
|
|
148
|
-
*
|
|
184
|
+
*
|
|
149
185
|
* An example of how to use getClusterLock:
|
|
150
186
|
* [getObolClusterLock](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts)
|
|
151
187
|
*/
|
|
152
|
-
async getClusterLock(configHash: string): Promise<ClusterLock> {
|
|
153
|
-
|
|
154
|
-
|
|
188
|
+
async getClusterLock (configHash: string): Promise<ClusterLock> {
|
|
189
|
+
const lock: ClusterLock = await this.request(
|
|
190
|
+
`/lock/configHash/${configHash}`,
|
|
191
|
+
{
|
|
155
192
|
method: 'GET',
|
|
156
|
-
}
|
|
157
|
-
|
|
193
|
+
},
|
|
194
|
+
)
|
|
195
|
+
return lock
|
|
158
196
|
}
|
|
159
197
|
}
|
|
160
|
-
|