@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
@@ -0,0 +1,237 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { Client } from '../../src';
11
+ import { CHAIN_CONFIGURATION } from '../../src/constants';
12
+ import { formatRecipientsForSplitV2, predictSplitV2Address, isSplitV2Deployed, deployOVMAndSplitV2, deployOVMContract, } from '../../src/splits/splitHelpers';
13
+ import { isContractAvailable } from '../../src/utils';
14
+ import { TEST_ADDRESSES } from '../fixtures';
15
+ // Mock the split helpers
16
+ jest.mock('../../src/splits/splitHelpers', () => ({
17
+ formatRecipientsForSplitV2: jest.fn(),
18
+ predictSplitV2Address: jest.fn(),
19
+ isSplitV2Deployed: jest.fn(),
20
+ deployOVMContract: jest.fn(),
21
+ deployOVMAndSplitV2: jest.fn(),
22
+ }));
23
+ // Mock the utils
24
+ jest.mock('../../src/utils', () => ({
25
+ isContractAvailable: jest.fn(),
26
+ }));
27
+ // Mock the validation
28
+ jest.mock('../../src/ajv', () => ({
29
+ validatePayload: jest.fn(data => data),
30
+ }));
31
+ // Type the mocked functions
32
+ const mockFormatRecipientsForSplitV2 = formatRecipientsForSplitV2;
33
+ const mockPredictSplitV2Address = predictSplitV2Address;
34
+ const mockIsSplitV2Deployed = isSplitV2Deployed;
35
+ const mockDeployOVMAndSplitV2 = deployOVMAndSplitV2;
36
+ const mockDeployOVMContract = deployOVMContract;
37
+ const mockIsContractAvailable = isContractAvailable;
38
+ describe('ObolSplits', () => {
39
+ let client;
40
+ let mockSigner;
41
+ let mockProvider;
42
+ beforeEach(() => {
43
+ // Clear all mocks before each test
44
+ jest.clearAllMocks();
45
+ mockSigner = {
46
+ getAddress: jest
47
+ .fn()
48
+ .mockResolvedValue('0x1234567890123456789012345678901234567890'),
49
+ signTypedData: jest.fn().mockResolvedValue('0xsigned'),
50
+ provider: {
51
+ getCode: jest.fn().mockResolvedValue('0x123456'),
52
+ },
53
+ };
54
+ mockProvider = {
55
+ getCode: jest.fn().mockResolvedValue('0x123456'),
56
+ };
57
+ client = new Client({ chainId: 1 }, mockSigner, mockProvider);
58
+ });
59
+ describe('createValidatorManagerAndRewardsSplit', () => {
60
+ const mockRewardsSplitPayload = {
61
+ rewardSplitRecipients: [
62
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_1, percentAllocation: 50 },
63
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_2, percentAllocation: 49 },
64
+ ],
65
+ OVMOwnerAddress: TEST_ADDRESSES.OVM_OWNER,
66
+ splitOwnerAddress: TEST_ADDRESSES.SPLIT_OWNER,
67
+ principalRecipient: TEST_ADDRESSES.PRINCIPAL_RECIPIENT,
68
+ distributorFeePercent: 0,
69
+ };
70
+ it('should create rewards-only split successfully', () => __awaiter(void 0, void 0, void 0, function* () {
71
+ // Mock helper functions
72
+ mockFormatRecipientsForSplitV2.mockReturnValue([
73
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_1, percentAllocation: 50 },
74
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_2, percentAllocation: 49 },
75
+ {
76
+ address: '0xDe5aE4De36c966747Ea7DF13BD9589642e2B1D0d',
77
+ percentAllocation: 1,
78
+ },
79
+ ]);
80
+ mockPredictSplitV2Address.mockResolvedValue('0xRewardsSplitAddress');
81
+ mockIsSplitV2Deployed.mockResolvedValue(false);
82
+ mockDeployOVMAndSplitV2.mockResolvedValue('0xOVMAddress');
83
+ mockIsContractAvailable.mockResolvedValue(true);
84
+ const result = yield client.splits.createValidatorManagerAndRewardsSplit(mockRewardsSplitPayload);
85
+ expect(result).toEqual({
86
+ withdrawal_address: '0xOVMAddress',
87
+ fee_recipient_address: '0xRewardsSplitAddress',
88
+ });
89
+ expect(mockFormatRecipientsForSplitV2).toHaveBeenCalled();
90
+ expect(mockPredictSplitV2Address).toHaveBeenCalled();
91
+ expect(mockIsSplitV2Deployed).toHaveBeenCalled();
92
+ expect(mockDeployOVMAndSplitV2).toHaveBeenCalled();
93
+ }));
94
+ it('should throw error when signer is not provided', () => __awaiter(void 0, void 0, void 0, function* () {
95
+ const clientWithoutSigner = new Client({ chainId: 1 }, undefined, mockProvider);
96
+ yield expect(clientWithoutSigner.splits.createValidatorManagerAndRewardsSplit(mockRewardsSplitPayload)).rejects.toThrow('Signer is required in createValidatorManagerAndRewardsSplit');
97
+ }));
98
+ it('should throw error when chain is not supported', () => __awaiter(void 0, void 0, void 0, function* () {
99
+ const clientUnsupportedChain = new Client({ chainId: 999 }, mockSigner, mockProvider);
100
+ yield expect(clientUnsupportedChain.splits.createValidatorManagerAndRewardsSplit(mockRewardsSplitPayload)).rejects.toThrow('Splitter configuration is not supported on 999 chain');
101
+ }));
102
+ it('should throw error when OVM factory is not configured', () => __awaiter(void 0, void 0, void 0, function* () {
103
+ // Mock chain configuration without OVM factory
104
+ const originalConfig = CHAIN_CONFIGURATION[1];
105
+ // Create a new config object without OVM_FACTORY_ADDRESS
106
+ const configWithoutOVM = Object.assign({}, originalConfig);
107
+ delete configWithoutOVM.OVM_FACTORY_ADDRESS;
108
+ CHAIN_CONFIGURATION[1] = configWithoutOVM;
109
+ yield expect(client.splits.createValidatorManagerAndRewardsSplit(mockRewardsSplitPayload)).rejects.toThrow('OVM contract factory is not configured for chain 1');
110
+ // Restore original config
111
+ CHAIN_CONFIGURATION[1] = originalConfig;
112
+ }));
113
+ });
114
+ describe('createValidatorManagerAndTotalSplit', () => {
115
+ const mockTotalSplitPayload = {
116
+ rewardSplitRecipients: [
117
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_1, percentAllocation: 50 },
118
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_2, percentAllocation: 49 },
119
+ ],
120
+ principalSplitRecipients: [
121
+ {
122
+ address: TEST_ADDRESSES.PRINCIPAL_RECIPIENT_1,
123
+ percentAllocation: 60,
124
+ },
125
+ {
126
+ address: TEST_ADDRESSES.PRINCIPAL_RECIPIENT_2,
127
+ percentAllocation: 40,
128
+ },
129
+ ],
130
+ OVMOwnerAddress: TEST_ADDRESSES.OVM_OWNER,
131
+ splitOwnerAddress: TEST_ADDRESSES.SPLIT_OWNER,
132
+ distributorFeePercent: 0,
133
+ };
134
+ it('should create total split successfully', () => __awaiter(void 0, void 0, void 0, function* () {
135
+ // Mock helper functions
136
+ mockFormatRecipientsForSplitV2
137
+ .mockReturnValueOnce([
138
+ // rewards recipients
139
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_1, percentAllocation: 50 },
140
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_2, percentAllocation: 49 },
141
+ {
142
+ address: '0xDe5aE4De36c966747Ea7DF13BD9589642e2B1D0d',
143
+ percentAllocation: 1,
144
+ },
145
+ ])
146
+ .mockReturnValueOnce([
147
+ // principal recipients
148
+ {
149
+ address: TEST_ADDRESSES.PRINCIPAL_RECIPIENT_1,
150
+ percentAllocation: 60,
151
+ },
152
+ {
153
+ address: TEST_ADDRESSES.PRINCIPAL_RECIPIENT_2,
154
+ percentAllocation: 40,
155
+ },
156
+ ]);
157
+ mockPredictSplitV2Address
158
+ .mockResolvedValueOnce('0xRewardsSplitAddress')
159
+ .mockResolvedValueOnce('0xPrincipalSplitAddress');
160
+ mockIsSplitV2Deployed
161
+ .mockResolvedValueOnce(false) // rewards split not deployed
162
+ .mockResolvedValueOnce(false); // principal split not deployed
163
+ mockDeployOVMAndSplitV2.mockResolvedValue('0xOVMAddress');
164
+ mockIsContractAvailable.mockResolvedValue(true);
165
+ const result = yield client.splits.createValidatorManagerAndTotalSplit(mockTotalSplitPayload);
166
+ expect(result).toEqual({
167
+ withdrawal_address: '0xOVMAddress',
168
+ fee_recipient_address: '0xRewardsSplitAddress',
169
+ });
170
+ expect(mockFormatRecipientsForSplitV2).toHaveBeenCalledTimes(2);
171
+ expect(mockPredictSplitV2Address).toHaveBeenCalledTimes(2);
172
+ expect(mockIsSplitV2Deployed).toHaveBeenCalledTimes(2);
173
+ expect(mockDeployOVMAndSplitV2).toHaveBeenCalled();
174
+ }));
175
+ it('should handle case when both splits are already deployed', () => __awaiter(void 0, void 0, void 0, function* () {
176
+ // Mock helper functions
177
+ mockFormatRecipientsForSplitV2
178
+ .mockReturnValueOnce([
179
+ // rewards recipients
180
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_1, percentAllocation: 50 },
181
+ { address: TEST_ADDRESSES.REWARD_RECIPIENT_2, percentAllocation: 49 },
182
+ {
183
+ address: '0xDe5aE4De36c966747Ea7DF13BD9589642e2B1D0d',
184
+ percentAllocation: 1,
185
+ },
186
+ ])
187
+ .mockReturnValueOnce([
188
+ // principal recipients
189
+ {
190
+ address: TEST_ADDRESSES.PRINCIPAL_RECIPIENT_1,
191
+ percentAllocation: 60,
192
+ },
193
+ {
194
+ address: TEST_ADDRESSES.PRINCIPAL_RECIPIENT_2,
195
+ percentAllocation: 40,
196
+ },
197
+ ]);
198
+ mockPredictSplitV2Address
199
+ .mockResolvedValueOnce('0xRewardsSplitAddress')
200
+ .mockResolvedValueOnce('0xPrincipalSplitAddress');
201
+ mockIsSplitV2Deployed
202
+ .mockResolvedValueOnce(true) // rewards split deployed
203
+ .mockResolvedValueOnce(true); // principal split deployed
204
+ mockDeployOVMContract.mockResolvedValue('0xOVMAddress');
205
+ mockIsContractAvailable.mockResolvedValue(true);
206
+ const result = yield client.splits.createValidatorManagerAndTotalSplit(mockTotalSplitPayload);
207
+ expect(result).toEqual({
208
+ withdrawal_address: '0xOVMAddress',
209
+ fee_recipient_address: '0xRewardsSplitAddress',
210
+ });
211
+ expect(mockDeployOVMContract).toHaveBeenCalledWith({
212
+ OVMOwnerAddress: mockTotalSplitPayload.OVMOwnerAddress,
213
+ principalRecipient: '0xPrincipalSplitAddress',
214
+ rewardRecipient: '0xRewardsSplitAddress',
215
+ principalThreshold: mockTotalSplitPayload.principalThreshold,
216
+ signer: mockSigner,
217
+ chainId: 1,
218
+ });
219
+ }));
220
+ it('should throw error when signer is not provided', () => __awaiter(void 0, void 0, void 0, function* () {
221
+ const clientWithoutSigner = new Client({ chainId: 1 }, undefined, mockProvider);
222
+ yield expect(clientWithoutSigner.splits.createValidatorManagerAndTotalSplit(mockTotalSplitPayload)).rejects.toThrow('Signer is required in createValidatorManagerAndTotalSplit');
223
+ }));
224
+ it('should throw error when chain is not supported', () => __awaiter(void 0, void 0, void 0, function* () {
225
+ const clientUnsupportedChain = new Client({ chainId: 999 }, mockSigner, mockProvider);
226
+ yield expect(clientUnsupportedChain.splits.createValidatorManagerAndTotalSplit(mockTotalSplitPayload)).rejects.toThrow('Splitter configuration is not supported on 999 chain');
227
+ }));
228
+ });
229
+ describe('constructor', () => {
230
+ it('should create Client instance with splits property', () => {
231
+ const testClient = new Client({ chainId: 1 }, mockSigner, mockProvider);
232
+ expect(testClient.splits).toBeDefined();
233
+ expect(testClient.splits.chainId).toBe(1);
234
+ expect(testClient.splits.provider).toBe(mockProvider);
235
+ });
236
+ });
237
+ });