@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.
Files changed (56) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/abi/OVMFactory.js +620 -0
  3. package/dist/cjs/src/abi/splitV2FactoryAbi.js +420 -0
  4. package/dist/cjs/src/ajv.js +33 -6
  5. package/dist/cjs/src/bytecodes.js +10 -1
  6. package/dist/cjs/src/constants.js +71 -15
  7. package/dist/cjs/src/index.js +21 -9
  8. package/dist/cjs/src/schema.js +70 -1
  9. package/dist/cjs/src/splits/splitHelpers.js +188 -14
  10. package/dist/cjs/src/splits/splits.js +283 -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/fixtures.js +13 -1
  15. package/dist/cjs/test/splits/splits.spec.js +239 -0
  16. package/dist/esm/package.json +1 -1
  17. package/dist/esm/src/abi/OVMFactory.js +617 -0
  18. package/dist/esm/src/abi/splitV2FactoryAbi.js +417 -0
  19. package/dist/esm/src/ajv.js +33 -6
  20. package/dist/esm/src/bytecodes.js +9 -0
  21. package/dist/esm/src/constants.js +70 -15
  22. package/dist/esm/src/index.js +20 -9
  23. package/dist/esm/src/schema.js +70 -1
  24. package/dist/esm/src/splits/splitHelpers.js +182 -13
  25. package/dist/esm/src/splits/splits.js +279 -0
  26. package/dist/esm/src/types.js +0 -1
  27. package/dist/esm/test/client/ajv.spec.js +267 -0
  28. package/dist/esm/test/client/methods.spec.js +393 -0
  29. package/dist/esm/test/fixtures.js +12 -0
  30. package/dist/esm/test/splits/splits.spec.js +237 -0
  31. package/dist/types/src/abi/OVMFactory.d.ts +662 -0
  32. package/dist/types/src/abi/splitV2FactoryAbi.d.ts +60 -0
  33. package/dist/types/src/bytecodes.d.ts +9 -0
  34. package/dist/types/src/constants.d.ts +10 -21
  35. package/dist/types/src/exits/verificationHelpers.d.ts +1 -0
  36. package/dist/types/src/index.d.ts +7 -0
  37. package/dist/types/src/schema.d.ts +145 -0
  38. package/dist/types/src/splits/splitHelpers.d.ts +39 -2
  39. package/dist/types/src/splits/splits.d.ts +51 -0
  40. package/dist/types/src/types.d.ts +87 -2
  41. package/dist/types/src/verification/common.d.ts +1 -0
  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 +1 -1
  47. package/src/abi/OVMFactory.ts +617 -0
  48. package/src/abi/splitV2FactoryAbi.ts +417 -0
  49. package/src/ajv.ts +55 -13
  50. package/src/bytecodes.ts +19 -0
  51. package/src/constants.ts +84 -16
  52. package/src/index.ts +36 -15
  53. package/src/schema.ts +79 -0
  54. package/src/splits/splitHelpers.ts +373 -18
  55. package/src/splits/splits.ts +406 -0
  56. package/src/types.ts +100 -3
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.CAPELLA_FORK_MAPPING = exports.PROVIDER_MAP = exports.OBOL_SDK_EMAIL = exports.DEFAULT_RETROACTIVE_FUNDING_TOTAL_SPLIT = exports.DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT = exports.CHAIN_CONFIGURATION = exports.AVAILABLE_SPLITTER_CHAINS = exports.TERMS_AND_CONDITIONS_HASH = exports.TERMS_AND_CONDITIONS_URL = exports.TERMS_AND_CONDITIONS_VERSION = exports.ETHER_TO_GWEI = exports.DEFAULT_CHAIN_ID = exports.DEFAULT_BASE_VERSION = exports.DEFAULT_BASE_URL = exports.DefinitionFlow = exports.GENESIS_VALIDATOR_ROOT = exports.DOMAIN_DEPOSIT = exports.DOMAIN_APPLICATION_BUILDER = exports.SDK_VERSION = exports.CONFIG_VERSION = exports.DKG_ALGORITHM = exports.signEnrPayload = exports.signOperatorConfigHashPayload = exports.signCreatorConfigHashPayload = exports.ENRTypedMessage = exports.OperatorTypedMessage = exports.OperatorConfigHashSigningTypes = exports.EnrSigningTypes = exports.CreatorTypedMessage = exports.Domain = exports.TermsAndConditionsSigningTypes = exports.CreatorConfigHashSigningTypes = exports.EIP712_DOMAIN_VERSION = exports.EIP712_DOMAIN_NAME = exports.CONFLICT_ERROR_MSG = void 0;
29
+ exports.CHAIN_PUBLIC_RPC_URL = exports.CAPELLA_FORK_MAPPING = exports.PROVIDER_MAP = exports.OBOL_SDK_EMAIL = exports.PRINCIPAL_THRESHOLD = exports.SPLITS_V2_SALT = exports.DEFAULT_RETROACTIVE_FUNDING_TOTAL_SPLIT = exports.DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT = exports.CHAIN_CONFIGURATION = exports.isChainSupportedForSplitters = exports.AVAILABLE_SPLITTER_CHAINS = exports.TERMS_AND_CONDITIONS_HASH = exports.TERMS_AND_CONDITIONS_URL = exports.TERMS_AND_CONDITIONS_VERSION = exports.ETHER_TO_GWEI = exports.DEFAULT_CHAIN_ID = exports.DEFAULT_BASE_VERSION = exports.DEFAULT_BASE_URL = exports.DefinitionFlow = exports.GENESIS_VALIDATOR_ROOT = exports.DOMAIN_DEPOSIT = exports.DOMAIN_APPLICATION_BUILDER = exports.SDK_VERSION = exports.CONFIG_VERSION = exports.DKG_ALGORITHM = exports.signEnrPayload = exports.signOperatorConfigHashPayload = exports.signCreatorConfigHashPayload = exports.ENRTypedMessage = exports.OperatorTypedMessage = exports.OperatorConfigHashSigningTypes = exports.EnrSigningTypes = exports.CreatorTypedMessage = exports.Domain = exports.TermsAndConditionsSigningTypes = exports.CreatorConfigHashSigningTypes = exports.EIP712_DOMAIN_VERSION = exports.EIP712_DOMAIN_NAME = exports.CONFLICT_ERROR_MSG = void 0;
30
30
  const package_json_1 = __importDefault(require("../package.json"));
31
31
  const types_1 = require("./types");
32
32
  const bytecodes_1 = require("./bytecodes");
@@ -131,50 +131,102 @@ exports.TERMS_AND_CONDITIONS_URL = exports.TERMS_AND_CONDITIONS_VERSION === 1
131
131
  ? 'https://obol.org/terms.pdf'
132
132
  : `https://obol.org/${exports.TERMS_AND_CONDITIONS_VERSION}/terms.pdf`;
133
133
  exports.TERMS_AND_CONDITIONS_HASH = '0xd33721644e8f3afab1495a74abe3523cec12d48b8da6cb760972492ca3f1a273';
134
- exports.AVAILABLE_SPLITTER_CHAINS = [
135
- types_1.FORK_MAPPING['0x00000000'],
136
- types_1.FORK_MAPPING['0x01017000'],
137
- ];
134
+ exports.AVAILABLE_SPLITTER_CHAINS = {
135
+ [types_1.FORK_MAPPING['0x00000000']]: true, // Mainnet
136
+ [types_1.FORK_MAPPING['0x01017000']]: true, // Holesky
137
+ [types_1.FORK_MAPPING['0x10000910']]: true, // Hoodi
138
+ };
139
+ const isChainSupportedForSplitters = (chainId) => {
140
+ return chainId in exports.AVAILABLE_SPLITTER_CHAINS;
141
+ };
142
+ exports.isChainSupportedForSplitters = isChainSupportedForSplitters;
138
143
  exports.CHAIN_CONFIGURATION = {
139
- [exports.AVAILABLE_SPLITTER_CHAINS[0]]: {
140
- SPLITMAIN_ADDRESS: {
144
+ [types_1.FORK_MAPPING['0x00000000']]: {
145
+ SPLITMAIN_CONTRACT: {
141
146
  address: '0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE',
142
147
  bytecode: bytecodes_1.MAINNET_SPLITMAIN_BYTECODE,
143
148
  },
144
- MULTICALL_ADDRESS: {
149
+ MULTICALL_CONTRACT: {
145
150
  address: '0xeefba1e63905ef1d7acba5a8513c70307c1ce441',
146
151
  bytecode: bytecodes_1.MAINNET_MULTICALL_BYTECODE,
147
152
  },
148
- OWR_FACTORY_ADDRESS: {
153
+ OWR_FACTORY_CONTRACT: {
149
154
  address: '0x119acd7844cbdd5fc09b1c6a4408f490c8f7f522',
150
155
  bytecode: bytecodes_1.MAINNET_OWR_FACTORY_BYTECODE,
151
156
  },
152
- RETROACTIVE_FUNDING_ADDRESS: {
157
+ RETROACTIVE_FUNDING_CONTRACT: {
153
158
  address: '0xDe5aE4De36c966747Ea7DF13BD9589642e2B1D0d',
154
159
  bytecode: '',
155
160
  },
161
+ // OVM and SplitV2 Contract Addresses
162
+ OVM_FACTORY_CONTRACT: {
163
+ address: '0xdfe2d8b26806583cf03b3cb623b0752f8670e93e',
164
+ bytecode: bytecodes_1.MAINNET_OVM_FACTORY_BYTECODE,
165
+ },
166
+ WAREHOUSE_CONTRACT: {
167
+ address: '0x8fb66F38cF86A3d5e8768f8F1754A24A6c661Fb8',
168
+ bytecode: bytecodes_1.MAINNET_WAREHOUSE_BYTECODE,
169
+ },
170
+ SPLIT_V2_FACTORY_CONTRACT: {
171
+ address: '0x5cbA88D55Cec83caD5A105Ad40C8c9aF20bE21d1',
172
+ bytecode: bytecodes_1.MAINNET_SPLIT_V2_FACTORY_BYTECODE,
173
+ },
156
174
  },
157
- [exports.AVAILABLE_SPLITTER_CHAINS[1]]: {
158
- SPLITMAIN_ADDRESS: {
175
+ [types_1.FORK_MAPPING['0x01017000']]: {
176
+ SPLITMAIN_CONTRACT: {
159
177
  address: '0xfC8a305728051367797DADE6Aa0344E0987f5286',
160
178
  bytecode: bytecodes_1.HOLESKY_SPLITMAIN_BYTECODE,
161
179
  },
162
- MULTICALL_ADDRESS: {
180
+ MULTICALL_CONTRACT: {
163
181
  address: '0xcA11bde05977b3631167028862bE2a173976CA11',
164
182
  bytecode: bytecodes_1.HOLESKY_MULTICALL_BYTECODE,
165
183
  },
166
- OWR_FACTORY_ADDRESS: {
184
+ OWR_FACTORY_CONTRACT: {
167
185
  address: '0xc0961353fcc43a99e3041db07ac646720e116256',
168
186
  bytecode: bytecodes_1.HOLESKY_OWR_FACTORY_BYTECODE,
169
187
  },
170
- RETROACTIVE_FUNDING_ADDRESS: {
188
+ RETROACTIVE_FUNDING_CONTRACT: {
189
+ address: '0x43F641fA70e09f0326ac66b4Ef0C416EaEcBC6f5',
190
+ bytecode: '',
191
+ },
192
+ },
193
+ [types_1.FORK_MAPPING['0x10000910']]: {
194
+ SPLITMAIN_CONTRACT: {
195
+ address: '0xc05ae267291705ac16F75283572294ed2a91CBc7',
196
+ bytecode: bytecodes_1.HOODI_SPLITMAIN_BYTECODE,
197
+ },
198
+ MULTICALL_CONTRACT: {
199
+ address: '0xcA11bde05977b3631167028862bE2a173976CA11',
200
+ bytecode: bytecodes_1.HOODI_MULTICALL_BYTECODE,
201
+ },
202
+ OWR_FACTORY_CONTRACT: {
203
+ address: '0x9ff0c649d0bf5fe7efa4d72e94bed7302ed5c8d7',
204
+ bytecode: bytecodes_1.HOODI_OWR_FACTORY_BYTECODE,
205
+ },
206
+ RETROACTIVE_FUNDING_CONTRACT: {
171
207
  address: '0x43F641fA70e09f0326ac66b4Ef0C416EaEcBC6f5',
172
208
  bytecode: '',
173
209
  },
210
+ // OVM and SplitV2 Contract Addresses
211
+ OVM_FACTORY_CONTRACT: {
212
+ address: '0x6F13d929C783a420AE4DC71C1dcc27A02038Ed09',
213
+ bytecode: bytecodes_1.HOODI_OVM_FACTORY_BYTECODE,
214
+ },
215
+ WAREHOUSE_CONTRACT: {
216
+ address: '0x8fb66F38cF86A3d5e8768f8F1754A24A6c661Fb8',
217
+ bytecode: bytecodes_1.HOODI_WAREHOUSE_BYTECODE,
218
+ },
219
+ SPLIT_V2_FACTORY_CONTRACT: {
220
+ address: '0x5cbA88D55Cec83caD5A105Ad40C8c9aF20bE21d1',
221
+ bytecode: bytecodes_1.HOODI_SPLIT_V2_FACTORY_BYTECODE,
222
+ },
174
223
  },
175
224
  };
176
225
  exports.DEFAULT_RETROACTIVE_FUNDING_REWARDS_ONLY_SPLIT = 1;
177
226
  exports.DEFAULT_RETROACTIVE_FUNDING_TOTAL_SPLIT = 0.1;
227
+ // OVM and SplitV2 Default Constants
228
+ exports.SPLITS_V2_SALT = '0x2fa740d39f3b04b2c7ef4e9f9e1a6e38f4c72c1a91d8595d5d31a3adf17c6b12';
229
+ exports.PRINCIPAL_THRESHOLD = 16;
178
230
  exports.OBOL_SDK_EMAIL = 'sdk@dvlabs.tech';
179
231
  exports.PROVIDER_MAP = {
180
232
  1: `${process.env.RPC_MAINNET}`, // Mainnet
@@ -194,3 +246,7 @@ exports.CAPELLA_FORK_MAPPING = {
194
246
  '0x01017000': '0x04017000', // Holesky
195
247
  '0x10000910': '0x40000910', // Hoodi
196
248
  };
249
+ exports.CHAIN_PUBLIC_RPC_URL = {
250
+ 1: 'https://ethereum-rpc.publicnode.com', // Mainnet
251
+ 560048: 'https://ethereum-hoodi-rpc.publicnode.com', // Hoodi
252
+ };
@@ -23,7 +23,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
23
23
  });
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.Client = exports.Exit = exports.Incentives = void 0;
26
+ exports.Client = exports.ObolSplits = exports.Exit = exports.Incentives = void 0;
27
27
  const uuid_1 = require("uuid");
28
28
  const base_js_1 = require("./base.js");
29
29
  const constants_js_1 = require("./constants.js");
@@ -35,6 +35,7 @@ const splitHelpers_js_1 = require("./splits/splitHelpers.js");
35
35
  const utils_js_1 = require("./utils.js");
36
36
  const incentives_js_1 = require("./incentives/incentives.js");
37
37
  const exit_js_1 = require("./exits/exit.js");
38
+ const splits_js_1 = require("./splits/splits.js");
38
39
  __exportStar(require("./types.js"), exports);
39
40
  __exportStar(require("./services.js"), exports);
40
41
  __exportStar(require("./verification/signature-validator.js"), exports);
@@ -44,6 +45,8 @@ var incentives_js_2 = require("./incentives/incentives.js");
44
45
  Object.defineProperty(exports, "Incentives", { enumerable: true, get: function () { return incentives_js_2.Incentives; } });
45
46
  var exit_js_2 = require("./exits/exit.js");
46
47
  Object.defineProperty(exports, "Exit", { enumerable: true, get: function () { return exit_js_2.Exit; } });
48
+ var splits_js_2 = require("./splits/splits.js");
49
+ Object.defineProperty(exports, "ObolSplits", { enumerable: true, get: function () { return splits_js_2.ObolSplits; } });
47
50
  /**
48
51
  * Obol sdk Client can be used for creating, managing and activating distributed validators.
49
52
  */
@@ -66,6 +69,7 @@ class Client extends base_js_1.Base {
66
69
  provider !== null && provider !== void 0 ? provider : (signer && 'provider' in signer ? signer.provider : undefined);
67
70
  this.incentives = new incentives_js_1.Incentives(this.signer, this.chainId, this.request.bind(this), this.provider);
68
71
  this.exit = new exit_js_1.Exit(this.chainId, this.provider);
72
+ this.splits = new splits_js_1.ObolSplits(this.signer, this.chainId, this.provider);
69
73
  }
70
74
  /**
71
75
  * Accepts Obol terms and conditions to be able to create or update data.
@@ -140,19 +144,23 @@ class Client extends base_js_1.Base {
140
144
  recoveryAddress,
141
145
  }, schema_js_1.rewardsSplitterPayloadSchema);
142
146
  // Check if we allow splitters on this chainId
143
- if (!constants_js_1.AVAILABLE_SPLITTER_CHAINS.includes(this.chainId)) {
147
+ if (!(0, constants_js_1.isChainSupportedForSplitters)(this.chainId)) {
144
148
  throw new Error(`Splitter configuration is not supported on ${this.chainId} chain`);
145
149
  }
146
- const checkSplitMainAddress = yield (0, utils_js_1.isContractAvailable)(constants_js_1.CHAIN_CONFIGURATION[this.chainId].SPLITMAIN_ADDRESS.address, this.signer.provider, constants_js_1.CHAIN_CONFIGURATION[this.chainId].SPLITMAIN_ADDRESS.bytecode);
147
- const checkMulticallAddress = yield (0, utils_js_1.isContractAvailable)(constants_js_1.CHAIN_CONFIGURATION[this.chainId].MULTICALL_ADDRESS.address, this.signer.provider, constants_js_1.CHAIN_CONFIGURATION[this.chainId].MULTICALL_ADDRESS.bytecode);
148
- const checkOWRFactoryAddress = yield (0, utils_js_1.isContractAvailable)(constants_js_1.CHAIN_CONFIGURATION[this.chainId].OWR_FACTORY_ADDRESS.address, this.signer.provider, constants_js_1.CHAIN_CONFIGURATION[this.chainId].OWR_FACTORY_ADDRESS.bytecode);
150
+ const chainConfig = constants_js_1.CHAIN_CONFIGURATION[this.chainId];
151
+ if (!(chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLITMAIN_CONTRACT)) {
152
+ throw new Error(`SPLITMAIN_CONTRACT is not configured for chain ${this.chainId}`);
153
+ }
154
+ const checkSplitMainAddress = yield (0, utils_js_1.isContractAvailable)(chainConfig.SPLITMAIN_CONTRACT.address, this.signer.provider, chainConfig.SPLITMAIN_CONTRACT.bytecode);
155
+ const checkMulticallAddress = yield (0, utils_js_1.isContractAvailable)(chainConfig.MULTICALL_CONTRACT.address, this.signer.provider, chainConfig.MULTICALL_CONTRACT.bytecode);
156
+ const checkOWRFactoryAddress = yield (0, utils_js_1.isContractAvailable)(chainConfig.OWR_FACTORY_CONTRACT.address, this.signer.provider, chainConfig.OWR_FACTORY_CONTRACT.bytecode);
149
157
  if (!checkMulticallAddress ||
150
158
  !checkSplitMainAddress ||
151
159
  !checkOWRFactoryAddress) {
152
160
  throw new Error(`Something isn not working as expected, check this issue with obol-sdk team on ${constants_js_1.OBOL_SDK_EMAIL}`);
153
161
  }
154
162
  const retroActiveFundingRecipient = {
155
- account: constants_js_1.CHAIN_CONFIGURATION[this.chainId].RETROACTIVE_FUNDING_ADDRESS.address,
163
+ account: chainConfig.RETROACTIVE_FUNDING_CONTRACT.address,
156
164
  percentAllocation: validatedPayload.ObolRAFSplit,
157
165
  };
158
166
  const copiedSplitRecipients = [...validatedPayload.splitRecipients];
@@ -210,15 +218,19 @@ class Client extends base_js_1.Base {
210
218
  controllerAddress,
211
219
  }, schema_js_1.totalSplitterPayloadSchema);
212
220
  // Check if we allow splitters on this chainId
213
- if (!constants_js_1.AVAILABLE_SPLITTER_CHAINS.includes(this.chainId)) {
221
+ if (!(0, constants_js_1.isChainSupportedForSplitters)(this.chainId)) {
214
222
  throw new Error(`Splitter configuration is not supported on ${this.chainId} chain`);
215
223
  }
216
- const checkSplitMainAddress = yield (0, utils_js_1.isContractAvailable)(constants_js_1.CHAIN_CONFIGURATION[this.chainId].SPLITMAIN_ADDRESS.address, this.signer.provider, constants_js_1.CHAIN_CONFIGURATION[this.chainId].SPLITMAIN_ADDRESS.bytecode);
224
+ const chainConfig = constants_js_1.CHAIN_CONFIGURATION[this.chainId];
225
+ if (!(chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLITMAIN_CONTRACT)) {
226
+ throw new Error(`SPLITMAIN_CONTRACT is not configured for chain ${this.chainId}`);
227
+ }
228
+ const checkSplitMainAddress = yield (0, utils_js_1.isContractAvailable)(chainConfig.SPLITMAIN_CONTRACT.address, this.signer.provider, chainConfig.SPLITMAIN_CONTRACT.bytecode);
217
229
  if (!checkSplitMainAddress) {
218
230
  throw new Error(`Something isn not working as expected, check this issue with obol-sdk team on ${constants_js_1.OBOL_SDK_EMAIL}`);
219
231
  }
220
232
  const retroActiveFundingRecipient = {
221
- account: constants_js_1.CHAIN_CONFIGURATION[this.chainId].RETROACTIVE_FUNDING_ADDRESS.address,
233
+ account: chainConfig.RETROACTIVE_FUNDING_CONTRACT.address,
222
234
  percentAllocation: validatedPayload.ObolRAFSplit,
223
235
  };
224
236
  const copiedSplitRecipients = [...validatedPayload.splitRecipients];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rewardsSplitterPayloadSchema = exports.totalSplitterPayloadSchema = exports.definitionSchema = exports.operatorPayloadSchema = void 0;
3
+ exports.ovmTotalSplitPayloadSchema = exports.ovmRewardsSplitPayloadSchema = exports.ovmBaseSplitPayload = exports.rewardsSplitterPayloadSchema = exports.totalSplitterPayloadSchema = exports.definitionSchema = exports.operatorPayloadSchema = void 0;
4
4
  const ethers_1 = require("ethers");
5
5
  const constants_1 = require("./constants");
6
6
  const ajv_1 = require("./ajv");
@@ -140,3 +140,72 @@ exports.rewardsSplitterPayloadSchema = {
140
140
  validateRewardsSplitRecipients: true,
141
141
  required: ['splitRecipients', 'principalRecipient', 'etherAmount'],
142
142
  };
143
+ exports.ovmBaseSplitPayload = {
144
+ rewardSplitRecipients: {
145
+ type: 'array',
146
+ items: {
147
+ type: 'object',
148
+ properties: {
149
+ address: {
150
+ type: 'string',
151
+ pattern: '^0x[a-fA-F0-9]{40}$',
152
+ },
153
+ percentAllocation: { type: 'number' },
154
+ },
155
+ required: ['address', 'percentAllocation'],
156
+ },
157
+ },
158
+ OVMOwnerAddress: {
159
+ type: 'string',
160
+ pattern: '^0x[a-fA-F0-9]{40}$',
161
+ },
162
+ splitOwnerAddress: {
163
+ type: 'string',
164
+ pattern: '^0x[a-fA-F0-9]{40}$',
165
+ default: ethers_1.ZeroAddress,
166
+ },
167
+ principalThreshold: {
168
+ type: 'number',
169
+ minimum: 16,
170
+ default: constants_1.PRINCIPAL_THRESHOLD,
171
+ },
172
+ distributorFeePercent: {
173
+ type: 'number',
174
+ minimum: 0,
175
+ maximum: 10,
176
+ default: 0,
177
+ },
178
+ };
179
+ exports.ovmRewardsSplitPayloadSchema = {
180
+ type: 'object',
181
+ properties: Object.assign(Object.assign({}, exports.ovmBaseSplitPayload), { principalRecipient: {
182
+ type: 'string',
183
+ pattern: '^0x[a-fA-F0-9]{40}$',
184
+ } }),
185
+ validateOVMRewardsSplitRecipients: true,
186
+ required: ['rewardSplitRecipients', 'OVMOwnerAddress', 'principalRecipient'],
187
+ };
188
+ exports.ovmTotalSplitPayloadSchema = {
189
+ type: 'object',
190
+ properties: Object.assign(Object.assign({}, exports.ovmBaseSplitPayload), { principalSplitRecipients: {
191
+ type: 'array',
192
+ items: {
193
+ type: 'object',
194
+ properties: {
195
+ address: {
196
+ type: 'string',
197
+ pattern: '^0x[a-fA-F0-9]{40}$',
198
+ },
199
+ percentAllocation: { type: 'number' },
200
+ },
201
+ required: ['address', 'percentAllocation'],
202
+ },
203
+ } }),
204
+ validateOVMRewardsSplitRecipients: true,
205
+ validateOVMTotalSplitRecipients: true,
206
+ required: [
207
+ 'rewardSplitRecipients',
208
+ 'principalSplitRecipients',
209
+ 'OVMOwnerAddress',
210
+ ],
211
+ };
@@ -9,20 +9,37 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.multicall = exports.getOWRTranches = exports.deploySplitterAndOWRContracts = exports.deploySplitterContract = exports.handleDeployOWRAndSplitter = exports.predictSplitterAddress = exports.formatSplitRecipients = void 0;
12
+ exports.deployOVMAndSplitV2 = exports.deployOVMContract = exports.isSplitV2Deployed = exports.predictSplitV2Address = exports.formatRecipientsForSplitV2 = exports.multicall = exports.getOWRTranches = exports.deploySplitterAndOWRContracts = exports.deploySplitterContract = exports.handleDeployOWRAndSplitter = exports.predictSplitterAddress = exports.formatSplitRecipients = void 0;
13
13
  const ethers_1 = require("ethers");
14
14
  const OWR_1 = require("../abi/OWR");
15
+ const OVMFactory_1 = require("../abi/OVMFactory");
15
16
  const SplitMain_1 = require("../abi/SplitMain");
16
17
  const Multicall_1 = require("../abi/Multicall");
17
18
  const constants_1 = require("../constants");
19
+ const splitV2FactoryAbi_1 = require("../abi/splitV2FactoryAbi");
18
20
  const splitMainContractInterface = new ethers_1.Interface(SplitMain_1.splitMainEthereumAbi);
19
21
  const owrFactoryContractInterface = new ethers_1.Interface(OWR_1.OWRFactoryContract.abi);
20
- const formatSplitRecipients = (recipients) => {
22
+ const ovmFactoryContractInterface = new ethers_1.Interface(OVMFactory_1.OVMFactoryContract.abi);
23
+ const splitV2FactoryInterface = new ethers_1.Interface(splitV2FactoryAbi_1.splitV2FactoryAbi);
24
+ // Helper function to extract common recipient formatting logic
25
+ const formatRecipientsCommon = (recipients) => {
26
+ const copiedRecipients = [...recipients];
27
+ // Handle both SplitRecipient and SplitV2Recipient types
28
+ const getAddress = (item) => item.account || item.address;
29
+ const getPercentAllocation = (item) => item.percentAllocation;
21
30
  // Has to be sorted when passed
22
- recipients.sort((a, b) => a.account.localeCompare(b.account));
23
- const accounts = recipients.map(item => item.account);
24
- const percentAllocations = recipients.map(recipient => {
25
- const splitTostring = (recipient.percentAllocation * 1e4).toFixed(0);
31
+ copiedRecipients.sort((a, b) => getAddress(a).localeCompare(getAddress(b)));
32
+ return {
33
+ sortedRecipients: copiedRecipients,
34
+ getAddress,
35
+ getPercentAllocation,
36
+ };
37
+ };
38
+ const formatSplitRecipients = (recipients) => {
39
+ const { sortedRecipients, getAddress, getPercentAllocation } = formatRecipientsCommon(recipients);
40
+ const accounts = sortedRecipients.map(item => getAddress(item));
41
+ const percentAllocations = sortedRecipients.map(recipient => {
42
+ const splitTostring = (getPercentAllocation(recipient) * 1e4).toFixed(0);
26
43
  return parseInt(splitTostring);
27
44
  });
28
45
  return { accounts, percentAllocations };
@@ -31,7 +48,7 @@ exports.formatSplitRecipients = formatSplitRecipients;
31
48
  const predictSplitterAddress = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
32
49
  var _a, _b, _c;
33
50
  try {
34
- const splitMainContractInstance = new ethers_1.Contract(constants_1.CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address, SplitMain_1.splitMainEthereumAbi, signer);
51
+ const splitMainContractInstance = new ethers_1.Contract(getChainConfig(chainId).SPLITMAIN_CONTRACT.address, SplitMain_1.splitMainEthereumAbi, signer);
35
52
  let predictedSplitterAddress;
36
53
  if (controllerAddress === ethers_1.ZeroAddress) {
37
54
  try {
@@ -134,7 +151,7 @@ exports.handleDeployOWRAndSplitter = handleDeployOWRAndSplitter;
134
151
  const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
135
152
  var _g, _h, _j, _k, _l;
136
153
  try {
137
- const OWRFactoryInstance = new ethers_1.Contract(constants_1.CHAIN_CONFIGURATION[chainId].OWR_FACTORY_ADDRESS.address, OWR_1.OWRFactoryContract.abi, signer);
154
+ const OWRFactoryInstance = new ethers_1.Contract(getChainConfig(chainId).OWR_FACTORY_CONTRACT.address, OWR_1.OWRFactoryContract.abi, signer);
138
155
  let tx;
139
156
  try {
140
157
  tx = yield OWRFactoryInstance.createOWRecipient(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, (0, ethers_1.parseEther)(owrArgs.amountOfPrincipalStake.toString()));
@@ -178,7 +195,7 @@ const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, v
178
195
  const deploySplitterContract = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
179
196
  var _m, _o, _p, _q, _r;
180
197
  try {
181
- const splitMainContractInstance = new ethers_1.Contract(constants_1.CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address, SplitMain_1.splitMainEthereumAbi, signer);
198
+ const splitMainContractInstance = new ethers_1.Contract(getChainConfig(chainId).SPLITMAIN_CONTRACT.address, SplitMain_1.splitMainEthereumAbi, signer);
182
199
  let tx;
183
200
  try {
184
201
  tx = yield splitMainContractInstance.createSplit(accounts, percentAllocations, distributorFee, controllerAddress);
@@ -226,14 +243,13 @@ const deploySplitterAndOWRContracts = ({ owrArgs, splitterArgs, signer, chainId,
226
243
  const splitTxData = encodeCreateSplitTxData(splitterArgs.accounts, splitterArgs.percentAllocations, splitterArgs.distributorFee, splitterArgs.controllerAddress);
227
244
  const owrTxData = encodeCreateOWRecipientTxData(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, owrArgs.amountOfPrincipalStake);
228
245
  executeCalls.push({
229
- target: constants_1.CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address,
246
+ target: getChainConfig(chainId).SPLITMAIN_CONTRACT.address,
230
247
  callData: splitTxData,
231
248
  }, {
232
- target: constants_1.CHAIN_CONFIGURATION[chainId].OWR_FACTORY_ADDRESS.address,
249
+ target: getChainConfig(chainId).OWR_FACTORY_CONTRACT.address,
233
250
  callData: owrTxData,
234
251
  });
235
- const multicallAddess = constants_1.CHAIN_CONFIGURATION[chainId].MULTICALL_ADDRESS.address;
236
- const executeMultiCalls = yield (0, exports.multicall)(executeCalls, signer, multicallAddess);
252
+ const executeMultiCalls = yield (0, exports.multicall)(executeCalls, signer, chainId);
237
253
  const splitAddressData = (_s = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[0]) === null || _s === void 0 ? void 0 : _s.topics[1];
238
254
  const formattedSplitterAddress = '0x' + (splitAddressData === null || splitAddressData === void 0 ? void 0 : splitAddressData.slice(26, 66));
239
255
  const owrAddressData = (_t = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[1]) === null || _t === void 0 ? void 0 : _t.topics[1];
@@ -275,9 +291,11 @@ const getOWRTranches = ({ owrAddress, signer, }) => __awaiter(void 0, void 0, vo
275
291
  }
276
292
  });
277
293
  exports.getOWRTranches = getOWRTranches;
278
- const multicall = (calls, signer, multicallAddress) => __awaiter(void 0, void 0, void 0, function* () {
294
+ const multicall = (calls, signer, chainId) => __awaiter(void 0, void 0, void 0, function* () {
279
295
  var _w, _x, _y;
280
296
  try {
297
+ const chainConfig = getChainConfig(chainId);
298
+ const multicallAddress = chainConfig.MULTICALL_CONTRACT.address;
281
299
  const multiCallContractInstance = new ethers_1.Contract(multicallAddress, Multicall_1.MultiCallContract.abi, signer);
282
300
  let tx;
283
301
  try {
@@ -325,3 +343,159 @@ const encodeCreateOWRecipientTxData = (recoveryAddress, principalRecipient, rewa
325
343
  (0, ethers_1.parseEther)(amountOfPrincipalStake.toString()),
326
344
  ]);
327
345
  };
346
+ // OVM and SplitV2 Helper Functions
347
+ // Helper function to format recipients specifically for SplitV2 (returns SplitV2Recipient[])
348
+ const formatRecipientsForSplitV2 = (splitRecipients) => {
349
+ const { sortedRecipients, getAddress, getPercentAllocation } = formatRecipientsCommon(splitRecipients);
350
+ return sortedRecipients
351
+ .filter(item => getAddress(item) !== '')
352
+ .map(item => ({
353
+ address: getAddress(item),
354
+ percentAllocation: parseFloat(getPercentAllocation(item).toString()),
355
+ }));
356
+ };
357
+ exports.formatRecipientsForSplitV2 = formatRecipientsForSplitV2;
358
+ // Helper function to create SplitV2 parameters
359
+ const createSplitV2Params = (recipients, distributorFeePercent) => {
360
+ const addresses = recipients.map(r => r.address);
361
+ const allocations = recipients.map(r => Math.floor(r.percentAllocation * 1e4)); // Convert to basis points
362
+ const totalAllocation = allocations.reduce((sum, allocation) => sum + allocation, 0);
363
+ return {
364
+ recipients: addresses,
365
+ allocations,
366
+ totalAllocation,
367
+ distributionIncentive: distributorFeePercent,
368
+ };
369
+ };
370
+ const predictSplitV2Address = ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
371
+ var _z, _0;
372
+ try {
373
+ const chainConfig = getChainConfig(chainId);
374
+ if (!((_z = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLIT_V2_FACTORY_CONTRACT) === null || _z === void 0 ? void 0 : _z.address)) {
375
+ throw new Error(`SplitV2 Factory not configured for chain ${chainId}`);
376
+ }
377
+ const splitV2FactoryContract = new ethers_1.Contract(chainConfig.SPLIT_V2_FACTORY_CONTRACT.address, splitV2FactoryAbi_1.splitV2FactoryAbi, signer);
378
+ const splitParams = createSplitV2Params(recipients, distributorFeePercent);
379
+ const predictedAddress = yield splitV2FactoryContract['predictDeterministicAddress((address[],uint256[],uint256,uint16),address,bytes32)'](splitParams, splitOwnerAddress, salt);
380
+ return predictedAddress;
381
+ }
382
+ catch (error) {
383
+ throw new Error(`Failed to predict SplitV2 address: ${(_0 = error.message) !== null && _0 !== void 0 ? _0 : 'SplitV2 contract call failed'}`);
384
+ }
385
+ });
386
+ exports.predictSplitV2Address = predictSplitV2Address;
387
+ const isSplitV2Deployed = ({ splitOwnerAddress, recipients, distributorFeePercent, salt, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
388
+ var _1;
389
+ try {
390
+ const chainConfig = getChainConfig(chainId);
391
+ if (!((_1 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLIT_V2_FACTORY_CONTRACT) === null || _1 === void 0 ? void 0 : _1.address)) {
392
+ throw new Error(`SplitV2 Factory not configured for chain ${chainId}`);
393
+ }
394
+ const splitV2FactoryContract = new ethers_1.Contract(chainConfig.SPLIT_V2_FACTORY_CONTRACT.address, splitV2FactoryAbi_1.splitV2FactoryAbi, signer);
395
+ const splitParams = createSplitV2Params(recipients, distributorFeePercent);
396
+ const [, exists] = yield splitV2FactoryContract.isDeployed(splitParams, splitOwnerAddress, salt);
397
+ return exists;
398
+ }
399
+ catch (error) {
400
+ // If the check fails, assume it's not deployed
401
+ return false;
402
+ }
403
+ });
404
+ exports.isSplitV2Deployed = isSplitV2Deployed;
405
+ const deployOVMContract = ({ OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
406
+ var _2, _3, _4;
407
+ try {
408
+ const chainConfig = getChainConfig(chainId);
409
+ if (!((_2 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.OVM_FACTORY_CONTRACT) === null || _2 === void 0 ? void 0 : _2.address)) {
410
+ throw new Error(`OVM Factory not configured for chain ${chainId}`);
411
+ }
412
+ const ovmFactoryContract = new ethers_1.Contract(chainConfig.OVM_FACTORY_CONTRACT.address, OVMFactory_1.OVMFactoryContract.abi, signer);
413
+ const tx = yield ovmFactoryContract.createObolValidatorManager(OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold);
414
+ const receipt = yield tx.wait();
415
+ // Extract OVM address from logs
416
+ const ovmAddressLog = (_3 = receipt === null || receipt === void 0 ? void 0 : receipt.logs[1]) === null || _3 === void 0 ? void 0 : _3.topics[1];
417
+ if (!ovmAddressLog) {
418
+ throw new Error('Failed to extract OVM address from transaction logs');
419
+ }
420
+ const ovmAddress = '0x' + ovmAddressLog.slice(26, 66);
421
+ return ovmAddress;
422
+ }
423
+ catch (error) {
424
+ throw new Error(`Failed to deploy OVM contract: ${(_4 = error.message) !== null && _4 !== void 0 ? _4 : 'OVM deployment failed'}`);
425
+ }
426
+ });
427
+ exports.deployOVMContract = deployOVMContract;
428
+ const deployOVMAndSplitV2 = ({ ovmArgs, rewardRecipients, isRewardsSplitterDeployed, distributorFeePercent, salt, signer, chainId, principalSplitRecipients, isPrincipalSplitDeployed, splitOwnerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
429
+ var _5, _6, _7, _8, _9, _10, _11, _12, _13, _14;
430
+ try {
431
+ const chainConfig = getChainConfig(chainId);
432
+ if (!((_5 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.OVM_FACTORY_CONTRACT) === null || _5 === void 0 ? void 0 : _5.address)) {
433
+ throw new Error(`OVM Factory not configured for chain ${chainId}`);
434
+ }
435
+ if (!((_6 = chainConfig === null || chainConfig === void 0 ? void 0 : chainConfig.SPLIT_V2_FACTORY_CONTRACT) === null || _6 === void 0 ? void 0 : _6.address)) {
436
+ throw new Error(`SplitV2 Factory not configured for chain ${chainId}`);
437
+ }
438
+ const executeCalls = [];
439
+ if (rewardRecipients && !isRewardsSplitterDeployed) {
440
+ // Create rewards split call data
441
+ const splitParams = createSplitV2Params(rewardRecipients, distributorFeePercent);
442
+ const rewardsSplitTxData = encodeCreateSplitV2DeterministicTxData(splitParams, splitOwnerAddress, salt);
443
+ executeCalls.push({
444
+ target: chainConfig.SPLIT_V2_FACTORY_CONTRACT.address,
445
+ callData: rewardsSplitTxData,
446
+ });
447
+ }
448
+ // Create principal split call data if needed (for total split scenario)
449
+ if (principalSplitRecipients && !isPrincipalSplitDeployed) {
450
+ const principalSplitParams = createSplitV2Params(principalSplitRecipients, distributorFeePercent);
451
+ const principalSplitTxData = encodeCreateSplitV2DeterministicTxData(principalSplitParams, splitOwnerAddress, salt);
452
+ executeCalls.push({
453
+ target: chainConfig.SPLIT_V2_FACTORY_CONTRACT.address,
454
+ callData: principalSplitTxData,
455
+ });
456
+ }
457
+ // Create OVM call data
458
+ const ovmTxData = encodeCreateOVMTxData(ovmArgs.OVMOwnerAddress, ovmArgs.principalRecipient, ovmArgs.rewardRecipient, ovmArgs.principalThreshold);
459
+ executeCalls.push({
460
+ target: chainConfig.OVM_FACTORY_CONTRACT.address,
461
+ callData: ovmTxData,
462
+ });
463
+ // Execute multicall
464
+ const executeMultiCalls = yield (0, exports.multicall)(executeCalls, signer, chainId);
465
+ // Extract addresses from events
466
+ let ovmAddress;
467
+ const logsCount = ((_7 = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs) === null || _7 === void 0 ? void 0 : _7.length) || 0;
468
+ if (logsCount === 2) {
469
+ 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));
470
+ }
471
+ else if (logsCount === 5) {
472
+ 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));
473
+ }
474
+ else {
475
+ 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));
476
+ }
477
+ if (!ovmAddress) {
478
+ throw new Error('Failed to extract contract addresses from multicall events');
479
+ }
480
+ return ovmAddress;
481
+ }
482
+ catch (error) {
483
+ throw new Error(`Failed to deploy OVM and SplitV2: ${(_14 = error.message) !== null && _14 !== void 0 ? _14 : 'Deployment failed'}`);
484
+ }
485
+ });
486
+ exports.deployOVMAndSplitV2 = deployOVMAndSplitV2;
487
+ const encodeCreateOVMTxData = (OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold) => {
488
+ return ovmFactoryContractInterface.encodeFunctionData('createObolValidatorManager', [OVMOwnerAddress, principalRecipient, rewardRecipient, principalThreshold]);
489
+ };
490
+ const encodeCreateSplitV2DeterministicTxData = (splitParams, splitOwnerAddress, salt) => {
491
+ // creatorAddress can be kept as default https://docs.splits.org/sdk/splits-v2#createsplit
492
+ return splitV2FactoryInterface.encodeFunctionData('createSplitDeterministic', [splitParams, splitOwnerAddress, ethers_1.ZeroAddress, salt]);
493
+ };
494
+ // Helper function to safely get chain configuration
495
+ const getChainConfig = (chainId) => {
496
+ const config = constants_1.CHAIN_CONFIGURATION[chainId];
497
+ if (!config) {
498
+ throw new Error(`Chain configuration not found for chain ID ${chainId}`);
499
+ }
500
+ return config;
501
+ };