@obolnetwork/obol-sdk 2.6.0 → 2.8.0

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 (56) hide show
  1. package/dist/cjs/package.json +4 -2
  2. package/dist/cjs/src/abi/OVMFactory.js +620 -0
  3. package/dist/cjs/src/ajv.js +33 -6
  4. package/dist/cjs/src/bytecodes.js +8 -1
  5. package/dist/cjs/src/constants.js +55 -7
  6. package/dist/cjs/src/exits/exit.js +82 -0
  7. package/dist/cjs/src/index.js +21 -9
  8. package/dist/cjs/src/schema.js +71 -1
  9. package/dist/cjs/src/splits/splitHelpers.js +218 -12
  10. package/dist/cjs/src/splits/splits.js +261 -0
  11. package/dist/cjs/src/types.js +0 -1
  12. package/dist/cjs/test/client/ajv.spec.js +269 -0
  13. package/dist/cjs/test/client/methods.spec.js +418 -0
  14. package/dist/cjs/test/exit/exit.spec.js +74 -3
  15. package/dist/cjs/test/fixtures.js +13 -1
  16. package/dist/cjs/test/splits/splits.spec.js +239 -0
  17. package/dist/esm/package.json +4 -2
  18. package/dist/esm/src/abi/OVMFactory.js +617 -0
  19. package/dist/esm/src/ajv.js +33 -6
  20. package/dist/esm/src/bytecodes.js +7 -0
  21. package/dist/esm/src/constants.js +54 -7
  22. package/dist/esm/src/exits/exit.js +83 -1
  23. package/dist/esm/src/index.js +20 -9
  24. package/dist/esm/src/schema.js +71 -1
  25. package/dist/esm/src/splits/splitHelpers.js +213 -13
  26. package/dist/esm/src/splits/splits.js +257 -0
  27. package/dist/esm/src/types.js +0 -1
  28. package/dist/esm/test/client/ajv.spec.js +267 -0
  29. package/dist/esm/test/client/methods.spec.js +393 -0
  30. package/dist/esm/test/exit/exit.spec.js +74 -3
  31. package/dist/esm/test/fixtures.js +12 -0
  32. package/dist/esm/test/splits/splits.spec.js +237 -0
  33. package/dist/types/src/abi/OVMFactory.d.ts +662 -0
  34. package/dist/types/src/bytecodes.d.ts +7 -0
  35. package/dist/types/src/constants.d.ts +10 -21
  36. package/dist/types/src/exits/exit.d.ts +21 -1
  37. package/dist/types/src/index.d.ts +7 -0
  38. package/dist/types/src/schema.d.ts +145 -0
  39. package/dist/types/src/splits/splitHelpers.d.ts +40 -1
  40. package/dist/types/src/splits/splits.d.ts +51 -0
  41. package/dist/types/src/types.d.ts +122 -6
  42. package/dist/types/test/client/ajv.spec.d.ts +1 -0
  43. package/dist/types/test/client/methods.spec.d.ts +1 -0
  44. package/dist/types/test/fixtures.d.ts +10 -0
  45. package/dist/types/test/splits/splits.spec.d.ts +1 -0
  46. package/package.json +4 -2
  47. package/src/abi/OVMFactory.ts +617 -0
  48. package/src/ajv.ts +55 -13
  49. package/src/bytecodes.ts +15 -0
  50. package/src/constants.ts +66 -8
  51. package/src/exits/exit.ts +98 -1
  52. package/src/index.ts +36 -15
  53. package/src/schema.ts +80 -0
  54. package/src/splits/splitHelpers.ts +360 -14
  55. package/src/splits/splits.ts +355 -0
  56. package/src/types.ts +138 -10
@@ -176,3 +176,148 @@ export declare const rewardsSplitterPayloadSchema: {
176
176
  validateRewardsSplitRecipients: boolean;
177
177
  required: string[];
178
178
  };
179
+ export declare const ovmBaseSplitPayload: {
180
+ rewardSplitRecipients: {
181
+ type: string;
182
+ items: {
183
+ type: string;
184
+ properties: {
185
+ address: {
186
+ type: string;
187
+ pattern: string;
188
+ };
189
+ percentAllocation: {
190
+ type: string;
191
+ };
192
+ };
193
+ required: string[];
194
+ };
195
+ };
196
+ OVMOwnerAddress: {
197
+ type: string;
198
+ pattern: string;
199
+ };
200
+ splitOwnerAddress: {
201
+ type: string;
202
+ pattern: string;
203
+ default: "0x0000000000000000000000000000000000000000";
204
+ };
205
+ principalThreshold: {
206
+ type: string;
207
+ minimum: number;
208
+ default: number;
209
+ };
210
+ distributorFeePercent: {
211
+ type: string;
212
+ minimum: number;
213
+ maximum: number;
214
+ default: number;
215
+ };
216
+ };
217
+ export declare const ovmRewardsSplitPayloadSchema: {
218
+ type: string;
219
+ properties: {
220
+ principalRecipient: {
221
+ type: string;
222
+ pattern: string;
223
+ };
224
+ rewardSplitRecipients: {
225
+ type: string;
226
+ items: {
227
+ type: string;
228
+ properties: {
229
+ address: {
230
+ type: string;
231
+ pattern: string;
232
+ };
233
+ percentAllocation: {
234
+ type: string;
235
+ };
236
+ };
237
+ required: string[];
238
+ };
239
+ };
240
+ OVMOwnerAddress: {
241
+ type: string;
242
+ pattern: string;
243
+ };
244
+ splitOwnerAddress: {
245
+ type: string;
246
+ pattern: string;
247
+ default: "0x0000000000000000000000000000000000000000";
248
+ };
249
+ principalThreshold: {
250
+ type: string;
251
+ minimum: number;
252
+ default: number;
253
+ };
254
+ distributorFeePercent: {
255
+ type: string;
256
+ minimum: number;
257
+ maximum: number;
258
+ default: number;
259
+ };
260
+ };
261
+ validateOVMRewardsSplitRecipients: boolean;
262
+ required: string[];
263
+ };
264
+ export declare const ovmTotalSplitPayloadSchema: {
265
+ type: string;
266
+ properties: {
267
+ principalSplitRecipients: {
268
+ type: string;
269
+ items: {
270
+ type: string;
271
+ properties: {
272
+ address: {
273
+ type: string;
274
+ pattern: string;
275
+ };
276
+ percentAllocation: {
277
+ type: string;
278
+ };
279
+ };
280
+ required: string[];
281
+ };
282
+ };
283
+ rewardSplitRecipients: {
284
+ type: string;
285
+ items: {
286
+ type: string;
287
+ properties: {
288
+ address: {
289
+ type: string;
290
+ pattern: string;
291
+ };
292
+ percentAllocation: {
293
+ type: string;
294
+ };
295
+ };
296
+ required: string[];
297
+ };
298
+ };
299
+ OVMOwnerAddress: {
300
+ type: string;
301
+ pattern: string;
302
+ };
303
+ splitOwnerAddress: {
304
+ type: string;
305
+ pattern: string;
306
+ default: "0x0000000000000000000000000000000000000000";
307
+ };
308
+ principalThreshold: {
309
+ type: string;
310
+ minimum: number;
311
+ default: number;
312
+ };
313
+ distributorFeePercent: {
314
+ type: string;
315
+ minimum: number;
316
+ maximum: number;
317
+ default: number;
318
+ };
319
+ };
320
+ validateOVMRewardsSplitRecipients: boolean;
321
+ validateOVMTotalSplitRecipients: boolean;
322
+ required: string[];
323
+ };
@@ -1,4 +1,5 @@
1
- import { type OWRTranches, type ClusterValidator, type ETH_ADDRESS, type SplitRecipient, type SignerType } from '../types';
1
+ import { type OWRTranches, type ClusterValidator, type ETH_ADDRESS, type SplitRecipient, type SignerType, type SplitV2Recipient, type OVMArgs } from '../types';
2
+ import { SplitsClient } from '@0xsplits/splits-sdk';
2
3
  type Call = {
3
4
  target: ETH_ADDRESS;
4
5
  callData: string;
@@ -62,4 +63,42 @@ export declare const getOWRTranches: ({ owrAddress, signer, }: {
62
63
  signer: SignerType;
63
64
  }) => Promise<OWRTranches>;
64
65
  export declare const multicall: (calls: Call[], signer: SignerType, multicallAddress: string) => Promise<any>;
66
+ export declare const formatRecipientsForSplitV2: (splitRecipients: SplitRecipient[] | SplitV2Recipient[]) => SplitV2Recipient[];
67
+ export declare const createSplitsClient: (signer: SignerType, chainId: number) => Promise<SplitsClient>;
68
+ export declare const predictSplitV2Address: ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }: {
69
+ splitOwnerAddress: string;
70
+ recipients: SplitV2Recipient[];
71
+ distributorFeePercent: number;
72
+ salt: `0x${string}`;
73
+ signer: SignerType;
74
+ chainId: number;
75
+ }) => Promise<string>;
76
+ export declare const isSplitV2Deployed: ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }: {
77
+ splitOwnerAddress: string;
78
+ recipients: SplitV2Recipient[];
79
+ distributorFeePercent: number;
80
+ salt: `0x${string}`;
81
+ signer: SignerType;
82
+ chainId: number;
83
+ }) => Promise<boolean>;
84
+ export declare const deployOVMContract: ({ OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold, signer, chainId, }: {
85
+ OVMOwnerAddress: string;
86
+ principalRecipient: string;
87
+ rewardRecipient: string;
88
+ principalThreshold: number;
89
+ signer: SignerType;
90
+ chainId: number;
91
+ }) => Promise<string>;
92
+ export declare const deployOVMAndSplitV2: ({ ovmArgs, rewardRecipients, isRewardsSplitterDeployed, distributorFeePercent, salt, signer, chainId, principalSplitRecipients, isPrincipalSplitDeployed, splitOwnerAddress, }: {
93
+ ovmArgs: OVMArgs;
94
+ rewardRecipients: SplitV2Recipient[];
95
+ isRewardsSplitterDeployed?: boolean | undefined;
96
+ distributorFeePercent: number;
97
+ salt: `0x${string}`;
98
+ signer: SignerType;
99
+ chainId: number;
100
+ principalSplitRecipients?: SplitV2Recipient[] | undefined;
101
+ isPrincipalSplitDeployed?: boolean | undefined;
102
+ splitOwnerAddress: string;
103
+ }) => Promise<string>;
65
104
  export {};
@@ -0,0 +1,51 @@
1
+ import { type ClusterValidator, type ProviderType, type SignerType, type OVMRewardsSplitPayload, type OVMTotalSplitPayload } from '../types';
2
+ /**
3
+ * ObolSplits can be used for creating and managing Obol splits.
4
+ * @class
5
+ * @internal Access it through Client.splits.
6
+ * @example
7
+ * const obolClient = new Client(config);
8
+ * await obolClient.splits.createValidatorManagerAndRewardsSplit(OVMRewardsSplitPayload);
9
+ */
10
+ export declare class ObolSplits {
11
+ private readonly signer;
12
+ readonly chainId: number;
13
+ readonly provider: ProviderType | undefined | null;
14
+ constructor(signer: SignerType | undefined, chainId: number, provider: ProviderType | undefined | null);
15
+ /**
16
+ * Creates an Obol OVM and Pull split configuration for rewards-only scenario.
17
+ *
18
+ * This method deploys OVM and SplitV2 contracts for managing validator rewards only.
19
+ * Principal is handled by a single address, while rewards are split among recipients.
20
+ *
21
+ * @remarks
22
+ * **⚠️ Important:** If you're storing the private key in an `.env` file, ensure it is securely managed
23
+ * and not pushed to version control.
24
+ *
25
+ * @param {OVMRewardsSplitPayload} payload - Data needed to deploy OVM and SplitV2
26
+ * @returns {Promise<ClusterValidator>} OVM address as withdrawal address and splitter as fee recipient
27
+ * @throws Will throw an error if the splitter configuration is not supported or deployment fails
28
+ *
29
+ * An example of how to use createValidatorManagerAndRewardsSplit:
30
+ * [createValidatorManagerAndRewardsSplit](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#L333)
31
+ */
32
+ createValidatorManagerAndRewardsSplit(payload: OVMRewardsSplitPayload): Promise<ClusterValidator>;
33
+ /**
34
+ * Creates an Obol OVM and Total split configuration for total split scenario.
35
+ *
36
+ * This method deploys OVM and SplitV2 contracts for managing both validator rewards and principal.
37
+ * Both rewards and principal are split among recipients, with rewards including RAF recipient.
38
+ *
39
+ * @remarks
40
+ * **⚠️ Important:** If you're storing the private key in an `.env` file, ensure it is securely managed
41
+ * and not pushed to version control.
42
+ *
43
+ * @param {OVMTotalSplitPayload} payload - Data needed to deploy OVM and SplitV2
44
+ * @returns {Promise<ClusterValidator>} OVM address as withdrawal address and splitter as fee recipient
45
+ * @throws Will throw an error if the splitter configuration is not supported or deployment fails
46
+ *
47
+ * An example of how to use createValidatorManagerAndTotalSplit:
48
+ * [createValidatorManagerAndTotalSplit](https://github.com/ObolNetwork/obol-sdk-examples/blob/main/TS-Example/index.ts#340)
49
+ */
50
+ createValidatorManagerAndTotalSplit(payload: OVMTotalSplitPayload): Promise<ClusterValidator>;
51
+ }
@@ -1,4 +1,4 @@
1
- import { type Wallet, type ethers, type JsonRpcApiProvider, type JsonRpcProvider, type JsonRpcSigner, type Provider, type Signer } from 'ethers';
1
+ import { type Wallet, type ethers, type JsonRpcApiProvider, type JsonRpcProvider, type JsonRpcSigner, type Provider } from 'ethers';
2
2
  /**
3
3
  * Permitted ChainID's
4
4
  */
@@ -139,6 +139,48 @@ export interface RewardsSplitPayload extends TotalSplitPayload {
139
139
  /** Address that can control where the owr erc-20 tokens can be pushed, if set to zero it goes to splitter or principal address. */
140
140
  recoveryAddress?: string;
141
141
  }
142
+ /**
143
+ * OVM and SplitV2 Base Params
144
+ */
145
+ export type OVMBaseSplitPayload = {
146
+ /** The split recipients addresses and splits. */
147
+ rewardSplitRecipients: SplitV2Recipient[];
148
+ /** Owner address for the OVM contract. */
149
+ OVMOwnerAddress: string;
150
+ /** Owner address for the splitter contracts. */
151
+ splitOwnerAddress?: string;
152
+ /** Principal threshold for OVM contract. */
153
+ principalThreshold?: number;
154
+ /** Distributor fee percentage (0-10). */
155
+ distributorFeePercent?: number;
156
+ };
157
+ /**
158
+ * OVM and SplitV2 Params for rewards-only split
159
+ */
160
+ export type OVMRewardsSplitPayload = OVMBaseSplitPayload & {
161
+ /** Principal recipient address (single address for rewards-only split). */
162
+ principalRecipient: string;
163
+ };
164
+ /**
165
+ * OVM and SplitV2 Params for total split scenario
166
+ */
167
+ export type OVMTotalSplitPayload = OVMBaseSplitPayload & {
168
+ /** Principal recipients addresses and splits (array for total split scenario). */
169
+ principalSplitRecipients: SplitV2Recipient[];
170
+ };
171
+ /**
172
+ * Union type for both OVM split scenarios
173
+ */
174
+ export type OVMSplitPayload = OVMRewardsSplitPayload | OVMTotalSplitPayload;
175
+ /**
176
+ * SplitV2 Recipient structure
177
+ */
178
+ export type SplitV2Recipient = {
179
+ /** Recipient address. */
180
+ address: string;
181
+ /** Percentage allocation (0-100 with up to 4 decimals). */
182
+ percentAllocation: number;
183
+ };
142
184
  /**
143
185
  * OWR Tranches
144
186
  */
@@ -247,7 +289,7 @@ export type SafeRpcUrl = string;
247
289
  /**
248
290
  * Signer Types
249
291
  */
250
- export type SignerType = Signer | JsonRpcSigner | Wallet;
292
+ export type SignerType = JsonRpcSigner | Wallet;
251
293
  /**
252
294
  * claimIncentives Response
253
295
  */
@@ -332,17 +374,52 @@ export interface ExitValidationPayload {
332
374
  * Represents the data structure for an already existing exit blob for exit validation.
333
375
  */
334
376
  export interface ExistingExitValidationBlobData {
335
- /** The public key of the validator to exit. */
377
+ /**
378
+ * The BLS public key of the validator in hex format
379
+ */
336
380
  public_key: string;
337
- /** The epoch at which the validator wishes to exit. */
381
+ /**
382
+ * The epoch number when the exit is scheduled to occur
383
+ */
338
384
  epoch: string;
339
- /** The index of the validator in the beacon chain. */
385
+ /**
386
+ * The unique index of the validator in the beacon chain
387
+ */
340
388
  validator_index: string;
341
- /** Collection of partial exit signatures from different shares. */
389
+ /**
390
+ * Array of distributed validator shares exit data, where each share contains
391
+ * the partial exit signature from each operator in the cluster
392
+ */
342
393
  shares_exit_data: Array<Record<string, {
343
394
  partial_exit_signature: string;
344
395
  }>>;
345
396
  }
397
+ export interface FullExitBlob {
398
+ /**
399
+ * The signed voluntary exit message containing the exit details and signature
400
+ */
401
+ signed_exit_message: {
402
+ /**
403
+ * The voluntary exit message details
404
+ */
405
+ message: {
406
+ /**
407
+ * The epoch number when the validator exit will be processed
408
+ */
409
+ epoch: string;
410
+ /**
411
+ * The unique index of the validator requesting to exit
412
+ */
413
+ validator_index: string;
414
+ };
415
+ /**
416
+ * The BLS12-381 hex-encoded signature of the exit message
417
+ */
418
+ signature: string;
419
+ };
420
+ /** The public key of the validator to exit. */
421
+ public_key: string;
422
+ }
346
423
  /**
347
424
  * Generic HTTP request function type.
348
425
  * Args:
@@ -352,3 +429,42 @@ export interface ExistingExitValidationBlobData {
352
429
  * Promise<any> - The response data.
353
430
  */
354
431
  export type HttpRequestFunc = (url: string, config?: Record<string, any>) => Promise<any>;
432
+ /**
433
+ * OVM Arguments for contract creation
434
+ */
435
+ export type OVMArgs = {
436
+ /** Owner address for the OVM contract. */
437
+ OVMOwnerAddress: string;
438
+ /** Principal recipient address. */
439
+ principalRecipient: string;
440
+ /** Rewards recipient of the cluster. */
441
+ rewardRecipient: string;
442
+ /** Principal threshold for OVM contract. */
443
+ principalThreshold: number;
444
+ };
445
+ export type ChainConfig = {
446
+ SPLITMAIN_ADDRESS: {
447
+ address: string;
448
+ bytecode: string;
449
+ };
450
+ MULTICALL_ADDRESS: {
451
+ address: string;
452
+ bytecode: string;
453
+ };
454
+ OWR_FACTORY_ADDRESS: {
455
+ address: string;
456
+ bytecode: string;
457
+ };
458
+ RETROACTIVE_FUNDING_ADDRESS: {
459
+ address: string;
460
+ bytecode: string;
461
+ };
462
+ OVM_FACTORY_ADDRESS?: {
463
+ address: string;
464
+ bytecode: string;
465
+ };
466
+ WAREHOUSE_ADDRESS?: {
467
+ address: string;
468
+ bytecode: string;
469
+ };
470
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,13 @@
1
+ export declare const TEST_ADDRESSES: {
2
+ readonly REWARD_RECIPIENT_1: "0x1234567890123456789012345678901234567890";
3
+ readonly REWARD_RECIPIENT_2: "0x2345678901234567890123456789012345678901";
4
+ readonly PRINCIPAL_RECIPIENT_1: "0x3456789012345678901234567890123456789012";
5
+ readonly PRINCIPAL_RECIPIENT_2: "0x4567890123456789012345678901234567890123";
6
+ readonly OVM_OWNER: "0x5678901234567890123456789012345678901234";
7
+ readonly SPLIT_OWNER: "0x6789012345678901234567890123456789012345";
8
+ readonly PRINCIPAL_RECIPIENT: "0x7890123456789012345678901234567890123456";
9
+ readonly ZERO_ADDRESS: string;
10
+ };
1
11
  export declare const enr = "enr:-HW4QLlrtMjFLGkFT1bwdGbvZQlH8hLi0M2g44JAxEYP3BZmYpcsy9Q56HPPD87fMucjvLv4-obEFacpsg0ehRilbHeAgmlkgnY0iXNlY3AyNTZrMaEDRaa5o2aSgqyFq_ERZcQTztrOij1mFtXX1bJuVI6ieak";
2
12
  export declare const clusterLockV1X6: {
3
13
  cluster_definition: {
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obolnetwork/obol-sdk",
3
- "version": "2.6.0",
3
+ "version": "2.8.0",
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"
@@ -40,6 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
+ "@0xsplits/splits-sdk": "^5.1.0",
43
44
  "@chainsafe/bls": "6.0.3",
44
45
  "@chainsafe/blst": "^0.2.9",
45
46
  "@chainsafe/discv5": "^0.5.1",
@@ -63,7 +64,8 @@
63
64
  "pdf-parse": "^1.1.1",
64
65
  "semver": "^7.6.0",
65
66
  "typescript-eslint": "^7.1.0",
66
- "uuid": "^9.0.0"
67
+ "uuid": "^9.0.0",
68
+ "viem": "^2.31.4"
67
69
  },
68
70
  "devDependencies": {
69
71
  "@release-it/conventional-changelog": "^8.0.1",