@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.
- 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/exits/exit.js +82 -0
- 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/exit/exit.spec.js +74 -3
- 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/exits/exit.js +83 -1
- 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/exit/exit.spec.js +74 -3
- 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/exits/exit.d.ts +21 -1
- 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 +122 -6
- 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/exits/exit.ts +98 -1
- 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 +138 -10
|
@@ -4,15 +4,31 @@ import {
|
|
|
4
4
|
type ETH_ADDRESS,
|
|
5
5
|
type SplitRecipient,
|
|
6
6
|
type SignerType,
|
|
7
|
+
type SplitV2Recipient,
|
|
8
|
+
type OVMArgs,
|
|
9
|
+
type ChainConfig,
|
|
7
10
|
} from '../types';
|
|
8
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
BrowserProvider,
|
|
13
|
+
Contract,
|
|
14
|
+
Interface,
|
|
15
|
+
parseEther,
|
|
16
|
+
type Wallet,
|
|
17
|
+
ZeroAddress,
|
|
18
|
+
} from 'ethers';
|
|
9
19
|
import { OWRContract, OWRFactoryContract } from '../abi/OWR';
|
|
20
|
+
import { OVMFactoryContract } from '../abi/OVMFactory';
|
|
10
21
|
import { splitMainEthereumAbi } from '../abi/SplitMain';
|
|
11
22
|
import { MultiCallContract } from '../abi/Multicall';
|
|
12
|
-
import { CHAIN_CONFIGURATION } from '../constants';
|
|
23
|
+
import { CHAIN_CONFIGURATION, CHAIN_PUBLIC_RPC_URL } from '../constants';
|
|
24
|
+
import { SplitsClient } from '@0xsplits/splits-sdk';
|
|
25
|
+
import { createPublicClient, createWalletClient, custom, http } from 'viem';
|
|
26
|
+
import { hoodi, mainnet } from 'viem/chains';
|
|
27
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
13
28
|
|
|
14
29
|
const splitMainContractInterface = new Interface(splitMainEthereumAbi);
|
|
15
30
|
const owrFactoryContractInterface = new Interface(OWRFactoryContract.abi);
|
|
31
|
+
const ovmFactoryContractInterface = new Interface(OVMFactoryContract.abi);
|
|
16
32
|
|
|
17
33
|
type Call = {
|
|
18
34
|
target: ETH_ADDRESS;
|
|
@@ -33,14 +49,39 @@ type SplitArgs = {
|
|
|
33
49
|
controllerAddress: ETH_ADDRESS;
|
|
34
50
|
};
|
|
35
51
|
|
|
52
|
+
// Helper function to extract common recipient formatting logic
|
|
53
|
+
const formatRecipientsCommon = (
|
|
54
|
+
recipients: SplitRecipient[] | SplitV2Recipient[],
|
|
55
|
+
): {
|
|
56
|
+
sortedRecipients: any[];
|
|
57
|
+
getAddress: (item: any) => string;
|
|
58
|
+
getPercentAllocation: (item: any) => number;
|
|
59
|
+
} => {
|
|
60
|
+
const copiedRecipients = [...recipients];
|
|
61
|
+
|
|
62
|
+
// Handle both SplitRecipient and SplitV2Recipient types
|
|
63
|
+
const getAddress = (item: any): string => item.account || item.address;
|
|
64
|
+
const getPercentAllocation = (item: any): number => item.percentAllocation;
|
|
65
|
+
|
|
66
|
+
// Has to be sorted when passed
|
|
67
|
+
copiedRecipients.sort((a, b) => getAddress(a).localeCompare(getAddress(b)));
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
sortedRecipients: copiedRecipients,
|
|
71
|
+
getAddress,
|
|
72
|
+
getPercentAllocation,
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
36
76
|
export const formatSplitRecipients = (
|
|
37
77
|
recipients: SplitRecipient[],
|
|
38
78
|
): { accounts: ETH_ADDRESS[]; percentAllocations: number[] } => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
79
|
+
const { sortedRecipients, getAddress, getPercentAllocation } =
|
|
80
|
+
formatRecipientsCommon(recipients);
|
|
81
|
+
|
|
82
|
+
const accounts = sortedRecipients.map(item => getAddress(item));
|
|
83
|
+
const percentAllocations = sortedRecipients.map(recipient => {
|
|
84
|
+
const splitTostring = (getPercentAllocation(recipient) * 1e4).toFixed(0);
|
|
44
85
|
return parseInt(splitTostring);
|
|
45
86
|
});
|
|
46
87
|
return { accounts, percentAllocations };
|
|
@@ -63,7 +104,7 @@ export const predictSplitterAddress = async ({
|
|
|
63
104
|
}): Promise<ETH_ADDRESS> => {
|
|
64
105
|
try {
|
|
65
106
|
const splitMainContractInstance = new Contract(
|
|
66
|
-
|
|
107
|
+
getChainConfig(chainId).SPLITMAIN_ADDRESS.address,
|
|
67
108
|
splitMainEthereumAbi,
|
|
68
109
|
signer,
|
|
69
110
|
);
|
|
@@ -217,7 +258,7 @@ const createOWRContract = async ({
|
|
|
217
258
|
}): Promise<ETH_ADDRESS> => {
|
|
218
259
|
try {
|
|
219
260
|
const OWRFactoryInstance = new Contract(
|
|
220
|
-
|
|
261
|
+
getChainConfig(chainId).OWR_FACTORY_ADDRESS.address,
|
|
221
262
|
OWRFactoryContract.abi,
|
|
222
263
|
signer,
|
|
223
264
|
);
|
|
@@ -304,7 +345,7 @@ export const deploySplitterContract = async ({
|
|
|
304
345
|
}): Promise<ETH_ADDRESS> => {
|
|
305
346
|
try {
|
|
306
347
|
const splitMainContractInstance = new Contract(
|
|
307
|
-
|
|
348
|
+
getChainConfig(chainId).SPLITMAIN_ADDRESS.address,
|
|
308
349
|
splitMainEthereumAbi,
|
|
309
350
|
signer,
|
|
310
351
|
);
|
|
@@ -403,16 +444,15 @@ export const deploySplitterAndOWRContracts = async ({
|
|
|
403
444
|
|
|
404
445
|
executeCalls.push(
|
|
405
446
|
{
|
|
406
|
-
target:
|
|
447
|
+
target: getChainConfig(chainId).SPLITMAIN_ADDRESS.address,
|
|
407
448
|
callData: splitTxData,
|
|
408
449
|
},
|
|
409
450
|
{
|
|
410
|
-
target:
|
|
451
|
+
target: getChainConfig(chainId).OWR_FACTORY_ADDRESS.address,
|
|
411
452
|
callData: owrTxData,
|
|
412
453
|
},
|
|
413
454
|
);
|
|
414
|
-
const multicallAddess =
|
|
415
|
-
CHAIN_CONFIGURATION[chainId].MULTICALL_ADDRESS.address;
|
|
455
|
+
const multicallAddess = getChainConfig(chainId).MULTICALL_ADDRESS.address;
|
|
416
456
|
|
|
417
457
|
const executeMultiCalls = await multicall(
|
|
418
458
|
executeCalls,
|
|
@@ -555,3 +595,309 @@ const encodeCreateOWRecipientTxData = (
|
|
|
555
595
|
parseEther(amountOfPrincipalStake.toString()),
|
|
556
596
|
]);
|
|
557
597
|
};
|
|
598
|
+
|
|
599
|
+
// OVM and SplitV2 Helper Functions
|
|
600
|
+
|
|
601
|
+
// Helper function to format recipients specifically for SplitV2 (returns SplitV2Recipient[])
|
|
602
|
+
export const formatRecipientsForSplitV2 = (
|
|
603
|
+
splitRecipients: SplitRecipient[] | SplitV2Recipient[],
|
|
604
|
+
): SplitV2Recipient[] => {
|
|
605
|
+
const { sortedRecipients, getAddress, getPercentAllocation } =
|
|
606
|
+
formatRecipientsCommon(splitRecipients);
|
|
607
|
+
|
|
608
|
+
return sortedRecipients
|
|
609
|
+
.filter(item => getAddress(item) !== '')
|
|
610
|
+
.map(item => ({
|
|
611
|
+
address: getAddress(item),
|
|
612
|
+
percentAllocation: parseFloat(getPercentAllocation(item).toString()),
|
|
613
|
+
}));
|
|
614
|
+
};
|
|
615
|
+
|
|
616
|
+
export const createSplitsClient = async (
|
|
617
|
+
signer: SignerType,
|
|
618
|
+
chainId: number,
|
|
619
|
+
): Promise<SplitsClient> => {
|
|
620
|
+
const chain = chainId === 1 ? mainnet : hoodi;
|
|
621
|
+
const client = createPublicClient({
|
|
622
|
+
chain,
|
|
623
|
+
transport: http(CHAIN_PUBLIC_RPC_URL[chainId]),
|
|
624
|
+
});
|
|
625
|
+
// convert signer to walletClient
|
|
626
|
+
if (
|
|
627
|
+
typeof window !== 'undefined' &&
|
|
628
|
+
signer.provider instanceof BrowserProvider
|
|
629
|
+
) {
|
|
630
|
+
// For browser environment
|
|
631
|
+
const address = await signer.getAddress();
|
|
632
|
+
const viemWalletClient = createWalletClient({
|
|
633
|
+
account: address,
|
|
634
|
+
chain,
|
|
635
|
+
transport: custom((window as any).ethereum),
|
|
636
|
+
});
|
|
637
|
+
return new SplitsClient({
|
|
638
|
+
publicClient: client,
|
|
639
|
+
walletClient: viemWalletClient,
|
|
640
|
+
chainId,
|
|
641
|
+
});
|
|
642
|
+
} else {
|
|
643
|
+
// For non-browser environment, extract private key from signer
|
|
644
|
+
const signerPrivateKey = (signer as Wallet)?.privateKey;
|
|
645
|
+
if (!signerPrivateKey) {
|
|
646
|
+
throw new Error('Signer private key not available');
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
const privateKey = signerPrivateKey.startsWith('0x')
|
|
650
|
+
? signerPrivateKey
|
|
651
|
+
: `0x${signerPrivateKey}`;
|
|
652
|
+
|
|
653
|
+
const scriptAccount = privateKeyToAccount(privateKey as `0x${string}`);
|
|
654
|
+
const account = scriptAccount;
|
|
655
|
+
|
|
656
|
+
const viemWalletClient = createWalletClient({
|
|
657
|
+
account,
|
|
658
|
+
chain,
|
|
659
|
+
transport: http(CHAIN_PUBLIC_RPC_URL[chainId]),
|
|
660
|
+
});
|
|
661
|
+
return new SplitsClient({
|
|
662
|
+
publicClient: client,
|
|
663
|
+
walletClient: viemWalletClient,
|
|
664
|
+
chainId,
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
export const predictSplitV2Address = async ({
|
|
670
|
+
splitOwnerAddress,
|
|
671
|
+
recipients,
|
|
672
|
+
distributorFeePercent,
|
|
673
|
+
salt,
|
|
674
|
+
signer,
|
|
675
|
+
chainId,
|
|
676
|
+
}: {
|
|
677
|
+
splitOwnerAddress: string;
|
|
678
|
+
recipients: SplitV2Recipient[];
|
|
679
|
+
distributorFeePercent: number;
|
|
680
|
+
salt: `0x${string}`;
|
|
681
|
+
signer: SignerType;
|
|
682
|
+
chainId: number;
|
|
683
|
+
}): Promise<string> => {
|
|
684
|
+
try {
|
|
685
|
+
const splitsClient = await createSplitsClient(signer, chainId);
|
|
686
|
+
|
|
687
|
+
const response = await splitsClient.splitV2.predictDeterministicAddress({
|
|
688
|
+
ownerAddress: splitOwnerAddress,
|
|
689
|
+
recipients,
|
|
690
|
+
distributorFeePercent,
|
|
691
|
+
salt,
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
return response.splitAddress;
|
|
695
|
+
} catch (error: any) {
|
|
696
|
+
throw new Error(
|
|
697
|
+
`Failed to predict SplitV2 address: ${error.message ?? 'SplitV2 SDK call failed'}`,
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
export const isSplitV2Deployed = async ({
|
|
703
|
+
splitOwnerAddress,
|
|
704
|
+
recipients,
|
|
705
|
+
distributorFeePercent,
|
|
706
|
+
salt,
|
|
707
|
+
signer,
|
|
708
|
+
chainId,
|
|
709
|
+
}: {
|
|
710
|
+
splitOwnerAddress: string;
|
|
711
|
+
recipients: SplitV2Recipient[];
|
|
712
|
+
distributorFeePercent: number;
|
|
713
|
+
salt: `0x${string}`;
|
|
714
|
+
signer: SignerType;
|
|
715
|
+
chainId: number;
|
|
716
|
+
}): Promise<boolean> => {
|
|
717
|
+
try {
|
|
718
|
+
const splitsClient = await createSplitsClient(signer, chainId);
|
|
719
|
+
const response = await splitsClient.splitV2.isDeployed({
|
|
720
|
+
ownerAddress: splitOwnerAddress,
|
|
721
|
+
recipients,
|
|
722
|
+
distributorFeePercent,
|
|
723
|
+
salt,
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
return response.deployed;
|
|
727
|
+
} catch (error: any) {
|
|
728
|
+
// If the check fails, assume it's not deployed
|
|
729
|
+
return false;
|
|
730
|
+
}
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
export const deployOVMContract = async ({
|
|
734
|
+
OVMOwnerAddress,
|
|
735
|
+
principalRecipient,
|
|
736
|
+
rewardRecipient,
|
|
737
|
+
principalThreshold,
|
|
738
|
+
signer,
|
|
739
|
+
chainId,
|
|
740
|
+
}: {
|
|
741
|
+
OVMOwnerAddress: string;
|
|
742
|
+
principalRecipient: string;
|
|
743
|
+
rewardRecipient: string;
|
|
744
|
+
principalThreshold: number;
|
|
745
|
+
signer: SignerType;
|
|
746
|
+
chainId: number;
|
|
747
|
+
}): Promise<string> => {
|
|
748
|
+
try {
|
|
749
|
+
const chainConfig = getChainConfig(chainId);
|
|
750
|
+
if (!chainConfig?.OVM_FACTORY_ADDRESS?.address) {
|
|
751
|
+
throw new Error(`OVM Factory not configured for chain ${chainId}`);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
const ovmFactoryContract = new Contract(
|
|
755
|
+
chainConfig.OVM_FACTORY_ADDRESS.address,
|
|
756
|
+
OVMFactoryContract.abi,
|
|
757
|
+
signer,
|
|
758
|
+
);
|
|
759
|
+
|
|
760
|
+
const tx = await ovmFactoryContract.createObolValidatorManager(
|
|
761
|
+
OVMOwnerAddress,
|
|
762
|
+
principalRecipient,
|
|
763
|
+
rewardRecipient,
|
|
764
|
+
principalThreshold,
|
|
765
|
+
);
|
|
766
|
+
|
|
767
|
+
const receipt = await tx.wait();
|
|
768
|
+
|
|
769
|
+
// Extract OVM address from logs
|
|
770
|
+
const ovmAddressLog = receipt?.logs[1]?.topics[1];
|
|
771
|
+
if (!ovmAddressLog) {
|
|
772
|
+
throw new Error('Failed to extract OVM address from transaction logs');
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
const ovmAddress = '0x' + ovmAddressLog.slice(26, 66);
|
|
776
|
+
return ovmAddress;
|
|
777
|
+
} catch (error: any) {
|
|
778
|
+
throw new Error(
|
|
779
|
+
`Failed to deploy OVM contract: ${error.message ?? 'OVM deployment failed'}`,
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
export const deployOVMAndSplitV2 = async ({
|
|
785
|
+
ovmArgs,
|
|
786
|
+
rewardRecipients,
|
|
787
|
+
isRewardsSplitterDeployed,
|
|
788
|
+
distributorFeePercent,
|
|
789
|
+
salt,
|
|
790
|
+
signer,
|
|
791
|
+
chainId,
|
|
792
|
+
principalSplitRecipients,
|
|
793
|
+
isPrincipalSplitDeployed,
|
|
794
|
+
splitOwnerAddress,
|
|
795
|
+
}: {
|
|
796
|
+
ovmArgs: OVMArgs;
|
|
797
|
+
rewardRecipients: SplitV2Recipient[];
|
|
798
|
+
isRewardsSplitterDeployed?: boolean;
|
|
799
|
+
distributorFeePercent: number;
|
|
800
|
+
salt: `0x${string}`;
|
|
801
|
+
signer: SignerType;
|
|
802
|
+
chainId: number;
|
|
803
|
+
principalSplitRecipients?: SplitV2Recipient[];
|
|
804
|
+
isPrincipalSplitDeployed?: boolean;
|
|
805
|
+
splitOwnerAddress: string;
|
|
806
|
+
}): Promise<string> => {
|
|
807
|
+
try {
|
|
808
|
+
const chainConfig = getChainConfig(chainId);
|
|
809
|
+
if (!chainConfig?.OVM_FACTORY_ADDRESS?.address) {
|
|
810
|
+
throw new Error(`OVM Factory not configured for chain ${chainId}`);
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
const splitsClient = await createSplitsClient(signer, chainId);
|
|
814
|
+
const executeCalls: any[] = [];
|
|
815
|
+
|
|
816
|
+
if (rewardRecipients && !isRewardsSplitterDeployed) {
|
|
817
|
+
// Create rewards split call data
|
|
818
|
+
const rewardsSplitTxData =
|
|
819
|
+
await splitsClient.splitV2.callData.createSplit({
|
|
820
|
+
recipients: rewardRecipients,
|
|
821
|
+
distributorFeePercent,
|
|
822
|
+
ownerAddress: splitOwnerAddress,
|
|
823
|
+
salt,
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
executeCalls.push(rewardsSplitTxData);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// Create principal split call data if needed (for total split scenario)
|
|
830
|
+
if (principalSplitRecipients && !isPrincipalSplitDeployed) {
|
|
831
|
+
const principalSplitTxData =
|
|
832
|
+
await splitsClient.splitV2.callData.createSplit({
|
|
833
|
+
recipients: principalSplitRecipients,
|
|
834
|
+
distributorFeePercent,
|
|
835
|
+
salt,
|
|
836
|
+
ownerAddress: splitOwnerAddress,
|
|
837
|
+
});
|
|
838
|
+
executeCalls.push(principalSplitTxData);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// Create OVM call data
|
|
842
|
+
const ovmTxData = encodeCreateOVMTxData(
|
|
843
|
+
ovmArgs.OVMOwnerAddress,
|
|
844
|
+
ovmArgs.principalRecipient,
|
|
845
|
+
ovmArgs.rewardRecipient,
|
|
846
|
+
ovmArgs.principalThreshold,
|
|
847
|
+
);
|
|
848
|
+
|
|
849
|
+
executeCalls.push({
|
|
850
|
+
address: chainConfig.OVM_FACTORY_ADDRESS.address,
|
|
851
|
+
data: ovmTxData,
|
|
852
|
+
});
|
|
853
|
+
|
|
854
|
+
// Execute multicall
|
|
855
|
+
const executeMultiCalls = await splitsClient.splitV2.multicall({
|
|
856
|
+
calls: executeCalls,
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
// Extract addresses from events
|
|
860
|
+
let ovmAddress: string | undefined;
|
|
861
|
+
const eventCount = executeMultiCalls?.events.length;
|
|
862
|
+
|
|
863
|
+
if (eventCount === 2) {
|
|
864
|
+
ovmAddress = executeMultiCalls?.events[0]?.address;
|
|
865
|
+
} else if (eventCount === 5) {
|
|
866
|
+
ovmAddress = executeMultiCalls?.events[3]?.address;
|
|
867
|
+
} else {
|
|
868
|
+
ovmAddress = executeMultiCalls?.events[6]?.address;
|
|
869
|
+
}
|
|
870
|
+
if (!ovmAddress) {
|
|
871
|
+
throw new Error(
|
|
872
|
+
'Failed to extract contract addresses from multicall events',
|
|
873
|
+
);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
return ovmAddress;
|
|
877
|
+
} catch (error: any) {
|
|
878
|
+
throw new Error(
|
|
879
|
+
`Failed to deploy OVM and SplitV2: ${error.message ?? 'Deployment failed'}`,
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
const encodeCreateOVMTxData = (
|
|
885
|
+
OVMOwnerAddress: string,
|
|
886
|
+
principalRecipient: string,
|
|
887
|
+
rewardRecipient: string,
|
|
888
|
+
principalThreshold: number,
|
|
889
|
+
): string => {
|
|
890
|
+
return ovmFactoryContractInterface.encodeFunctionData(
|
|
891
|
+
'createObolValidatorManager',
|
|
892
|
+
[OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold],
|
|
893
|
+
);
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
// Helper function to safely get chain configuration
|
|
897
|
+
const getChainConfig = (chainId: number): ChainConfig => {
|
|
898
|
+
const config = CHAIN_CONFIGURATION[chainId];
|
|
899
|
+
if (!config) {
|
|
900
|
+
throw new Error(`Chain configuration not found for chain ID ${chainId}`);
|
|
901
|
+
}
|
|
902
|
+
return config;
|
|
903
|
+
};
|