@obolnetwork/obol-sdk 2.8.0 → 2.9.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 (40) hide show
  1. package/dist/cjs/package.json +2 -4
  2. package/dist/cjs/src/abi/splitV2FactoryAbi.js +420 -0
  3. package/dist/cjs/src/ajv.js +24 -0
  4. package/dist/cjs/src/bytecodes.js +3 -1
  5. package/dist/cjs/src/constants.js +24 -16
  6. package/dist/cjs/src/index.js +10 -10
  7. package/dist/cjs/src/schema.js +29 -3
  8. package/dist/cjs/src/splits/splitHelpers.js +100 -109
  9. package/dist/cjs/src/splits/splits.js +77 -16
  10. package/dist/cjs/test/client/ajv.spec.js +32 -0
  11. package/dist/cjs/test/splits/splits.spec.js +76 -2
  12. package/dist/esm/package.json +2 -4
  13. package/dist/esm/src/abi/splitV2FactoryAbi.js +417 -0
  14. package/dist/esm/src/ajv.js +24 -0
  15. package/dist/esm/src/bytecodes.js +2 -0
  16. package/dist/esm/src/constants.js +25 -17
  17. package/dist/esm/src/index.js +10 -10
  18. package/dist/esm/src/schema.js +28 -2
  19. package/dist/esm/src/splits/splitHelpers.js +101 -110
  20. package/dist/esm/src/splits/splits.js +79 -18
  21. package/dist/esm/test/client/ajv.spec.js +33 -1
  22. package/dist/esm/test/splits/splits.spec.js +77 -3
  23. package/dist/types/src/abi/splitV2FactoryAbi.d.ts +60 -0
  24. package/dist/types/src/bytecodes.d.ts +2 -0
  25. package/dist/types/src/exits/verificationHelpers.d.ts +1 -0
  26. package/dist/types/src/schema.d.ts +30 -3
  27. package/dist/types/src/splits/splitHelpers.d.ts +17 -3
  28. package/dist/types/src/splits/splits.d.ts +28 -1
  29. package/dist/types/src/types.d.ts +21 -6
  30. package/dist/types/src/verification/common.d.ts +1 -0
  31. package/package.json +2 -4
  32. package/src/abi/splitV2FactoryAbi.ts +417 -0
  33. package/src/ajv.ts +33 -0
  34. package/src/bytecodes.ts +4 -0
  35. package/src/constants.ts +26 -16
  36. package/src/index.ts +14 -14
  37. package/src/schema.ts +29 -2
  38. package/src/splits/splitHelpers.ts +169 -124
  39. package/src/splits/splits.ts +115 -17
  40. package/src/types.ts +24 -6
@@ -1,6 +1,6 @@
1
1
  import pjson from '../package.json';
2
2
  import { FORK_MAPPING } from './types';
3
- import { HOLESKY_MULTICALL_BYTECODE, HOLESKY_OWR_FACTORY_BYTECODE, HOLESKY_SPLITMAIN_BYTECODE, HOODI_MULTICALL_BYTECODE, HOODI_OVM_FACTORY_BYTECODE, HOODI_OWR_FACTORY_BYTECODE, HOODI_SPLITMAIN_BYTECODE, HOODI_WAREHOUSE_BYTECODE, MAINNET_MULTICALL_BYTECODE, MAINNET_OVM_FACTORY_BYTECODE, MAINNET_OWR_FACTORY_BYTECODE, MAINNET_SPLITMAIN_BYTECODE, MAINNET_WAREHOUSE_BYTECODE, } from './bytecodes';
3
+ import { HOLESKY_MULTICALL_BYTECODE, HOLESKY_OWR_FACTORY_BYTECODE, HOLESKY_SPLITMAIN_BYTECODE, HOODI_MULTICALL_BYTECODE, HOODI_OVM_FACTORY_BYTECODE, HOODI_OWR_FACTORY_BYTECODE, HOODI_SPLIT_V2_FACTORY_BYTECODE, HOODI_SPLITMAIN_BYTECODE, HOODI_WAREHOUSE_BYTECODE, MAINNET_MULTICALL_BYTECODE, MAINNET_OVM_FACTORY_BYTECODE, MAINNET_OWR_FACTORY_BYTECODE, MAINNET_SPLIT_V2_FACTORY_BYTECODE, MAINNET_SPLITMAIN_BYTECODE, MAINNET_WAREHOUSE_BYTECODE, } from './bytecodes';
4
4
  import * as dotenv from 'dotenv';
5
5
  dotenv.config();
6
6
  export const CONFLICT_ERROR_MSG = 'Conflict';
@@ -108,76 +108,84 @@ export const isChainSupportedForSplitters = (chainId) => {
108
108
  };
109
109
  export const CHAIN_CONFIGURATION = {
110
110
  [FORK_MAPPING['0x00000000']]: {
111
- SPLITMAIN_ADDRESS: {
111
+ SPLITMAIN_CONTRACT: {
112
112
  address: '0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE',
113
113
  bytecode: MAINNET_SPLITMAIN_BYTECODE,
114
114
  },
115
- MULTICALL_ADDRESS: {
115
+ MULTICALL_CONTRACT: {
116
116
  address: '0xeefba1e63905ef1d7acba5a8513c70307c1ce441',
117
117
  bytecode: MAINNET_MULTICALL_BYTECODE,
118
118
  },
119
- OWR_FACTORY_ADDRESS: {
119
+ OWR_FACTORY_CONTRACT: {
120
120
  address: '0x119acd7844cbdd5fc09b1c6a4408f490c8f7f522',
121
121
  bytecode: MAINNET_OWR_FACTORY_BYTECODE,
122
122
  },
123
- RETROACTIVE_FUNDING_ADDRESS: {
123
+ RETROACTIVE_FUNDING_CONTRACT: {
124
124
  address: '0xDe5aE4De36c966747Ea7DF13BD9589642e2B1D0d',
125
125
  bytecode: '',
126
126
  },
127
127
  // OVM and SplitV2 Contract Addresses
128
- OVM_FACTORY_ADDRESS: {
128
+ OVM_FACTORY_CONTRACT: {
129
129
  address: '0xdfe2d8b26806583cf03b3cb623b0752f8670e93e',
130
130
  bytecode: MAINNET_OVM_FACTORY_BYTECODE,
131
131
  },
132
- WAREHOUSE_ADDRESS: {
132
+ WAREHOUSE_CONTRACT: {
133
133
  address: '0x8fb66F38cF86A3d5e8768f8F1754A24A6c661Fb8',
134
134
  bytecode: MAINNET_WAREHOUSE_BYTECODE,
135
135
  },
136
+ SPLIT_V2_FACTORY_CONTRACT: {
137
+ address: '0x5cbA88D55Cec83caD5A105Ad40C8c9aF20bE21d1',
138
+ bytecode: MAINNET_SPLIT_V2_FACTORY_BYTECODE,
139
+ },
136
140
  },
137
141
  [FORK_MAPPING['0x01017000']]: {
138
- SPLITMAIN_ADDRESS: {
142
+ SPLITMAIN_CONTRACT: {
139
143
  address: '0xfC8a305728051367797DADE6Aa0344E0987f5286',
140
144
  bytecode: HOLESKY_SPLITMAIN_BYTECODE,
141
145
  },
142
- MULTICALL_ADDRESS: {
146
+ MULTICALL_CONTRACT: {
143
147
  address: '0xcA11bde05977b3631167028862bE2a173976CA11',
144
148
  bytecode: HOLESKY_MULTICALL_BYTECODE,
145
149
  },
146
- OWR_FACTORY_ADDRESS: {
150
+ OWR_FACTORY_CONTRACT: {
147
151
  address: '0xc0961353fcc43a99e3041db07ac646720e116256',
148
152
  bytecode: HOLESKY_OWR_FACTORY_BYTECODE,
149
153
  },
150
- RETROACTIVE_FUNDING_ADDRESS: {
154
+ RETROACTIVE_FUNDING_CONTRACT: {
151
155
  address: '0x43F641fA70e09f0326ac66b4Ef0C416EaEcBC6f5',
152
156
  bytecode: '',
153
157
  },
154
158
  },
155
159
  [FORK_MAPPING['0x10000910']]: {
156
- SPLITMAIN_ADDRESS: {
160
+ SPLITMAIN_CONTRACT: {
157
161
  address: '0xc05ae267291705ac16F75283572294ed2a91CBc7',
158
162
  bytecode: HOODI_SPLITMAIN_BYTECODE,
159
163
  },
160
- MULTICALL_ADDRESS: {
164
+ MULTICALL_CONTRACT: {
161
165
  address: '0xcA11bde05977b3631167028862bE2a173976CA11',
162
166
  bytecode: HOODI_MULTICALL_BYTECODE,
163
167
  },
164
- OWR_FACTORY_ADDRESS: {
168
+ OWR_FACTORY_CONTRACT: {
165
169
  address: '0x9ff0c649d0bf5fe7efa4d72e94bed7302ed5c8d7',
166
170
  bytecode: HOODI_OWR_FACTORY_BYTECODE,
167
171
  },
168
- RETROACTIVE_FUNDING_ADDRESS: {
172
+ RETROACTIVE_FUNDING_CONTRACT: {
169
173
  address: '0x43F641fA70e09f0326ac66b4Ef0C416EaEcBC6f5',
170
174
  bytecode: '',
171
175
  },
172
176
  // OVM and SplitV2 Contract Addresses
173
- OVM_FACTORY_ADDRESS: {
177
+ OVM_FACTORY_CONTRACT: {
174
178
  address: '0x6F13d929C783a420AE4DC71C1dcc27A02038Ed09',
175
179
  bytecode: HOODI_OVM_FACTORY_BYTECODE,
176
180
  },
177
- WAREHOUSE_ADDRESS: {
181
+ WAREHOUSE_CONTRACT: {
178
182
  address: '0x8fb66F38cF86A3d5e8768f8F1754A24A6c661Fb8',
179
183
  bytecode: HOODI_WAREHOUSE_BYTECODE,
180
184
  },
185
+ SPLIT_V2_FACTORY_CONTRACT: {
186
+ address: '0x5cbA88D55Cec83caD5A105Ad40C8c9aF20bE21d1',
187
+ bytecode: HOODI_SPLIT_V2_FACTORY_BYTECODE,
188
+ },
181
189
  },
182
190
  };
183
191
  export const DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT = 1;
@@ -128,19 +128,19 @@ export class Client extends Base {
128
128
  throw new Error(`Splitter configuration is not supported on ${this.chainId} chain`);
129
129
  }
130
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}`);
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
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);
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);
137
137
  if (!checkMulticallAddress ||
138
138
  !checkSplitMainAddress ||
139
139
  !checkOWRFactoryAddress) {
140
140
  throw new Error(`Something isn not working as expected, check this issue with obol-sdk team on ${OBOL_SDK_EMAIL}`);
141
141
  }
142
142
  const retroActiveFundingRecipient = {
143
- account: chainConfig.RETROACTIVE_FUNDING_ADDRESS.address,
143
+ account: chainConfig.RETROACTIVE_FUNDING_CONTRACT.address,
144
144
  percentAllocation: validatedPayload.ObolRAFSplit,
145
145
  };
146
146
  const copiedSplitRecipients = [...validatedPayload.splitRecipients];
@@ -202,15 +202,15 @@ export class Client extends Base {
202
202
  throw new Error(`Splitter configuration is not supported on ${this.chainId} chain`);
203
203
  }
204
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}`);
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
207
  }
208
- const checkSplitMainAddress = yield isContractAvailable(chainConfig.SPLITMAIN_ADDRESS.address, this.signer.provider, chainConfig.SPLITMAIN_ADDRESS.bytecode);
208
+ const checkSplitMainAddress = yield isContractAvailable(chainConfig.SPLITMAIN_CONTRACT.address, this.signer.provider, chainConfig.SPLITMAIN_CONTRACT.bytecode);
209
209
  if (!checkSplitMainAddress) {
210
210
  throw new Error(`Something isn not working as expected, check this issue with obol-sdk team on ${OBOL_SDK_EMAIL}`);
211
211
  }
212
212
  const retroActiveFundingRecipient = {
213
- account: chainConfig.RETROACTIVE_FUNDING_ADDRESS.address,
213
+ account: chainConfig.RETROACTIVE_FUNDING_CONTRACT.address,
214
214
  percentAllocation: validatedPayload.ObolRAFSplit,
215
215
  };
216
216
  const copiedSplitRecipients = [...validatedPayload.splitRecipients];
@@ -1,7 +1,6 @@
1
1
  import { ZeroAddress } from 'ethers';
2
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';
5
4
  export const operatorPayloadSchema = {
6
5
  type: 'object',
7
6
  properties: {
@@ -160,7 +159,7 @@ export const ovmBaseSplitPayload = {
160
159
  splitOwnerAddress: {
161
160
  type: 'string',
162
161
  pattern: '^0x[a-fA-F0-9]{40}$',
163
- default: zeroAddress,
162
+ default: ZeroAddress,
164
163
  },
165
164
  principalThreshold: {
166
165
  type: 'number',
@@ -207,3 +206,30 @@ export const ovmTotalSplitPayloadSchema = {
207
206
  'OVMOwnerAddress',
208
207
  ],
209
208
  };
209
+ export const ovmRequestWithdrawalPayloadSchema = {
210
+ type: 'object',
211
+ properties: {
212
+ ovmAddress: {
213
+ type: 'string',
214
+ pattern: '^0x[a-fA-F0-9]{40}$',
215
+ },
216
+ pubKeys: {
217
+ type: 'array',
218
+ minItems: 1,
219
+ items: {
220
+ type: 'string',
221
+ pattern: '^0x[a-fA-F0-9]{96}$', // 48 bytes = 96 hex chars + 0x prefix
222
+ },
223
+ },
224
+ amounts: {
225
+ type: 'array',
226
+ minItems: 1,
227
+ items: {
228
+ type: 'string',
229
+ pattern: '^[0-9]+$',
230
+ },
231
+ },
232
+ },
233
+ validateOVMRequestWithdrawalPayload: true,
234
+ required: ['ovmAddress', 'pubKeys', 'amounts'],
235
+ };
@@ -7,19 +7,17 @@ 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 { BrowserProvider, Contract, Interface, parseEther, ZeroAddress, } from 'ethers';
10
+ import { Contract, Interface, parseEther, ZeroAddress } from 'ethers';
11
11
  import { OWRContract, OWRFactoryContract } from '../abi/OWR';
12
- import { OVMFactoryContract } from '../abi/OVMFactory';
12
+ import { OVMFactoryContract, OVMContract } from '../abi/OVMFactory';
13
13
  import { splitMainEthereumAbi } from '../abi/SplitMain';
14
14
  import { MultiCallContract } from '../abi/Multicall';
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
+ import { CHAIN_CONFIGURATION } from '../constants';
16
+ import { splitV2FactoryAbi } from '../abi/splitV2FactoryAbi';
20
17
  const splitMainContractInterface = new Interface(splitMainEthereumAbi);
21
18
  const owrFactoryContractInterface = new Interface(OWRFactoryContract.abi);
22
19
  const ovmFactoryContractInterface = new Interface(OVMFactoryContract.abi);
20
+ const splitV2FactoryInterface = new Interface(splitV2FactoryAbi);
23
21
  // Helper function to extract common recipient formatting logic
24
22
  const formatRecipientsCommon = (recipients) => {
25
23
  const copiedRecipients = [...recipients];
@@ -46,7 +44,7 @@ export const formatSplitRecipients = (recipients) => {
46
44
  export const predictSplitterAddress = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
47
45
  var _a, _b, _c;
48
46
  try {
49
- const splitMainContractInstance = new Contract(getChainConfig(chainId).SPLITMAIN_ADDRESS.address, splitMainEthereumAbi, signer);
47
+ const splitMainContractInstance = new Contract(getChainConfig(chainId).SPLITMAIN_CONTRACT.address, splitMainEthereumAbi, signer);
50
48
  let predictedSplitterAddress;
51
49
  if (controllerAddress === ZeroAddress) {
52
50
  try {
@@ -147,7 +145,7 @@ export const handleDeployOWRAndSplitter = ({ signer, isSplitterDeployed, predict
147
145
  const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
148
146
  var _g, _h, _j, _k, _l;
149
147
  try {
150
- const OWRFactoryInstance = new Contract(getChainConfig(chainId).OWR_FACTORY_ADDRESS.address, OWRFactoryContract.abi, signer);
148
+ const OWRFactoryInstance = new Contract(getChainConfig(chainId).OWR_FACTORY_CONTRACT.address, OWRFactoryContract.abi, signer);
151
149
  let tx;
152
150
  try {
153
151
  tx = yield OWRFactoryInstance.createOWRecipient(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, parseEther(owrArgs.amountOfPrincipalStake.toString()));
@@ -191,7 +189,7 @@ const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, v
191
189
  export const deploySplitterContract = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
192
190
  var _m, _o, _p, _q, _r;
193
191
  try {
194
- const splitMainContractInstance = new Contract(getChainConfig(chainId).SPLITMAIN_ADDRESS.address, splitMainEthereumAbi, signer);
192
+ const splitMainContractInstance = new Contract(getChainConfig(chainId).SPLITMAIN_CONTRACT.address, splitMainEthereumAbi, signer);
195
193
  let tx;
196
194
  try {
197
195
  tx = yield splitMainContractInstance.createSplit(accounts, percentAllocations, distributorFee, controllerAddress);
@@ -238,14 +236,13 @@ export const deploySplitterAndOWRContracts = ({ owrArgs, splitterArgs, signer, c
238
236
  const splitTxData = encodeCreateSplitTxData(splitterArgs.accounts, splitterArgs.percentAllocations, splitterArgs.distributorFee, splitterArgs.controllerAddress);
239
237
  const owrTxData = encodeCreateOWRecipientTxData(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, owrArgs.amountOfPrincipalStake);
240
238
  executeCalls.push({
241
- target: getChainConfig(chainId).SPLITMAIN_ADDRESS.address,
239
+ target: getChainConfig(chainId).SPLITMAIN_CONTRACT.address,
242
240
  callData: splitTxData,
243
241
  }, {
244
- target: getChainConfig(chainId).OWR_FACTORY_ADDRESS.address,
242
+ target: getChainConfig(chainId).OWR_FACTORY_CONTRACT.address,
245
243
  callData: owrTxData,
246
244
  });
247
- const multicallAddess = getChainConfig(chainId).MULTICALL_ADDRESS.address;
248
- const executeMultiCalls = yield multicall(executeCalls, signer, multicallAddess);
245
+ const executeMultiCalls = yield multicall(executeCalls, signer, chainId);
249
246
  const splitAddressData = (_s = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[0]) === null || _s === void 0 ? void 0 : _s.topics[1];
250
247
  const formattedSplitterAddress = '0x' + (splitAddressData === null || splitAddressData === void 0 ? void 0 : splitAddressData.slice(26, 66));
251
248
  const owrAddressData = (_t = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[1]) === null || _t === void 0 ? void 0 : _t.topics[1];
@@ -285,9 +282,11 @@ export const getOWRTranches = ({ owrAddress, signer, }) => __awaiter(void 0, voi
285
282
  throw new Error(`Unexpected error in getOWRTranches: ${(_v = error.message) !== null && _v !== void 0 ? _v : 'Unknown error while fetching OWR tranche data'}`);
286
283
  }
287
284
  });
288
- export const multicall = (calls, signer, multicallAddress) => __awaiter(void 0, void 0, void 0, function* () {
285
+ export const multicall = (calls, signer, chainId) => __awaiter(void 0, void 0, void 0, function* () {
289
286
  var _w, _x, _y;
290
287
  try {
288
+ const chainConfig = getChainConfig(chainId);
289
+ const multicallAddress = chainConfig.MULTICALL_CONTRACT.address;
291
290
  const multiCallContractInstance = new Contract(multicallAddress, MultiCallContract.abi, signer);
292
291
  let tx;
293
292
  try {
@@ -345,77 +344,45 @@ export const formatRecipientsForSplitV2 = (splitRecipients) => {
345
344
  percentAllocation: parseFloat(getPercentAllocation(item).toString()),
346
345
  }));
347
346
  };
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
- });
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
+ };
393
359
  export const predictSplitV2Address = ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
394
- var _z;
360
+ var _z, _0;
395
361
  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;
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;
404
370
  }
405
371
  catch (error) {
406
- throw new Error(`Failed to predict SplitV2 address: ${(_z = error.message) !== null && _z !== void 0 ? _z : 'SplitV2 SDK call failed'}`);
372
+ throw new Error(`Failed to predict SplitV2 address: ${(_0 = error.message) !== null && _0 !== void 0 ? _0 : 'SplitV2 contract call failed'}`);
407
373
  }
408
374
  });
409
375
  export const isSplitV2Deployed = ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
376
+ var _1;
410
377
  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;
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;
419
386
  }
420
387
  catch (error) {
421
388
  // If the check fails, assume it's not deployed
@@ -423,17 +390,17 @@ export const isSplitV2Deployed = ({ splitOwnerAddress, recipients, distributorFe
423
390
  }
424
391
  });
425
392
  export const deployOVMContract = ({ OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
426
- var _0, _1, _2;
393
+ var _2, _3, _4;
427
394
  try {
428
395
  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)) {
396
+ if (!((_2 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.OVM_FACTORY_CONTRACT) === null || _2 === void 0 ? void 0 : _2.address)) {
430
397
  throw new Error(`OVM Factory not configured for chain ${chainId}`);
431
398
  }
432
- const ovmFactoryContract = new Contract(chainConfig.OVM_FACTORY_ADDRESS.address, OVMFactoryContract.abi, signer);
399
+ const ovmFactoryContract = new Contract(chainConfig.OVM_FACTORY_CONTRACT.address, OVMFactoryContract.abi, signer);
433
400
  const tx = yield ovmFactoryContract.createObolValidatorManager(OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold);
434
401
  const receipt = yield tx.wait();
435
402
  // 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];
403
+ const ovmAddressLog = (_3 = receipt === null || receipt === void 0 ? void 0 : receipt.logs[1]) === null || _3 === void 0 ? void 0 : _3.topics[1];
437
404
  if (!ovmAddressLog) {
438
405
  throw new Error('Failed to extract OVM address from transaction logs');
439
406
  }
@@ -441,59 +408,57 @@ export const deployOVMContract = ({ OVMOwnerAddress, principalRecipient, rewardR
441
408
  return ovmAddress;
442
409
  }
443
410
  catch (error) {
444
- throw new Error(`Failed to deploy OVM contract: ${(_2 = error.message) !== null && _2 !== void 0 ? _2 : 'OVM deployment failed'}`);
411
+ throw new Error(`Failed to deploy OVM contract: ${(_4 = error.message) !== null && _4 !== void 0 ? _4 : 'OVM deployment failed'}`);
445
412
  }
446
413
  });
447
414
  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;
415
+ var _5, _6, _7, _8, _9, _10, _11, _12, _13, _14;
449
416
  try {
450
417
  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)) {
418
+ if (!((_5 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.OVM_FACTORY_CONTRACT) === null || _5 === void 0 ? void 0 : _5.address)) {
452
419
  throw new Error(`OVM Factory not configured for chain ${chainId}`);
453
420
  }
454
- const splitsClient = yield createSplitsClient(signer, chainId);
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
+ }
455
424
  const executeCalls = [];
456
425
  if (rewardRecipients && !isRewardsSplitterDeployed) {
457
426
  // Create rewards split call data
458
- const rewardsSplitTxData = yield splitsClient.splitV2.callData.createSplit({
459
- recipients: rewardRecipients,
460
- distributorFeePercent,
461
- ownerAddress: splitOwnerAddress,
462
- salt,
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,
463
432
  });
464
- executeCalls.push(rewardsSplitTxData);
465
433
  }
466
434
  // Create principal split call data if needed (for total split scenario)
467
435
  if (principalSplitRecipients && !isPrincipalSplitDeployed) {
468
- const principalSplitTxData = yield splitsClient.splitV2.callData.createSplit({
469
- recipients: principalSplitRecipients,
470
- distributorFeePercent,
471
- salt,
472
- ownerAddress: splitOwnerAddress,
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,
473
441
  });
474
- executeCalls.push(principalSplitTxData);
475
442
  }
476
443
  // Create OVM call data
477
444
  const ovmTxData = encodeCreateOVMTxData(ovmArgs.OVMOwnerAddress, ovmArgs.principalRecipient, ovmArgs.rewardRecipient, ovmArgs.principalThreshold);
478
445
  executeCalls.push({
479
- address: chainConfig.OVM_FACTORY_ADDRESS.address,
480
- data: ovmTxData,
446
+ target: chainConfig.OVM_FACTORY_CONTRACT.address,
447
+ callData: ovmTxData,
481
448
  });
482
449
  // Execute multicall
483
- const executeMultiCalls = yield splitsClient.splitV2.multicall({
484
- calls: executeCalls,
485
- });
450
+ const executeMultiCalls = yield multicall(executeCalls, signer, chainId);
486
451
  // Extract addresses from events
487
452
  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;
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));
491
456
  }
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;
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));
494
459
  }
495
460
  else {
496
- ovmAddress = (_6 = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.events[6]) === null || _6 === void 0 ? void 0 : _6.address;
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));
497
462
  }
498
463
  if (!ovmAddress) {
499
464
  throw new Error('Failed to extract contract addresses from multicall events');
@@ -501,12 +466,16 @@ export const deployOVMAndSplitV2 = ({ ovmArgs, rewardRecipients, isRewardsSplitt
501
466
  return ovmAddress;
502
467
  }
503
468
  catch (error) {
504
- throw new Error(`Failed to deploy OVM and SplitV2: ${(_7 = error.message) !== null && _7 !== void 0 ? _7 : 'Deployment failed'}`);
469
+ throw new Error(`Failed to deploy OVM and SplitV2: ${(_14 = error.message) !== null && _14 !== void 0 ? _14 : 'Deployment failed'}`);
505
470
  }
506
471
  });
507
472
  const encodeCreateOVMTxData = (OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold) => {
508
473
  return ovmFactoryContractInterface.encodeFunctionData('createObolValidatorManager', [OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold]);
509
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
+ };
510
479
  // Helper function to safely get chain configuration
511
480
  const getChainConfig = (chainId) => {
512
481
  const config = CHAIN_CONFIGURATION[chainId];
@@ -515,3 +484,25 @@ const getChainConfig = (chainId) => {
515
484
  }
516
485
  return config;
517
486
  };
487
+ /**
488
+ * Requests withdrawal from an OVM contract
489
+ * @param ovmAddress - The address of the OVM contract
490
+ * @param pubKeys - Array of validator public keys in bytes format
491
+ * @param amounts - Array of withdrawal amounts in wei (uint64)
492
+ * @param signer - The signer to use for the transaction
493
+ * @returns Promise that resolves to the transaction hash
494
+ */
495
+ export const requestWithdrawalFromOVM = ({ ovmAddress, pubKeys, amounts, signer, }) => __awaiter(void 0, void 0, void 0, function* () {
496
+ var _15;
497
+ try {
498
+ // Convert string amounts to bigint
499
+ const bigintAmounts = amounts.map(amount => BigInt(amount));
500
+ const ovmContract = new Contract(ovmAddress, OVMContract.abi, signer);
501
+ const tx = yield ovmContract.requestWithdrawal(pubKeys, bigintAmounts);
502
+ const receipt = yield tx.wait();
503
+ return { txHash: receipt.hash };
504
+ }
505
+ catch (error) {
506
+ throw new Error(`Failed to request withdrawal from OVM: ${(_15 = error.message) !== null && _15 !== void 0 ? _15 : 'Request withdrawal failed'}`);
507
+ }
508
+ });