@obolnetwork/obol-sdk 2.5.1 → 2.6.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 +3 -3
- package/dist/cjs/src/constants.js +13 -1
- package/dist/cjs/src/exits/ethUtils.js +57 -0
- package/dist/cjs/src/exits/exit.js +420 -0
- package/dist/cjs/src/exits/verificationHelpers.js +86 -0
- package/dist/cjs/src/{incentiveHelpers.js → incentives/incentiveHelpers.js} +1 -1
- package/dist/cjs/src/{incentives.js → incentives/incentives.js} +3 -3
- package/dist/cjs/src/index.js +22 -4
- package/dist/cjs/src/splits/splitHelpers.js +327 -0
- package/dist/cjs/src/types.js +1 -0
- package/dist/cjs/test/exit/ethUtils.spec.js +83 -0
- package/dist/cjs/test/exit/exit.spec.js +328 -0
- package/dist/cjs/test/exit/verificationHelpers.spec.js +68 -0
- package/dist/cjs/test/{incentives.test.js → incentives/incentives.spec.js} +4 -4
- package/dist/esm/package.json +3 -3
- package/dist/esm/src/constants.js +12 -0
- package/dist/esm/src/exits/ethUtils.js +52 -0
- package/dist/esm/src/exits/exit.js +393 -0
- package/dist/esm/src/exits/verificationHelpers.js +81 -0
- package/dist/esm/src/{incentiveHelpers.js → incentives/incentiveHelpers.js} +1 -1
- package/dist/esm/src/{incentives.js → incentives/incentives.js} +3 -3
- package/dist/esm/src/index.js +20 -3
- package/dist/esm/src/splits/splitHelpers.js +317 -0
- package/dist/esm/src/types.js +1 -0
- package/dist/esm/test/exit/ethUtils.spec.js +81 -0
- package/dist/esm/test/exit/exit.spec.js +303 -0
- package/dist/esm/test/exit/verificationHelpers.spec.js +66 -0
- package/dist/esm/test/{incentives.test.js → incentives/incentives.spec.js} +4 -4
- package/dist/types/src/constants.d.ts +5 -0
- package/dist/types/src/exits/ethUtils.d.ts +13 -0
- package/dist/types/src/exits/exit.d.ts +180 -0
- package/dist/types/src/exits/verificationHelpers.d.ts +20 -0
- package/dist/types/src/{incentiveHelpers.d.ts → incentives/incentiveHelpers.d.ts} +1 -1
- package/dist/types/src/{incentives.d.ts → incentives/incentives.d.ts} +1 -1
- package/dist/types/src/index.d.ts +16 -2
- package/dist/types/src/{splitHelpers.d.ts → splits/splitHelpers.d.ts} +1 -1
- package/dist/types/src/types.d.ts +98 -0
- package/dist/types/test/exit/verificationHelpers.spec.d.ts +1 -0
- package/dist/types/test/incentives/incentives.spec.d.ts +1 -0
- package/package.json +3 -3
- package/src/constants.ts +13 -0
- package/src/exits/ethUtils.ts +49 -0
- package/src/exits/exit.ts +564 -0
- package/src/exits/verificationHelpers.ts +110 -0
- package/src/{incentiveHelpers.ts → incentives/incentiveHelpers.ts} +2 -2
- package/src/{incentives.ts → incentives/incentives.ts} +3 -3
- package/src/index.ts +29 -3
- package/src/splits/splitHelpers.ts +557 -0
- package/src/types.ts +123 -0
- package/dist/cjs/src/splitHelpers.js +0 -187
- package/dist/cjs/test/methods.test.js +0 -418
- package/dist/esm/src/splitHelpers.js +0 -177
- package/dist/esm/test/methods.test.js +0 -393
- package/src/splitHelpers.ts +0 -355
- /package/dist/types/test/{incentives.test.d.ts → exit/ethUtils.spec.d.ts} +0 -0
- /package/dist/types/test/{methods.test.d.ts → exit/exit.spec.d.ts} +0 -0
package/src/types.ts
CHANGED
|
@@ -352,3 +352,126 @@ export type SignerType = Signer | JsonRpcSigner | Wallet;
|
|
|
352
352
|
* claimIncentives Response
|
|
353
353
|
*/
|
|
354
354
|
export type ClaimIncentivesResponse = { txHash: string | null };
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Represents the structure of an Ethereum operator for exit validation, primarily their ENR.
|
|
358
|
+
*/
|
|
359
|
+
export interface ExitOperator {
|
|
360
|
+
/** The operator's Ethereum Node Record (ENR). */
|
|
361
|
+
enr: string;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Represents the core definition of a cluster relevant for exit validation.
|
|
366
|
+
*/
|
|
367
|
+
export interface ExitClusterDefinition {
|
|
368
|
+
/** The cluster nodes operators with their ENRs. */
|
|
369
|
+
operators: ExitOperator[];
|
|
370
|
+
|
|
371
|
+
/** The cluster fork version. */
|
|
372
|
+
fork_version: string;
|
|
373
|
+
|
|
374
|
+
/** The distributed validator threshold. */
|
|
375
|
+
threshold: number;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Represents a distributed validator's information relevant for exit validation.
|
|
380
|
+
*/
|
|
381
|
+
export interface ExitDistributedValidator {
|
|
382
|
+
/** The public key of the distributed validator. */
|
|
383
|
+
distributed_public_key: string;
|
|
384
|
+
|
|
385
|
+
/** The public key shares of the distributed validator. */
|
|
386
|
+
public_shares: string[];
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Combined cluster information needed for exit validation in the SDK.
|
|
391
|
+
*/
|
|
392
|
+
export interface ExitClusterConfig {
|
|
393
|
+
/** The cluster definition with operators, fork version and threshold. */
|
|
394
|
+
definition: ExitClusterDefinition;
|
|
395
|
+
|
|
396
|
+
/** The cluster distributed validators. */
|
|
397
|
+
distributed_validators: ExitDistributedValidator[];
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Represents the message part of a signed exit for exit validation.
|
|
402
|
+
*/
|
|
403
|
+
export interface ExitValidationMessage {
|
|
404
|
+
/** The epoch at which the validator wishes to exit. */
|
|
405
|
+
epoch: string;
|
|
406
|
+
|
|
407
|
+
/** The index of the validator in the beacon chain. */
|
|
408
|
+
validator_index: string;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Represents a signed exit message for exit validation.
|
|
413
|
+
*/
|
|
414
|
+
export interface SignedExitValidationMessage {
|
|
415
|
+
/** The exit message containing epoch and validator index. */
|
|
416
|
+
message: ExitValidationMessage;
|
|
417
|
+
|
|
418
|
+
/** BLS signature of the exit message. */
|
|
419
|
+
signature: string;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Represents a single partial exit blob for exit validation.
|
|
424
|
+
*/
|
|
425
|
+
export interface ExitValidationBlob {
|
|
426
|
+
/** The public key of the validator to exit. */
|
|
427
|
+
public_key: string;
|
|
428
|
+
|
|
429
|
+
/** The signed exit message for the validator. */
|
|
430
|
+
signed_exit_message: SignedExitValidationMessage;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Represents the overall exit payload structure for exit validation.
|
|
435
|
+
*/
|
|
436
|
+
export interface ExitValidationPayload {
|
|
437
|
+
/** Array of partial exits for validators. */
|
|
438
|
+
partial_exits: ExitValidationBlob[];
|
|
439
|
+
|
|
440
|
+
/** Operator's share index (1-based). */
|
|
441
|
+
share_idx: number;
|
|
442
|
+
|
|
443
|
+
/** Signature of the ExitValidationPayload by the operator. */
|
|
444
|
+
signature: string;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Represents the data structure for an already existing exit blob for exit validation.
|
|
449
|
+
*/
|
|
450
|
+
export interface ExistingExitValidationBlobData {
|
|
451
|
+
/** The public key of the validator to exit. */
|
|
452
|
+
public_key: string;
|
|
453
|
+
|
|
454
|
+
/** The epoch at which the validator wishes to exit. */
|
|
455
|
+
epoch: string;
|
|
456
|
+
|
|
457
|
+
/** The index of the validator in the beacon chain. */
|
|
458
|
+
validator_index: string;
|
|
459
|
+
|
|
460
|
+
/** Collection of partial exit signatures from different shares. */
|
|
461
|
+
shares_exit_data: Array<Record<string, { partial_exit_signature: string }>>;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Generic HTTP request function type.
|
|
466
|
+
* Args:
|
|
467
|
+
* url: string - The URL to request.
|
|
468
|
+
* config?: Record<string, any> - Optional request configuration (e.g., method, headers, body for POST).
|
|
469
|
+
* Returns:
|
|
470
|
+
* Promise<any> - The response data.
|
|
471
|
+
*/
|
|
472
|
+
export type HttpRequestFunc = (
|
|
473
|
+
url: string,
|
|
474
|
+
config?: Record<string, any>,
|
|
475
|
+
) => Promise<any>;
|
|
476
|
+
|
|
477
|
+
// Add other SDK-specific types below or import from other type files
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.multicall = exports.getOWRTranches = exports.deploySplitterAndOWRContracts = exports.deploySplitterContract = exports.handleDeployOWRAndSplitter = exports.predictSplitterAddress = exports.formatSplitRecipients = void 0;
|
|
13
|
-
const ethers_1 = require("ethers");
|
|
14
|
-
const OWR_1 = require("./abi/OWR");
|
|
15
|
-
const SplitMain_1 = require("./abi/SplitMain");
|
|
16
|
-
const Multicall_1 = require("./abi/Multicall");
|
|
17
|
-
const constants_1 = require("./constants");
|
|
18
|
-
const splitMainContractInterface = new ethers_1.Interface(SplitMain_1.splitMainEthereumAbi);
|
|
19
|
-
const owrFactoryContractInterface = new ethers_1.Interface(OWR_1.OWRFactoryContract.abi);
|
|
20
|
-
const formatSplitRecipients = (recipients) => {
|
|
21
|
-
// 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);
|
|
26
|
-
return parseInt(splitTostring);
|
|
27
|
-
});
|
|
28
|
-
return { accounts, percentAllocations };
|
|
29
|
-
};
|
|
30
|
-
exports.formatSplitRecipients = formatSplitRecipients;
|
|
31
|
-
const predictSplitterAddress = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
-
try {
|
|
33
|
-
let predictedSplitterAddress;
|
|
34
|
-
const splitMainContractInstance = new ethers_1.Contract(constants_1.CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address, SplitMain_1.splitMainEthereumAbi, signer);
|
|
35
|
-
if (controllerAddress === ethers_1.ZeroAddress) {
|
|
36
|
-
predictedSplitterAddress =
|
|
37
|
-
yield splitMainContractInstance.predictImmutableSplitAddress(accounts, percentAllocations, distributorFee);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
// It throws on deployed Immutable splitter
|
|
41
|
-
predictedSplitterAddress =
|
|
42
|
-
yield splitMainContractInstance.createSplit.staticCall(accounts, percentAllocations, distributorFee, controllerAddress);
|
|
43
|
-
}
|
|
44
|
-
return predictedSplitterAddress;
|
|
45
|
-
}
|
|
46
|
-
catch (e) {
|
|
47
|
-
throw e;
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
exports.predictSplitterAddress = predictSplitterAddress;
|
|
51
|
-
const handleDeployOWRAndSplitter = ({ signer, isSplitterDeployed, predictedSplitterAddress, accounts, percentAllocations, etherAmount, principalRecipient, chainId, distributorFee, controllerAddress, recoveryAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
52
|
-
try {
|
|
53
|
-
if (isSplitterDeployed) {
|
|
54
|
-
const owrAddress = yield createOWRContract({
|
|
55
|
-
owrArgs: {
|
|
56
|
-
principalRecipient,
|
|
57
|
-
amountOfPrincipalStake: etherAmount,
|
|
58
|
-
predictedSplitterAddress,
|
|
59
|
-
recoveryAddress,
|
|
60
|
-
},
|
|
61
|
-
signer,
|
|
62
|
-
chainId,
|
|
63
|
-
});
|
|
64
|
-
return {
|
|
65
|
-
withdrawal_address: owrAddress,
|
|
66
|
-
fee_recipient_address: predictedSplitterAddress,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
const { owrAddress, splitterAddress } = yield (0, exports.deploySplitterAndOWRContracts)({
|
|
71
|
-
owrArgs: {
|
|
72
|
-
principalRecipient,
|
|
73
|
-
amountOfPrincipalStake: etherAmount,
|
|
74
|
-
predictedSplitterAddress,
|
|
75
|
-
recoveryAddress,
|
|
76
|
-
},
|
|
77
|
-
splitterArgs: {
|
|
78
|
-
accounts,
|
|
79
|
-
percentAllocations,
|
|
80
|
-
distributorFee,
|
|
81
|
-
controllerAddress,
|
|
82
|
-
},
|
|
83
|
-
signer,
|
|
84
|
-
chainId,
|
|
85
|
-
});
|
|
86
|
-
return {
|
|
87
|
-
withdrawal_address: owrAddress,
|
|
88
|
-
fee_recipient_address: splitterAddress,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
catch (e) {
|
|
93
|
-
throw e;
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
exports.handleDeployOWRAndSplitter = handleDeployOWRAndSplitter;
|
|
97
|
-
const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
98
|
-
var _a;
|
|
99
|
-
try {
|
|
100
|
-
const OWRFactoryInstance = new ethers_1.Contract(constants_1.CHAIN_CONFIGURATION[chainId].OWR_FACTORY_ADDRESS.address, OWR_1.OWRFactoryContract.abi, signer);
|
|
101
|
-
const tx = yield OWRFactoryInstance.createOWRecipient(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, (0, ethers_1.parseEther)(owrArgs.amountOfPrincipalStake.toString()));
|
|
102
|
-
const receipt = yield tx.wait();
|
|
103
|
-
const OWRAddressData = (_a = receipt === null || receipt === void 0 ? void 0 : receipt.logs[0]) === null || _a === void 0 ? void 0 : _a.topics[1];
|
|
104
|
-
const formattedOWRAddress = '0x' + (OWRAddressData === null || OWRAddressData === void 0 ? void 0 : OWRAddressData.slice(26, 66));
|
|
105
|
-
return formattedOWRAddress;
|
|
106
|
-
}
|
|
107
|
-
catch (e) {
|
|
108
|
-
throw e;
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
const deploySplitterContract = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
|
-
var _b;
|
|
113
|
-
try {
|
|
114
|
-
const splitMainContractInstance = new ethers_1.Contract(constants_1.CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address, SplitMain_1.splitMainEthereumAbi, signer);
|
|
115
|
-
const tx = yield splitMainContractInstance.createSplit(accounts, percentAllocations, distributorFee, controllerAddress);
|
|
116
|
-
const receipt = yield tx.wait();
|
|
117
|
-
const splitterAddressData = (_b = receipt === null || receipt === void 0 ? void 0 : receipt.logs[0]) === null || _b === void 0 ? void 0 : _b.topics[1];
|
|
118
|
-
const formattedSplitterAddress = '0x' + (splitterAddressData === null || splitterAddressData === void 0 ? void 0 : splitterAddressData.slice(26, 66));
|
|
119
|
-
return formattedSplitterAddress;
|
|
120
|
-
}
|
|
121
|
-
catch (e) {
|
|
122
|
-
throw e;
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
exports.deploySplitterContract = deploySplitterContract;
|
|
126
|
-
const deploySplitterAndOWRContracts = ({ owrArgs, splitterArgs, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
127
|
-
var _c, _d;
|
|
128
|
-
const executeCalls = [];
|
|
129
|
-
try {
|
|
130
|
-
const splitTxData = encodeCreateSplitTxData(splitterArgs.accounts, splitterArgs.percentAllocations, splitterArgs.distributorFee, splitterArgs.controllerAddress);
|
|
131
|
-
const owrTxData = encodeCreateOWRecipientTxData(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, owrArgs.amountOfPrincipalStake);
|
|
132
|
-
executeCalls.push({
|
|
133
|
-
target: constants_1.CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address,
|
|
134
|
-
callData: splitTxData,
|
|
135
|
-
}, {
|
|
136
|
-
target: constants_1.CHAIN_CONFIGURATION[chainId].OWR_FACTORY_ADDRESS.address,
|
|
137
|
-
callData: owrTxData,
|
|
138
|
-
});
|
|
139
|
-
const multicallAddess = constants_1.CHAIN_CONFIGURATION[chainId].MULTICALL_ADDRESS.address;
|
|
140
|
-
const executeMultiCalls = yield (0, exports.multicall)(executeCalls, signer, multicallAddess);
|
|
141
|
-
const splitAddressData = (_c = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[0]) === null || _c === void 0 ? void 0 : _c.topics[1];
|
|
142
|
-
const formattedSplitterAddress = '0x' + (splitAddressData === null || splitAddressData === void 0 ? void 0 : splitAddressData.slice(26, 66));
|
|
143
|
-
const owrAddressData = (_d = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[1]) === null || _d === void 0 ? void 0 : _d.topics[1];
|
|
144
|
-
const formattedOwrAddress = '0x' + (owrAddressData === null || owrAddressData === void 0 ? void 0 : owrAddressData.slice(26, 66));
|
|
145
|
-
return {
|
|
146
|
-
owrAddress: formattedOwrAddress,
|
|
147
|
-
splitterAddress: formattedSplitterAddress,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
catch (e) {
|
|
151
|
-
throw e;
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
exports.deploySplitterAndOWRContracts = deploySplitterAndOWRContracts;
|
|
155
|
-
const getOWRTranches = ({ owrAddress, signer, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
156
|
-
const owrContract = new ethers_1.Contract(owrAddress, OWR_1.OWRContract.abi, signer);
|
|
157
|
-
const res = yield owrContract.getTranches();
|
|
158
|
-
return {
|
|
159
|
-
principalRecipient: res.principalRecipient,
|
|
160
|
-
rewardRecipient: res.rewardRecipient,
|
|
161
|
-
amountOfPrincipalStake: res.amountOfPrincipalStake,
|
|
162
|
-
};
|
|
163
|
-
});
|
|
164
|
-
exports.getOWRTranches = getOWRTranches;
|
|
165
|
-
const multicall = (calls, signer, multicallAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
166
|
-
const multiCallContractInstance = new ethers_1.Contract(multicallAddress, Multicall_1.MultiCallContract.abi, signer);
|
|
167
|
-
const tx = yield multiCallContractInstance.aggregate(calls);
|
|
168
|
-
const receipt = yield tx.wait();
|
|
169
|
-
return receipt;
|
|
170
|
-
});
|
|
171
|
-
exports.multicall = multicall;
|
|
172
|
-
const encodeCreateSplitTxData = (accounts, percentAllocations, distributorFee, controller) => {
|
|
173
|
-
return splitMainContractInterface.encodeFunctionData('createSplit', [
|
|
174
|
-
accounts,
|
|
175
|
-
percentAllocations,
|
|
176
|
-
distributorFee,
|
|
177
|
-
controller,
|
|
178
|
-
]);
|
|
179
|
-
};
|
|
180
|
-
const encodeCreateOWRecipientTxData = (recoveryAddress, principalRecipient, rewardRecipient, amountOfPrincipalStake) => {
|
|
181
|
-
return owrFactoryContractInterface.encodeFunctionData('createOWRecipient', [
|
|
182
|
-
recoveryAddress,
|
|
183
|
-
principalRecipient,
|
|
184
|
-
rewardRecipient,
|
|
185
|
-
(0, ethers_1.parseEther)(amountOfPrincipalStake.toString()),
|
|
186
|
-
]);
|
|
187
|
-
};
|