@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
@@ -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, AVAILABLE_SPLITTER_CHAINS, CHAIN_CONFIGURATION, DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT, OBOL_SDK_EMAIL, } from './constants.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, 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 (!AVAILABLE_SPLITTER_CHAINS.includes(this.chainId)) {
127
+ if (!isChainSupportedForSplitters(this.chainId)) {
125
128
  throw new Error(`Splitter configuration is not supported on ${this.chainId} chain`);
126
129
  }
127
- const checkSplitMainAddress = yield isContractAvailable(CHAIN_CONFIGURATION[this.chainId].SPLITMAIN_ADDRESS.address, this.signer.provider, CHAIN_CONFIGURATION[this.chainId].SPLITMAIN_ADDRESS.bytecode);
128
- const checkMulticallAddress = yield isContractAvailable(CHAIN_CONFIGURATION[this.chainId].MULTICALL_ADDRESS.address, this.signer.provider, CHAIN_CONFIGURATION[this.chainId].MULTICALL_ADDRESS.bytecode);
129
- const checkOWRFactoryAddress = yield isContractAvailable(CHAIN_CONFIGURATION[this.chainId].OWR_FACTORY_ADDRESS.address, this.signer.provider, CHAIN_CONFIGURATION[this.chainId].OWR_FACTORY_ADDRESS.bytecode);
130
+ const chainConfig = CHAIN_CONFIGURATION[this.chainId];
131
+ if (!(chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLITMAIN_ADDRESS)) {
132
+ throw new Error(`SPLITMAIN_ADDRESS is not configured for chain ${this.chainId}`);
133
+ }
134
+ const checkSplitMainAddress = yield isContractAvailable(chainConfig.SPLITMAIN_ADDRESS.address, this.signer.provider, chainConfig.SPLITMAIN_ADDRESS.bytecode);
135
+ const checkMulticallAddress = yield isContractAvailable(chainConfig.MULTICALL_ADDRESS.address, this.signer.provider, chainConfig.MULTICALL_ADDRESS.bytecode);
136
+ const checkOWRFactoryAddress = yield isContractAvailable(chainConfig.OWR_FACTORY_ADDRESS.address, this.signer.provider, chainConfig.OWR_FACTORY_ADDRESS.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: CHAIN_CONFIGURATION[this.chainId].RETROACTIVE_FUNDING_ADDRESS.address,
143
+ account: chainConfig.RETROACTIVE_FUNDING_ADDRESS.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 (!AVAILABLE_SPLITTER_CHAINS.includes(this.chainId)) {
201
+ if (!isChainSupportedForSplitters(this.chainId)) {
195
202
  throw new Error(`Splitter configuration is not supported on ${this.chainId} chain`);
196
203
  }
197
- const checkSplitMainAddress = yield isContractAvailable(CHAIN_CONFIGURATION[this.chainId].SPLITMAIN_ADDRESS.address, this.signer.provider, CHAIN_CONFIGURATION[this.chainId].SPLITMAIN_ADDRESS.bytecode);
204
+ const chainConfig = CHAIN_CONFIGURATION[this.chainId];
205
+ if (!(chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLITMAIN_ADDRESS)) {
206
+ throw new Error(`SPLITMAIN_ADDRESS is not configured for chain ${this.chainId}`);
207
+ }
208
+ const checkSplitMainAddress = yield isContractAvailable(chainConfig.SPLITMAIN_ADDRESS.address, this.signer.provider, chainConfig.SPLITMAIN_ADDRESS.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: CHAIN_CONFIGURATION[this.chainId].RETROACTIVE_FUNDING_ADDRESS.address,
213
+ account: chainConfig.RETROACTIVE_FUNDING_ADDRESS.address,
203
214
  percentAllocation: validatedPayload.ObolRAFSplit,
204
215
  };
205
216
  const copiedSplitRecipients = [...validatedPayload.splitRecipients];
@@ -1,6 +1,7 @@
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
+ import { zeroAddress } from 'viem';
4
5
  export const operatorPayloadSchema = {
5
6
  type: 'object',
6
7
  properties: {
@@ -137,3 +138,72 @@ export const rewardsSplitterPayloadSchema = {
137
138
  validateRewardsSplitRecipients: true,
138
139
  required: ['splitRecipients', 'principalRecipient', 'etherAmount'],
139
140
  };
141
+ export const ovmBaseSplitPayload = {
142
+ rewardSplitRecipients: {
143
+ type: 'array',
144
+ items: {
145
+ type: 'object',
146
+ properties: {
147
+ address: {
148
+ type: 'string',
149
+ pattern: '^0x[a-fA-F0-9]{40}$',
150
+ },
151
+ percentAllocation: { type: 'number' },
152
+ },
153
+ required: ['address', 'percentAllocation'],
154
+ },
155
+ },
156
+ OVMOwnerAddress: {
157
+ type: 'string',
158
+ pattern: '^0x[a-fA-F0-9]{40}$',
159
+ },
160
+ splitOwnerAddress: {
161
+ type: 'string',
162
+ pattern: '^0x[a-fA-F0-9]{40}$',
163
+ default: zeroAddress,
164
+ },
165
+ principalThreshold: {
166
+ type: 'number',
167
+ minimum: 16,
168
+ default: PRINCIPAL_THRESHOLD,
169
+ },
170
+ distributorFeePercent: {
171
+ type: 'number',
172
+ minimum: 0,
173
+ maximum: 10,
174
+ default: 0,
175
+ },
176
+ };
177
+ export const ovmRewardsSplitPayloadSchema = {
178
+ type: 'object',
179
+ properties: Object.assign(Object.assign({}, ovmBaseSplitPayload), { principalRecipient: {
180
+ type: 'string',
181
+ pattern: '^0x[a-fA-F0-9]{40}$',
182
+ } }),
183
+ validateOVMRewardsSplitRecipients: true,
184
+ required: ['rewardSplitRecipients', 'OVMOwnerAddress', 'principalRecipient'],
185
+ };
186
+ export const ovmTotalSplitPayloadSchema = {
187
+ type: 'object',
188
+ properties: Object.assign(Object.assign({}, ovmBaseSplitPayload), { principalSplitRecipients: {
189
+ type: 'array',
190
+ items: {
191
+ type: 'object',
192
+ properties: {
193
+ address: {
194
+ type: 'string',
195
+ pattern: '^0x[a-fA-F0-9]{40}$',
196
+ },
197
+ percentAllocation: { type: 'number' },
198
+ },
199
+ required: ['address', 'percentAllocation'],
200
+ },
201
+ } }),
202
+ validateOVMRewardsSplitRecipients: true,
203
+ validateOVMTotalSplitRecipients: true,
204
+ required: [
205
+ 'rewardSplitRecipients',
206
+ 'principalSplitRecipients',
207
+ 'OVMOwnerAddress',
208
+ ],
209
+ };
@@ -7,19 +7,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { Contract, Interface, parseEther, ZeroAddress } from 'ethers';
10
+ import { BrowserProvider, 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
- import { CHAIN_CONFIGURATION } from '../constants';
15
+ import { CHAIN_CONFIGURATION, CHAIN_PUBLIC_RPC_URL } from '../constants';
16
+ import { SplitsClient } from '@0xsplits/splits-sdk';
17
+ import { createPublicClient, createWalletClient, custom, http } from 'viem';
18
+ import { hoodi, mainnet } from 'viem/chains';
19
+ import { privateKeyToAccount } from 'viem/accounts';
15
20
  const splitMainContractInterface = new Interface(splitMainEthereumAbi);
16
21
  const owrFactoryContractInterface = new Interface(OWRFactoryContract.abi);
17
- export const formatSplitRecipients = (recipients) => {
22
+ const ovmFactoryContractInterface = new Interface(OVMFactoryContract.abi);
23
+ // Helper function to extract common recipient formatting logic
24
+ const formatRecipientsCommon = (recipients) => {
25
+ const copiedRecipients = [...recipients];
26
+ // Handle both SplitRecipient and SplitV2Recipient types
27
+ const getAddress = (item) => item.account || item.address;
28
+ const getPercentAllocation = (item) => item.percentAllocation;
18
29
  // Has to be sorted when passed
19
- recipients.sort((a, b) => a.account.localeCompare(b.account));
20
- const accounts = recipients.map(item => item.account);
21
- const percentAllocations = recipients.map(recipient => {
22
- const splitTostring = (recipient.percentAllocation * 1e4).toFixed(0);
30
+ copiedRecipients.sort((a, b) => getAddress(a).localeCompare(getAddress(b)));
31
+ return {
32
+ sortedRecipients: copiedRecipients,
33
+ getAddress,
34
+ getPercentAllocation,
35
+ };
36
+ };
37
+ export const formatSplitRecipients = (recipients) => {
38
+ const { sortedRecipients, getAddress, getPercentAllocation } = formatRecipientsCommon(recipients);
39
+ const accounts = sortedRecipients.map(item => getAddress(item));
40
+ const percentAllocations = sortedRecipients.map(recipient => {
41
+ const splitTostring = (getPercentAllocation(recipient) * 1e4).toFixed(0);
23
42
  return parseInt(splitTostring);
24
43
  });
25
44
  return { accounts, percentAllocations };
@@ -27,7 +46,7 @@ export const formatSplitRecipients = (recipients) => {
27
46
  export const predictSplitterAddress = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
28
47
  var _a, _b, _c;
29
48
  try {
30
- const splitMainContractInstance = new Contract(CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address, splitMainEthereumAbi, signer);
49
+ const splitMainContractInstance = new Contract(getChainConfig(chainId).SPLITMAIN_ADDRESS.address, splitMainEthereumAbi, signer);
31
50
  let predictedSplitterAddress;
32
51
  if (controllerAddress === ZeroAddress) {
33
52
  try {
@@ -128,7 +147,7 @@ export const handleDeployOWRAndSplitter = ({ signer, isSplitterDeployed, predict
128
147
  const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
129
148
  var _g, _h, _j, _k, _l;
130
149
  try {
131
- const OWRFactoryInstance = new Contract(CHAIN_CONFIGURATION[chainId].OWR_FACTORY_ADDRESS.address, OWRFactoryContract.abi, signer);
150
+ const OWRFactoryInstance = new Contract(getChainConfig(chainId).OWR_FACTORY_ADDRESS.address, OWRFactoryContract.abi, signer);
132
151
  let tx;
133
152
  try {
134
153
  tx = yield OWRFactoryInstance.createOWRecipient(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, parseEther(owrArgs.amountOfPrincipalStake.toString()));
@@ -172,7 +191,7 @@ const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, v
172
191
  export const deploySplitterContract = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
173
192
  var _m, _o, _p, _q, _r;
174
193
  try {
175
- const splitMainContractInstance = new Contract(CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address, splitMainEthereumAbi, signer);
194
+ const splitMainContractInstance = new Contract(getChainConfig(chainId).SPLITMAIN_ADDRESS.address, splitMainEthereumAbi, signer);
176
195
  let tx;
177
196
  try {
178
197
  tx = yield splitMainContractInstance.createSplit(accounts, percentAllocations, distributorFee, controllerAddress);
@@ -219,13 +238,13 @@ export const deploySplitterAndOWRContracts = ({ owrArgs, splitterArgs, signer, c
219
238
  const splitTxData = encodeCreateSplitTxData(splitterArgs.accounts, splitterArgs.percentAllocations, splitterArgs.distributorFee, splitterArgs.controllerAddress);
220
239
  const owrTxData = encodeCreateOWRecipientTxData(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, owrArgs.amountOfPrincipalStake);
221
240
  executeCalls.push({
222
- target: CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address,
241
+ target: getChainConfig(chainId).SPLITMAIN_ADDRESS.address,
223
242
  callData: splitTxData,
224
243
  }, {
225
- target: CHAIN_CONFIGURATION[chainId].OWR_FACTORY_ADDRESS.address,
244
+ target: getChainConfig(chainId).OWR_FACTORY_ADDRESS.address,
226
245
  callData: owrTxData,
227
246
  });
228
- const multicallAddess = CHAIN_CONFIGURATION[chainId].MULTICALL_ADDRESS.address;
247
+ const multicallAddess = getChainConfig(chainId).MULTICALL_ADDRESS.address;
229
248
  const executeMultiCalls = yield multicall(executeCalls, signer, multicallAddess);
230
249
  const splitAddressData = (_s = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[0]) === null || _s === void 0 ? void 0 : _s.topics[1];
231
250
  const formattedSplitterAddress = '0x' + (splitAddressData === null || splitAddressData === void 0 ? void 0 : splitAddressData.slice(26, 66));
@@ -315,3 +334,184 @@ const encodeCreateOWRecipientTxData = (recoveryAddress, principalRecipient, rewa
315
334
  parseEther(amountOfPrincipalStake.toString()),
316
335
  ]);
317
336
  };
337
+ // OVM and SplitV2 Helper Functions
338
+ // Helper function to format recipients specifically for SplitV2 (returns SplitV2Recipient[])
339
+ export const formatRecipientsForSplitV2 = (splitRecipients) => {
340
+ const { sortedRecipients, getAddress, getPercentAllocation } = formatRecipientsCommon(splitRecipients);
341
+ return sortedRecipients
342
+ .filter(item => getAddress(item) !== '')
343
+ .map(item => ({
344
+ address: getAddress(item),
345
+ percentAllocation: parseFloat(getPercentAllocation(item).toString()),
346
+ }));
347
+ };
348
+ export const createSplitsClient = (signer, chainId) => __awaiter(void 0, void 0, void 0, function* () {
349
+ const chain = chainId === 1 ? mainnet : hoodi;
350
+ const client = createPublicClient({
351
+ chain,
352
+ transport: http(CHAIN_PUBLIC_RPC_URL[chainId]),
353
+ });
354
+ // convert signer to walletClient
355
+ if (typeof window !== 'undefined' &&
356
+ signer.provider instanceof BrowserProvider) {
357
+ // For browser environment
358
+ const address = yield signer.getAddress();
359
+ const viemWalletClient = createWalletClient({
360
+ account: address,
361
+ chain,
362
+ transport: custom(window.ethereum),
363
+ });
364
+ return new SplitsClient({
365
+ publicClient: client,
366
+ walletClient: viemWalletClient,
367
+ chainId,
368
+ });
369
+ }
370
+ else {
371
+ // For non-browser environment, extract private key from signer
372
+ const signerPrivateKey = signer === null || signer === void 0 ? void 0 : signer.privateKey;
373
+ if (!signerPrivateKey) {
374
+ throw new Error('Signer private key not available');
375
+ }
376
+ const privateKey = signerPrivateKey.startsWith('0x')
377
+ ? signerPrivateKey
378
+ : `0x${signerPrivateKey}`;
379
+ const scriptAccount = privateKeyToAccount(privateKey);
380
+ const account = scriptAccount;
381
+ const viemWalletClient = createWalletClient({
382
+ account,
383
+ chain,
384
+ transport: http(CHAIN_PUBLIC_RPC_URL[chainId]),
385
+ });
386
+ return new SplitsClient({
387
+ publicClient: client,
388
+ walletClient: viemWalletClient,
389
+ chainId,
390
+ });
391
+ }
392
+ });
393
+ export const predictSplitV2Address = ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
394
+ var _z;
395
+ try {
396
+ const splitsClient = yield createSplitsClient(signer, chainId);
397
+ const response = yield splitsClient.splitV2.predictDeterministicAddress({
398
+ ownerAddress: splitOwnerAddress,
399
+ recipients,
400
+ distributorFeePercent,
401
+ salt,
402
+ });
403
+ return response.splitAddress;
404
+ }
405
+ catch (error) {
406
+ throw new Error(`Failed to predict SplitV2 address: ${(_z = error.message) !== null && _z !== void 0 ? _z : 'SplitV2 SDK call failed'}`);
407
+ }
408
+ });
409
+ export const isSplitV2Deployed = ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
410
+ try {
411
+ const splitsClient = yield createSplitsClient(signer, chainId);
412
+ const response = yield splitsClient.splitV2.isDeployed({
413
+ ownerAddress: splitOwnerAddress,
414
+ recipients,
415
+ distributorFeePercent,
416
+ salt,
417
+ });
418
+ return response.deployed;
419
+ }
420
+ catch (error) {
421
+ // If the check fails, assume it's not deployed
422
+ return false;
423
+ }
424
+ });
425
+ export const deployOVMContract = ({ OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
426
+ var _0, _1, _2;
427
+ try {
428
+ const chainConfig = getChainConfig(chainId);
429
+ if (!((_0 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.OVM_FACTORY_ADDRESS) === null || _0 === void 0 ? void 0 : _0.address)) {
430
+ throw new Error(`OVM Factory not configured for chain ${chainId}`);
431
+ }
432
+ const ovmFactoryContract = new Contract(chainConfig.OVM_FACTORY_ADDRESS.address, OVMFactoryContract.abi, signer);
433
+ const tx = yield ovmFactoryContract.createObolValidatorManager(OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold);
434
+ const receipt = yield tx.wait();
435
+ // Extract OVM address from logs
436
+ const ovmAddressLog = (_1 = receipt === null || receipt === void 0 ? void 0 : receipt.logs[1]) === null || _1 === void 0 ? void 0 : _1.topics[1];
437
+ if (!ovmAddressLog) {
438
+ throw new Error('Failed to extract OVM address from transaction logs');
439
+ }
440
+ const ovmAddress = '0x' + ovmAddressLog.slice(26, 66);
441
+ return ovmAddress;
442
+ }
443
+ catch (error) {
444
+ throw new Error(`Failed to deploy OVM contract: ${(_2 = error.message) !== null && _2 !== void 0 ? _2 : 'OVM deployment failed'}`);
445
+ }
446
+ });
447
+ export const deployOVMAndSplitV2 = ({ ovmArgs, rewardRecipients, isRewardsSplitterDeployed, distributorFeePercent, salt, signer, chainId, principalSplitRecipients, isPrincipalSplitDeployed, splitOwnerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
448
+ var _3, _4, _5, _6, _7;
449
+ try {
450
+ const chainConfig = getChainConfig(chainId);
451
+ if (!((_3 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.OVM_FACTORY_ADDRESS) === null || _3 === void 0 ? void 0 : _3.address)) {
452
+ throw new Error(`OVM Factory not configured for chain ${chainId}`);
453
+ }
454
+ const splitsClient = yield createSplitsClient(signer, chainId);
455
+ const executeCalls = [];
456
+ if (rewardRecipients && !isRewardsSplitterDeployed) {
457
+ // Create rewards split call data
458
+ const rewardsSplitTxData = yield splitsClient.splitV2.callData.createSplit({
459
+ recipients: rewardRecipients,
460
+ distributorFeePercent,
461
+ ownerAddress: splitOwnerAddress,
462
+ salt,
463
+ });
464
+ executeCalls.push(rewardsSplitTxData);
465
+ }
466
+ // Create principal split call data if needed (for total split scenario)
467
+ if (principalSplitRecipients && !isPrincipalSplitDeployed) {
468
+ const principalSplitTxData = yield splitsClient.splitV2.callData.createSplit({
469
+ recipients: principalSplitRecipients,
470
+ distributorFeePercent,
471
+ salt,
472
+ ownerAddress: splitOwnerAddress,
473
+ });
474
+ executeCalls.push(principalSplitTxData);
475
+ }
476
+ // Create OVM call data
477
+ const ovmTxData = encodeCreateOVMTxData(ovmArgs.OVMOwnerAddress, ovmArgs.principalRecipient, ovmArgs.rewardRecipient, ovmArgs.principalThreshold);
478
+ executeCalls.push({
479
+ address: chainConfig.OVM_FACTORY_ADDRESS.address,
480
+ data: ovmTxData,
481
+ });
482
+ // Execute multicall
483
+ const executeMultiCalls = yield splitsClient.splitV2.multicall({
484
+ calls: executeCalls,
485
+ });
486
+ // Extract addresses from events
487
+ let ovmAddress;
488
+ const eventCount = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.events.length;
489
+ if (eventCount === 2) {
490
+ ovmAddress = (_4 = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.events[0]) === null || _4 === void 0 ? void 0 : _4.address;
491
+ }
492
+ else if (eventCount === 5) {
493
+ ovmAddress = (_5 = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.events[3]) === null || _5 === void 0 ? void 0 : _5.address;
494
+ }
495
+ else {
496
+ ovmAddress = (_6 = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.events[6]) === null || _6 === void 0 ? void 0 : _6.address;
497
+ }
498
+ if (!ovmAddress) {
499
+ throw new Error('Failed to extract contract addresses from multicall events');
500
+ }
501
+ return ovmAddress;
502
+ }
503
+ catch (error) {
504
+ throw new Error(`Failed to deploy OVM and SplitV2: ${(_7 = error.message) !== null && _7 !== void 0 ? _7 : 'Deployment failed'}`);
505
+ }
506
+ });
507
+ const encodeCreateOVMTxData = (OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold) => {
508
+ return ovmFactoryContractInterface.encodeFunctionData('createObolValidatorManager', [OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold]);
509
+ };
510
+ // Helper function to safely get chain configuration
511
+ const getChainConfig = (chainId) => {
512
+ const config = CHAIN_CONFIGURATION[chainId];
513
+ if (!config) {
514
+ throw new Error(`Chain configuration not found for chain ID ${chainId}`);
515
+ }
516
+ return config;
517
+ };