@ssv-labs/ssv-sdk 0.1.2 → 1.0.1

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 (59) hide show
  1. package/README.html +4 -7
  2. package/README.md +37 -26
  3. package/dist/{KeyShares-7biQfDev.js → KeyShares-Bk9uzOlK.js} +255 -75
  4. package/dist/{KeyShares-DEqBZits.mjs → KeyShares-Dlp4Pa3b.mjs} +259 -79
  5. package/dist/abi/mainnet/v4/getter.d.ts +699 -74
  6. package/dist/abi/mainnet/v4/setter.d.ts +939 -59
  7. package/dist/api/subgraph/index.d.ts +36 -1
  8. package/dist/config/create.d.ts +2 -2
  9. package/dist/config/globals.d.ts +3 -0
  10. package/dist/{globals-CDOcDUnk.mjs → config-BdEJjnYA.mjs} +107 -79
  11. package/dist/{globals-DsaKgq3v.js → config-ClGS9Tic.js} +73 -45
  12. package/dist/contract-interactions/create.d.ts +1 -1
  13. package/dist/contract-interactions/types.d.ts +9 -3
  14. package/dist/graphql/graphql.d.ts +4663 -922
  15. package/dist/keys.js +1 -1
  16. package/dist/keys.mjs +5 -5
  17. package/dist/libs/api/index.d.ts +2 -0
  18. package/dist/libs/cluster/index.d.ts +3 -1
  19. package/dist/libs/cluster/methods/deposit.d.ts +150 -5
  20. package/dist/libs/cluster/methods/exit-validators.d.ts +149 -0
  21. package/dist/libs/cluster/methods/index.d.ts +3 -1
  22. package/dist/libs/cluster/methods/liquidate-cluster.d.ts +149 -0
  23. package/dist/libs/cluster/methods/liquidate-ssv.d.ts +430 -0
  24. package/dist/libs/cluster/methods/migrate-cluster-to-eth.d.ts +431 -0
  25. package/dist/libs/cluster/methods/reactivate-cluster.d.ts +149 -0
  26. package/dist/libs/cluster/methods/register-validators.d.ts +2222 -309
  27. package/dist/libs/cluster/methods/remove-validators.d.ts +149 -0
  28. package/dist/libs/cluster/methods/set-fee-recipient.d.ts +149 -0
  29. package/dist/libs/cluster/methods/withdraw.d.ts +149 -0
  30. package/dist/libs/dao/index.d.ts +8 -0
  31. package/dist/libs/dao/methods/commit-root.d.ts +432 -0
  32. package/dist/libs/dao/methods/index.d.ts +3 -0
  33. package/dist/libs/dao/methods/update-network-fee-ssv.d.ts +430 -0
  34. package/dist/libs/dao/methods/withdraw-network-ssv-earnings.d.ts +430 -0
  35. package/dist/libs/operator/index.d.ts +1525 -32
  36. package/dist/libs/operator/methods.d.ts +1731 -2
  37. package/dist/libs/ssv-keys/Encryption/__test__/RsaKeys.d.ts +1 -1
  38. package/dist/libs/ssv-keys/KeyShares/KeySharesItem.d.ts +1 -1
  39. package/dist/libs/ssv-keys/SSVKeys.d.ts +1 -1
  40. package/dist/libs/ssv-keys/exceptions/index.d.ts +1 -1
  41. package/dist/libs/ssv-keys/index.d.ts +1 -1
  42. package/dist/libs/ssv-keys/interfaces/index.d.ts +2 -2
  43. package/dist/libs/utils/index.d.ts +6 -4
  44. package/dist/libs/utils/methods/calc-deposit-from-runway.d.ts +11 -0
  45. package/dist/libs/utils/methods/get-cluster-balance.d.ts +3 -1
  46. package/dist/libs/utils/methods/keyshares.d.ts +4 -2
  47. package/dist/libs/utils/methods/keystores.d.ts +4 -4
  48. package/dist/main.d.ts +1 -0
  49. package/dist/main.js +2714 -729
  50. package/dist/main.mjs +2746 -761
  51. package/dist/sdk.d.ts +8 -4
  52. package/dist/types/contract-interactions.d.ts +11 -0
  53. package/dist/types/methods.d.ts +4 -3
  54. package/dist/utils/cluster.d.ts +3 -3
  55. package/dist/utils/funding.d.ts +29 -0
  56. package/dist/utils/zod/config.d.ts +1 -1
  57. package/dist/utils.js +38 -38
  58. package/dist/utils.mjs +34 -34
  59. package/package.json +29 -17
@@ -1,30 +1,49 @@
1
+ import { GetClusterBalanceQueryVariables, GetClusterQueryVariables, GetClusterSnapshotQueryVariables, GetClustersQueryVariables, GetDaoValuesQueryVariables, GetOperatorQueryVariables, GetOperatorsQueryVariables, GetOwnerNonceByBlockQueryVariables, GetValidatorQueryVariables, GetValidatorsQueryVariables } from '../../graphql/graphql';
1
2
  import { RemoveConfigArg } from '../../types/methods';
2
3
  import { GraphQLClient } from 'graphql-request';
3
- import { GetClusterBalanceQueryVariables, GetClusterQueryVariables, GetClusterSnapshotQueryVariables, GetClustersQueryVariables, GetOperatorQueryVariables, GetOperatorsQueryVariables, GetOwnerNonceByBlockQueryVariables, GetValidatorQueryVariables, GetValidatorsQueryVariables } from '../../graphql/graphql';
4
4
  export declare const getOwnerNonce: (client: GraphQLClient, args: GetOwnerNonceByBlockQueryVariables) => Promise<string>;
5
+ export declare const toSolidityCluster: (client: GraphQLClient, args: GetClusterSnapshotQueryVariables) => Promise<{
6
+ active: boolean;
7
+ validatorCount: string;
8
+ balance: string;
9
+ index: string;
10
+ networkFeeIndex: string;
11
+ effectiveBalance: string;
12
+ } | null | undefined>;
13
+ /**
14
+ * @deprecated Use `toSolidityCluster` instead.
15
+ */
5
16
  export declare const getClusterSnapshot: (client: GraphQLClient, args: GetClusterSnapshotQueryVariables) => Promise<{
6
17
  active: boolean;
7
18
  validatorCount: string;
8
19
  balance: string;
9
20
  index: string;
10
21
  networkFeeIndex: string;
22
+ effectiveBalance: string;
11
23
  } | null | undefined>;
12
24
  export declare const getCluster: (client: GraphQLClient, args: GetClusterQueryVariables) => Promise<{
25
+ feeAsset: import('../../graphql/graphql').ClusterFeeAssetTypes;
13
26
  active: boolean;
14
27
  validatorCount: string;
15
28
  balance: string;
16
29
  index: string;
17
30
  networkFeeIndex: string;
18
31
  operatorIds: Array<string>;
32
+ effectiveBalance: string;
33
+ owner: {
34
+ id: import('viem').Address;
35
+ };
19
36
  } | null | undefined>;
20
37
  export declare const getClusters: (client: GraphQLClient, args: GetClustersQueryVariables) => Promise<{
21
38
  id: string;
39
+ feeAsset: import('../../graphql/graphql').ClusterFeeAssetTypes;
22
40
  active: boolean;
23
41
  validatorCount: string;
24
42
  balance: string;
25
43
  index: string;
26
44
  networkFeeIndex: string;
27
45
  operatorIds: Array<string>;
46
+ effectiveBalance: string;
28
47
  }[]>;
29
48
  export declare const getOperator: (client: GraphQLClient, args: GetOperatorQueryVariables) => Promise<{
30
49
  publicKey: string;
@@ -41,6 +60,8 @@ export declare const getOperators: (client: GraphQLClient, args: GetOperatorsQue
41
60
  validatorCount: string;
42
61
  isPrivate: boolean;
43
62
  whitelistedContract: import('viem').Address;
63
+ fee: string;
64
+ feeSSV: string;
44
65
  }[]>;
45
66
  export declare const getValidators: (client: GraphQLClient, args: GetValidatorsQueryVariables) => Promise<{
46
67
  id: import('viem').Address;
@@ -49,8 +70,21 @@ export declare const getValidator: (client: GraphQLClient, args: GetValidatorQue
49
70
  id: import('viem').Address;
50
71
  } | null | undefined>;
51
72
  export declare const getClusterBalance: (client: GraphQLClient, args: GetClusterBalanceQueryVariables) => Promise<import('../../graphql/graphql').GetClusterBalanceQuery>;
73
+ export declare const getDaoValues: (client: GraphQLClient, args: GetDaoValuesQueryVariables) => Promise<{
74
+ networkFee: string;
75
+ networkFeeIndex: string;
76
+ networkFeeIndexBlockNumber: string;
77
+ networkFeeSSV: string;
78
+ networkFeeIndexSSV: string;
79
+ networkFeeIndexBlockNumberSSV: string;
80
+ liquidationThreshold: string;
81
+ liquidationThresholdSSV: string;
82
+ minimumLiquidationCollateral: string;
83
+ minimumLiquidationCollateralSSV: string;
84
+ } | null | undefined>;
52
85
  export declare const getQueries: (client: GraphQLClient) => {
53
86
  getOwnerNonce: RemoveConfigArg<typeof getOwnerNonce>;
87
+ toSolidityCluster: RemoveConfigArg<typeof toSolidityCluster>;
54
88
  getClusterSnapshot: RemoveConfigArg<typeof getClusterSnapshot>;
55
89
  getCluster: RemoveConfigArg<typeof getCluster>;
56
90
  getClusters: RemoveConfigArg<typeof getClusters>;
@@ -59,4 +93,5 @@ export declare const getQueries: (client: GraphQLClient) => {
59
93
  getValidators: RemoveConfigArg<typeof getValidators>;
60
94
  getValidator: RemoveConfigArg<typeof getValidator>;
61
95
  getClusterBalance: RemoveConfigArg<typeof getClusterBalance>;
96
+ getDaoValues: RemoveConfigArg<typeof getDaoValues>;
62
97
  };
@@ -6,7 +6,7 @@ import { Address, Chain, PublicClient, WalletClient } from 'viem';
6
6
  import { ContractAddresses } from './chains';
7
7
  export type ConfigReturnType = {
8
8
  publicClient: PublicClient;
9
- walletClient: WalletClient;
9
+ walletClient?: WalletClient;
10
10
  chain: Chain;
11
11
  api: ReturnType<typeof createQueries> & ReturnType<typeof createSSVAPI>;
12
12
  contractAddresses: {
@@ -31,7 +31,7 @@ export type ConfigReturnType = {
31
31
  };
32
32
  export declare const isConfig: (props: unknown) => props is ConfigReturnType;
33
33
  type CreateContractInteractionsArgs = {
34
- walletClient: WalletClient;
34
+ walletClient?: WalletClient;
35
35
  publicClient: PublicClient;
36
36
  addresses: ContractAddresses;
37
37
  };
@@ -20,9 +20,12 @@ export declare const globals: {
20
20
  MAX_VALIDATORS_COUNT_MULTI_FLOW: number;
21
21
  CLUSTER_VALIDITY_PERIOD_MINIMUM: number;
22
22
  OPERATOR_VALIDATORS_LIMIT_PRESERVE: number;
23
+ SSV_DEDUCTED_DIGITS: bigint;
24
+ ETH_DEDUCTED_DIGITS: bigint;
23
25
  MINIMUM_OPERATOR_FEE_PER_BLOCK: bigint;
24
26
  MIN_VALIDATORS_COUNT_PER_BULK_REGISTRATION: number;
25
27
  DEFAULT_ADDRESS_WHITELIST: string;
28
+ VUNITS_PRECISION: number;
26
29
  };
27
30
  export type ClusterSize = (typeof globals.CLUSTER_SIZES)[keyof typeof globals.CLUSTER_SIZES];
28
31
  export declare const registerValidatorsByClusterSizeLimits: {
@@ -128,6 +128,41 @@ const contracts = {
128
128
  token: "0x9F5d4Ec84fC4785788aB44F9de973cF34F7A038e"
129
129
  }
130
130
  };
131
+ const globals = {
132
+ MAX_WEI_AMOUNT: 115792089237316195423570985008687907853269984665640564039457584007913129639935n,
133
+ CLUSTER_SIZES: {
134
+ QUAD_CLUSTER: 4,
135
+ SEPT_CLUSTER: 7,
136
+ DECA_CLUSTER: 10,
137
+ TRISKAIDEKA_CLUSTER: 13
138
+ },
139
+ FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE: {
140
+ QUAD_CLUSTER: 80,
141
+ SEPT_CLUSTER: 40,
142
+ DECA_CLUSTER: 30,
143
+ TRISKAIDEKA_CLUSTER: 20
144
+ },
145
+ BLOCKS_PER_DAY: 7200n,
146
+ OPERATORS_PER_PAGE: 50,
147
+ BLOCKS_PER_YEAR: 2628000n,
148
+ DEFAULT_CLUSTER_PERIOD: 730,
149
+ NUMBERS_OF_WEEKS_IN_YEAR: 52.1429,
150
+ MAX_VALIDATORS_COUNT_MULTI_FLOW: 50,
151
+ CLUSTER_VALIDITY_PERIOD_MINIMUM: 30,
152
+ OPERATOR_VALIDATORS_LIMIT_PRESERVE: 5,
153
+ SSV_DEDUCTED_DIGITS: 10000000n,
154
+ ETH_DEDUCTED_DIGITS: 100000n,
155
+ MINIMUM_OPERATOR_FEE_PER_BLOCK: 1000000000n,
156
+ MIN_VALIDATORS_COUNT_PER_BULK_REGISTRATION: 1,
157
+ DEFAULT_ADDRESS_WHITELIST: "0x0000000000000000000000000000000000000000",
158
+ VUNITS_PRECISION: 1e4
159
+ };
160
+ const registerValidatorsByClusterSizeLimits = {
161
+ [globals.CLUSTER_SIZES.QUAD_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.QUAD_CLUSTER,
162
+ [globals.CLUSTER_SIZES.SEPT_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.SEPT_CLUSTER,
163
+ [globals.CLUSTER_SIZES.DECA_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.DECA_CLUSTER,
164
+ [globals.CLUSTER_SIZES.TRISKAIDEKA_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.TRISKAIDEKA_CLUSTER
165
+ };
131
166
  const bigintMax = (...args) => {
132
167
  return args.filter((x) => !isUndefined(x)).reduce((max, cur) => cur > max ? cur : max);
133
168
  };
@@ -138,14 +173,14 @@ const bigintRound = (value, precision) => {
138
173
  const remainder = value % precision;
139
174
  return remainder >= precision / 2n ? value + (precision - remainder) : value - remainder;
140
175
  };
141
- const bigintFloor = (value, precision = 10000000n) => {
176
+ const bigintFloor = (value, precision = globals.SSV_DEDUCTED_DIGITS) => {
142
177
  return value - value % precision;
143
178
  };
144
179
  const bigintAbs = (n) => n < 0n ? -n : n;
145
180
  const isBigIntChanged = (a, b, tolerance = parseUnits("0.0001", 18)) => {
146
181
  return bigintAbs(a - b) > tolerance;
147
182
  };
148
- const roundOperatorFee = (fee, precision = 10000000n) => {
183
+ const roundOperatorFee = (fee, precision = globals.SSV_DEDUCTED_DIGITS) => {
149
184
  return bigintRound(fee, precision);
150
185
  };
151
186
  const stringifyBigints = (anything) => {
@@ -168,7 +203,7 @@ const isClusterId = (clusterId) => {
168
203
  const [ownerAddress, ...operatorIds] = clusterId.split("-");
169
204
  return isAddress(ownerAddress) && operatorIds.length >= 4 && operatorIds.every((id) => !isNaN(Number(id)));
170
205
  };
171
- const getClusterSnapshot = (cluster) => {
206
+ const toSolidityCluster = (cluster) => {
172
207
  return {
173
208
  active: cluster.active,
174
209
  balance: BigInt(cluster.balance),
@@ -239,8 +274,21 @@ class KeysharesValidationError extends Error {
239
274
  }
240
275
  const validateConsistentOperatorIds = (keyshares) => {
241
276
  const operatorIds = sortNumbers(keyshares[0].payload.operatorIds);
277
+ const hasOperatorData = keyshares.every(
278
+ (share) => (share.data.operators ?? []).length > 0
279
+ );
242
280
  keyshares.every(({ payload, data }) => {
243
281
  const payloadOperatorIds = sortNumbers(payload.operatorIds).toString();
282
+ if (!hasOperatorData) {
283
+ const valid2 = payloadOperatorIds === operatorIds.toString();
284
+ if (!valid2) {
285
+ throw new KeysharesValidationError(
286
+ 6
287
+ /* InconsistentOperators */
288
+ );
289
+ }
290
+ return true;
291
+ }
244
292
  const dataOperatorIds = getOperatorIds(data.operators ?? []).toString();
245
293
  const valid = payloadOperatorIds === dataOperatorIds && dataOperatorIds === operatorIds.toString();
246
294
  if (!valid) {
@@ -254,7 +302,16 @@ const validateConsistentOperatorIds = (keyshares) => {
254
302
  return operatorIds;
255
303
  };
256
304
  const ensureValidatorsUniqueness = (keyshares) => {
257
- const set = new Set(keyshares.map(({ data }) => data.publicKey));
305
+ const keys = keyshares.map(
306
+ ({ data, payload }) => data.publicKey ?? payload.publicKey
307
+ );
308
+ if (keys.some((key) => !key)) {
309
+ throw new KeysharesValidationError(
310
+ 4
311
+ /* DuplicateValidatorKeys */
312
+ );
313
+ }
314
+ const set = new Set(keys);
258
315
  if (set.size !== keyshares.length) {
259
316
  throw new KeysharesValidationError(
260
317
  4
@@ -264,6 +321,12 @@ const ensureValidatorsUniqueness = (keyshares) => {
264
321
  return true;
265
322
  };
266
323
  const validateConsistentOperatorPublicKeys = (keyshares, operators) => {
324
+ const hasOperatorData = keyshares.every(
325
+ (share) => (share.data.operators ?? []).length > 0
326
+ );
327
+ if (!hasOperatorData) {
328
+ return true;
329
+ }
267
330
  const operatorsMap = new Map(operators.map((o) => [o.id, o.publicKey]));
268
331
  const valid = keyshares.every(({ data }) => {
269
332
  return data.operators?.every(({ id, operatorKey }) => {
@@ -319,15 +382,9 @@ const configArgsSchema = z.object({
319
382
  }
320
383
  return true;
321
384
  }),
322
- walletClient: z.custom().superRefine((val, ctx) => {
385
+ walletClient: z.custom().optional().superRefine((val, ctx) => {
323
386
  const client = val;
324
- if (!client) {
325
- ctx.addIssue({
326
- code: z.ZodIssueCode.custom,
327
- message: "Wallet client must be provided"
328
- });
329
- return false;
330
- }
387
+ if (!client) return true;
331
388
  if (client.chain === void 0) {
332
389
  ctx.addIssue({
333
390
  code: z.ZodIssueCode.custom,
@@ -362,88 +419,59 @@ const configArgsSchema = z.object({
362
419
  (val) => {
363
420
  const publicClient = val.publicClient;
364
421
  const walletClient = val.walletClient;
422
+ if (!walletClient) {
423
+ return true;
424
+ }
365
425
  return publicClient?.chain?.id === walletClient?.chain?.id;
366
426
  },
367
427
  {
368
428
  message: "Public and wallet client chains must be the same"
369
429
  }
370
430
  );
371
- const globals = {
372
- MAX_WEI_AMOUNT: 115792089237316195423570985008687907853269984665640564039457584007913129639935n,
373
- CLUSTER_SIZES: {
374
- QUAD_CLUSTER: 4,
375
- SEPT_CLUSTER: 7,
376
- DECA_CLUSTER: 10,
377
- TRISKAIDEKA_CLUSTER: 13
378
- },
379
- FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE: {
380
- QUAD_CLUSTER: 80,
381
- SEPT_CLUSTER: 40,
382
- DECA_CLUSTER: 30,
383
- TRISKAIDEKA_CLUSTER: 20
384
- },
385
- BLOCKS_PER_DAY: 7160n,
386
- OPERATORS_PER_PAGE: 50,
387
- BLOCKS_PER_YEAR: 2613400n,
388
- DEFAULT_CLUSTER_PERIOD: 730,
389
- NUMBERS_OF_WEEKS_IN_YEAR: 52.1429,
390
- MAX_VALIDATORS_COUNT_MULTI_FLOW: 50,
391
- CLUSTER_VALIDITY_PERIOD_MINIMUM: 30,
392
- OPERATOR_VALIDATORS_LIMIT_PRESERVE: 5,
393
- MINIMUM_OPERATOR_FEE_PER_BLOCK: 1000000000n,
394
- MIN_VALIDATORS_COUNT_PER_BULK_REGISTRATION: 1,
395
- DEFAULT_ADDRESS_WHITELIST: "0x0000000000000000000000000000000000000000"
396
- };
397
- const registerValidatorsByClusterSizeLimits = {
398
- [globals.CLUSTER_SIZES.QUAD_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.QUAD_CLUSTER,
399
- [globals.CLUSTER_SIZES.SEPT_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.SEPT_CLUSTER,
400
- [globals.CLUSTER_SIZES.DECA_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.DECA_CLUSTER,
401
- [globals.CLUSTER_SIZES.TRISKAIDEKA_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.TRISKAIDEKA_CLUSTER
402
- };
403
431
  export {
404
- formatBigintInput as A,
405
- ms as B,
406
- sortNumbers as C,
407
- getOperatorIds as D,
408
- decodeOperatorPublicKey as E,
409
- tryCatch as F,
410
- configArgsSchema as G,
432
+ roundOperatorFee as A,
433
+ sortNumbers as B,
434
+ stringifyBigints as C,
435
+ toSolidityCluster as D,
436
+ tryCatch as E,
437
+ validateConsistentOperatorIds as F,
438
+ validateConsistentOperatorPublicKeys as G,
411
439
  contracts as H,
412
440
  paid_graph_endpoints as I,
413
441
  graph_endpoints as J,
414
- KeysharesValidationErrors as K,
442
+ KeysharesValidationError as K,
415
443
  rest_endpoints as L,
416
444
  registerValidatorsByClusterSizeLimits as M,
417
445
  globals as N,
418
- hoodi as O,
446
+ chainIds as O,
419
447
  chains as P,
420
- chainIds as Q,
448
+ hoodi as Q,
421
449
  networks as R,
422
450
  _percentageFormatter as _,
423
- bigintMin as a,
424
- bigintMax as b,
425
- bigintRound as c,
426
- bigintFloor as d,
427
- bigintAbs as e,
428
- bigintifyNumbers as f,
429
- createClusterId as g,
430
- isClusterId as h,
431
- isBigIntChanged as i,
432
- getClusterSnapshot as j,
433
- createEmptyCluster as k,
434
- add0x as l,
435
- isKeySharesItem as m,
436
- KeysharesValidationErrorsMessages as n,
437
- KeysharesValidationError as o,
451
+ KeysharesValidationErrors as a,
452
+ KeysharesValidationErrorsMessages as b,
453
+ add0x as c,
454
+ bigintAbs as d,
455
+ bigintFloor as e,
456
+ bigintFormatter as f,
457
+ bigintMax as g,
458
+ bigintMin as h,
459
+ bigintRound as i,
460
+ bigintifyNumbers as j,
461
+ configArgsSchema as k,
462
+ createClusterId as l,
463
+ createEmptyCluster as m,
464
+ decodeOperatorPublicKey as n,
465
+ ensureNoKeysharesErrors as o,
438
466
  ensureValidatorsUniqueness as p,
439
- validateConsistentOperatorPublicKeys as q,
440
- roundOperatorFee as r,
441
- stringifyBigints as s,
442
- ensureNoKeysharesErrors as t,
443
- numberFormatter as u,
444
- validateConsistentOperatorIds as v,
445
- percentageFormatter as w,
446
- bigintFormatter as x,
447
- ethFormatter as y,
448
- formatSSV as z
467
+ ethFormatter as q,
468
+ formatBigintInput as r,
469
+ formatSSV as s,
470
+ getOperatorIds as t,
471
+ isBigIntChanged as u,
472
+ isClusterId as v,
473
+ isKeySharesItem as w,
474
+ ms as x,
475
+ numberFormatter as y,
476
+ percentageFormatter as z
449
477
  };
@@ -129,6 +129,41 @@ const contracts = {
129
129
  token: "0x9F5d4Ec84fC4785788aB44F9de973cF34F7A038e"
130
130
  }
131
131
  };
132
+ const globals = {
133
+ MAX_WEI_AMOUNT: 115792089237316195423570985008687907853269984665640564039457584007913129639935n,
134
+ CLUSTER_SIZES: {
135
+ QUAD_CLUSTER: 4,
136
+ SEPT_CLUSTER: 7,
137
+ DECA_CLUSTER: 10,
138
+ TRISKAIDEKA_CLUSTER: 13
139
+ },
140
+ FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE: {
141
+ QUAD_CLUSTER: 80,
142
+ SEPT_CLUSTER: 40,
143
+ DECA_CLUSTER: 30,
144
+ TRISKAIDEKA_CLUSTER: 20
145
+ },
146
+ BLOCKS_PER_DAY: 7200n,
147
+ OPERATORS_PER_PAGE: 50,
148
+ BLOCKS_PER_YEAR: 2628000n,
149
+ DEFAULT_CLUSTER_PERIOD: 730,
150
+ NUMBERS_OF_WEEKS_IN_YEAR: 52.1429,
151
+ MAX_VALIDATORS_COUNT_MULTI_FLOW: 50,
152
+ CLUSTER_VALIDITY_PERIOD_MINIMUM: 30,
153
+ OPERATOR_VALIDATORS_LIMIT_PRESERVE: 5,
154
+ SSV_DEDUCTED_DIGITS: 10000000n,
155
+ ETH_DEDUCTED_DIGITS: 100000n,
156
+ MINIMUM_OPERATOR_FEE_PER_BLOCK: 1000000000n,
157
+ MIN_VALIDATORS_COUNT_PER_BULK_REGISTRATION: 1,
158
+ DEFAULT_ADDRESS_WHITELIST: "0x0000000000000000000000000000000000000000",
159
+ VUNITS_PRECISION: 1e4
160
+ };
161
+ const registerValidatorsByClusterSizeLimits = {
162
+ [globals.CLUSTER_SIZES.QUAD_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.QUAD_CLUSTER,
163
+ [globals.CLUSTER_SIZES.SEPT_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.SEPT_CLUSTER,
164
+ [globals.CLUSTER_SIZES.DECA_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.DECA_CLUSTER,
165
+ [globals.CLUSTER_SIZES.TRISKAIDEKA_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.TRISKAIDEKA_CLUSTER
166
+ };
132
167
  const bigintMax = (...args) => {
133
168
  return args.filter((x) => !lodashEs.isUndefined(x)).reduce((max, cur) => cur > max ? cur : max);
134
169
  };
@@ -139,14 +174,14 @@ const bigintRound = (value, precision) => {
139
174
  const remainder = value % precision;
140
175
  return remainder >= precision / 2n ? value + (precision - remainder) : value - remainder;
141
176
  };
142
- const bigintFloor = (value, precision = 10000000n) => {
177
+ const bigintFloor = (value, precision = globals.SSV_DEDUCTED_DIGITS) => {
143
178
  return value - value % precision;
144
179
  };
145
180
  const bigintAbs = (n) => n < 0n ? -n : n;
146
181
  const isBigIntChanged = (a, b, tolerance = viem.parseUnits("0.0001", 18)) => {
147
182
  return bigintAbs(a - b) > tolerance;
148
183
  };
149
- const roundOperatorFee = (fee, precision = 10000000n) => {
184
+ const roundOperatorFee = (fee, precision = globals.SSV_DEDUCTED_DIGITS) => {
150
185
  return bigintRound(fee, precision);
151
186
  };
152
187
  const stringifyBigints = (anything) => {
@@ -169,7 +204,7 @@ const isClusterId = (clusterId) => {
169
204
  const [ownerAddress, ...operatorIds] = clusterId.split("-");
170
205
  return viem.isAddress(ownerAddress) && operatorIds.length >= 4 && operatorIds.every((id) => !isNaN(Number(id)));
171
206
  };
172
- const getClusterSnapshot = (cluster) => {
207
+ const toSolidityCluster = (cluster) => {
173
208
  return {
174
209
  active: cluster.active,
175
210
  balance: BigInt(cluster.balance),
@@ -240,8 +275,21 @@ class KeysharesValidationError extends Error {
240
275
  }
241
276
  const validateConsistentOperatorIds = (keyshares) => {
242
277
  const operatorIds = sortNumbers(keyshares[0].payload.operatorIds);
278
+ const hasOperatorData = keyshares.every(
279
+ (share) => (share.data.operators ?? []).length > 0
280
+ );
243
281
  keyshares.every(({ payload, data }) => {
244
282
  const payloadOperatorIds = sortNumbers(payload.operatorIds).toString();
283
+ if (!hasOperatorData) {
284
+ const valid2 = payloadOperatorIds === operatorIds.toString();
285
+ if (!valid2) {
286
+ throw new KeysharesValidationError(
287
+ 6
288
+ /* InconsistentOperators */
289
+ );
290
+ }
291
+ return true;
292
+ }
245
293
  const dataOperatorIds = getOperatorIds(data.operators ?? []).toString();
246
294
  const valid = payloadOperatorIds === dataOperatorIds && dataOperatorIds === operatorIds.toString();
247
295
  if (!valid) {
@@ -255,7 +303,16 @@ const validateConsistentOperatorIds = (keyshares) => {
255
303
  return operatorIds;
256
304
  };
257
305
  const ensureValidatorsUniqueness = (keyshares) => {
258
- const set = new Set(keyshares.map(({ data }) => data.publicKey));
306
+ const keys = keyshares.map(
307
+ ({ data, payload }) => data.publicKey ?? payload.publicKey
308
+ );
309
+ if (keys.some((key) => !key)) {
310
+ throw new KeysharesValidationError(
311
+ 4
312
+ /* DuplicateValidatorKeys */
313
+ );
314
+ }
315
+ const set = new Set(keys);
259
316
  if (set.size !== keyshares.length) {
260
317
  throw new KeysharesValidationError(
261
318
  4
@@ -265,6 +322,12 @@ const ensureValidatorsUniqueness = (keyshares) => {
265
322
  return true;
266
323
  };
267
324
  const validateConsistentOperatorPublicKeys = (keyshares, operators) => {
325
+ const hasOperatorData = keyshares.every(
326
+ (share) => (share.data.operators ?? []).length > 0
327
+ );
328
+ if (!hasOperatorData) {
329
+ return true;
330
+ }
268
331
  const operatorsMap = new Map(operators.map((o) => [o.id, o.publicKey]));
269
332
  const valid = keyshares.every(({ data }) => {
270
333
  return data.operators?.every(({ id, operatorKey }) => {
@@ -320,15 +383,9 @@ const configArgsSchema = zod.z.object({
320
383
  }
321
384
  return true;
322
385
  }),
323
- walletClient: zod.z.custom().superRefine((val, ctx) => {
386
+ walletClient: zod.z.custom().optional().superRefine((val, ctx) => {
324
387
  const client = val;
325
- if (!client) {
326
- ctx.addIssue({
327
- code: zod.z.ZodIssueCode.custom,
328
- message: "Wallet client must be provided"
329
- });
330
- return false;
331
- }
388
+ if (!client) return true;
332
389
  if (client.chain === void 0) {
333
390
  ctx.addIssue({
334
391
  code: zod.z.ZodIssueCode.custom,
@@ -363,44 +420,15 @@ const configArgsSchema = zod.z.object({
363
420
  (val) => {
364
421
  const publicClient = val.publicClient;
365
422
  const walletClient = val.walletClient;
423
+ if (!walletClient) {
424
+ return true;
425
+ }
366
426
  return publicClient?.chain?.id === walletClient?.chain?.id;
367
427
  },
368
428
  {
369
429
  message: "Public and wallet client chains must be the same"
370
430
  }
371
431
  );
372
- const globals = {
373
- MAX_WEI_AMOUNT: 115792089237316195423570985008687907853269984665640564039457584007913129639935n,
374
- CLUSTER_SIZES: {
375
- QUAD_CLUSTER: 4,
376
- SEPT_CLUSTER: 7,
377
- DECA_CLUSTER: 10,
378
- TRISKAIDEKA_CLUSTER: 13
379
- },
380
- FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE: {
381
- QUAD_CLUSTER: 80,
382
- SEPT_CLUSTER: 40,
383
- DECA_CLUSTER: 30,
384
- TRISKAIDEKA_CLUSTER: 20
385
- },
386
- BLOCKS_PER_DAY: 7160n,
387
- OPERATORS_PER_PAGE: 50,
388
- BLOCKS_PER_YEAR: 2613400n,
389
- DEFAULT_CLUSTER_PERIOD: 730,
390
- NUMBERS_OF_WEEKS_IN_YEAR: 52.1429,
391
- MAX_VALIDATORS_COUNT_MULTI_FLOW: 50,
392
- CLUSTER_VALIDITY_PERIOD_MINIMUM: 30,
393
- OPERATOR_VALIDATORS_LIMIT_PRESERVE: 5,
394
- MINIMUM_OPERATOR_FEE_PER_BLOCK: 1000000000n,
395
- MIN_VALIDATORS_COUNT_PER_BULK_REGISTRATION: 1,
396
- DEFAULT_ADDRESS_WHITELIST: "0x0000000000000000000000000000000000000000"
397
- };
398
- const registerValidatorsByClusterSizeLimits = {
399
- [globals.CLUSTER_SIZES.QUAD_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.QUAD_CLUSTER,
400
- [globals.CLUSTER_SIZES.SEPT_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.SEPT_CLUSTER,
401
- [globals.CLUSTER_SIZES.DECA_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.DECA_CLUSTER,
402
- [globals.CLUSTER_SIZES.TRISKAIDEKA_CLUSTER]: globals.FIXED_VALIDATORS_COUNT_PER_CLUSTER_SIZE.TRISKAIDEKA_CLUSTER
403
- };
404
432
  exports.KeysharesValidationError = KeysharesValidationError;
405
433
  exports.KeysharesValidationErrors = KeysharesValidationErrors;
406
434
  exports.KeysharesValidationErrorsMessages = KeysharesValidationErrorsMessages;
@@ -425,7 +453,6 @@ exports.ensureValidatorsUniqueness = ensureValidatorsUniqueness;
425
453
  exports.ethFormatter = ethFormatter;
426
454
  exports.formatBigintInput = formatBigintInput;
427
455
  exports.formatSSV = formatSSV;
428
- exports.getClusterSnapshot = getClusterSnapshot;
429
456
  exports.getOperatorIds = getOperatorIds;
430
457
  exports.globals = globals;
431
458
  exports.graph_endpoints = graph_endpoints;
@@ -443,6 +470,7 @@ exports.rest_endpoints = rest_endpoints;
443
470
  exports.roundOperatorFee = roundOperatorFee;
444
471
  exports.sortNumbers = sortNumbers;
445
472
  exports.stringifyBigints = stringifyBigints;
473
+ exports.toSolidityCluster = toSolidityCluster;
446
474
  exports.tryCatch = tryCatch;
447
475
  exports.validateConsistentOperatorIds = validateConsistentOperatorIds;
448
476
  exports.validateConsistentOperatorPublicKeys = validateConsistentOperatorPublicKeys;
@@ -1,3 +1,3 @@
1
1
  import { ContractNames, ReadProps, ReaderFunctions, WriteProps, WriterFunctions } from './types';
2
- export declare const createWriter: <T extends ContractNames>({ abi, publicClient, walletClient, contractAddress, }: WriteProps) => WriterFunctions<T>;
2
+ export declare const createWriter: <T extends ContractNames>({ abi, publicClient, walletClient, contractAddress, eventSources, }: WriteProps) => WriterFunctions<T>;
3
3
  export declare const createReader: <T extends ContractNames>({ abi, publicClient, contractAddress, }: ReadProps) => ReaderFunctions<T>;
@@ -43,15 +43,21 @@ export type WriteReturnType<T extends SupportedEvents> = Promise<{
43
43
  events: T[];
44
44
  }>;
45
45
  }>;
46
- export type WriteOptions<K extends WriteFns> = Omit<SimulateContractParameters<SupportedAbis, K['name']>, 'chain' | 'args' | 'value' | 'abi' | 'functionName' | 'address' | 'account' | 'value'>;
47
- export type SmartFnWriteOptions<K extends Record<string, unknown>> = Omit<SimulateContractParameters, 'chain' | 'args' | 'value' | 'abi' | 'functionName' | 'address' | 'account' | 'value'> & {
46
+ export type WriteOptions<K extends WriteFns> = Omit<SimulateContractParameters<SupportedAbis, K['name']>, 'chain' | 'args' | 'value' | 'abi' | 'functionName' | 'address' | 'account'>;
47
+ export type SmartFnWriteOptions<K extends Record<string, unknown>> = Omit<SimulateContractParameters, 'chain' | 'args' | 'value' | 'abi' | 'functionName' | 'address' | 'account'> & {
48
48
  args: K;
49
+ value?: bigint;
50
+ };
51
+ export type EventSource = {
52
+ abi: Abi;
53
+ address: Address;
49
54
  };
50
55
  export type WriteProps = {
51
56
  abi: Abi;
52
57
  publicClient: PublicClient;
53
- walletClient: WalletClient;
58
+ walletClient?: WalletClient;
54
59
  contractAddress: Address;
60
+ eventSources?: EventSource[];
55
61
  };
56
62
  export type ReadProps = {
57
63
  abi: SupportedAbis;