@obolnetwork/obol-sdk 2.0.1 → 2.1.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/README.md +6 -0
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/abi/Multicall.js +148 -0
- package/dist/cjs/src/abi/OWR.js +133 -0
- package/dist/cjs/src/abi/SplitMain.js +929 -0
- package/dist/cjs/src/ajv.js +17 -2
- package/dist/cjs/src/bytecodes.js +9 -0
- package/dist/cjs/src/constants.js +48 -1
- package/dist/cjs/src/index.js +146 -0
- package/dist/cjs/src/schema.js +52 -5
- package/dist/cjs/src/splitHelpers.js +177 -0
- package/dist/cjs/src/utils.js +22 -1
- package/dist/cjs/test/fixtures.js +1 -1
- package/dist/cjs/test/methods.test.js +215 -11
- package/dist/esm/package.json +1 -1
- package/dist/esm/src/abi/Multicall.js +145 -0
- package/dist/esm/src/abi/OWR.js +130 -0
- package/dist/esm/src/abi/SplitMain.js +926 -0
- package/dist/esm/src/ajv.js +17 -2
- package/dist/esm/src/bytecodes.js +6 -0
- package/dist/esm/src/constants.js +47 -0
- package/dist/esm/src/index.js +148 -2
- package/dist/esm/src/schema.js +51 -4
- package/dist/esm/src/splitHelpers.js +168 -0
- package/dist/esm/src/utils.js +19 -0
- package/dist/esm/test/fixtures.js +1 -1
- package/dist/esm/test/methods.test.js +193 -12
- package/dist/types/src/abi/Multicall.d.ts +35 -0
- package/dist/types/src/abi/OWR.d.ts +52 -0
- package/dist/types/src/abi/SplitMain.d.ts +1159 -0
- package/dist/types/src/bytecodes.d.ts +6 -0
- package/dist/types/src/constants.d.ts +25 -0
- package/dist/types/src/index.d.ts +29 -1
- package/dist/types/src/schema.d.ts +85 -4
- package/dist/types/src/splitHelpers.d.ts +62 -0
- package/dist/types/src/types.d.ts +39 -2
- package/dist/types/src/utils.d.ts +3 -0
- package/package.json +1 -1
- package/src/abi/Multicall.ts +145 -0
- package/src/abi/OWR.ts +130 -0
- package/src/abi/SplitMain.ts +927 -0
- package/src/ajv.ts +33 -2
- package/src/bytecodes.ts +12 -0
- package/src/constants.ts +59 -0
- package/src/index.ts +244 -2
- package/src/schema.ts +67 -4
- package/src/splitHelpers.ts +341 -0
- package/src/types.ts +49 -2
- package/src/utils.ts +21 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Contract, Interface, parseEther, ZeroAddress, } from 'ethers';
|
|
11
|
+
import { OWRFactoryContract } from './abi/OWR';
|
|
12
|
+
import { splitMainEthereumAbi } from './abi/SplitMain';
|
|
13
|
+
import { MultiCallContract } from './abi/Multicall';
|
|
14
|
+
import { CHAIN_CONFIGURATION } from './constants';
|
|
15
|
+
const splitMainContractInterface = new Interface(splitMainEthereumAbi);
|
|
16
|
+
const owrFactoryContractInterface = new Interface(OWRFactoryContract.abi);
|
|
17
|
+
export const formatSplitRecipients = (recipients) => {
|
|
18
|
+
// Has to be sorted when passed
|
|
19
|
+
recipients.sort((a, b) => a.account.localeCompare(b.account));
|
|
20
|
+
const accounts = recipients.map(item => item.account);
|
|
21
|
+
const percentAllocations = recipients.map(recipient => {
|
|
22
|
+
const splitTostring = (recipient.percentAllocation * 1e4).toFixed(0);
|
|
23
|
+
return parseInt(splitTostring);
|
|
24
|
+
});
|
|
25
|
+
return { accounts, percentAllocations };
|
|
26
|
+
};
|
|
27
|
+
export const predictSplitterAddress = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
28
|
+
try {
|
|
29
|
+
let predictedSplitterAddress;
|
|
30
|
+
const splitMainContractInstance = new Contract(CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address, splitMainEthereumAbi, signer);
|
|
31
|
+
if (controllerAddress === ZeroAddress) {
|
|
32
|
+
predictedSplitterAddress =
|
|
33
|
+
yield splitMainContractInstance.predictImmutableSplitAddress(accounts, percentAllocations, distributorFee);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// It throws on deployed Immutable splitter
|
|
37
|
+
predictedSplitterAddress =
|
|
38
|
+
yield splitMainContractInstance.createSplit.staticCall(accounts, percentAllocations, distributorFee, controllerAddress);
|
|
39
|
+
}
|
|
40
|
+
return predictedSplitterAddress;
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
throw e;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
export const handleDeployOWRAndSplitter = ({ signer, isSplitterDeployed, predictedSplitterAddress, accounts, percentAllocations, etherAmount, principalRecipient, chainId, distributorFee, controllerAddress, recoveryAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
|
+
try {
|
|
48
|
+
if (isSplitterDeployed) {
|
|
49
|
+
const owrAddress = yield createOWRContract({
|
|
50
|
+
owrArgs: {
|
|
51
|
+
principalRecipient,
|
|
52
|
+
amountOfPrincipalStake: etherAmount,
|
|
53
|
+
predictedSplitterAddress,
|
|
54
|
+
recoveryAddress,
|
|
55
|
+
},
|
|
56
|
+
signer,
|
|
57
|
+
chainId,
|
|
58
|
+
});
|
|
59
|
+
return {
|
|
60
|
+
withdrawal_address: owrAddress,
|
|
61
|
+
fee_recipient_address: predictedSplitterAddress,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
const { owrAddress, splitterAddress } = yield deploySplitterAndOWRContracts({
|
|
66
|
+
owrArgs: {
|
|
67
|
+
principalRecipient,
|
|
68
|
+
amountOfPrincipalStake: etherAmount,
|
|
69
|
+
predictedSplitterAddress,
|
|
70
|
+
recoveryAddress,
|
|
71
|
+
},
|
|
72
|
+
splitterArgs: {
|
|
73
|
+
accounts,
|
|
74
|
+
percentAllocations,
|
|
75
|
+
distributorFee,
|
|
76
|
+
controllerAddress,
|
|
77
|
+
},
|
|
78
|
+
signer,
|
|
79
|
+
chainId,
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
withdrawal_address: owrAddress,
|
|
83
|
+
fee_recipient_address: splitterAddress,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
throw e;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const createOWRContract = ({ owrArgs, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
var _a;
|
|
93
|
+
try {
|
|
94
|
+
const OWRFactoryInstance = new Contract(CHAIN_CONFIGURATION[chainId].OWR_FACTORY_ADDRESS.address, OWRFactoryContract.abi, signer);
|
|
95
|
+
const tx = yield OWRFactoryInstance.createOWRecipient(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, parseEther(owrArgs.amountOfPrincipalStake.toString()));
|
|
96
|
+
const receipt = yield tx.wait();
|
|
97
|
+
const OWRAddressData = (_a = receipt === null || receipt === void 0 ? void 0 : receipt.logs[0]) === null || _a === void 0 ? void 0 : _a.topics[1];
|
|
98
|
+
const formattedOWRAddress = '0x' + (OWRAddressData === null || OWRAddressData === void 0 ? void 0 : OWRAddressData.slice(26, 66));
|
|
99
|
+
return formattedOWRAddress;
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
throw e;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
export const deploySplitterContract = ({ signer, accounts, percentAllocations, chainId, distributorFee, controllerAddress, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
106
|
+
var _b;
|
|
107
|
+
try {
|
|
108
|
+
const splitMainContractInstance = new Contract(CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address, splitMainEthereumAbi, signer);
|
|
109
|
+
const tx = yield splitMainContractInstance.createSplit(accounts, percentAllocations, distributorFee, controllerAddress);
|
|
110
|
+
const receipt = yield tx.wait();
|
|
111
|
+
const splitterAddressData = (_b = receipt === null || receipt === void 0 ? void 0 : receipt.logs[0]) === null || _b === void 0 ? void 0 : _b.topics[1];
|
|
112
|
+
const formattedSplitterAddress = '0x' + (splitterAddressData === null || splitterAddressData === void 0 ? void 0 : splitterAddressData.slice(26, 66));
|
|
113
|
+
return formattedSplitterAddress;
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
throw e;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
export const deploySplitterAndOWRContracts = ({ owrArgs, splitterArgs, signer, chainId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
120
|
+
var _c, _d;
|
|
121
|
+
const executeCalls = [];
|
|
122
|
+
try {
|
|
123
|
+
const splitTxData = encodeCreateSplitTxData(splitterArgs.accounts, splitterArgs.percentAllocations, splitterArgs.distributorFee, splitterArgs.controllerAddress);
|
|
124
|
+
const owrTxData = encodeCreateOWRecipientTxData(owrArgs.recoveryAddress, owrArgs.principalRecipient, owrArgs.predictedSplitterAddress, owrArgs.amountOfPrincipalStake);
|
|
125
|
+
executeCalls.push({
|
|
126
|
+
target: CHAIN_CONFIGURATION[chainId].SPLITMAIN_ADDRESS.address,
|
|
127
|
+
callData: splitTxData,
|
|
128
|
+
}, {
|
|
129
|
+
target: CHAIN_CONFIGURATION[chainId].OWR_FACTORY_ADDRESS.address,
|
|
130
|
+
callData: owrTxData,
|
|
131
|
+
});
|
|
132
|
+
const multicallAddess = CHAIN_CONFIGURATION[chainId].MULTICALL_ADDRESS.address;
|
|
133
|
+
const executeMultiCalls = yield multicall(executeCalls, signer, multicallAddess);
|
|
134
|
+
const splitAddressData = (_c = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[0]) === null || _c === void 0 ? void 0 : _c.topics[1];
|
|
135
|
+
const formattedSplitterAddress = '0x' + (splitAddressData === null || splitAddressData === void 0 ? void 0 : splitAddressData.slice(26, 66));
|
|
136
|
+
const owrAddressData = (_d = executeMultiCalls === null || executeMultiCalls === void 0 ? void 0 : executeMultiCalls.logs[1]) === null || _d === void 0 ? void 0 : _d.topics[1];
|
|
137
|
+
const formattedOwrAddress = '0x' + (owrAddressData === null || owrAddressData === void 0 ? void 0 : owrAddressData.slice(26, 66));
|
|
138
|
+
return {
|
|
139
|
+
owrAddress: formattedOwrAddress,
|
|
140
|
+
splitterAddress: formattedSplitterAddress,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
throw e;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
export const multicall = (calls, signer, multicallAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
|
+
const multiCallContractInstance = new Contract(multicallAddress, MultiCallContract.abi, signer);
|
|
149
|
+
const tx = yield multiCallContractInstance.aggregate(calls);
|
|
150
|
+
const receipt = yield tx.wait();
|
|
151
|
+
return receipt;
|
|
152
|
+
});
|
|
153
|
+
const encodeCreateSplitTxData = (accounts, percentAllocations, distributorFee, controller) => {
|
|
154
|
+
return splitMainContractInterface.encodeFunctionData('createSplit', [
|
|
155
|
+
accounts,
|
|
156
|
+
percentAllocations,
|
|
157
|
+
distributorFee,
|
|
158
|
+
controller,
|
|
159
|
+
]);
|
|
160
|
+
};
|
|
161
|
+
const encodeCreateOWRecipientTxData = (recoveryAddress, principalRecipient, rewardRecipient, amountOfPrincipalStake) => {
|
|
162
|
+
return owrFactoryContractInterface.encodeFunctionData('createOWRecipient', [
|
|
163
|
+
recoveryAddress,
|
|
164
|
+
principalRecipient,
|
|
165
|
+
rewardRecipient,
|
|
166
|
+
parseEther(amountOfPrincipalStake.toString()),
|
|
167
|
+
]);
|
|
168
|
+
};
|
package/dist/esm/src/utils.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import { DefinitionFlow } from './constants';
|
|
2
11
|
export const hexWithout0x = (hex) => {
|
|
3
12
|
return hex.slice(2, hex.length);
|
|
@@ -38,3 +47,13 @@ export const definitionFlow = (clusterDefinition) => {
|
|
|
38
47
|
}
|
|
39
48
|
return null;
|
|
40
49
|
};
|
|
50
|
+
export const findDeployedBytecode = (contractAddress, provider) => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
+
return yield (provider === null || provider === void 0 ? void 0 : provider.getCode(contractAddress));
|
|
52
|
+
});
|
|
53
|
+
export const isContractAvailable = (contractAddress, provider, bytecode) => __awaiter(void 0, void 0, void 0, function* () {
|
|
54
|
+
const code = yield findDeployedBytecode(contractAddress, provider);
|
|
55
|
+
if (bytecode) {
|
|
56
|
+
return !!code && code === bytecode;
|
|
57
|
+
}
|
|
58
|
+
return !!code && code !== '0x' && code !== '0x0';
|
|
59
|
+
});
|
|
@@ -176,7 +176,7 @@ export const clusterConfigV1X8 = {
|
|
|
176
176
|
{ address: '0xC35CfCd67b9C27345a54EDEcC1033F2284148c81' },
|
|
177
177
|
{ address: '0x33807D6F1DCe44b9C599fFE03640762A6F08C496' },
|
|
178
178
|
{ address: '0xc6e76F72Ea672FAe05C357157CfC37720F0aF26f' },
|
|
179
|
-
{ address: '
|
|
179
|
+
{ address: '0xf6fF1a7A14D01e86a175bA958d3B6C75f2213966' },
|
|
180
180
|
],
|
|
181
181
|
validators: [
|
|
182
182
|
{
|
|
@@ -7,7 +7,7 @@ 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 { ethers } from 'ethers';
|
|
10
|
+
import { ethers, JsonRpcProvider } from 'ethers';
|
|
11
11
|
import { Client, validateClusterLock } from '../src/index';
|
|
12
12
|
import { clusterConfigV1X7, clusterConfigV1X8, clusterLockV1X6, clusterLockV1X7, clusterLockV1X8, nullDepositAmountsClusterLockV1X8, } from './fixtures.js';
|
|
13
13
|
import { SDK_VERSION } from '../src/constants';
|
|
@@ -16,22 +16,18 @@ import { validatePayload } from '../src/ajv';
|
|
|
16
16
|
import { HttpResponse, http } from 'msw';
|
|
17
17
|
import { setupServer } from 'msw/node';
|
|
18
18
|
import { hashTermsAndConditions } from '../src/verification/termsAndConditions';
|
|
19
|
+
import * as utils from '../src/utils';
|
|
20
|
+
import * as splitsHelpers from '../src/splitHelpers';
|
|
19
21
|
/* eslint no-new: 0 */
|
|
20
22
|
describe('Cluster Client', () => {
|
|
21
23
|
var _a, _b;
|
|
22
24
|
const mockConfigHash = '0x1f6c94e6c070393a68c1aa6073a21cb1fd57f0e14d2a475a2958990ab728c2fd';
|
|
23
25
|
const mnemonic = (_b = (_a = ethers.Wallet.createRandom().mnemonic) === null || _a === void 0 ? void 0 : _a.phrase) !== null && _b !== void 0 ? _b : '';
|
|
24
26
|
const privateKey = ethers.Wallet.fromPhrase(mnemonic).privateKey;
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
// try {
|
|
30
|
-
// new Client({ chainId: 1 }, mockSigner)
|
|
31
|
-
// } catch (error: any) {
|
|
32
|
-
// expect(error.message).toBe('Obol-SDK is in Beta phase, mainnet is not yet supported')
|
|
33
|
-
// }
|
|
34
|
-
// })
|
|
27
|
+
const provider = new JsonRpcProvider('https://ethereum-holesky.publicnode.com');
|
|
28
|
+
const wallet = new ethers.Wallet(privateKey, provider);
|
|
29
|
+
const mockSigner = wallet.connect(provider);
|
|
30
|
+
const clientInstance = new Client({ baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 17000 }, mockSigner);
|
|
35
31
|
test('createTermsAndConditions should return "successful authorization"', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
32
|
clientInstance['request'] = jest
|
|
37
33
|
.fn()
|
|
@@ -138,7 +134,7 @@ describe('Cluster Client', () => {
|
|
|
138
134
|
describe('Cluster Client without a signer', () => {
|
|
139
135
|
const clientInstance = new Client({
|
|
140
136
|
baseUrl: 'https://obol-api-dev.gcp.obol.tech',
|
|
141
|
-
chainId:
|
|
137
|
+
chainId: 17000,
|
|
142
138
|
});
|
|
143
139
|
test('createClusterDefinition should throw an error without signer', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
140
|
try {
|
|
@@ -198,3 +194,188 @@ describe('Cluster Client without a signer', () => {
|
|
|
198
194
|
expect(termsAndConditionsHash).toEqual('0xd33721644e8f3afab1495a74abe3523cec12d48b8da6cb760972492ca3f1a273');
|
|
199
195
|
}));
|
|
200
196
|
});
|
|
197
|
+
describe('createObolRewardsSplit', () => {
|
|
198
|
+
var _a, _b;
|
|
199
|
+
jest
|
|
200
|
+
.spyOn(utils, 'isContractAvailable')
|
|
201
|
+
.mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve(true); }));
|
|
202
|
+
jest
|
|
203
|
+
.spyOn(splitsHelpers, 'predictSplitterAddress')
|
|
204
|
+
.mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve('0xPredictedAddress'); }));
|
|
205
|
+
jest.spyOn(splitsHelpers, 'handleDeployOWRAndSplitter').mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
206
|
+
return yield Promise.resolve({
|
|
207
|
+
withdrawal_address: '0xWithdrawalAddress',
|
|
208
|
+
fee_recipient_address: '0xFeeRecipientAddress',
|
|
209
|
+
});
|
|
210
|
+
}));
|
|
211
|
+
const mnemonic = (_b = (_a = ethers.Wallet.createRandom().mnemonic) === null || _a === void 0 ? void 0 : _a.phrase) !== null && _b !== void 0 ? _b : '';
|
|
212
|
+
const privateKey = ethers.Wallet.fromPhrase(mnemonic).privateKey;
|
|
213
|
+
const provider = new JsonRpcProvider('https://ethereum-holesky.publicnode.com');
|
|
214
|
+
const wallet = new ethers.Wallet(privateKey, provider);
|
|
215
|
+
const mockSigner = wallet.connect(provider);
|
|
216
|
+
const clientInstance = new Client({ baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 17000 }, mockSigner);
|
|
217
|
+
const clientInstanceWithourSigner = new Client({
|
|
218
|
+
baseUrl: 'https://obol-api-dev.gcp.obol.tech',
|
|
219
|
+
chainId: 17000,
|
|
220
|
+
});
|
|
221
|
+
const mockSplitRecipients = [
|
|
222
|
+
{
|
|
223
|
+
account: '0x86B8145c98e5BD25BA722645b15eD65f024a87EC',
|
|
224
|
+
percentAllocation: 99,
|
|
225
|
+
},
|
|
226
|
+
];
|
|
227
|
+
const mockPrincipalRecipient = '0x86B8145c98e5BD25BA722645b15eD65f024a87EC';
|
|
228
|
+
const mockEtherAmount = 64;
|
|
229
|
+
it('should throw an error if signer is not defined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
230
|
+
yield expect(clientInstanceWithourSigner.createObolRewardsSplit({
|
|
231
|
+
splitRecipients: mockSplitRecipients,
|
|
232
|
+
principalRecipient: mockPrincipalRecipient,
|
|
233
|
+
etherAmount: mockEtherAmount,
|
|
234
|
+
})).rejects.toThrow('Signer is required in createObolRewardsSplit');
|
|
235
|
+
}));
|
|
236
|
+
it('should throw an error if chainId is not supported', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
237
|
+
const unsupportedSplitterChainClient = new Client({ baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 100 }, mockSigner);
|
|
238
|
+
try {
|
|
239
|
+
yield unsupportedSplitterChainClient.createObolRewardsSplit({
|
|
240
|
+
splitRecipients: mockSplitRecipients,
|
|
241
|
+
principalRecipient: mockPrincipalRecipient,
|
|
242
|
+
etherAmount: mockEtherAmount,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
expect(error.message).toEqual('Splitter configuration is not supported on 100 chain');
|
|
247
|
+
}
|
|
248
|
+
}));
|
|
249
|
+
test('should throw an error on invalid recipients', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
250
|
+
try {
|
|
251
|
+
yield clientInstance.createObolRewardsSplit({
|
|
252
|
+
splitRecipients: [
|
|
253
|
+
{
|
|
254
|
+
account: '0x86B8145c98e5BD25BA722645b15eD65f024a87EC',
|
|
255
|
+
percentAllocation: 22,
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
principalRecipient: mockPrincipalRecipient,
|
|
259
|
+
etherAmount: mockEtherAmount,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
expect(error.message).toEqual('Schema compilation errors\', must pass "validateSplitRecipients" keyword validation');
|
|
264
|
+
}
|
|
265
|
+
}));
|
|
266
|
+
test('should throw an error if ObolRAFSplit is less than 1', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
267
|
+
try {
|
|
268
|
+
yield clientInstance.createObolRewardsSplit({
|
|
269
|
+
splitRecipients: mockSplitRecipients,
|
|
270
|
+
principalRecipient: mockPrincipalRecipient,
|
|
271
|
+
etherAmount: mockEtherAmount,
|
|
272
|
+
ObolRAFSplit: 0.5,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
expect(error.message).toEqual("Schema compilation errors', must be >= 1");
|
|
277
|
+
}
|
|
278
|
+
}));
|
|
279
|
+
it('should return the correct withdrawal and fee recipient addresses', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
280
|
+
const result = yield clientInstance.createObolRewardsSplit({
|
|
281
|
+
splitRecipients: mockSplitRecipients,
|
|
282
|
+
principalRecipient: mockPrincipalRecipient,
|
|
283
|
+
etherAmount: mockEtherAmount,
|
|
284
|
+
});
|
|
285
|
+
expect(result).toEqual({
|
|
286
|
+
withdrawal_address: '0xWithdrawalAddress',
|
|
287
|
+
fee_recipient_address: '0xFeeRecipientAddress',
|
|
288
|
+
});
|
|
289
|
+
}));
|
|
290
|
+
});
|
|
291
|
+
describe('createObolTotalSplit', () => {
|
|
292
|
+
var _a, _b;
|
|
293
|
+
jest
|
|
294
|
+
.spyOn(utils, 'isContractAvailable')
|
|
295
|
+
.mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve(true); }));
|
|
296
|
+
jest
|
|
297
|
+
.spyOn(splitsHelpers, 'predictSplitterAddress')
|
|
298
|
+
.mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve('0xPredictedAddress'); }));
|
|
299
|
+
jest
|
|
300
|
+
.spyOn(splitsHelpers, 'deploySplitterContract')
|
|
301
|
+
.mockImplementation(() => __awaiter(void 0, void 0, void 0, function* () { return yield Promise.resolve('0xSplitterAddress'); }));
|
|
302
|
+
const mnemonic = (_b = (_a = ethers.Wallet.createRandom().mnemonic) === null || _a === void 0 ? void 0 : _a.phrase) !== null && _b !== void 0 ? _b : '';
|
|
303
|
+
const privateKey = ethers.Wallet.fromPhrase(mnemonic).privateKey;
|
|
304
|
+
const provider = new JsonRpcProvider('https://ethereum-holesky.publicnode.com');
|
|
305
|
+
const wallet = new ethers.Wallet(privateKey, provider);
|
|
306
|
+
const mockSigner = wallet.connect(provider);
|
|
307
|
+
const clientInstance = new Client({ baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 17000 }, mockSigner);
|
|
308
|
+
const clientInstanceWithourSigner = new Client({
|
|
309
|
+
baseUrl: 'https://obol-api-dev.gcp.obol.tech',
|
|
310
|
+
chainId: 17000,
|
|
311
|
+
});
|
|
312
|
+
const mockSplitRecipients = [
|
|
313
|
+
{
|
|
314
|
+
account: '0x86B8145c98e5BD25BA722645b15eD65f024a87EC',
|
|
315
|
+
percentAllocation: 99.9,
|
|
316
|
+
},
|
|
317
|
+
];
|
|
318
|
+
it('should throw an error if signer is not defined', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
319
|
+
yield expect(clientInstanceWithourSigner.createObolTotalSplit({
|
|
320
|
+
splitRecipients: mockSplitRecipients,
|
|
321
|
+
})).rejects.toThrow('Signer is required in createObolTotalSplit');
|
|
322
|
+
}));
|
|
323
|
+
it('should throw an error if chainId is not supported', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
324
|
+
const unsupportedSplitterChainClient = new Client({ baseUrl: 'https://obol-api-dev.gcp.obol.tech', chainId: 100 }, mockSigner);
|
|
325
|
+
try {
|
|
326
|
+
yield unsupportedSplitterChainClient.createObolTotalSplit({
|
|
327
|
+
splitRecipients: mockSplitRecipients,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
expect(error.message).toEqual('Splitter configuration is not supported on 100 chain');
|
|
332
|
+
}
|
|
333
|
+
}));
|
|
334
|
+
test('should throw an error on invalid recipients', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
335
|
+
try {
|
|
336
|
+
yield clientInstance.createObolTotalSplit({
|
|
337
|
+
splitRecipients: [
|
|
338
|
+
{
|
|
339
|
+
account: '0x86B8145c98e5BD25BA722645b15eD65f024a87EC',
|
|
340
|
+
percentAllocation: 22,
|
|
341
|
+
},
|
|
342
|
+
],
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
expect(error.message).toEqual('Schema compilation errors\', must pass "validateSplitRecipients" keyword validation');
|
|
347
|
+
}
|
|
348
|
+
}));
|
|
349
|
+
test('should throw an error if ObolRAFSplit is less than 0.1', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
350
|
+
try {
|
|
351
|
+
yield clientInstance.createObolTotalSplit({
|
|
352
|
+
splitRecipients: mockSplitRecipients,
|
|
353
|
+
ObolRAFSplit: 0.05,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
expect(error.message).toEqual("Schema compilation errors', must be >= 0.1");
|
|
358
|
+
}
|
|
359
|
+
}));
|
|
360
|
+
it('should return the correct withdrawal and fee recipient addresses and ObolRAFSplit', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
361
|
+
const result = yield clientInstance.createObolTotalSplit({
|
|
362
|
+
splitRecipients: mockSplitRecipients,
|
|
363
|
+
ObolRAFSplit: 0.5,
|
|
364
|
+
});
|
|
365
|
+
// 0xPredictedAddress and not 0xSplitterAddress since were mocking isContractAvailable response to be true
|
|
366
|
+
expect(result).toEqual({
|
|
367
|
+
withdrawal_address: '0xPredictedAddress',
|
|
368
|
+
fee_recipient_address: '0xPredictedAddress',
|
|
369
|
+
});
|
|
370
|
+
}));
|
|
371
|
+
it('should return the correct withdrawal and fee recipient addresses without passing ObolRAFSplit', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
372
|
+
const result = yield clientInstance.createObolTotalSplit({
|
|
373
|
+
splitRecipients: mockSplitRecipients,
|
|
374
|
+
});
|
|
375
|
+
// 0xPredictedAddress and not 0xSplitterAddress since were mocking isContractAvailable response to be true
|
|
376
|
+
expect(result).toEqual({
|
|
377
|
+
withdrawal_address: '0xPredictedAddress',
|
|
378
|
+
fee_recipient_address: '0xPredictedAddress',
|
|
379
|
+
});
|
|
380
|
+
}));
|
|
381
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare const MultiCallContract: {
|
|
2
|
+
abi: ({
|
|
3
|
+
constant: boolean;
|
|
4
|
+
inputs: {
|
|
5
|
+
components: {
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
}[];
|
|
9
|
+
name: string;
|
|
10
|
+
type: string;
|
|
11
|
+
}[];
|
|
12
|
+
name: string;
|
|
13
|
+
outputs: {
|
|
14
|
+
name: string;
|
|
15
|
+
type: string;
|
|
16
|
+
}[];
|
|
17
|
+
payable: boolean;
|
|
18
|
+
stateMutability: string;
|
|
19
|
+
type: string;
|
|
20
|
+
} | {
|
|
21
|
+
constant: boolean;
|
|
22
|
+
inputs: {
|
|
23
|
+
name: string;
|
|
24
|
+
type: string;
|
|
25
|
+
}[];
|
|
26
|
+
name: string;
|
|
27
|
+
outputs: {
|
|
28
|
+
name: string;
|
|
29
|
+
type: string;
|
|
30
|
+
}[];
|
|
31
|
+
payable: boolean;
|
|
32
|
+
stateMutability: string;
|
|
33
|
+
type: string;
|
|
34
|
+
})[];
|
|
35
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export declare const OWRFactoryContract: {
|
|
2
|
+
abi: ({
|
|
3
|
+
inputs: {
|
|
4
|
+
internalType: string;
|
|
5
|
+
name: string;
|
|
6
|
+
type: string;
|
|
7
|
+
}[];
|
|
8
|
+
stateMutability: string;
|
|
9
|
+
type: string;
|
|
10
|
+
name?: undefined;
|
|
11
|
+
anonymous?: undefined;
|
|
12
|
+
outputs?: undefined;
|
|
13
|
+
} | {
|
|
14
|
+
inputs: {
|
|
15
|
+
internalType: string;
|
|
16
|
+
name: string;
|
|
17
|
+
type: string;
|
|
18
|
+
}[];
|
|
19
|
+
name: string;
|
|
20
|
+
type: string;
|
|
21
|
+
stateMutability?: undefined;
|
|
22
|
+
anonymous?: undefined;
|
|
23
|
+
outputs?: undefined;
|
|
24
|
+
} | {
|
|
25
|
+
anonymous: boolean;
|
|
26
|
+
inputs: {
|
|
27
|
+
indexed: boolean;
|
|
28
|
+
internalType: string;
|
|
29
|
+
name: string;
|
|
30
|
+
type: string;
|
|
31
|
+
}[];
|
|
32
|
+
name: string;
|
|
33
|
+
type: string;
|
|
34
|
+
stateMutability?: undefined;
|
|
35
|
+
outputs?: undefined;
|
|
36
|
+
} | {
|
|
37
|
+
inputs: {
|
|
38
|
+
internalType: string;
|
|
39
|
+
name: string;
|
|
40
|
+
type: string;
|
|
41
|
+
}[];
|
|
42
|
+
name: string;
|
|
43
|
+
outputs: {
|
|
44
|
+
internalType: string;
|
|
45
|
+
name: string;
|
|
46
|
+
type: string;
|
|
47
|
+
}[];
|
|
48
|
+
stateMutability: string;
|
|
49
|
+
type: string;
|
|
50
|
+
anonymous?: undefined;
|
|
51
|
+
})[];
|
|
52
|
+
};
|