@dripfi/drip-sdk 1.3.7 → 1.3.8
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/.prettierrc +10 -0
- package/.vscode/settings.json +11 -16
- package/dist/DripApi.d.ts +1 -1
- package/dist/DripApi.js +303 -365
- package/dist/DripConfig.js +26 -31
- package/dist/DripSdk.d.ts +1 -1
- package/dist/DripSdk.js +480 -593
- package/dist/contracts/BaseDripContract.js +1 -0
- package/dist/contracts/DripSwapAndRecyclerContract.js +11 -24
- package/dist/contracts/DripTokenContract.js +10 -23
- package/dist/contracts/DripTokenRecyclerContract.js +5 -16
- package/dist/contracts/PerqVestingContract.js +41 -64
- package/dist/index.d.ts +1 -1
- package/dist/test.js +18 -29
- package/dist/types/MyPerqData.d.ts +11 -39
- package/eslint.config.mjs +43 -0
- package/package.json +27 -23
- package/.eslintrc.json +0 -38
package/dist/DripSdk.js
CHANGED
@@ -1,13 +1,4 @@
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
4
|
};
|
@@ -23,6 +14,14 @@ const PerqVestingContract_1 = __importDefault(require("./contracts/PerqVestingCo
|
|
23
14
|
const utils_1 = require("ethers/lib/utils");
|
24
15
|
const WethTokenAbi_json_1 = __importDefault(require("./contracts/abi/WethTokenAbi.json"));
|
25
16
|
class DripSdk {
|
17
|
+
dripApi;
|
18
|
+
dripTokenContract;
|
19
|
+
dripTokenRecyclerContract;
|
20
|
+
dripSwapAndRecyclerContract;
|
21
|
+
perqVestingContract;
|
22
|
+
spoolSdk;
|
23
|
+
signer;
|
24
|
+
dripConfig;
|
26
25
|
constructor(chain, signer, dripRoute) {
|
27
26
|
this.signer = signer;
|
28
27
|
this.dripConfig = new DripConfig_1.DripConfig(chain, dripRoute);
|
@@ -35,25 +34,17 @@ class DripSdk {
|
|
35
34
|
this.dripSwapAndRecyclerContract = new DripSwapAndRecyclerContract_1.default(this.dripConfig.dripSwapAndRecyclerAddress, signer);
|
36
35
|
this.perqVestingContract = new PerqVestingContract_1.default(this.dripConfig.perqVestingAddress, signer);
|
37
36
|
}
|
38
|
-
getAllVaults() {
|
39
|
-
return
|
40
|
-
return this.dripApi.fetchAllVaults();
|
41
|
-
});
|
37
|
+
async getAllVaults() {
|
38
|
+
return this.dripApi.fetchAllVaults();
|
42
39
|
}
|
43
|
-
getVaultDetails(vaultAddress) {
|
44
|
-
return
|
45
|
-
return this.dripApi.fetchVaultDetails(vaultAddress);
|
46
|
-
});
|
40
|
+
async getVaultDetails(vaultAddress) {
|
41
|
+
return this.dripApi.fetchVaultDetails(vaultAddress);
|
47
42
|
}
|
48
|
-
getVaultStats() {
|
49
|
-
return
|
50
|
-
return this.dripApi.fetchVaultStats();
|
51
|
-
});
|
43
|
+
async getVaultStats() {
|
44
|
+
return this.dripApi.fetchVaultStats();
|
52
45
|
}
|
53
|
-
getTokenPrice(tokenName) {
|
54
|
-
return
|
55
|
-
return this.dripApi.fetchTokenPrice(tokenName);
|
56
|
-
});
|
46
|
+
async getTokenPrice(tokenName) {
|
47
|
+
return this.dripApi.fetchTokenPrice(tokenName);
|
57
48
|
}
|
58
49
|
updateSigner(newSigner) {
|
59
50
|
this.signer = newSigner;
|
@@ -61,623 +52,519 @@ class DripSdk {
|
|
61
52
|
this.dripTokenContract.updateSigner(newSigner);
|
62
53
|
this.dripTokenRecyclerContract.updateSigner(newSigner);
|
63
54
|
}
|
64
|
-
newDeposit(tokenAddress, vaultAddress, amount) {
|
65
|
-
return
|
66
|
-
return this.doDeposit(tokenAddress, vaultAddress, amount, false);
|
67
|
-
});
|
55
|
+
async newDeposit(tokenAddress, vaultAddress, amount) {
|
56
|
+
return this.doDeposit(tokenAddress, vaultAddress, amount, false);
|
68
57
|
}
|
69
|
-
deposit(tokenAddress, vaultAddress, amount) {
|
70
|
-
return
|
71
|
-
return this.doDeposit(tokenAddress, vaultAddress, amount, true);
|
72
|
-
});
|
58
|
+
async deposit(tokenAddress, vaultAddress, amount) {
|
59
|
+
return this.doDeposit(tokenAddress, vaultAddress, amount, true);
|
73
60
|
}
|
74
|
-
doDeposit(tokenAddress, vaultAddress, amount, checkAllowance) {
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
yield this.approveTokenForDeposit(tokenAddress, amountWithDecimals.toString());
|
85
|
-
}
|
86
|
-
}
|
87
|
-
const amountToDeposit = ethers_1.ethers.utils.parseUnits(amountWithDecimals.toString(), decimals);
|
88
|
-
const signerAddress = yield this.signer.getAddress();
|
89
|
-
if (!signerAddress) {
|
90
|
-
throw Error('Error fetching address');
|
91
|
-
}
|
92
|
-
const depositBagStruct = {
|
93
|
-
smartVault: vaultAddress.toLowerCase(),
|
94
|
-
assets: [amountToDeposit],
|
95
|
-
receiver: signerAddress,
|
96
|
-
referral: ethers_1.ethers.constants.AddressZero,
|
97
|
-
doFlush: false,
|
98
|
-
};
|
99
|
-
const depositTx = yield this.spoolSdk.deposit(depositBagStruct);
|
100
|
-
const txReceipt = yield depositTx.wait();
|
101
|
-
return txReceipt.transactionHash;
|
102
|
-
});
|
103
|
-
}
|
104
|
-
getTokenAllowanceForCurrency(tokenAddress) {
|
105
|
-
return __awaiter(this, void 0, void 0, function* () {
|
106
|
-
if (!this.signer) {
|
107
|
-
throw Error('No signer provided');
|
61
|
+
async doDeposit(tokenAddress, vaultAddress, amount, checkAllowance) {
|
62
|
+
if (!this.signer) {
|
63
|
+
throw Error('No signer provided');
|
64
|
+
}
|
65
|
+
const decimals = await this.getERC20Precission(tokenAddress);
|
66
|
+
const amountWithDecimals = parseFloat(parseFloat(amount).toFixed(decimals));
|
67
|
+
if (checkAllowance) {
|
68
|
+
const currentTokenAllowance = parseFloat(ethers_1.ethers.utils.formatUnits(await this.getTokenAllowanceForDeposit(tokenAddress), decimals));
|
69
|
+
if (amountWithDecimals > currentTokenAllowance) {
|
70
|
+
await this.approveTokenForDeposit(tokenAddress, amountWithDecimals.toString());
|
108
71
|
}
|
109
|
-
|
110
|
-
|
111
|
-
|
72
|
+
}
|
73
|
+
const amountToDeposit = ethers_1.ethers.utils.parseUnits(amountWithDecimals.toString(), decimals);
|
74
|
+
const signerAddress = await this.signer.getAddress();
|
75
|
+
if (!signerAddress) {
|
76
|
+
throw Error('Error fetching address');
|
77
|
+
}
|
78
|
+
const depositBagStruct = {
|
79
|
+
smartVault: vaultAddress.toLowerCase(),
|
80
|
+
assets: [amountToDeposit],
|
81
|
+
receiver: signerAddress,
|
82
|
+
referral: ethers_1.ethers.constants.AddressZero,
|
83
|
+
doFlush: false,
|
84
|
+
};
|
85
|
+
const depositTx = await this.spoolSdk.deposit(depositBagStruct);
|
86
|
+
const txReceipt = await depositTx.wait();
|
87
|
+
return txReceipt.transactionHash;
|
88
|
+
}
|
89
|
+
async getTokenAllowanceForCurrency(tokenAddress) {
|
90
|
+
if (!this.signer) {
|
91
|
+
throw Error('No signer provided');
|
92
|
+
}
|
93
|
+
const currentTokenAllowance = await this.getTokenAllowanceForDeposit(tokenAddress);
|
94
|
+
return currentTokenAllowance.toString();
|
112
95
|
}
|
113
|
-
getTokenAllowanceForRecycler(tokenAddress) {
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
return allowance;
|
120
|
-
});
|
96
|
+
async getTokenAllowanceForRecycler(tokenAddress) {
|
97
|
+
if (!this.signer) {
|
98
|
+
throw Error('No signer provided');
|
99
|
+
}
|
100
|
+
const allowance = await this.getERC20TokenAllowance(this.dripTokenRecyclerContract.getContractAddress(), tokenAddress);
|
101
|
+
return allowance;
|
121
102
|
}
|
122
|
-
getTokenAllowanceForSwapAndRecycler(tokenAddress) {
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
return allowance;
|
129
|
-
});
|
103
|
+
async getTokenAllowanceForSwapAndRecycler(tokenAddress) {
|
104
|
+
if (!this.signer) {
|
105
|
+
throw Error('No signer provided');
|
106
|
+
}
|
107
|
+
const allowance = await this.getERC20TokenAllowance(this.dripSwapAndRecyclerContract.getContractAddress(), tokenAddress);
|
108
|
+
return allowance;
|
130
109
|
}
|
131
|
-
getExpectedSwapResult(fromTokenAddress, toTokenAddress, amount, decimals) {
|
132
|
-
return
|
133
|
-
return this.dripApi.getExpectedSwapResult(fromTokenAddress, toTokenAddress, amount, decimals);
|
134
|
-
});
|
110
|
+
async getExpectedSwapResult(fromTokenAddress, toTokenAddress, amount, decimals) {
|
111
|
+
return this.dripApi.getExpectedSwapResult(fromTokenAddress, toTokenAddress, amount, decimals);
|
135
112
|
}
|
136
|
-
getUserBalance() {
|
137
|
-
|
138
|
-
|
139
|
-
return this.dripApi.getUserBalance(userAddress);
|
140
|
-
});
|
113
|
+
async getUserBalance() {
|
114
|
+
const userAddress = await this.signer.getAddress();
|
115
|
+
return this.dripApi.getUserBalance(userAddress);
|
141
116
|
}
|
142
|
-
getUserBoostedNfts(vaultAddress) {
|
143
|
-
|
144
|
-
|
145
|
-
return this.dripApi.getUserBoostedNfts(userAddress, vaultAddress);
|
146
|
-
});
|
117
|
+
async getUserBoostedNfts(vaultAddress) {
|
118
|
+
const userAddress = await this.signer.getAddress();
|
119
|
+
return this.dripApi.getUserBoostedNfts(userAddress, vaultAddress);
|
147
120
|
}
|
148
|
-
getRewardsPerHour(vaultAddress) {
|
149
|
-
|
150
|
-
|
151
|
-
return this.dripApi.fetchRewardsPerHour(userAddress, vaultAddress);
|
152
|
-
});
|
121
|
+
async getRewardsPerHour(vaultAddress) {
|
122
|
+
const userAddress = await this.signer.getAddress();
|
123
|
+
return this.dripApi.fetchRewardsPerHour(userAddress, vaultAddress);
|
153
124
|
}
|
154
|
-
getRewards() {
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
return userRewards;
|
159
|
-
});
|
125
|
+
async getRewards() {
|
126
|
+
const userAddress = await this.signer.getAddress();
|
127
|
+
const userRewards = this.dripApi.fetchUserRewards(userAddress);
|
128
|
+
return userRewards;
|
160
129
|
}
|
161
|
-
getMyPerqBalance() {
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
return myPerqBalance;
|
166
|
-
});
|
130
|
+
async getMyPerqBalance() {
|
131
|
+
const userAddress = await this.signer.getAddress();
|
132
|
+
const myPerqBalance = this.dripApi.fetchMyPerqData(userAddress);
|
133
|
+
return myPerqBalance;
|
167
134
|
}
|
168
|
-
getUserVaultBalance(vaultAddress) {
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
// Processed and claimable
|
192
|
-
claimable = claimable.add(estimatedValueOfNFT);
|
193
|
-
}
|
194
|
-
else {
|
195
|
-
// Not processed, pending withdrawal
|
196
|
-
pendingWithdraws = pendingWithdraws.add(estimatedValueOfNFT);
|
197
|
-
}
|
135
|
+
async getUserVaultBalance(vaultAddress) {
|
136
|
+
if (!this.signer) {
|
137
|
+
throw Error('No signer provided');
|
138
|
+
}
|
139
|
+
const userAddress = await this.signer.getAddress();
|
140
|
+
// Parallel fetch of vault, deposits and wnfts
|
141
|
+
const [vault, userVaultBalance, userWnftsForVault] = await Promise.all([
|
142
|
+
this.getVaultDetails(vaultAddress),
|
143
|
+
this.dripApi.fetchUserVaultDeposits(userAddress, vaultAddress),
|
144
|
+
this.dripApi.fetchAllUserWNFTForVault(vaultAddress, userAddress),
|
145
|
+
]);
|
146
|
+
const decimals = await this.getERC20Precission(vault.depositToken.tokenAddress);
|
147
|
+
// Calculate withdrawals
|
148
|
+
let pendingWithdraws = ethers_1.BigNumber.from(0);
|
149
|
+
let claimable = ethers_1.BigNumber.from(0);
|
150
|
+
for (const wnft of userWnftsForVault) {
|
151
|
+
if (!wnft.isBurned && wnft.svtWithdrawn) {
|
152
|
+
const currentBlockNumber = wnft.blockNumber - 1;
|
153
|
+
const assetsPerSvtAtBlock = await this.dripApi.fetchAssetPerSvtAtBlock(vaultAddress, currentBlockNumber);
|
154
|
+
const estimatedValueOfNFT = ethers_1.BigNumber.from(ethers_1.ethers.utils.formatUnits(ethers_1.BigNumber.from(wnft.svtWithdrawn).mul(assetsPerSvtAtBlock), 36).split('.')[0]);
|
155
|
+
if (wnft.isDHWFinished) {
|
156
|
+
// Processed and claimable
|
157
|
+
claimable = claimable.add(estimatedValueOfNFT);
|
198
158
|
}
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
userBalance: ((_a = userVaultBalance.deposited) === null || _a === void 0 ? void 0 : _a.toString()) || '0',
|
203
|
-
pendingUserBalance: ((_b = userVaultBalance.pending) === null || _b === void 0 ? void 0 : _b.toString()) || '0',
|
204
|
-
pendingWithdrawalBalance: ethers_1.ethers.utils.formatUnits(pendingWithdraws, decimals) || '0',
|
205
|
-
claimableBalance: ethers_1.ethers.utils.formatUnits(claimable, decimals) || '0',
|
206
|
-
};
|
207
|
-
});
|
208
|
-
}
|
209
|
-
fastWithdraw(vaultAddress, amountToWithdraw) {
|
210
|
-
return __awaiter(this, void 0, void 0, function* () {
|
211
|
-
var _a, _b;
|
212
|
-
if (!this.signer) {
|
213
|
-
throw Error('No signer provided');
|
214
|
-
}
|
215
|
-
const userAddress = yield this.signer.getAddress();
|
216
|
-
if (!this.signer) {
|
217
|
-
throw Error('No signer provided');
|
218
|
-
}
|
219
|
-
const vault = yield this.getVaultDetails(vaultAddress);
|
220
|
-
const redeemBagStruct = yield this.generateRedeemBagStruct(vault, userAddress, amountToWithdraw);
|
221
|
-
const currentBlockNumber = yield ((_a = this.signer.provider) === null || _a === void 0 ? void 0 : _a.getBlockNumber());
|
222
|
-
if (!currentBlockNumber) {
|
223
|
-
throw Error('Error fetching block number');
|
224
|
-
}
|
225
|
-
const redeemTx = yield ((_b = this.spoolSdk) === null || _b === void 0 ? void 0 : _b.redeemFast(redeemBagStruct, userAddress, currentBlockNumber));
|
226
|
-
const txReceipt = yield redeemTx.wait();
|
227
|
-
return txReceipt.transactionHash;
|
228
|
-
});
|
229
|
-
}
|
230
|
-
swapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, ethAmount) {
|
231
|
-
return __awaiter(this, void 0, void 0, function* () {
|
232
|
-
return this.doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, true, ethAmount);
|
233
|
-
});
|
234
|
-
}
|
235
|
-
newSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, ethAmount) {
|
236
|
-
return __awaiter(this, void 0, void 0, function* () {
|
237
|
-
return this.doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, false, ethAmount);
|
238
|
-
});
|
239
|
-
}
|
240
|
-
doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, checkAllowance, ethAmount) {
|
241
|
-
return __awaiter(this, void 0, void 0, function* () {
|
242
|
-
const userAddress = yield this.signer.getAddress();
|
243
|
-
if (!this.signer) {
|
244
|
-
throw Error('No signer provided');
|
245
|
-
}
|
246
|
-
const decimals = yield this.getERC20Precission(fromTokenAddress);
|
247
|
-
const amountWithDecimals = parseFloat(parseFloat(fromTokenAmount).toFixed(decimals));
|
248
|
-
if (amountWithDecimals > 0 && checkAllowance) {
|
249
|
-
const currentTokenAllowance = parseFloat(ethers_1.ethers.utils.formatUnits(yield this.getTokenAllowanceForSwapAndDeposit(fromTokenAddress), decimals));
|
250
|
-
if (amountWithDecimals > currentTokenAllowance) {
|
251
|
-
yield this.approveTokenForSwapAndDeposit(fromTokenAddress, amountWithDecimals.toString());
|
159
|
+
else {
|
160
|
+
// Not processed, pending withdrawal
|
161
|
+
pendingWithdraws = pendingWithdraws.add(estimatedValueOfNFT);
|
252
162
|
}
|
253
163
|
}
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
}
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
}
|
281
|
-
const vault = yield this.getVaultDetails(vaultAddress);
|
282
|
-
const redeemBagStruct = yield this.generateRedeemBagStruct(vault, userAddress, amountToWithdraw);
|
283
|
-
const redeemTx = yield this.spoolSdk.redeem(redeemBagStruct, userAddress, false);
|
284
|
-
const redeemTxReceipt = yield redeemTx.wait();
|
285
|
-
return redeemTxReceipt.transactionHash;
|
286
|
-
});
|
287
|
-
}
|
288
|
-
claimWithdraws(vaultAddress) {
|
289
|
-
return __awaiter(this, void 0, void 0, function* () {
|
290
|
-
const userAddress = yield this.signer.getAddress();
|
291
|
-
if (!this.signer) {
|
292
|
-
throw Error('No signer provided');
|
293
|
-
}
|
294
|
-
const wnfts = yield this.dripApi.fetchEnrichedUserWNFTForVault(vaultAddress, userAddress);
|
295
|
-
//! Shares come as Strings instead of BigNumber from our Backend
|
296
|
-
const nftIds = wnfts
|
297
|
-
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
298
|
-
.map((item) => item.nftId.toString());
|
299
|
-
const nftAmounts = wnfts
|
300
|
-
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
301
|
-
.map((item) => item.shares.toString());
|
302
|
-
const claimWithdrawTx = yield this.spoolSdk.claimWithdrawal(vaultAddress.toLowerCase(), nftIds, nftAmounts, userAddress);
|
303
|
-
const txReceipt = yield claimWithdrawTx.wait();
|
304
|
-
return txReceipt.transactionHash;
|
305
|
-
});
|
306
|
-
}
|
307
|
-
getVaultsClaimableData() {
|
308
|
-
return __awaiter(this, void 0, void 0, function* () {
|
309
|
-
if (!this.signer) {
|
310
|
-
throw Error('No signer provided');
|
311
|
-
}
|
312
|
-
const userAddress = yield this.signer.getAddress();
|
313
|
-
return yield this.dripApi.fetchVaultsClaimableData(userAddress);
|
314
|
-
});
|
315
|
-
}
|
316
|
-
getBeansBalance() {
|
317
|
-
return __awaiter(this, void 0, void 0, function* () {
|
318
|
-
const userAddress = yield this.signer.getAddress();
|
319
|
-
return this.dripApi.fetchBeansBalance(userAddress);
|
320
|
-
});
|
164
|
+
}
|
165
|
+
return {
|
166
|
+
hasWithdrawsToClaim: claimable.gt(0),
|
167
|
+
userBalance: userVaultBalance.deposited?.toString() || '0',
|
168
|
+
pendingUserBalance: userVaultBalance.pending?.toString() || '0',
|
169
|
+
pendingWithdrawalBalance: ethers_1.ethers.utils.formatUnits(pendingWithdraws, decimals) || '0',
|
170
|
+
claimableBalance: ethers_1.ethers.utils.formatUnits(claimable, decimals) || '0',
|
171
|
+
};
|
172
|
+
}
|
173
|
+
async fastWithdraw(vaultAddress, amountToWithdraw) {
|
174
|
+
if (!this.signer) {
|
175
|
+
throw Error('No signer provided');
|
176
|
+
}
|
177
|
+
const userAddress = await this.signer.getAddress();
|
178
|
+
if (!this.signer) {
|
179
|
+
throw Error('No signer provided');
|
180
|
+
}
|
181
|
+
const vault = await this.getVaultDetails(vaultAddress);
|
182
|
+
const redeemBagStruct = await this.generateRedeemBagStruct(vault, userAddress, amountToWithdraw);
|
183
|
+
const currentBlockNumber = await this.signer.provider?.getBlockNumber();
|
184
|
+
if (!currentBlockNumber) {
|
185
|
+
throw Error('Error fetching block number');
|
186
|
+
}
|
187
|
+
const redeemTx = await this.spoolSdk?.redeemFast(redeemBagStruct, userAddress, currentBlockNumber);
|
188
|
+
const txReceipt = await redeemTx.wait();
|
189
|
+
return txReceipt.transactionHash;
|
321
190
|
}
|
322
|
-
|
323
|
-
return
|
324
|
-
const userAddress = yield this.signer.getAddress();
|
325
|
-
return this.dripApi.fetchBeansHistory(userAddress);
|
326
|
-
});
|
191
|
+
async swapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, ethAmount) {
|
192
|
+
return this.doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, true, ethAmount);
|
327
193
|
}
|
328
|
-
|
329
|
-
return
|
330
|
-
if (this.dripConfig.dripTokenRecyclerAddress === DripConfig_1.NULL_ADDRESS) {
|
331
|
-
throw Error('Recycler contract address not defined');
|
332
|
-
}
|
333
|
-
const decimals = yield this.getERC20Precission(tokenAddress);
|
334
|
-
const amountWithDecimals = ethers_1.ethers.utils.parseUnits(amountToRecycle, decimals).toString();
|
335
|
-
const recycleTx = yield this.dripTokenRecyclerContract.recycle(amountWithDecimals, beneficiary, price, deadline, signature);
|
336
|
-
const receipt = yield recycleTx.wait();
|
337
|
-
return receipt.transactionHash;
|
338
|
-
});
|
194
|
+
async newSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, ethAmount) {
|
195
|
+
return this.doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, false, ethAmount);
|
339
196
|
}
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
return __awaiter(this, void 0, void 0, function* () {
|
352
|
-
if (this.dripConfig.dripSwapAndRecyclerAddress === DripConfig_1.NULL_ADDRESS) {
|
353
|
-
throw Error('Recycler contract address not defined');
|
197
|
+
async doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, checkAllowance, ethAmount) {
|
198
|
+
const userAddress = await this.signer.getAddress();
|
199
|
+
if (!this.signer) {
|
200
|
+
throw Error('No signer provided');
|
201
|
+
}
|
202
|
+
const decimals = await this.getERC20Precission(fromTokenAddress);
|
203
|
+
const amountWithDecimals = parseFloat(parseFloat(fromTokenAmount).toFixed(decimals));
|
204
|
+
if (amountWithDecimals > 0 && checkAllowance) {
|
205
|
+
const currentTokenAllowance = parseFloat(ethers_1.ethers.utils.formatUnits(await this.getTokenAllowanceForSwapAndDeposit(fromTokenAddress), decimals));
|
206
|
+
if (amountWithDecimals > currentTokenAllowance) {
|
207
|
+
await this.approveTokenForSwapAndDeposit(fromTokenAddress, amountWithDecimals.toString());
|
354
208
|
}
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
209
|
+
}
|
210
|
+
const fromToken = ethers_1.ethers.utils.parseUnits(amountWithDecimals.toString(), decimals);
|
211
|
+
const swapInfo = await this.dripApi.getSwapInfo(fromTokenAddress, toTokenAddress, fromToken, userAddress);
|
212
|
+
const swapDepositBagStruct = {
|
213
|
+
inTokens: [fromTokenAddress],
|
214
|
+
inAmounts: [fromToken],
|
215
|
+
smartVault: vaultAddress.toLowerCase(),
|
216
|
+
swapInfo,
|
217
|
+
receiver: userAddress,
|
218
|
+
referral: ethers_1.ethers.constants.AddressZero,
|
219
|
+
doFlush: false,
|
220
|
+
};
|
221
|
+
const swapAndDepositRequest = ethAmount
|
222
|
+
? await this.spoolSdk.swapAndDeposit(swapDepositBagStruct, { value: ethers_1.ethers.utils.parseEther(ethAmount) })
|
223
|
+
: await this.spoolSdk.swapAndDeposit(swapDepositBagStruct);
|
224
|
+
const txReceipt = await swapAndDepositRequest.wait();
|
225
|
+
return txReceipt?.transactionHash;
|
226
|
+
}
|
227
|
+
async withdraw(vaultAddress, amountToWithdraw) {
|
228
|
+
if (!this.signer) {
|
229
|
+
throw Error('No signer provided');
|
230
|
+
}
|
231
|
+
const userAddress = await this.signer.getAddress();
|
232
|
+
if (!this.signer) {
|
233
|
+
throw Error('No signer provided');
|
234
|
+
}
|
235
|
+
const vault = await this.getVaultDetails(vaultAddress);
|
236
|
+
const redeemBagStruct = await this.generateRedeemBagStruct(vault, userAddress, amountToWithdraw);
|
237
|
+
const redeemTx = await this.spoolSdk.redeem(redeemBagStruct, userAddress, false);
|
238
|
+
const redeemTxReceipt = await redeemTx.wait();
|
239
|
+
return redeemTxReceipt.transactionHash;
|
240
|
+
}
|
241
|
+
async claimWithdraws(vaultAddress) {
|
242
|
+
const userAddress = await this.signer.getAddress();
|
243
|
+
if (!this.signer) {
|
244
|
+
throw Error('No signer provided');
|
245
|
+
}
|
246
|
+
const wnfts = await this.dripApi.fetchEnrichedUserWNFTForVault(vaultAddress, userAddress);
|
247
|
+
//! Shares come as Strings instead of BigNumber from our Backend
|
248
|
+
const nftIds = wnfts
|
249
|
+
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
250
|
+
.map((item) => item.nftId.toString());
|
251
|
+
const nftAmounts = wnfts
|
252
|
+
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
253
|
+
.map((item) => item.shares.toString());
|
254
|
+
const claimWithdrawTx = await this.spoolSdk.claimWithdrawal(vaultAddress.toLowerCase(), nftIds, nftAmounts, userAddress);
|
255
|
+
const txReceipt = await claimWithdrawTx.wait();
|
256
|
+
return txReceipt.transactionHash;
|
257
|
+
}
|
258
|
+
async getVaultsClaimableData() {
|
259
|
+
if (!this.signer) {
|
260
|
+
throw Error('No signer provided');
|
261
|
+
}
|
262
|
+
const userAddress = await this.signer.getAddress();
|
263
|
+
return await this.dripApi.fetchVaultsClaimableData(userAddress);
|
368
264
|
}
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
index
|
373
|
-
};
|
374
|
-
const signedPayload = yield this.signPayload(payload);
|
375
|
-
return this.dripApi.upgradeLoyaltyCard(signedPayload);
|
376
|
-
});
|
265
|
+
async getBeansBalance() {
|
266
|
+
const userAddress = await this.signer.getAddress();
|
267
|
+
return this.dripApi.fetchBeansBalance(userAddress);
|
377
268
|
}
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
return this.dripApi.fetchOwnedLoyaltyCard(signerAddress);
|
382
|
-
});
|
269
|
+
async getBeansHistory() {
|
270
|
+
const userAddress = await this.signer.getAddress();
|
271
|
+
return this.dripApi.fetchBeansHistory(userAddress);
|
383
272
|
}
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
}
|
273
|
+
async recycleTokens(tokenAddress = this.dripConfig.dripTokenAddress, amountToRecycle, beneficiary = DripConfig_1.NULL_ADDRESS, price, deadline, signature) {
|
274
|
+
if (this.dripConfig.dripTokenRecyclerAddress === DripConfig_1.NULL_ADDRESS) {
|
275
|
+
throw Error('Recycler contract address not defined');
|
276
|
+
}
|
277
|
+
const decimals = await this.getERC20Precission(tokenAddress);
|
278
|
+
const amountWithDecimals = ethers_1.ethers.utils.parseUnits(amountToRecycle, decimals).toString();
|
279
|
+
const recycleTx = await this.dripTokenRecyclerContract.recycle(amountWithDecimals, beneficiary, price, deadline, signature);
|
280
|
+
const receipt = await recycleTx.wait();
|
281
|
+
return receipt.transactionHash;
|
282
|
+
}
|
283
|
+
async swapAndRecycleETH(beneficiary, path, minAmountOutWithDecimals, amountOfEth, price, deadline, signature) {
|
284
|
+
if (this.dripConfig.dripSwapAndRecyclerAddress === DripConfig_1.NULL_ADDRESS) {
|
285
|
+
throw Error('Recycler contract address not defined');
|
286
|
+
}
|
287
|
+
const swapAndRecycleTx = await this.dripSwapAndRecyclerContract.swapETHAndRecycle(beneficiary, path, minAmountOutWithDecimals, amountOfEth, price, deadline, signature);
|
288
|
+
const receipt = await swapAndRecycleTx.wait();
|
289
|
+
return receipt.transactionHash;
|
388
290
|
}
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
291
|
+
async swapAndRecycleERC20(beneficiary, path, minAmountOutWithDecimals, amountInWithDecimals, price, deadline, signature) {
|
292
|
+
if (this.dripConfig.dripSwapAndRecyclerAddress === DripConfig_1.NULL_ADDRESS) {
|
293
|
+
throw Error('Recycler contract address not defined');
|
294
|
+
}
|
295
|
+
console.log('swap and recycle ERC-20 with this: ', {
|
296
|
+
beneficiary,
|
297
|
+
path,
|
298
|
+
amountInWithDecimals,
|
299
|
+
minAmountOutWithDecimals,
|
300
|
+
price,
|
301
|
+
deadline,
|
302
|
+
signature,
|
303
|
+
});
|
304
|
+
const swapAndRecycleTx = await this.dripSwapAndRecyclerContract.swapAndRecycle(beneficiary, path, amountInWithDecimals, minAmountOutWithDecimals, price, deadline, signature);
|
305
|
+
const receipt = await swapAndRecycleTx.wait();
|
306
|
+
return receipt.transactionHash;
|
307
|
+
}
|
308
|
+
async upgradeLoyaltyCard(index) {
|
309
|
+
const payload = {
|
310
|
+
index,
|
311
|
+
};
|
312
|
+
const signedPayload = await this.signPayload(payload);
|
313
|
+
return this.dripApi.upgradeLoyaltyCard(signedPayload);
|
314
|
+
}
|
315
|
+
async getOwnedLoyaltyCard() {
|
316
|
+
const signerAddress = await this.signer.getAddress();
|
317
|
+
return this.dripApi.fetchOwnedLoyaltyCard(signerAddress);
|
318
|
+
}
|
319
|
+
async getAllLoyaltyCards() {
|
320
|
+
return this.dripApi.fetchAllLoyaltyCards();
|
321
|
+
}
|
322
|
+
async approveTokenForRecycler(tokenAddress, amount) {
|
323
|
+
if (!this.signer) {
|
324
|
+
throw Error('No signer provided');
|
325
|
+
}
|
326
|
+
if (this.dripConfig.dripTokenRecyclerAddress === DripConfig_1.NULL_ADDRESS) {
|
327
|
+
throw Error('Recycler contract address not defined');
|
328
|
+
}
|
329
|
+
return await this.approveToken(tokenAddress, amount, this.dripConfig.dripTokenRecyclerAddress);
|
399
330
|
}
|
400
|
-
approveTokenForSwapAndRecycler(tokenAddress, amount) {
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
return yield this.approveToken(tokenAddress, amount, this.dripConfig.dripSwapAndRecyclerAddress);
|
409
|
-
});
|
331
|
+
async approveTokenForSwapAndRecycler(tokenAddress, amount) {
|
332
|
+
if (!this.signer) {
|
333
|
+
throw Error('No signer provided');
|
334
|
+
}
|
335
|
+
if (this.dripConfig.dripSwapAndRecyclerAddress === DripConfig_1.NULL_ADDRESS) {
|
336
|
+
throw Error('Recycler contract address not defined');
|
337
|
+
}
|
338
|
+
return await this.approveToken(tokenAddress, amount, this.dripConfig.dripSwapAndRecyclerAddress);
|
410
339
|
}
|
411
|
-
approveTokenForSwapAndDeposit(tokenAddress, amount) {
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
return yield this.approveToken(tokenAddress, amount, swapAndDepositContractAddress);
|
418
|
-
});
|
340
|
+
async approveTokenForSwapAndDeposit(tokenAddress, amount) {
|
341
|
+
if (!this.signer) {
|
342
|
+
throw Error('No signer provided');
|
343
|
+
}
|
344
|
+
const swapAndDepositContractAddress = await this.dripConfig.getSwapAndDepositContractAddress(this.signer);
|
345
|
+
return await this.approveToken(tokenAddress, amount, swapAndDepositContractAddress);
|
419
346
|
}
|
420
|
-
approveTokenForDeposit(tokenAddress, amount) {
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
return yield this.approveToken(tokenAddress, amount, smartVaultManagerAddress);
|
427
|
-
});
|
347
|
+
async approveTokenForDeposit(tokenAddress, amount) {
|
348
|
+
if (!this.signer) {
|
349
|
+
throw Error('No signer provided');
|
350
|
+
}
|
351
|
+
const smartVaultManagerAddress = await this.dripConfig.getSmartVaultManagerAddress(this.signer);
|
352
|
+
return await this.approveToken(tokenAddress, amount, smartVaultManagerAddress);
|
428
353
|
}
|
429
354
|
getDripTokenContractAddress() {
|
430
355
|
return this.dripConfig.dripTokenAddress;
|
431
356
|
}
|
432
|
-
getSwapPerqForBeansInfo() {
|
433
|
-
return
|
434
|
-
return this.dripApi.getSwapPerqForBeansInfo();
|
435
|
-
});
|
436
|
-
}
|
437
|
-
transferErc20Token(tokenAddress, amount, receiver) {
|
438
|
-
return __awaiter(this, void 0, void 0, function* () {
|
439
|
-
if (!this.signer) {
|
440
|
-
throw Error('No signer provided');
|
441
|
-
}
|
442
|
-
const decimals = yield this.getERC20Precission(tokenAddress);
|
443
|
-
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
444
|
-
const approveTx = yield erc20Instance.transfer(receiver, ethers_1.ethers.utils.parseUnits(amount, decimals));
|
445
|
-
const receipt = yield approveTx.wait();
|
446
|
-
return receipt.transactionHash;
|
447
|
-
});
|
448
|
-
}
|
449
|
-
wrapEther(amount, tokenAddress) {
|
450
|
-
return __awaiter(this, void 0, void 0, function* () {
|
451
|
-
if (!this.signer) {
|
452
|
-
throw Error('No signer provided');
|
453
|
-
}
|
454
|
-
const wethContract = new ethers_1.ethers.Contract(tokenAddress, WethTokenAbi_json_1.default, this.signer);
|
455
|
-
const decimals = yield wethContract.decimals();
|
456
|
-
const amountWithDecimals = ethers_1.ethers.utils.parseUnits(amount, decimals);
|
457
|
-
const depositTx = yield wethContract.deposit({ value: amountWithDecimals });
|
458
|
-
const receipt = yield depositTx.wait();
|
459
|
-
return receipt.transactionHash;
|
460
|
-
});
|
461
|
-
}
|
462
|
-
getVestingStart() {
|
463
|
-
return __awaiter(this, void 0, void 0, function* () {
|
464
|
-
try {
|
465
|
-
const startBigNumber = yield this.perqVestingContract.start();
|
466
|
-
return startBigNumber.toString();
|
467
|
-
}
|
468
|
-
catch (error) {
|
469
|
-
if (error instanceof Error) {
|
470
|
-
throw new Error(`Failed to get vesting start time: ${error.message}`);
|
471
|
-
}
|
472
|
-
throw new Error('Failed to get vesting start time: Unknown error');
|
473
|
-
}
|
474
|
-
});
|
357
|
+
async getSwapPerqForBeansInfo() {
|
358
|
+
return this.dripApi.getSwapPerqForBeansInfo();
|
475
359
|
}
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
360
|
+
async transferErc20Token(tokenAddress, amount, receiver) {
|
361
|
+
if (!this.signer) {
|
362
|
+
throw Error('No signer provided');
|
363
|
+
}
|
364
|
+
const decimals = await this.getERC20Precission(tokenAddress);
|
365
|
+
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
366
|
+
const approveTx = await erc20Instance.transfer(receiver, ethers_1.ethers.utils.parseUnits(amount, decimals));
|
367
|
+
const receipt = await approveTx.wait();
|
368
|
+
return receipt.transactionHash;
|
369
|
+
}
|
370
|
+
async wrapEther(amount, tokenAddress) {
|
371
|
+
if (!this.signer) {
|
372
|
+
throw Error('No signer provided');
|
373
|
+
}
|
374
|
+
const wethContract = new ethers_1.ethers.Contract(tokenAddress, WethTokenAbi_json_1.default, this.signer);
|
375
|
+
const decimals = await wethContract.decimals();
|
376
|
+
const amountWithDecimals = ethers_1.ethers.utils.parseUnits(amount, decimals);
|
377
|
+
const depositTx = await wethContract.deposit({ value: amountWithDecimals });
|
378
|
+
const receipt = await depositTx.wait();
|
379
|
+
return receipt.transactionHash;
|
380
|
+
}
|
381
|
+
async getVestingStart() {
|
382
|
+
try {
|
383
|
+
const startBigNumber = await this.perqVestingContract.start();
|
384
|
+
return startBigNumber.toString();
|
385
|
+
}
|
386
|
+
catch (error) {
|
387
|
+
if (error instanceof Error) {
|
388
|
+
throw new Error(`Failed to get vesting start time: ${error.message}`);
|
501
389
|
}
|
502
|
-
|
390
|
+
throw new Error('Failed to get vesting start time: Unknown error');
|
391
|
+
}
|
503
392
|
}
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
throw new Error(`Failed to get releasable amount: ${error.message}`);
|
513
|
-
}
|
514
|
-
throw new Error('Failed to get releasable amount: Unknown error');
|
393
|
+
async getVestingEnd() {
|
394
|
+
try {
|
395
|
+
const endBigNumber = await this.perqVestingContract.end();
|
396
|
+
return endBigNumber.toString();
|
397
|
+
}
|
398
|
+
catch (error) {
|
399
|
+
if (error instanceof Error) {
|
400
|
+
throw new Error(`Failed to get vesting end time: ${error.message}`);
|
515
401
|
}
|
516
|
-
|
402
|
+
throw new Error('Failed to get vesting end time: Unknown error');
|
403
|
+
}
|
517
404
|
}
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
throw new Error(`Failed to get total releasable amount: ${error.message}`);
|
527
|
-
}
|
528
|
-
throw new Error('Failed to get total releasable amount: Unknown error');
|
405
|
+
async getVestedAmount(beneficiary) {
|
406
|
+
try {
|
407
|
+
const vestedAmount = await this.perqVestingContract.vested(beneficiary);
|
408
|
+
return (0, utils_1.formatUnits)(vestedAmount, 18);
|
409
|
+
}
|
410
|
+
catch (error) {
|
411
|
+
if (error instanceof Error) {
|
412
|
+
throw new Error(`Failed to get vested amount: ${error.message}`);
|
529
413
|
}
|
530
|
-
|
531
|
-
|
532
|
-
getAllVestingInfo(beneficiaryAddress) {
|
533
|
-
return __awaiter(this, void 0, void 0, function* () {
|
534
|
-
const [startTimestamp, endTimestamp, vested, releasable, releasableTotal] = yield Promise.all([
|
535
|
-
this.getVestingStart(),
|
536
|
-
this.getVestingEnd(),
|
537
|
-
this.getVestedAmount(beneficiaryAddress),
|
538
|
-
this.getReleasableAmount(beneficiaryAddress),
|
539
|
-
this.getReleasableTotalAmount(beneficiaryAddress),
|
540
|
-
]);
|
541
|
-
return {
|
542
|
-
startTimestamp,
|
543
|
-
endTimestamp,
|
544
|
-
vested,
|
545
|
-
releasable,
|
546
|
-
releasableTotal,
|
547
|
-
};
|
548
|
-
});
|
414
|
+
throw new Error('Failed to get vested amount: Unknown error');
|
415
|
+
}
|
549
416
|
}
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
if (error instanceof Error) {
|
559
|
-
throw new Error(`Failed to get total releasable amount: ${error.message}`);
|
560
|
-
}
|
561
|
-
throw new Error('Failed to get total releasable amount: Unknown error');
|
417
|
+
async getReleasableAmount(beneficiary) {
|
418
|
+
try {
|
419
|
+
const releasableAmount = await this.perqVestingContract.releasable(beneficiary);
|
420
|
+
return (0, utils_1.formatUnits)(releasableAmount, 18);
|
421
|
+
}
|
422
|
+
catch (error) {
|
423
|
+
if (error instanceof Error) {
|
424
|
+
throw new Error(`Failed to get releasable amount: ${error.message}`);
|
562
425
|
}
|
563
|
-
|
426
|
+
throw new Error('Failed to get releasable amount: Unknown error');
|
427
|
+
}
|
564
428
|
}
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
if (error instanceof Error) {
|
574
|
-
throw new Error(`Failed to get total releasable amount: ${error.message}`);
|
575
|
-
}
|
576
|
-
throw new Error('Failed to get total releasable amount: Unknown error');
|
429
|
+
async getReleasableTotalAmount(beneficiary) {
|
430
|
+
try {
|
431
|
+
const releasableTotalAmount = await this.perqVestingContract.releasableTotal(beneficiary);
|
432
|
+
return (0, utils_1.formatUnits)(releasableTotalAmount, 18);
|
433
|
+
}
|
434
|
+
catch (error) {
|
435
|
+
if (error instanceof Error) {
|
436
|
+
throw new Error(`Failed to get total releasable amount: ${error.message}`);
|
577
437
|
}
|
578
|
-
|
438
|
+
throw new Error('Failed to get total releasable amount: Unknown error');
|
439
|
+
}
|
579
440
|
}
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
441
|
+
async getAllVestingInfo(beneficiaryAddress) {
|
442
|
+
const [startTimestamp, endTimestamp, vested, releasable, releasableTotal] = await Promise.all([
|
443
|
+
this.getVestingStart(),
|
444
|
+
this.getVestingEnd(),
|
445
|
+
this.getVestedAmount(beneficiaryAddress),
|
446
|
+
this.getReleasableAmount(beneficiaryAddress),
|
447
|
+
this.getReleasableTotalAmount(beneficiaryAddress),
|
448
|
+
]);
|
449
|
+
return {
|
450
|
+
startTimestamp,
|
451
|
+
endTimestamp,
|
452
|
+
vested,
|
453
|
+
releasable,
|
454
|
+
releasableTotal,
|
455
|
+
};
|
456
|
+
}
|
457
|
+
async claimVestedPerq(amount) {
|
458
|
+
try {
|
459
|
+
const claimTx = await this.perqVestingContract.claim(amount);
|
460
|
+
const txReceipt = await claimTx.wait();
|
461
|
+
return txReceipt.transactionHash;
|
462
|
+
}
|
463
|
+
catch (error) {
|
464
|
+
if (error instanceof Error) {
|
465
|
+
throw new Error(`Failed to get total releasable amount: ${error.message}`);
|
584
466
|
}
|
585
|
-
|
586
|
-
|
587
|
-
payload
|
588
|
-
};
|
589
|
-
const signerAddress = yield this.signer.getAddress();
|
590
|
-
// Get enriched payload with nonce before signing
|
591
|
-
const enrichedPayload = yield this.getEnrichedPayload(basePayload);
|
592
|
-
// Create message to sign
|
593
|
-
const message = JSON.stringify(enrichedPayload);
|
594
|
-
// Sign the message
|
595
|
-
const signature = yield this.signer.signMessage(message);
|
596
|
-
return {
|
597
|
-
signature,
|
598
|
-
signerAddress,
|
599
|
-
payload: enrichedPayload,
|
600
|
-
};
|
601
|
-
});
|
602
|
-
}
|
603
|
-
getEnrichedPayload(payload) {
|
604
|
-
return __awaiter(this, void 0, void 0, function* () {
|
605
|
-
return this.dripApi.getNonceEnrichedPayload(payload.payload);
|
606
|
-
});
|
467
|
+
throw new Error('Failed to get total releasable amount: Unknown error');
|
468
|
+
}
|
607
469
|
}
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
vaultAddress: vault.vaultAddress.toLowerCase(),
|
618
|
-
});
|
619
|
-
}
|
620
|
-
else {
|
621
|
-
return this.spoolSdk.views.userInfo.getMinimumBurnRedeemBag({
|
622
|
-
userAddress: signerAddress.toLowerCase(),
|
623
|
-
vaultAddress: vault.vaultAddress.toLowerCase(),
|
624
|
-
assetsToWithdraw: [Number(amountToWithdraw)]
|
625
|
-
});
|
470
|
+
async burnVestedPerq(amount, price, deadline, signature) {
|
471
|
+
try {
|
472
|
+
const burnTx = await this.perqVestingContract.burn(amount, price, deadline, signature);
|
473
|
+
const txReceipt = await burnTx.wait();
|
474
|
+
return txReceipt.transactionHash;
|
475
|
+
}
|
476
|
+
catch (error) {
|
477
|
+
if (error instanceof Error) {
|
478
|
+
throw new Error(`Failed to get total releasable amount: ${error.message}`);
|
626
479
|
}
|
627
|
-
|
480
|
+
throw new Error('Failed to get total releasable amount: Unknown error');
|
481
|
+
}
|
628
482
|
}
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
483
|
+
async signPayload(payload) {
|
484
|
+
if (!this.signer) {
|
485
|
+
throw new Error('No signer provided');
|
486
|
+
}
|
487
|
+
// Wrap the payload in a Basepayload to enrich it later on
|
488
|
+
const basePayload = {
|
489
|
+
payload,
|
490
|
+
};
|
491
|
+
const signerAddress = await this.signer.getAddress();
|
492
|
+
// Get enriched payload with nonce before signing
|
493
|
+
const enrichedPayload = await this.getEnrichedPayload(basePayload);
|
494
|
+
// Create message to sign
|
495
|
+
const message = JSON.stringify(enrichedPayload);
|
496
|
+
// Sign the message
|
497
|
+
const signature = await this.signer.signMessage(message);
|
498
|
+
return {
|
499
|
+
signature,
|
500
|
+
signerAddress,
|
501
|
+
payload: enrichedPayload,
|
502
|
+
};
|
503
|
+
}
|
504
|
+
async getEnrichedPayload(payload) {
|
505
|
+
return this.dripApi.getNonceEnrichedPayload(payload.payload);
|
506
|
+
}
|
507
|
+
async generateRedeemBagStruct(vault, signerAddress, amountToWithdraw) {
|
508
|
+
if (!this.spoolSdk) {
|
509
|
+
throw Error('No spool sdk provided');
|
510
|
+
}
|
511
|
+
const isFullWithdraw = !amountToWithdraw;
|
512
|
+
if (isFullWithdraw) {
|
513
|
+
return this.spoolSdk.views.userInfo.getMaxRedeemBag({
|
514
|
+
userAddress: signerAddress.toLowerCase(),
|
515
|
+
vaultAddress: vault.vaultAddress.toLowerCase(),
|
516
|
+
});
|
517
|
+
}
|
518
|
+
else {
|
519
|
+
return this.spoolSdk.views.userInfo.getMinimumBurnRedeemBag({
|
520
|
+
userAddress: signerAddress.toLowerCase(),
|
521
|
+
vaultAddress: vault.vaultAddress.toLowerCase(),
|
522
|
+
assetsToWithdraw: [Number(amountToWithdraw)],
|
523
|
+
});
|
524
|
+
}
|
638
525
|
}
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
return allowance;
|
647
|
-
});
|
526
|
+
async getERC20Precission(tokenAddress) {
|
527
|
+
if (!this.signer) {
|
528
|
+
throw Error('No signer provided');
|
529
|
+
}
|
530
|
+
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
531
|
+
const decimals = await erc20Instance.decimals();
|
532
|
+
return decimals;
|
648
533
|
}
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
return allowance;
|
657
|
-
});
|
534
|
+
async getTokenAllowanceForDeposit(tokenAddress) {
|
535
|
+
if (!this.signer) {
|
536
|
+
throw Error('No signer provided');
|
537
|
+
}
|
538
|
+
const smartVaultManagerAddress = await this.dripConfig.getSmartVaultManagerAddress(this.signer);
|
539
|
+
const allowance = await this.getERC20TokenAllowance(smartVaultManagerAddress, tokenAddress);
|
540
|
+
return allowance;
|
658
541
|
}
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
const allowance = yield erc20Instance.allowance(signerAddress, spender);
|
667
|
-
return allowance;
|
668
|
-
});
|
542
|
+
async getTokenAllowanceForSwapAndDeposit(tokenAddress) {
|
543
|
+
if (!this.signer) {
|
544
|
+
throw Error('No signer provided');
|
545
|
+
}
|
546
|
+
const swapAndDepositAddress = await this.dripConfig.getSwapAndDepositContractAddress(this.signer);
|
547
|
+
const allowance = await this.getERC20TokenAllowance(swapAndDepositAddress, tokenAddress);
|
548
|
+
return allowance;
|
669
549
|
}
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
550
|
+
async getERC20TokenAllowance(spender, tokenAddress) {
|
551
|
+
if (!this.signer) {
|
552
|
+
throw Error('No signer provided');
|
553
|
+
}
|
554
|
+
const signerAddress = await this.signer.getAddress();
|
555
|
+
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
556
|
+
const allowance = await erc20Instance.allowance(signerAddress, spender);
|
557
|
+
return allowance;
|
558
|
+
}
|
559
|
+
async approveToken(tokenAddress, amount, spender) {
|
560
|
+
if (!this.signer) {
|
561
|
+
throw Error('No signer provided');
|
562
|
+
}
|
563
|
+
const decimals = await this.getERC20Precission(tokenAddress);
|
564
|
+
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
565
|
+
const approveTx = await erc20Instance.approve(spender, ethers_1.ethers.utils.parseUnits(amount, decimals));
|
566
|
+
const receipt = await approveTx.wait();
|
567
|
+
return receipt.transactionHash;
|
681
568
|
}
|
682
569
|
}
|
683
570
|
exports.default = DripSdk;
|