@obolnetwork/obol-sdk 2.7.0 → 2.8.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.
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/abi/OVMFactory.js +620 -0
- package/dist/cjs/src/abi/splitV2FactoryAbi.js +420 -0
- package/dist/cjs/src/ajv.js +33 -6
- package/dist/cjs/src/bytecodes.js +10 -1
- package/dist/cjs/src/constants.js +71 -15
- package/dist/cjs/src/index.js +21 -9
- package/dist/cjs/src/schema.js +70 -1
- package/dist/cjs/src/splits/splitHelpers.js +188 -14
- package/dist/cjs/src/splits/splits.js +283 -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 +1 -1
- package/dist/esm/src/abi/OVMFactory.js +617 -0
- package/dist/esm/src/abi/splitV2FactoryAbi.js +417 -0
- package/dist/esm/src/ajv.js +33 -6
- package/dist/esm/src/bytecodes.js +9 -0
- package/dist/esm/src/constants.js +70 -15
- package/dist/esm/src/index.js +20 -9
- package/dist/esm/src/schema.js +70 -1
- package/dist/esm/src/splits/splitHelpers.js +182 -13
- package/dist/esm/src/splits/splits.js +279 -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/abi/splitV2FactoryAbi.d.ts +60 -0
- package/dist/types/src/bytecodes.d.ts +9 -0
- package/dist/types/src/constants.d.ts +10 -21
- package/dist/types/src/exits/verificationHelpers.d.ts +1 -0
- 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 +39 -2
- package/dist/types/src/splits/splits.d.ts +51 -0
- package/dist/types/src/types.d.ts +87 -2
- package/dist/types/src/verification/common.d.ts +1 -0
- 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 +1 -1
- package/src/abi/OVMFactory.ts +617 -0
- package/src/abi/splitV2FactoryAbi.ts +417 -0
- package/src/ajv.ts +55 -13
- package/src/bytecodes.ts +19 -0
- package/src/constants.ts +84 -16
- package/src/index.ts +36 -15
- package/src/schema.ts +79 -0
- package/src/splits/splitHelpers.ts +373 -18
- package/src/splits/splits.ts +406 -0
- package/src/types.ts +100 -3
package/dist/esm/src/index.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { v4 as uuidv4 } from 'uuid';
|
|
11
11
|
import { Base } from './base.js';
|
|
12
|
-
import { CONFLICT_ERROR_MSG, CreatorConfigHashSigningTypes, Domain, DKG_ALGORITHM, CONFIG_VERSION, OperatorConfigHashSigningTypes, EnrSigningTypes, TERMS_AND_CONDITIONS_VERSION, TermsAndConditionsSigningTypes, DEFAULT_BASE_VERSION, TERMS_AND_CONDITIONS_HASH,
|
|
12
|
+
import { CONFLICT_ERROR_MSG, CreatorConfigHashSigningTypes, Domain, DKG_ALGORITHM, CONFIG_VERSION, OperatorConfigHashSigningTypes, EnrSigningTypes, TERMS_AND_CONDITIONS_VERSION, TermsAndConditionsSigningTypes, DEFAULT_BASE_VERSION, TERMS_AND_CONDITIONS_HASH, CHAIN_CONFIGURATION, DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT, OBOL_SDK_EMAIL, isChainSupportedForSplitters, } from './constants.js';
|
|
13
13
|
import { ConflictError } from './errors.js';
|
|
14
14
|
import { clusterConfigOrDefinitionHash } from './verification/common.js';
|
|
15
15
|
import { validatePayload } from './ajv.js';
|
|
@@ -18,6 +18,7 @@ import { deploySplitterContract, formatSplitRecipients, handleDeployOWRAndSplitt
|
|
|
18
18
|
import { isContractAvailable } from './utils.js';
|
|
19
19
|
import { Incentives } from './incentives/incentives.js';
|
|
20
20
|
import { Exit } from './exits/exit.js';
|
|
21
|
+
import { ObolSplits } from './splits/splits.js';
|
|
21
22
|
export * from './types.js';
|
|
22
23
|
export * from './services.js';
|
|
23
24
|
export * from './verification/signature-validator.js';
|
|
@@ -25,6 +26,7 @@ export * from './verification/common.js';
|
|
|
25
26
|
export * from './constants.js';
|
|
26
27
|
export { Incentives } from './incentives/incentives.js';
|
|
27
28
|
export { Exit } from './exits/exit.js';
|
|
29
|
+
export { ObolSplits } from './splits/splits.js';
|
|
28
30
|
/**
|
|
29
31
|
* Obol sdk Client can be used for creating, managing and activating distributed validators.
|
|
30
32
|
*/
|
|
@@ -47,6 +49,7 @@ export class Client extends Base {
|
|
|
47
49
|
provider !== null && provider !== void 0 ? provider : (signer && 'provider' in signer ? signer.provider : undefined);
|
|
48
50
|
this.incentives = new Incentives(this.signer, this.chainId, this.request.bind(this), this.provider);
|
|
49
51
|
this.exit = new Exit(this.chainId, this.provider);
|
|
52
|
+
this.splits = new ObolSplits(this.signer, this.chainId, this.provider);
|
|
50
53
|
}
|
|
51
54
|
/**
|
|
52
55
|
* Accepts Obol terms and conditions to be able to create or update data.
|
|
@@ -121,19 +124,23 @@ export class Client extends Base {
|
|
|
121
124
|
recoveryAddress,
|
|
122
125
|
}, rewardsSplitterPayloadSchema);
|
|
123
126
|
// Check if we allow splitters on this chainId
|
|
124
|
-
if (!
|
|
127
|
+
if (!isChainSupportedForSplitters(this.chainId)) {
|
|
125
128
|
throw new Error(`Splitter configuration is not supported on ${this.chainId} chain`);
|
|
126
129
|
}
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
const chainConfig = CHAIN_CONFIGURATION[this.chainId];
|
|
131
|
+
if (!(chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLITMAIN_CONTRACT)) {
|
|
132
|
+
throw new Error(`SPLITMAIN_CONTRACT is not configured for chain ${this.chainId}`);
|
|
133
|
+
}
|
|
134
|
+
const checkSplitMainAddress = yield isContractAvailable(chainConfig.SPLITMAIN_CONTRACT.address, this.signer.provider, chainConfig.SPLITMAIN_CONTRACT.bytecode);
|
|
135
|
+
const checkMulticallAddress = yield isContractAvailable(chainConfig.MULTICALL_CONTRACT.address, this.signer.provider, chainConfig.MULTICALL_CONTRACT.bytecode);
|
|
136
|
+
const checkOWRFactoryAddress = yield isContractAvailable(chainConfig.OWR_FACTORY_CONTRACT.address, this.signer.provider, chainConfig.OWR_FACTORY_CONTRACT.bytecode);
|
|
130
137
|
if (!checkMulticallAddress ||
|
|
131
138
|
!checkSplitMainAddress ||
|
|
132
139
|
!checkOWRFactoryAddress) {
|
|
133
140
|
throw new Error(`Something isn not working as expected, check this issue with obol-sdk team on ${OBOL_SDK_EMAIL}`);
|
|
134
141
|
}
|
|
135
142
|
const retroActiveFundingRecipient = {
|
|
136
|
-
account:
|
|
143
|
+
account: chainConfig.RETROACTIVE_FUNDING_CONTRACT.address,
|
|
137
144
|
percentAllocation: validatedPayload.ObolRAFSplit,
|
|
138
145
|
};
|
|
139
146
|
const copiedSplitRecipients = [...validatedPayload.splitRecipients];
|
|
@@ -191,15 +198,19 @@ export class Client extends Base {
|
|
|
191
198
|
controllerAddress,
|
|
192
199
|
}, totalSplitterPayloadSchema);
|
|
193
200
|
// Check if we allow splitters on this chainId
|
|
194
|
-
if (!
|
|
201
|
+
if (!isChainSupportedForSplitters(this.chainId)) {
|
|
195
202
|
throw new Error(`Splitter configuration is not supported on ${this.chainId} chain`);
|
|
196
203
|
}
|
|
197
|
-
const
|
|
204
|
+
const chainConfig = CHAIN_CONFIGURATION[this.chainId];
|
|
205
|
+
if (!(chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLITMAIN_CONTRACT)) {
|
|
206
|
+
throw new Error(`SPLITMAIN_CONTRACT is not configured for chain ${this.chainId}`);
|
|
207
|
+
}
|
|
208
|
+
const checkSplitMainAddress = yield isContractAvailable(chainConfig.SPLITMAIN_CONTRACT.address, this.signer.provider, chainConfig.SPLITMAIN_CONTRACT.bytecode);
|
|
198
209
|
if (!checkSplitMainAddress) {
|
|
199
210
|
throw new Error(`Something isn not working as expected, check this issue with obol-sdk team on ${OBOL_SDK_EMAIL}`);
|
|
200
211
|
}
|
|
201
212
|
const retroActiveFundingRecipient = {
|
|
202
|
-
account:
|
|
213
|
+
account: chainConfig.RETROACTIVE_FUNDING_CONTRACT.address,
|
|
203
214
|
percentAllocation: validatedPayload.ObolRAFSplit,
|
|
204
215
|
};
|
|
205
216
|
const copiedSplitRecipients = [...validatedPayload.splitRecipients];
|
package/dist/esm/src/schema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ZeroAddress } from 'ethers';
|
|
2
|
-
import { DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT, DEFAULT_RETROACTIVE_FUNDING_TOTAL_SPLIT, } from './constants';
|
|
2
|
+
import { DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT, DEFAULT_RETROACTIVE_FUNDING_TOTAL_SPLIT, PRINCIPAL_THRESHOLD, } from './constants';
|
|
3
3
|
import { VALID_DEPOSIT_AMOUNTS, VALID_NON_COMPOUNDING_AMOUNTS } from './ajv';
|
|
4
4
|
export const operatorPayloadSchema = {
|
|
5
5
|
type: 'object',
|
|
@@ -137,3 +137,72 @@ export const rewardsSplitterPayloadSchema = {
|
|
|
137
137
|
validateRewardsSplitRecipients: true,
|
|
138
138
|
required: ['splitRecipients', 'principalRecipient', 'etherAmount'],
|
|
139
139
|
};
|
|
140
|
+
export const ovmBaseSplitPayload = {
|
|
141
|
+
rewardSplitRecipients: {
|
|
142
|
+
type: 'array',
|
|
143
|
+
items: {
|
|
144
|
+
type: 'object',
|
|
145
|
+
properties: {
|
|
146
|
+
address: {
|
|
147
|
+
type: 'string',
|
|
148
|
+
pattern: '^0x[a-fA-F0-9]{40}$',
|
|
149
|
+
},
|
|
150
|
+
percentAllocation: { type: 'number' },
|
|
151
|
+
},
|
|
152
|
+
required: ['address', 'percentAllocation'],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
OVMOwnerAddress: {
|
|
156
|
+
type: 'string',
|
|
157
|
+
pattern: '^0x[a-fA-F0-9]{40}$',
|
|
158
|
+
},
|
|
159
|
+
splitOwnerAddress: {
|
|
160
|
+
type: 'string',
|
|
161
|
+
pattern: '^0x[a-fA-F0-9]{40}$',
|
|
162
|
+
default: ZeroAddress,
|
|
163
|
+
},
|
|
164
|
+
principalThreshold: {
|
|
165
|
+
type: 'number',
|
|
166
|
+
minimum: 16,
|
|
167
|
+
default: PRINCIPAL_THRESHOLD,
|
|
168
|
+
},
|
|
169
|
+
distributorFeePercent: {
|
|
170
|
+
type: 'number',
|
|
171
|
+
minimum: 0,
|
|
172
|
+
maximum: 10,
|
|
173
|
+
default: 0,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
export const ovmRewardsSplitPayloadSchema = {
|
|
177
|
+
type: 'object',
|
|
178
|
+
properties: Object.assign(Object.assign({}, ovmBaseSplitPayload), { principalRecipient: {
|
|
179
|
+
type: 'string',
|
|
180
|
+
pattern: '^0x[a-fA-F0-9]{40}$',
|
|
181
|
+
} }),
|
|
182
|
+
validateOVMRewardsSplitRecipients: true,
|
|
183
|
+
required: ['rewardSplitRecipients', 'OVMOwnerAddress', 'principalRecipient'],
|
|
184
|
+
};
|
|
185
|
+
export const ovmTotalSplitPayloadSchema = {
|
|
186
|
+
type: 'object',
|
|
187
|
+
properties: Object.assign(Object.assign({}, ovmBaseSplitPayload), { principalSplitRecipients: {
|
|
188
|
+
type: 'array',
|
|
189
|
+
items: {
|
|
190
|
+
type: 'object',
|
|
191
|
+
properties: {
|
|
192
|
+
address: {
|
|
193
|
+
type: 'string',
|
|
194
|
+
pattern: '^0x[a-fA-F0-9]{40}$',
|
|
195
|
+
},
|
|
196
|
+
percentAllocation: { type: 'number' },
|
|
197
|
+
},
|
|
198
|
+
required: ['address', 'percentAllocation'],
|
|
199
|
+
},
|
|
200
|
+
} }),
|
|
201
|
+
validateOVMRewardsSplitRecipients: true,
|
|
202
|
+
validateOVMTotalSplitRecipients: true,
|
|
203
|
+
required: [
|
|
204
|
+
'rewardSplitRecipients',
|
|
205
|
+
'principalSplitRecipients',
|
|
206
|
+
'OVMOwnerAddress',
|
|
207
|
+
],
|
|
208
|
+
};
|
|
@@ -9,17 +9,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { Contract, Interface, parseEther, ZeroAddress } from 'ethers';
|
|
11
11
|
import { OWRContract, OWRFactoryContract } from '../abi/OWR';
|
|
12
|
+
import { OVMFactoryContract } from '../abi/OVMFactory';
|
|
12
13
|
import { splitMainEthereumAbi } from '../abi/SplitMain';
|
|
13
14
|
import { MultiCallContract } from '../abi/Multicall';
|
|
14
15
|
import { CHAIN_CONFIGURATION } from '../constants';
|
|
16
|
+
import { splitV2FactoryAbi } from '../abi/splitV2FactoryAbi';
|
|
15
17
|
const splitMainContractInterface = new Interface(splitMainEthereumAbi);
|
|
16
18
|
const owrFactoryContractInterface = new Interface(OWRFactoryContract.abi);
|
|
17
|
-
|
|
19
|
+
const ovmFactoryContractInterface = new Interface(OVMFactoryContract.abi);
|
|
20
|
+
const splitV2FactoryInterface = new Interface(splitV2FactoryAbi);
|
|
21
|
+
// Helper function to extract common recipient formatting logic
|
|
22
|
+
const formatRecipientsCommon = (recipients) => {
|
|
23
|
+
const copiedRecipients = [...recipients];
|
|
24
|
+
// Handle both SplitRecipient and SplitV2Recipient types
|
|
25
|
+
const getAddress = (item) => item.account || item.address;
|
|
26
|
+
const getPercentAllocation = (item) => item.percentAllocation;
|
|
18
27
|
// Has to be sorted when passed
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
copiedRecipients.sort((a, b) => getAddress(a).localeCompare(getAddress(b)));
|
|
29
|
+
return {
|
|
30
|
+
sortedRecipients: copiedRecipients,
|
|
31
|
+
getAddress,
|
|
32
|
+
getPercentAllocation,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export const formatSplitRecipients = (recipients) => {
|
|
36
|
+
const { sortedRecipients, getAddress, getPercentAllocation } = formatRecipientsCommon(recipients);
|
|
37
|
+
const accounts = sortedRecipients.map(item => getAddress(item));
|
|
38
|
+
const percentAllocations = sortedRecipients.map(recipient => {
|
|
39
|
+
const splitTostring = (getPercentAllocation(recipient) * 1e4).toFixed(0);
|
|
23
40
|
return parseInt(splitTostring);
|
|
24
41
|
});
|
|
25
42
|
return { accounts, percentAllocations };
|
|
@@ -27,7 +44,7 @@ export const formatSplitRecipients = (recipients) => {
|
|
|
27
44
|
export const predictSplitterAddress = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
45
|
var _a, _b, _c;
|
|
29
46
|
try {
|
|
30
|
-
const splitMainContractInstance = new Contract(
|
|
47
|
+
const splitMainContractInstance = new Contract(getChainConfig(chainId).SPLITMAIN_CONTRACT.address, splitMainEthereumAbi, signer);
|
|
31
48
|
let predictedSplitterAddress;
|
|
32
49
|
if (controllerAddress === ZeroAddress) {
|
|
33
50
|
try {
|
|
@@ -128,7 +145,7 @@ export const handleDeployOWRAndSplitter = ({ signer, isSplitterDeployed, predict
|
|
|
128
145
|
const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
129
146
|
var _g, _h, _j, _k, _l;
|
|
130
147
|
try {
|
|
131
|
-
const OWRFactoryInstance = new Contract(
|
|
148
|
+
const OWRFactoryInstance = new Contract(getChainConfig(chainId).OWR_FACTORY_CONTRACT.address, OWRFactoryContract.abi, signer);
|
|
132
149
|
let tx;
|
|
133
150
|
try {
|
|
134
151
|
tx = yield OWRFactoryInstance.createOWRecipient(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, parseEther(owrArgs.amountOfPrincipalStake.toString()));
|
|
@@ -172,7 +189,7 @@ const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, v
|
|
|
172
189
|
export const deploySplitterContract = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
173
190
|
var _m, _o, _p, _q, _r;
|
|
174
191
|
try {
|
|
175
|
-
const splitMainContractInstance = new Contract(
|
|
192
|
+
const splitMainContractInstance = new Contract(getChainConfig(chainId).SPLITMAIN_CONTRACT.address, splitMainEthereumAbi, signer);
|
|
176
193
|
let tx;
|
|
177
194
|
try {
|
|
178
195
|
tx = yield splitMainContractInstance.createSplit(accounts, percentAllocations, distributorFee, controllerAddress);
|
|
@@ -219,14 +236,13 @@ export const deploySplitterAndOWRContracts = ({ owrArgs, splitterArgs, signer, c
|
|
|
219
236
|
const splitTxData = encodeCreateSplitTxData(splitterArgs.accounts, splitterArgs.percentAllocations, splitterArgs.distributorFee, splitterArgs.controllerAddress);
|
|
220
237
|
const owrTxData = encodeCreateOWRecipientTxData(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, owrArgs.amountOfPrincipalStake);
|
|
221
238
|
executeCalls.push({
|
|
222
|
-
target:
|
|
239
|
+
target: getChainConfig(chainId).SPLITMAIN_CONTRACT.address,
|
|
223
240
|
callData: splitTxData,
|
|
224
241
|
}, {
|
|
225
|
-
target:
|
|
242
|
+
target: getChainConfig(chainId).OWR_FACTORY_CONTRACT.address,
|
|
226
243
|
callData: owrTxData,
|
|
227
244
|
});
|
|
228
|
-
const
|
|
229
|
-
const executeMultiCalls = yield multicall(executeCalls, signer, multicallAddess);
|
|
245
|
+
const executeMultiCalls = yield multicall(executeCalls, signer, chainId);
|
|
230
246
|
const splitAddressData = (_s = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[0]) === null || _s === void 0 ? void 0 : _s.topics[1];
|
|
231
247
|
const formattedSplitterAddress = '0x' + (splitAddressData === null || splitAddressData === void 0 ? void 0 : splitAddressData.slice(26, 66));
|
|
232
248
|
const owrAddressData = (_t = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[1]) === null || _t === void 0 ? void 0 : _t.topics[1];
|
|
@@ -266,9 +282,11 @@ export const getOWRTranches = ({ owrAddress, signer, }) => __awaiter(void 0, voi
|
|
|
266
282
|
throw new Error(`Unexpected error in getOWRTranches: ${(_v = error.message) !== null && _v !== void 0 ? _v : 'Unknown error while fetching OWR tranche data'}`);
|
|
267
283
|
}
|
|
268
284
|
});
|
|
269
|
-
export const multicall = (calls, signer,
|
|
285
|
+
export const multicall = (calls, signer, chainId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
270
286
|
var _w, _x, _y;
|
|
271
287
|
try {
|
|
288
|
+
const chainConfig = getChainConfig(chainId);
|
|
289
|
+
const multicallAddress = chainConfig.MULTICALL_CONTRACT.address;
|
|
272
290
|
const multiCallContractInstance = new Contract(multicallAddress, MultiCallContract.abi, signer);
|
|
273
291
|
let tx;
|
|
274
292
|
try {
|
|
@@ -315,3 +333,154 @@ const encodeCreateOWRecipientTxData = (recoveryAddress, principalRecipient, rewa
|
|
|
315
333
|
parseEther(amountOfPrincipalStake.toString()),
|
|
316
334
|
]);
|
|
317
335
|
};
|
|
336
|
+
// OVM and SplitV2 Helper Functions
|
|
337
|
+
// Helper function to format recipients specifically for SplitV2 (returns SplitV2Recipient[])
|
|
338
|
+
export const formatRecipientsForSplitV2 = (splitRecipients) => {
|
|
339
|
+
const { sortedRecipients, getAddress, getPercentAllocation } = formatRecipientsCommon(splitRecipients);
|
|
340
|
+
return sortedRecipients
|
|
341
|
+
.filter(item => getAddress(item) !== '')
|
|
342
|
+
.map(item => ({
|
|
343
|
+
address: getAddress(item),
|
|
344
|
+
percentAllocation: parseFloat(getPercentAllocation(item).toString()),
|
|
345
|
+
}));
|
|
346
|
+
};
|
|
347
|
+
// Helper function to create SplitV2 parameters
|
|
348
|
+
const createSplitV2Params = (recipients, distributorFeePercent) => {
|
|
349
|
+
const addresses = recipients.map(r => r.address);
|
|
350
|
+
const allocations = recipients.map(r => Math.floor(r.percentAllocation * 1e4)); // Convert to basis points
|
|
351
|
+
const totalAllocation = allocations.reduce((sum, allocation) => sum + allocation, 0);
|
|
352
|
+
return {
|
|
353
|
+
recipients: addresses,
|
|
354
|
+
allocations,
|
|
355
|
+
totalAllocation,
|
|
356
|
+
distributionIncentive: distributorFeePercent,
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
export const predictSplitV2Address = ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
360
|
+
var _z, _0;
|
|
361
|
+
try {
|
|
362
|
+
const chainConfig = getChainConfig(chainId);
|
|
363
|
+
if (!((_z = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLIT_V2_FACTORY_CONTRACT) === null || _z === void 0 ? void 0 : _z.address)) {
|
|
364
|
+
throw new Error(`SplitV2 Factory not configured for chain ${chainId}`);
|
|
365
|
+
}
|
|
366
|
+
const splitV2FactoryContract = new Contract(chainConfig.SPLIT_V2_FACTORY_CONTRACT.address, splitV2FactoryAbi, signer);
|
|
367
|
+
const splitParams = createSplitV2Params(recipients, distributorFeePercent);
|
|
368
|
+
const predictedAddress = yield splitV2FactoryContract['predictDeterministicAddress((address[],uint256[],uint256,uint16),address,bytes32)'](splitParams, splitOwnerAddress, salt);
|
|
369
|
+
return predictedAddress;
|
|
370
|
+
}
|
|
371
|
+
catch (error) {
|
|
372
|
+
throw new Error(`Failed to predict SplitV2 address: ${(_0 = error.message) !== null && _0 !== void 0 ? _0 : 'SplitV2 contract call failed'}`);
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
export const isSplitV2Deployed = ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
376
|
+
var _1;
|
|
377
|
+
try {
|
|
378
|
+
const chainConfig = getChainConfig(chainId);
|
|
379
|
+
if (!((_1 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLIT_V2_FACTORY_CONTRACT) === null || _1 === void 0 ? void 0 : _1.address)) {
|
|
380
|
+
throw new Error(`SplitV2 Factory not configured for chain ${chainId}`);
|
|
381
|
+
}
|
|
382
|
+
const splitV2FactoryContract = new Contract(chainConfig.SPLIT_V2_FACTORY_CONTRACT.address, splitV2FactoryAbi, signer);
|
|
383
|
+
const splitParams = createSplitV2Params(recipients, distributorFeePercent);
|
|
384
|
+
const [, exists] = yield splitV2FactoryContract.isDeployed(splitParams, splitOwnerAddress, salt);
|
|
385
|
+
return exists;
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
// If the check fails, assume it's not deployed
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
export const deployOVMContract = ({ OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
393
|
+
var _2, _3, _4;
|
|
394
|
+
try {
|
|
395
|
+
const chainConfig = getChainConfig(chainId);
|
|
396
|
+
if (!((_2 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.OVM_FACTORY_CONTRACT) === null || _2 === void 0 ? void 0 : _2.address)) {
|
|
397
|
+
throw new Error(`OVM Factory not configured for chain ${chainId}`);
|
|
398
|
+
}
|
|
399
|
+
const ovmFactoryContract = new Contract(chainConfig.OVM_FACTORY_CONTRACT.address, OVMFactoryContract.abi, signer);
|
|
400
|
+
const tx = yield ovmFactoryContract.createObolValidatorManager(OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold);
|
|
401
|
+
const receipt = yield tx.wait();
|
|
402
|
+
// Extract OVM address from logs
|
|
403
|
+
const ovmAddressLog = (_3 = receipt === null || receipt === void 0 ? void 0 : receipt.logs[1]) === null || _3 === void 0 ? void 0 : _3.topics[1];
|
|
404
|
+
if (!ovmAddressLog) {
|
|
405
|
+
throw new Error('Failed to extract OVM address from transaction logs');
|
|
406
|
+
}
|
|
407
|
+
const ovmAddress = '0x' + ovmAddressLog.slice(26, 66);
|
|
408
|
+
return ovmAddress;
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
throw new Error(`Failed to deploy OVM contract: ${(_4 = error.message) !== null && _4 !== void 0 ? _4 : 'OVM deployment failed'}`);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
export const deployOVMAndSplitV2 = ({ ovmArgs, rewardRecipients, isRewardsSplitterDeployed, distributorFeePercent, salt, signer, chainId, principalSplitRecipients, isPrincipalSplitDeployed, splitOwnerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
415
|
+
var _5, _6, _7, _8, _9, _10, _11, _12, _13, _14;
|
|
416
|
+
try {
|
|
417
|
+
const chainConfig = getChainConfig(chainId);
|
|
418
|
+
if (!((_5 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.OVM_FACTORY_CONTRACT) === null || _5 === void 0 ? void 0 : _5.address)) {
|
|
419
|
+
throw new Error(`OVM Factory not configured for chain ${chainId}`);
|
|
420
|
+
}
|
|
421
|
+
if (!((_6 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLIT_V2_FACTORY_CONTRACT) === null || _6 === void 0 ? void 0 : _6.address)) {
|
|
422
|
+
throw new Error(`SplitV2 Factory not configured for chain ${chainId}`);
|
|
423
|
+
}
|
|
424
|
+
const executeCalls = [];
|
|
425
|
+
if (rewardRecipients && !isRewardsSplitterDeployed) {
|
|
426
|
+
// Create rewards split call data
|
|
427
|
+
const splitParams = createSplitV2Params(rewardRecipients, distributorFeePercent);
|
|
428
|
+
const rewardsSplitTxData = encodeCreateSplitV2DeterministicTxData(splitParams, splitOwnerAddress, salt);
|
|
429
|
+
executeCalls.push({
|
|
430
|
+
target: chainConfig.SPLIT_V2_FACTORY_CONTRACT.address,
|
|
431
|
+
callData: rewardsSplitTxData,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
// Create principal split call data if needed (for total split scenario)
|
|
435
|
+
if (principalSplitRecipients && !isPrincipalSplitDeployed) {
|
|
436
|
+
const principalSplitParams = createSplitV2Params(principalSplitRecipients, distributorFeePercent);
|
|
437
|
+
const principalSplitTxData = encodeCreateSplitV2DeterministicTxData(principalSplitParams, splitOwnerAddress, salt);
|
|
438
|
+
executeCalls.push({
|
|
439
|
+
target: chainConfig.SPLIT_V2_FACTORY_CONTRACT.address,
|
|
440
|
+
callData: principalSplitTxData,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
// Create OVM call data
|
|
444
|
+
const ovmTxData = encodeCreateOVMTxData(ovmArgs.OVMOwnerAddress, ovmArgs.principalRecipient, ovmArgs.rewardRecipient, ovmArgs.principalThreshold);
|
|
445
|
+
executeCalls.push({
|
|
446
|
+
target: chainConfig.OVM_FACTORY_CONTRACT.address,
|
|
447
|
+
callData: ovmTxData,
|
|
448
|
+
});
|
|
449
|
+
// Execute multicall
|
|
450
|
+
const executeMultiCalls = yield multicall(executeCalls, signer, chainId);
|
|
451
|
+
// Extract addresses from events
|
|
452
|
+
let ovmAddress;
|
|
453
|
+
const logsCount = ((_7 = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs) === null || _7 === void 0 ? void 0 : _7.length) || 0;
|
|
454
|
+
if (logsCount === 2) {
|
|
455
|
+
ovmAddress = '0x' + ((_9 = (_8 = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[1]) === null || _8 === void 0 ? void 0 : _8.topics[1]) === null || _9 === void 0 ? void 0 : _9.slice(26, 66));
|
|
456
|
+
}
|
|
457
|
+
else if (logsCount === 5) {
|
|
458
|
+
ovmAddress = '0x' + ((_11 = (_10 = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[4]) === null || _10 === void 0 ? void 0 : _10.topics[1]) === null || _11 === void 0 ? void 0 : _11.slice(26, 66));
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
ovmAddress = '0x' + ((_13 = (_12 = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[7]) === null || _12 === void 0 ? void 0 : _12.topics[1]) === null || _13 === void 0 ? void 0 : _13.slice(26, 66));
|
|
462
|
+
}
|
|
463
|
+
if (!ovmAddress) {
|
|
464
|
+
throw new Error('Failed to extract contract addresses from multicall events');
|
|
465
|
+
}
|
|
466
|
+
return ovmAddress;
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
throw new Error(`Failed to deploy OVM and SplitV2: ${(_14 = error.message) !== null && _14 !== void 0 ? _14 : 'Deployment failed'}`);
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
const encodeCreateOVMTxData = (OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold) => {
|
|
473
|
+
return ovmFactoryContractInterface.encodeFunctionData('createObolValidatorManager', [OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold]);
|
|
474
|
+
};
|
|
475
|
+
const encodeCreateSplitV2DeterministicTxData = (splitParams, splitOwnerAddress, salt) => {
|
|
476
|
+
// creatorAddress can be kept as default https://docs.splits.org/sdk/splits-v2#createsplit
|
|
477
|
+
return splitV2FactoryInterface.encodeFunctionData('createSplitDeterministic', [splitParams, splitOwnerAddress, ZeroAddress, salt]);
|
|
478
|
+
};
|
|
479
|
+
// Helper function to safely get chain configuration
|
|
480
|
+
const getChainConfig = (chainId) => {
|
|
481
|
+
const config = CHAIN_CONFIGURATION[chainId];
|
|
482
|
+
if (!config) {
|
|
483
|
+
throw new Error(`Chain configuration not found for chain ID ${chainId}`);
|
|
484
|
+
}
|
|
485
|
+
return config;
|
|
486
|
+
};
|