@obolnetwork/obol-sdk 2.7.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.
- package/dist/cjs/package.json +4 -2
- package/dist/cjs/src/abi/OVMFactory.js +620 -0
- package/dist/cjs/src/ajv.js +33 -6
- package/dist/cjs/src/bytecodes.js +8 -1
- package/dist/cjs/src/constants.js +55 -7
- package/dist/cjs/src/index.js +21 -9
- package/dist/cjs/src/schema.js +71 -1
- package/dist/cjs/src/splits/splitHelpers.js +218 -12
- package/dist/cjs/src/splits/splits.js +261 -0
- package/dist/cjs/src/types.js +0 -1
- package/dist/cjs/test/client/ajv.spec.js +269 -0
- package/dist/cjs/test/client/methods.spec.js +418 -0
- package/dist/cjs/test/fixtures.js +13 -1
- package/dist/cjs/test/splits/splits.spec.js +239 -0
- package/dist/esm/package.json +4 -2
- package/dist/esm/src/abi/OVMFactory.js +617 -0
- package/dist/esm/src/ajv.js +33 -6
- package/dist/esm/src/bytecodes.js +7 -0
- package/dist/esm/src/constants.js +54 -7
- package/dist/esm/src/index.js +20 -9
- package/dist/esm/src/schema.js +71 -1
- package/dist/esm/src/splits/splitHelpers.js +213 -13
- package/dist/esm/src/splits/splits.js +257 -0
- package/dist/esm/src/types.js +0 -1
- package/dist/esm/test/client/ajv.spec.js +267 -0
- package/dist/esm/test/client/methods.spec.js +393 -0
- package/dist/esm/test/fixtures.js +12 -0
- package/dist/esm/test/splits/splits.spec.js +237 -0
- package/dist/types/src/abi/OVMFactory.d.ts +662 -0
- package/dist/types/src/bytecodes.d.ts +7 -0
- package/dist/types/src/constants.d.ts +10 -21
- package/dist/types/src/index.d.ts +7 -0
- package/dist/types/src/schema.d.ts +145 -0
- package/dist/types/src/splits/splitHelpers.d.ts +40 -1
- package/dist/types/src/splits/splits.d.ts +51 -0
- package/dist/types/src/types.d.ts +83 -2
- package/dist/types/test/client/ajv.spec.d.ts +1 -0
- package/dist/types/test/client/methods.spec.d.ts +1 -0
- package/dist/types/test/fixtures.d.ts +10 -0
- package/dist/types/test/splits/splits.spec.d.ts +1 -0
- package/package.json +4 -2
- package/src/abi/OVMFactory.ts +617 -0
- package/src/ajv.ts +55 -13
- package/src/bytecodes.ts +15 -0
- package/src/constants.ts +66 -8
- package/src/index.ts +36 -15
- package/src/schema.ts +80 -0
- package/src/splits/splitHelpers.ts +360 -14
- package/src/splits/splits.ts +355 -0
- package/src/types.ts +96 -3
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
import { ZeroAddress } from 'ethers';
|
|
2
|
+
// Test address constants for OVM splits
|
|
3
|
+
export const TEST_ADDRESSES = {
|
|
4
|
+
REWARD_RECIPIENT_1: '0x1234567890123456789012345678901234567890',
|
|
5
|
+
REWARD_RECIPIENT_2: '0x2345678901234567890123456789012345678901',
|
|
6
|
+
PRINCIPAL_RECIPIENT_1: '0x3456789012345678901234567890123456789012',
|
|
7
|
+
PRINCIPAL_RECIPIENT_2: '0x4567890123456789012345678901234567890123',
|
|
8
|
+
OVM_OWNER: '0x5678901234567890123456789012345678901234',
|
|
9
|
+
SPLIT_OWNER: '0x6789012345678901234567890123456789012345',
|
|
10
|
+
PRINCIPAL_RECIPIENT: '0x7890123456789012345678901234567890123456',
|
|
11
|
+
ZERO_ADDRESS: ZeroAddress,
|
|
12
|
+
};
|
|
1
13
|
export const enr = 'enr:-HW4QLlrtMjFLGkFT1bwdGbvZQlH8hLi0M2g44JAxEYP3BZmYpcsy9Q56HPPD87fMucjvLv4-obEFacpsg0ehRilbHeAgmlkgnY0iXNlY3AyNTZrMaEDRaa5o2aSgqyFq_ERZcQTztrOij1mFtXX1bJuVI6ieak';
|
|
2
14
|
// v1.6.0
|
|
3
15
|
export const clusterLockV1X6 = {
|
|
@@ -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
|
+
});
|