@obolnetwork/obol-sdk 1.0.8 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/cjs/src/ajv.js +17 -0
- package/dist/cjs/src/base.js +39 -0
- package/dist/cjs/src/constants.js +86 -0
- package/dist/cjs/src/errors.js +11 -0
- package/dist/cjs/src/hash.js +172 -0
- package/dist/cjs/src/index.js +158 -0
- package/dist/cjs/src/schema.js +72 -0
- package/dist/cjs/src/services.js +32 -0
- package/dist/cjs/src/types.js +18 -0
- package/dist/cjs/src/utils.js +11 -0
- package/dist/cjs/src/verify.js +326 -0
- package/dist/cjs/test/fixtures.js +101 -0
- package/dist/cjs/test/methods.test.js +128 -0
- package/dist/esm/src/ajv.js +10 -0
- package/dist/esm/src/base.js +35 -0
- package/dist/esm/src/constants.js +79 -0
- package/dist/esm/src/errors.js +7 -0
- package/dist/esm/src/hash.js +165 -0
- package/dist/esm/src/index.js +140 -0
- package/dist/esm/src/schema.js +69 -0
- package/dist/esm/src/services.js +28 -0
- package/dist/esm/src/types.js +15 -0
- package/dist/esm/src/utils.js +6 -0
- package/dist/esm/src/verify.js +295 -0
- package/dist/esm/test/fixtures.js +98 -0
- package/dist/esm/test/methods.test.js +126 -0
- package/dist/types/src/ajv.d.ts +2 -0
- package/dist/{base.d.ts → types/src/base.d.ts} +13 -14
- package/dist/types/src/constants.d.ts +79 -0
- package/dist/{errors.d.ts → types/src/errors.d.ts} +4 -5
- package/dist/{hash.d.ts → types/src/hash.d.ts} +56 -64
- package/dist/{index.d.ts → types/src/index.d.ts} +64 -49
- package/dist/types/src/schema.d.ts +57 -0
- package/dist/types/src/services.d.ts +11 -0
- package/dist/{types.d.ts → types/src/types.d.ts} +153 -150
- package/dist/types/src/utils.d.ts +2 -0
- package/dist/types/src/verify.d.ts +4 -0
- package/dist/{fixtures.d.ts → types/test/fixtures.d.ts} +61 -62
- package/dist/types/test/methods.test.d.ts +1 -0
- package/package.json +55 -21
- package/src/ajv.ts +11 -0
- package/src/base.ts +44 -0
- package/src/constants.ts +118 -0
- package/src/errors.ts +11 -0
- package/src/hash.ts +250 -0
- package/src/index.ts +160 -0
- package/src/schema.ts +70 -0
- package/src/services.ts +20 -0
- package/src/types.ts +211 -0
- package/src/utils.ts +7 -0
- package/src/verify.ts +479 -0
- package/dist/ajv.d.ts +0 -4
- package/dist/ajv.d.ts.map +0 -1
- package/dist/base.d.ts.map +0 -1
- package/dist/cluster.test.d.ts +0 -2
- package/dist/cluster.test.d.ts.map +0 -1
- package/dist/constants.d.ts +0 -18
- package/dist/constants.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/fixtures.d.ts.map +0 -1
- package/dist/hash.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.es.js +0 -15527
- package/dist/index.js +0 -15531
- package/dist/types.d.ts.map +0 -1
package/src/verify.ts
ADDED
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
import * as semver from 'semver';
|
|
2
|
+
import { init, aggregateSignatures, verifyMultiple, verifyAggregate } from "@chainsafe/bls";
|
|
3
|
+
import { ENR } from '@chainsafe/discv5';
|
|
4
|
+
import { ByteVectorType, ContainerType, fromHexString } from '@chainsafe/ssz';
|
|
5
|
+
import { UintNumberByteLen, UintNumberType } from '@chainsafe/ssz/lib/type/uint.js';
|
|
6
|
+
import {
|
|
7
|
+
SignTypedDataVersion,
|
|
8
|
+
TypedDataUtils,
|
|
9
|
+
} from '@metamask/eth-sig-util';
|
|
10
|
+
import elliptic from 'elliptic';
|
|
11
|
+
import { ethers } from 'ethers';
|
|
12
|
+
|
|
13
|
+
import { BuilderRegistrationMessage, ClusterDefintion, ClusterLock, DepositData, DistributedValidator, FORK_MAPPING } from "./types.js";
|
|
14
|
+
import { clusterConfigOrDefinitionHash, clusterLockHash } from './hash.js';
|
|
15
|
+
import { DOMAIN_APPLICATION_BUILDER, DOMAIN_DEPOSIT, DefinitionFlow, GENESIS_VALIDATOR_ROOT, signCreatorConfigHashPayload, signEnrPayload, signOperatorConfigHashPayload } from './constants.js';
|
|
16
|
+
import { hexWithout0x } from './utils.js';
|
|
17
|
+
|
|
18
|
+
const builderRegistrationMessageType = new ContainerType({
|
|
19
|
+
fee_recipient: new ByteVectorType(20),
|
|
20
|
+
gas_limit: new UintNumberType(8 as UintNumberByteLen),
|
|
21
|
+
timestamp: new UintNumberType(8 as UintNumberByteLen),
|
|
22
|
+
pubkey: new ByteVectorType(48),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
//For domain computation that is used in deposit data and builder registration verification for dv
|
|
26
|
+
const forkDataType = new ContainerType({
|
|
27
|
+
currentVersion: new ByteVectorType(4),
|
|
28
|
+
genesisValidatorsRoot: new ByteVectorType(32),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const depositMessageType = new ContainerType({
|
|
32
|
+
pubkey: new ByteVectorType(48),
|
|
33
|
+
withdrawal_credentials: new ByteVectorType(32),
|
|
34
|
+
amount: new UintNumberType(8),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const signingRootType = new ContainerType({
|
|
38
|
+
objectRoot: new ByteVectorType(32),
|
|
39
|
+
domain: new ByteVectorType(32),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const definitionFlow = (
|
|
43
|
+
clusterDefinition: ClusterDefintion,
|
|
44
|
+
): DefinitionFlow | null => {
|
|
45
|
+
if (
|
|
46
|
+
clusterDefinition.creator.address &&
|
|
47
|
+
clusterDefinition.creator.config_signature &&
|
|
48
|
+
clusterDefinition.operators.every(operator => {
|
|
49
|
+
return (
|
|
50
|
+
operator.address &&
|
|
51
|
+
operator.config_signature &&
|
|
52
|
+
operator.enr &&
|
|
53
|
+
operator.enr_signature
|
|
54
|
+
);
|
|
55
|
+
})
|
|
56
|
+
) {
|
|
57
|
+
return DefinitionFlow.Group;
|
|
58
|
+
} else if (
|
|
59
|
+
clusterDefinition.creator.address &&
|
|
60
|
+
clusterDefinition.creator.config_signature &&
|
|
61
|
+
clusterDefinition.operators.every(operator => {
|
|
62
|
+
return (
|
|
63
|
+
!operator.address &&
|
|
64
|
+
!operator.config_signature &&
|
|
65
|
+
operator.enr &&
|
|
66
|
+
!operator.enr_signature
|
|
67
|
+
);
|
|
68
|
+
})
|
|
69
|
+
) {
|
|
70
|
+
return DefinitionFlow.Solo;
|
|
71
|
+
} else if (
|
|
72
|
+
!clusterDefinition.creator.address &&
|
|
73
|
+
!clusterDefinition.creator.config_signature &&
|
|
74
|
+
clusterDefinition.operators.every(operator => {
|
|
75
|
+
return (
|
|
76
|
+
!operator.address &&
|
|
77
|
+
!operator.config_signature &&
|
|
78
|
+
operator.enr &&
|
|
79
|
+
!operator.enr_signature
|
|
80
|
+
);
|
|
81
|
+
})
|
|
82
|
+
) {
|
|
83
|
+
return DefinitionFlow.Charon;
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
//cluster-definition signatures verificatin
|
|
90
|
+
|
|
91
|
+
const getPOSTConfigHashSigner = (
|
|
92
|
+
signature: string,
|
|
93
|
+
configHash: string,
|
|
94
|
+
chainId: FORK_MAPPING,): string => {
|
|
95
|
+
try {
|
|
96
|
+
const sig = ethers.Signature.from(signature);
|
|
97
|
+
const data = signCreatorConfigHashPayload(
|
|
98
|
+
{ creator_config_hash: configHash },
|
|
99
|
+
chainId,
|
|
100
|
+
);
|
|
101
|
+
const digest = TypedDataUtils.eip712Hash(data, SignTypedDataVersion.V4);
|
|
102
|
+
|
|
103
|
+
return ethers.recoverAddress(digest, sig).toLowerCase();
|
|
104
|
+
} catch (err) {
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const getPUTConfigHashSigner = (
|
|
110
|
+
signature: string,
|
|
111
|
+
configHash: string,
|
|
112
|
+
chainId: number,
|
|
113
|
+
): string => {
|
|
114
|
+
try {
|
|
115
|
+
const sig = ethers.Signature.from(signature);
|
|
116
|
+
const data = signOperatorConfigHashPayload(
|
|
117
|
+
{ operator_config_hash: configHash },
|
|
118
|
+
chainId,
|
|
119
|
+
);
|
|
120
|
+
const digest = TypedDataUtils.eip712Hash(data, SignTypedDataVersion.V4);
|
|
121
|
+
|
|
122
|
+
return ethers.recoverAddress(digest, sig).toLowerCase();
|
|
123
|
+
} catch (err) {
|
|
124
|
+
throw err;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const getEnrSigner = (
|
|
129
|
+
signature: string,
|
|
130
|
+
payload: string,
|
|
131
|
+
chainId: number,
|
|
132
|
+
): string => {
|
|
133
|
+
try {
|
|
134
|
+
const sig = ethers.Signature.from(signature);
|
|
135
|
+
|
|
136
|
+
const data = signEnrPayload({ enr: payload }, chainId);
|
|
137
|
+
const digest = TypedDataUtils.eip712Hash(data, SignTypedDataVersion.V4);
|
|
138
|
+
|
|
139
|
+
return ethers.recoverAddress(digest, sig).toLowerCase();
|
|
140
|
+
} catch (err) {
|
|
141
|
+
throw err;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const verifyDefinitionSignatures = (
|
|
146
|
+
clusterDefinition: ClusterDefintion,
|
|
147
|
+
definitionType: DefinitionFlow,
|
|
148
|
+
): boolean => {
|
|
149
|
+
if (definitionType === 'Charon-Command') {
|
|
150
|
+
return true;
|
|
151
|
+
} else {
|
|
152
|
+
const configSigner = getPOSTConfigHashSigner(
|
|
153
|
+
clusterDefinition.creator.config_signature as string,
|
|
154
|
+
clusterDefinition.config_hash,
|
|
155
|
+
FORK_MAPPING[clusterDefinition.fork_version as keyof typeof FORK_MAPPING],
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
if (configSigner !== clusterDefinition.creator.address.toLowerCase()) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
if (definitionType === 'LP-Solo') {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
return clusterDefinition.operators.every(operator => {
|
|
165
|
+
const configSigner = getPUTConfigHashSigner(
|
|
166
|
+
operator.config_signature as string,
|
|
167
|
+
clusterDefinition.config_hash,
|
|
168
|
+
FORK_MAPPING[clusterDefinition.fork_version as keyof typeof FORK_MAPPING],
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const enrSigner = getEnrSigner(
|
|
172
|
+
operator.enr_signature as string,
|
|
173
|
+
operator.enr as string,
|
|
174
|
+
FORK_MAPPING[clusterDefinition.fork_version as keyof typeof FORK_MAPPING],
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
if (
|
|
178
|
+
configSigner !== operator.address.toLowerCase() ||
|
|
179
|
+
enrSigner !== operator.address.toLowerCase()
|
|
180
|
+
) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return true;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
//cluster-lock data verification
|
|
189
|
+
const computeSigningRoot = (
|
|
190
|
+
sszObjectRoot: Uint8Array,
|
|
191
|
+
domain: Uint8Array,
|
|
192
|
+
): Uint8Array => {
|
|
193
|
+
const val1 = signingRootType.defaultValue();
|
|
194
|
+
val1.objectRoot = sszObjectRoot;
|
|
195
|
+
val1.domain = domain;
|
|
196
|
+
return Buffer.from(signingRootType.hashTreeRoot(val1).buffer);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const computeDepositMsgRoot = (msg: Partial<DepositData>): Buffer => {
|
|
200
|
+
const depositMsgVal = depositMessageType.defaultValue();
|
|
201
|
+
|
|
202
|
+
depositMsgVal.pubkey = fromHexString(msg.pubkey as string);
|
|
203
|
+
depositMsgVal.withdrawal_credentials = fromHexString(
|
|
204
|
+
msg.withdrawal_credentials as string,
|
|
205
|
+
);
|
|
206
|
+
depositMsgVal.amount = parseInt(msg.amount as string);
|
|
207
|
+
return Buffer.from(depositMessageType.hashTreeRoot(depositMsgVal).buffer);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const computeForkDataRoot = (
|
|
211
|
+
currentVersion: Uint8Array,
|
|
212
|
+
genesisValidatorsRoot: Uint8Array,
|
|
213
|
+
): Uint8Array => {
|
|
214
|
+
const forkDataVal = forkDataType.defaultValue();
|
|
215
|
+
forkDataVal.currentVersion = currentVersion;
|
|
216
|
+
forkDataVal.genesisValidatorsRoot = genesisValidatorsRoot;
|
|
217
|
+
return Buffer.from(forkDataType.hashTreeRoot(forkDataVal).buffer);
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
const computebuilderRegistrationMsgRoot = (
|
|
221
|
+
msg: BuilderRegistrationMessage,
|
|
222
|
+
): Buffer => {
|
|
223
|
+
const builderRegistrationMsgVal =
|
|
224
|
+
builderRegistrationMessageType.defaultValue();
|
|
225
|
+
|
|
226
|
+
builderRegistrationMsgVal.fee_recipient = fromHexString(msg.fee_recipient);
|
|
227
|
+
builderRegistrationMsgVal.gas_limit = msg.gas_limit;
|
|
228
|
+
builderRegistrationMsgVal.timestamp = msg.timestamp;
|
|
229
|
+
builderRegistrationMsgVal.pubkey = fromHexString(msg.pubkey);
|
|
230
|
+
return Buffer.from(
|
|
231
|
+
builderRegistrationMessageType.hashTreeRoot(builderRegistrationMsgVal)
|
|
232
|
+
.buffer,
|
|
233
|
+
);
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
// DV data verification
|
|
238
|
+
const computeDomain = (
|
|
239
|
+
domainType: Uint8Array,
|
|
240
|
+
lockForkVersion: string,
|
|
241
|
+
genesisValidatorsRoot: Uint8Array = fromHexString(GENESIS_VALIDATOR_ROOT),
|
|
242
|
+
): Uint8Array => {
|
|
243
|
+
const forkVersion = fromHexString(
|
|
244
|
+
lockForkVersion.substring(2, lockForkVersion.length),
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
const forkDataRoot = computeForkDataRoot(forkVersion, genesisValidatorsRoot);
|
|
248
|
+
const domain = new Uint8Array(32);
|
|
249
|
+
domain.set(domainType);
|
|
250
|
+
domain.set(forkDataRoot.subarray(0, 28), 4);
|
|
251
|
+
return domain;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const verifyDepositData = (
|
|
255
|
+
validator: DistributedValidator,
|
|
256
|
+
withdrawalAddress: string,
|
|
257
|
+
): boolean => {
|
|
258
|
+
const eth1AddressWithdrawalPrefix = '0x01';
|
|
259
|
+
if (
|
|
260
|
+
eth1AddressWithdrawalPrefix +
|
|
261
|
+
'0'.repeat(22) +
|
|
262
|
+
withdrawalAddress.toLowerCase().slice(2) !==
|
|
263
|
+
validator.deposit_data.withdrawal_credentials
|
|
264
|
+
) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (validator.distributed_public_key !== validator.deposit_data.pubkey) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return true;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const verifyBuilderRegistration = (
|
|
276
|
+
validator: DistributedValidator,
|
|
277
|
+
feeRecipientAddress: string,
|
|
278
|
+
): boolean => {
|
|
279
|
+
if (
|
|
280
|
+
validator.distributed_public_key !==
|
|
281
|
+
validator.builder_registration.message.pubkey
|
|
282
|
+
) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
if (
|
|
286
|
+
feeRecipientAddress.toLowerCase() !==
|
|
287
|
+
validator.builder_registration.message.fee_recipient.toLowerCase()
|
|
288
|
+
) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return true;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
export const signingRoot = (
|
|
296
|
+
domain: Uint8Array,
|
|
297
|
+
messageBuffer: Buffer,
|
|
298
|
+
): Uint8Array => {
|
|
299
|
+
return computeSigningRoot(messageBuffer, domain);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const verifyLockData = async (
|
|
303
|
+
clusterLock: ClusterLock,
|
|
304
|
+
): Promise<boolean> => {
|
|
305
|
+
const ec = new elliptic.ec('secp256k1');
|
|
306
|
+
const validators = clusterLock.distributed_validators;
|
|
307
|
+
const nodeSignatures = clusterLock.node_signatures;
|
|
308
|
+
const depositDomain = computeDomain(
|
|
309
|
+
fromHexString(DOMAIN_DEPOSIT),
|
|
310
|
+
clusterLock.cluster_definition.fork_version,
|
|
311
|
+
);
|
|
312
|
+
const builderDomain = computeDomain(
|
|
313
|
+
fromHexString(DOMAIN_APPLICATION_BUILDER),
|
|
314
|
+
clusterLock.cluster_definition.fork_version,
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
const pubShares = [];
|
|
318
|
+
const pubKeys = [];
|
|
319
|
+
const builderRegistrationAndDepositDataMessages = [];
|
|
320
|
+
const blsSignatures = [];
|
|
321
|
+
|
|
322
|
+
await init('herumi');
|
|
323
|
+
|
|
324
|
+
for (let i = 0; i < validators.length; i++) {
|
|
325
|
+
const validator = validators[i];
|
|
326
|
+
const validatorPublicShares = validator['public_shares'];
|
|
327
|
+
|
|
328
|
+
for (const element of validatorPublicShares) {
|
|
329
|
+
pubShares.push(fromHexString(element));
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
//Deposit data signature
|
|
333
|
+
if (semver.gte(clusterLock.cluster_definition.version, 'v1.6.0')) {
|
|
334
|
+
if (
|
|
335
|
+
!verifyDepositData(
|
|
336
|
+
validator,
|
|
337
|
+
clusterLock.cluster_definition.validators[i].withdrawal_address,
|
|
338
|
+
)
|
|
339
|
+
) {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
const depositMessageBuffer = computeDepositMsgRoot(
|
|
344
|
+
validator.deposit_data,
|
|
345
|
+
);
|
|
346
|
+
const depositDataMessage = signingRoot(
|
|
347
|
+
depositDomain,
|
|
348
|
+
depositMessageBuffer,
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
pubKeys.push(fromHexString(validator.distributed_public_key));
|
|
352
|
+
builderRegistrationAndDepositDataMessages.push(depositDataMessage);
|
|
353
|
+
blsSignatures.push(fromHexString(validator.deposit_data.signature));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
//Builder registration signature
|
|
357
|
+
if (semver.gte(clusterLock.cluster_definition.version, 'v1.7.0')) {
|
|
358
|
+
if (
|
|
359
|
+
!verifyBuilderRegistration(
|
|
360
|
+
validator,
|
|
361
|
+
clusterLock.cluster_definition.validators[i].fee_recipient_address,
|
|
362
|
+
)
|
|
363
|
+
) {
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const builderRegistrationMessageBuffer =
|
|
368
|
+
computebuilderRegistrationMsgRoot(
|
|
369
|
+
validator.builder_registration.message,
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
const builderRegistrationMessage = signingRoot(
|
|
373
|
+
builderDomain,
|
|
374
|
+
builderRegistrationMessageBuffer,
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
pubKeys.push(fromHexString(validator.distributed_public_key));
|
|
378
|
+
builderRegistrationAndDepositDataMessages.push(
|
|
379
|
+
builderRegistrationMessage,
|
|
380
|
+
);
|
|
381
|
+
blsSignatures.push(
|
|
382
|
+
fromHexString(validator.builder_registration.signature),
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (
|
|
388
|
+
blsSignatures.length &&
|
|
389
|
+
pubKeys.length &&
|
|
390
|
+
builderRegistrationAndDepositDataMessages.length
|
|
391
|
+
) {
|
|
392
|
+
// verify all deposit data and builder registration bls signatures
|
|
393
|
+
const aggregateBLSSignature = aggregateSignatures(blsSignatures);
|
|
394
|
+
|
|
395
|
+
if (
|
|
396
|
+
!verifyMultiple(
|
|
397
|
+
pubKeys,
|
|
398
|
+
builderRegistrationAndDepositDataMessages,
|
|
399
|
+
aggregateBLSSignature,
|
|
400
|
+
)
|
|
401
|
+
) {
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (semver.gte(clusterLock.cluster_definition.version, 'v1.7.0')) {
|
|
407
|
+
const lockHashWithout0x = hexWithout0x(clusterLock.lock_hash);
|
|
408
|
+
//node(ENR) signatures
|
|
409
|
+
for (let i = 0; i < nodeSignatures.length; i++) {
|
|
410
|
+
const pubkey = ENR.decodeTxt(
|
|
411
|
+
clusterLock.cluster_definition.operators[i].enr as string,
|
|
412
|
+
).publicKey.toString('hex');
|
|
413
|
+
|
|
414
|
+
const ENRsignature = {
|
|
415
|
+
r: nodeSignatures[i].slice(2, 66),
|
|
416
|
+
s: nodeSignatures[i].slice(66, 130),
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
const nodeSignatureVerification = ec
|
|
420
|
+
.keyFromPublic(pubkey, 'hex')
|
|
421
|
+
.verify(lockHashWithout0x, ENRsignature);
|
|
422
|
+
|
|
423
|
+
if (!nodeSignatureVerification) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
//signature aggregate
|
|
430
|
+
if (
|
|
431
|
+
!verifyAggregate(
|
|
432
|
+
pubShares,
|
|
433
|
+
fromHexString(clusterLock.lock_hash),
|
|
434
|
+
fromHexString(clusterLock.signature_aggregate),
|
|
435
|
+
)
|
|
436
|
+
) {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return true;
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
export const isValidClusterLock = async (
|
|
444
|
+
clusterLock: ClusterLock,
|
|
445
|
+
): Promise<boolean> => {
|
|
446
|
+
try {
|
|
447
|
+
const definitionType = definitionFlow(clusterLock.cluster_definition);
|
|
448
|
+
if (!definitionType) {
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
const isValidDefinitionData = verifyDefinitionSignatures(
|
|
452
|
+
clusterLock.cluster_definition,
|
|
453
|
+
definitionType,
|
|
454
|
+
);
|
|
455
|
+
if (!isValidDefinitionData) {
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if (
|
|
460
|
+
clusterConfigOrDefinitionHash(clusterLock.cluster_definition, false) !==
|
|
461
|
+
clusterLock.cluster_definition.definition_hash
|
|
462
|
+
) {
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
465
|
+
if (clusterLockHash(clusterLock) !== clusterLock.lock_hash) {
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const isValidLockData = await verifyLockData(clusterLock);
|
|
470
|
+
if (!isValidLockData) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
return true;
|
|
474
|
+
} catch (err) {
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
|
package/dist/ajv.d.ts
DELETED
package/dist/ajv.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ajv.d.ts","sourceRoot":"","sources":["../src/ajv.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AAEvC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,WAAW,EAAE,GAAG,SAAS,GAAG,IAAI,CAQzF"}
|
package/dist/base.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,aAAK,MAAM,GAAG;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF,8BAAsB,IAAI;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;gBAIT,EAAE,OAA0B,EAAE,OAA0B,EAAE,EAAE,MAAM;cAM9D,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;CAqBhF"}
|
package/dist/cluster.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cluster.test.d.ts","sourceRoot":"","sources":["../src/cluster.test.ts"],"names":[],"mappings":""}
|
package/dist/constants.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export declare const CONFLICT_ERROR_MSG = "Conflict";
|
|
2
|
-
export declare const CreatorConfigHashSigningTypes: {
|
|
3
|
-
CreatorConfigHash: {
|
|
4
|
-
name: string;
|
|
5
|
-
type: string;
|
|
6
|
-
}[];
|
|
7
|
-
};
|
|
8
|
-
export declare const Domain: (chainId: number) => {
|
|
9
|
-
name: string;
|
|
10
|
-
version: string;
|
|
11
|
-
chainId: number;
|
|
12
|
-
};
|
|
13
|
-
export declare const dkg_algorithm = "default";
|
|
14
|
-
export declare const config_version = "v1.7.0";
|
|
15
|
-
export declare const SDK_VERSION = "1.0.7";
|
|
16
|
-
export declare const DEFAULT_BASE_URL = "https://api.obol.tech";
|
|
17
|
-
export declare const DEFAULT_CHAIN_ID = 1;
|
|
18
|
-
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,aAAa,CAAA;AAI5C,eAAO,MAAM,6BAA6B;;;;;CAEzC,CAAC;AACF,eAAO,MAAM,MAAM,YAAY,MAAM;;;;CAMpC,CAAA;AAGD,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC,eAAO,MAAM,cAAc,WAAW,CAAC;AAEvC,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AACxD,eAAO,MAAM,gBAAgB,IAAI,CAAC"}
|
package/dist/errors.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;IACpC,IAAI,SAAkB;;CAQvB"}
|
package/dist/fixtures.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../src/fixtures.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoF1B,CAAA;AAGF,eAAO,MAAM,aAAa;;;;;;;;;CAazB,CAAA"}
|
package/dist/hash.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EAEb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,YAC/B,gBAAgB,cACb,OAAO,KAClB,MAOF,CAAC;AAEF,eAAO,MAAM,yBAAyB,YAC3B,gBAAgB,cACb,OAAO,KAClB,cAAc,oBAAoB,CAyCpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAAS,MAAM,KAAG,UAE7C,CAAC;AAEF;;;GAGG;AACH,QAAA,MAAM,0BAA0B;;EAE9B,CAAC;AAEH,QAAA,MAAM,yBAAyB;;EAE7B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;EAKhC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;EAG/B,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;EAGlC,CAAC;AAUH,aAAK,oBAAoB,GAAG;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,YAAY,CAAC;IACxB,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,cAAc,CAAC;IAC1B,aAAa,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,cAAc,CAAC;IAC7B,SAAS,EAAE,iBAAiB,CAC1B,OAAO,qBAAqB,GAAG,OAAO,0BAA0B,CACjE,CAAC;IACF,OAAO,EAAE,OAAO,oBAAoB,GAAG,OAAO,yBAAyB,CAAC;IACxE,UAAU,EAAE,iBAAiB,CAAC,OAAO,uBAAuB,CAAC,CAAC;IAC9D,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B,CAAC;AAEF,oBAAY,2BAA2B,GACrC,aAAa,CAAC,oBAAoB,CAAC,CAAC;AAEtC;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,eACjC,OAAO,gCAwBpB,CAAC"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGxE,cAAc,SAAS,CAAC;AAExB;;GAEG;AACH,qBAAa,MAAO,SAAQ,IAAI;IAC9B,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;;;;OAOG;gBACS,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,EAAE,MAAM,EAAE,MAAM;IAMlG;;;;;;;;OAQG;IACG,uBAAuB,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IA0C1E;;;;;;OAMG;IACG,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IASzE;;;;;;OAMG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;CAQ/D"}
|