@dripfi/drip-sdk 1.3.6 → 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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- 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 -6
- package/dist/DripSdk.js +476 -654
- 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/dist/types/UserVaultBalance.d.ts +1 -1
- 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,688 +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');
|
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());
|
91
71
|
}
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
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();
|
103
95
|
}
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
return currentTokenAllowance.toString();
|
111
|
-
});
|
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;
|
112
102
|
}
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
return allowance;
|
120
|
-
});
|
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;
|
121
109
|
}
|
122
|
-
|
123
|
-
return
|
124
|
-
if (!this.signer) {
|
125
|
-
throw Error('No signer provided');
|
126
|
-
}
|
127
|
-
const allowance = yield this.getERC20TokenAllowance(this.dripSwapAndRecyclerContract.getContractAddress(), tokenAddress);
|
128
|
-
return allowance;
|
129
|
-
});
|
110
|
+
async getExpectedSwapResult(fromTokenAddress, toTokenAddress, amount, decimals) {
|
111
|
+
return this.dripApi.getExpectedSwapResult(fromTokenAddress, toTokenAddress, amount, decimals);
|
130
112
|
}
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
});
|
113
|
+
async getUserBalance() {
|
114
|
+
const userAddress = await this.signer.getAddress();
|
115
|
+
return this.dripApi.getUserBalance(userAddress);
|
135
116
|
}
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
return this.dripApi.getUserBalance(userAddress);
|
140
|
-
});
|
117
|
+
async getUserBoostedNfts(vaultAddress) {
|
118
|
+
const userAddress = await this.signer.getAddress();
|
119
|
+
return this.dripApi.getUserBoostedNfts(userAddress, vaultAddress);
|
141
120
|
}
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
return this.dripApi.getUserBoostedNfts(userAddress, vaultAddress);
|
146
|
-
});
|
121
|
+
async getRewardsPerHour(vaultAddress) {
|
122
|
+
const userAddress = await this.signer.getAddress();
|
123
|
+
return this.dripApi.fetchRewardsPerHour(userAddress, vaultAddress);
|
147
124
|
}
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
});
|
125
|
+
async getRewards() {
|
126
|
+
const userAddress = await this.signer.getAddress();
|
127
|
+
const userRewards = this.dripApi.fetchUserRewards(userAddress);
|
128
|
+
return userRewards;
|
153
129
|
}
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
return userRewards;
|
159
|
-
});
|
130
|
+
async getMyPerqBalance() {
|
131
|
+
const userAddress = await this.signer.getAddress();
|
132
|
+
const myPerqBalance = this.dripApi.fetchMyPerqData(userAddress);
|
133
|
+
return myPerqBalance;
|
160
134
|
}
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
for (const wnft of userWnftsForVault) {
|
185
|
-
if (!wnft.isBurned && wnft.svtWithdrawn) {
|
186
|
-
const currentBlockNumber = wnft.blockNumber - 1;
|
187
|
-
const assetsPerSvtAtBlock = yield this.dripApi.fetchAssetPerSvtAtBlock(vaultAddress, currentBlockNumber);
|
188
|
-
const estimatedValueOfNFT = ethers_1.BigNumber.from(ethers_1.ethers.utils.formatUnits(ethers_1.BigNumber.from(wnft.svtWithdrawn).mul(assetsPerSvtAtBlock), 36).split('.')[0]);
|
189
|
-
if (wnft.isDHWFinished) {
|
190
|
-
// Processed and claimable
|
191
|
-
claimable = claimable.add(estimatedValueOfNFT);
|
192
|
-
}
|
193
|
-
else {
|
194
|
-
// Not processed, pending withdrawal
|
195
|
-
pendingWithdraws = pendingWithdraws.add(estimatedValueOfNFT);
|
196
|
-
}
|
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);
|
197
158
|
}
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
userBalance: userVaultBalance.deposited.toString(),
|
202
|
-
pendingUserBalance: userVaultBalance.pending.toString(),
|
203
|
-
pendingWithdrawalBalance: ethers_1.ethers.utils.formatUnits(pendingWithdraws, decimals),
|
204
|
-
withdrawableBalance: ethers_1.ethers.utils.formatUnits(claimable, decimals),
|
205
|
-
};
|
206
|
-
});
|
207
|
-
}
|
208
|
-
fastWithdraw(vaultAddress, amountToWithdraw) {
|
209
|
-
return __awaiter(this, void 0, void 0, function* () {
|
210
|
-
var _a, _b;
|
211
|
-
if (!this.signer) {
|
212
|
-
throw Error('No signer provided');
|
213
|
-
}
|
214
|
-
const userAddress = yield this.signer.getAddress();
|
215
|
-
if (!this.signer) {
|
216
|
-
throw Error('No signer provided');
|
217
|
-
}
|
218
|
-
const vault = yield this.getVaultDetails(vaultAddress);
|
219
|
-
const redeemBagStruct = yield this.generateRedeemBagStruct(vault, userAddress, amountToWithdraw);
|
220
|
-
const currentBlockNumber = yield ((_a = this.signer.provider) === null || _a === void 0 ? void 0 : _a.getBlockNumber());
|
221
|
-
if (!currentBlockNumber) {
|
222
|
-
throw Error('Error fetching block number');
|
223
|
-
}
|
224
|
-
const redeemTx = yield ((_b = this.spoolSdk) === null || _b === void 0 ? void 0 : _b.redeemFast(redeemBagStruct, userAddress, currentBlockNumber));
|
225
|
-
const txReceipt = yield redeemTx.wait();
|
226
|
-
return txReceipt.transactionHash;
|
227
|
-
});
|
228
|
-
}
|
229
|
-
swapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, ethAmount) {
|
230
|
-
return __awaiter(this, void 0, void 0, function* () {
|
231
|
-
return this.doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, true, ethAmount);
|
232
|
-
});
|
233
|
-
}
|
234
|
-
newSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, ethAmount) {
|
235
|
-
return __awaiter(this, void 0, void 0, function* () {
|
236
|
-
return this.doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, false, ethAmount);
|
237
|
-
});
|
238
|
-
}
|
239
|
-
doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, checkAllowance, ethAmount) {
|
240
|
-
return __awaiter(this, void 0, void 0, function* () {
|
241
|
-
const userAddress = yield this.signer.getAddress();
|
242
|
-
if (!this.signer) {
|
243
|
-
throw Error('No signer provided');
|
244
|
-
}
|
245
|
-
const decimals = yield this.getERC20Precission(fromTokenAddress);
|
246
|
-
const amountWithDecimals = parseFloat(parseFloat(fromTokenAmount).toFixed(decimals));
|
247
|
-
if (amountWithDecimals > 0 && checkAllowance) {
|
248
|
-
const currentTokenAllowance = parseFloat(ethers_1.ethers.utils.formatUnits(yield this.getTokenAllowanceForSwapAndDeposit(fromTokenAddress), decimals));
|
249
|
-
if (amountWithDecimals > currentTokenAllowance) {
|
250
|
-
yield this.approveTokenForSwapAndDeposit(fromTokenAddress, amountWithDecimals.toString());
|
159
|
+
else {
|
160
|
+
// Not processed, pending withdrawal
|
161
|
+
pendingWithdraws = pendingWithdraws.add(estimatedValueOfNFT);
|
251
162
|
}
|
252
163
|
}
|
253
|
-
|
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
|
-
const vault = yield this.getVaultDetails(vaultAddress);
|
281
|
-
const redeemBagStruct = yield this.generateRedeemBagStruct(vault, userAddress, amountToWithdraw);
|
282
|
-
const redeemTx = yield this.spoolSdk.redeem(redeemBagStruct, userAddress, false);
|
283
|
-
const redeemTxReceipt = yield redeemTx.wait();
|
284
|
-
return redeemTxReceipt.transactionHash;
|
285
|
-
});
|
286
|
-
}
|
287
|
-
claimWithdraws(vaultAddress) {
|
288
|
-
return __awaiter(this, void 0, void 0, function* () {
|
289
|
-
const userAddress = yield this.signer.getAddress();
|
290
|
-
if (!this.signer) {
|
291
|
-
throw Error('No signer provided');
|
292
|
-
}
|
293
|
-
const wnfts = yield this.dripApi.fetchEnrichedUserWNFTForVault(vaultAddress, userAddress);
|
294
|
-
//! Shares come as Strings instead of BigNumber from our Backend
|
295
|
-
const nftIds = wnfts
|
296
|
-
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
297
|
-
.map((item) => item.nftId.toString());
|
298
|
-
const nftAmounts = wnfts
|
299
|
-
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
300
|
-
.map((item) => item.shares.toString());
|
301
|
-
const claimWithdrawTx = yield this.spoolSdk.claimWithdrawal(vaultAddress.toLowerCase(), nftIds, nftAmounts, userAddress);
|
302
|
-
const txReceipt = yield claimWithdrawTx.wait();
|
303
|
-
return txReceipt.transactionHash;
|
304
|
-
});
|
305
|
-
}
|
306
|
-
getVaultsClaimableData() {
|
307
|
-
return __awaiter(this, void 0, void 0, function* () {
|
308
|
-
if (!this.signer) {
|
309
|
-
throw Error('No signer provided');
|
310
|
-
}
|
311
|
-
const userAddress = yield this.signer.getAddress();
|
312
|
-
return yield this.dripApi.fetchVaultsClaimableData(userAddress);
|
313
|
-
});
|
314
|
-
}
|
315
|
-
getBeansBalance() {
|
316
|
-
return __awaiter(this, void 0, void 0, function* () {
|
317
|
-
const userAddress = yield this.signer.getAddress();
|
318
|
-
return this.dripApi.fetchBeansBalance(userAddress);
|
319
|
-
});
|
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;
|
320
190
|
}
|
321
|
-
|
322
|
-
return
|
323
|
-
const userAddress = yield this.signer.getAddress();
|
324
|
-
return this.dripApi.fetchBeansHistory(userAddress);
|
325
|
-
});
|
191
|
+
async swapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, ethAmount) {
|
192
|
+
return this.doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, true, ethAmount);
|
326
193
|
}
|
327
|
-
|
328
|
-
return
|
329
|
-
if (this.dripConfig.dripTokenRecyclerAddress === DripConfig_1.NULL_ADDRESS) {
|
330
|
-
throw Error('Recycler contract address not defined');
|
331
|
-
}
|
332
|
-
const decimals = yield this.getERC20Precission(tokenAddress);
|
333
|
-
const amountWithDecimals = ethers_1.ethers.utils.parseUnits(amountToRecycle, decimals).toString();
|
334
|
-
const recycleTx = yield this.dripTokenRecyclerContract.recycle(amountWithDecimals, beneficiary, price, deadline, signature);
|
335
|
-
const receipt = yield recycleTx.wait();
|
336
|
-
return receipt.transactionHash;
|
337
|
-
});
|
194
|
+
async newSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, ethAmount) {
|
195
|
+
return this.doSwapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, false, ethAmount);
|
338
196
|
}
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
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());
|
343
208
|
}
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
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;
|
348
257
|
}
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
beneficiary,
|
356
|
-
path,
|
357
|
-
amountInWithDecimals,
|
358
|
-
minAmountOutWithDecimals,
|
359
|
-
price,
|
360
|
-
deadline,
|
361
|
-
signature
|
362
|
-
});
|
363
|
-
const swapAndRecycleTx = yield this.dripSwapAndRecyclerContract.swapAndRecycle(beneficiary, path, amountInWithDecimals, minAmountOutWithDecimals, price, deadline, signature);
|
364
|
-
const receipt = yield swapAndRecycleTx.wait();
|
365
|
-
return receipt.transactionHash;
|
366
|
-
});
|
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);
|
367
264
|
}
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
index
|
372
|
-
};
|
373
|
-
const signedPayload = yield this.signPayload(payload);
|
374
|
-
return this.dripApi.upgradeLoyaltyCard(signedPayload);
|
375
|
-
});
|
265
|
+
async getBeansBalance() {
|
266
|
+
const userAddress = await this.signer.getAddress();
|
267
|
+
return this.dripApi.fetchBeansBalance(userAddress);
|
376
268
|
}
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
return this.dripApi.fetchOwnedLoyaltyCard(signerAddress);
|
381
|
-
});
|
269
|
+
async getBeansHistory() {
|
270
|
+
const userAddress = await this.signer.getAddress();
|
271
|
+
return this.dripApi.fetchBeansHistory(userAddress);
|
382
272
|
}
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
}
|
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;
|
387
290
|
}
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
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);
|
398
330
|
}
|
399
|
-
approveTokenForSwapAndRecycler(tokenAddress, amount) {
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
return yield this.approveToken(tokenAddress, amount, this.dripConfig.dripSwapAndRecyclerAddress);
|
408
|
-
});
|
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);
|
409
339
|
}
|
410
|
-
approveTokenForSwapAndDeposit(tokenAddress, amount) {
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
return yield this.approveToken(tokenAddress, amount, swapAndDepositContractAddress);
|
417
|
-
});
|
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);
|
418
346
|
}
|
419
|
-
approveTokenForDeposit(tokenAddress, amount) {
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
return yield this.approveToken(tokenAddress, amount, smartVaultManagerAddress);
|
426
|
-
});
|
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);
|
427
353
|
}
|
428
354
|
getDripTokenContractAddress() {
|
429
355
|
return this.dripConfig.dripTokenAddress;
|
430
356
|
}
|
431
|
-
getSwapPerqForBeansInfo() {
|
432
|
-
return
|
433
|
-
return this.dripApi.getSwapPerqForBeansInfo();
|
434
|
-
});
|
435
|
-
}
|
436
|
-
transferErc20Token(tokenAddress, amount, receiver) {
|
437
|
-
return __awaiter(this, void 0, void 0, function* () {
|
438
|
-
if (!this.signer) {
|
439
|
-
throw Error('No signer provided');
|
440
|
-
}
|
441
|
-
const decimals = yield this.getERC20Precission(tokenAddress);
|
442
|
-
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
443
|
-
const approveTx = yield erc20Instance.transfer(receiver, ethers_1.ethers.utils.parseUnits(amount, decimals));
|
444
|
-
const receipt = yield approveTx.wait();
|
445
|
-
return receipt.transactionHash;
|
446
|
-
});
|
447
|
-
}
|
448
|
-
wrapEther(amount, tokenAddress) {
|
449
|
-
return __awaiter(this, void 0, void 0, function* () {
|
450
|
-
if (!this.signer) {
|
451
|
-
throw Error('No signer provided');
|
452
|
-
}
|
453
|
-
const wethContract = new ethers_1.ethers.Contract(tokenAddress, WethTokenAbi_json_1.default, this.signer);
|
454
|
-
const decimals = yield wethContract.decimals();
|
455
|
-
const amountWithDecimals = ethers_1.ethers.utils.parseUnits(amount, decimals);
|
456
|
-
const depositTx = yield wethContract.deposit({ value: amountWithDecimals });
|
457
|
-
const receipt = yield depositTx.wait();
|
458
|
-
return receipt.transactionHash;
|
459
|
-
});
|
460
|
-
}
|
461
|
-
getVestingStart() {
|
462
|
-
return __awaiter(this, void 0, void 0, function* () {
|
463
|
-
try {
|
464
|
-
const startBigNumber = yield this.perqVestingContract.start();
|
465
|
-
return startBigNumber.toString();
|
466
|
-
}
|
467
|
-
catch (error) {
|
468
|
-
if (error instanceof Error) {
|
469
|
-
throw new Error(`Failed to get vesting start time: ${error.message}`);
|
470
|
-
}
|
471
|
-
throw new Error('Failed to get vesting start time: Unknown error');
|
472
|
-
}
|
473
|
-
});
|
357
|
+
async getSwapPerqForBeansInfo() {
|
358
|
+
return this.dripApi.getSwapPerqForBeansInfo();
|
474
359
|
}
|
475
|
-
|
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
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
return __awaiter(this, void 0, void 0, function* () {
|
505
|
-
try {
|
506
|
-
const releasableAmount = yield this.perqVestingContract.releasable(beneficiary);
|
507
|
-
return (0, utils_1.formatUnits)(releasableAmount, 18);
|
508
|
-
}
|
509
|
-
catch (error) {
|
510
|
-
if (error instanceof Error) {
|
511
|
-
throw new Error(`Failed to get releasable amount: ${error.message}`);
|
512
|
-
}
|
513
|
-
throw new Error('Failed to get releasable amount: Unknown error');
|
514
|
-
}
|
515
|
-
});
|
516
|
-
}
|
517
|
-
getReleasableTotalAmount(beneficiary) {
|
518
|
-
return __awaiter(this, void 0, void 0, function* () {
|
519
|
-
try {
|
520
|
-
const releasableTotalAmount = yield this.perqVestingContract.releasableTotal(beneficiary);
|
521
|
-
return (0, utils_1.formatUnits)(releasableTotalAmount, 18);
|
522
|
-
}
|
523
|
-
catch (error) {
|
524
|
-
if (error instanceof Error) {
|
525
|
-
throw new Error(`Failed to get total releasable amount: ${error.message}`);
|
526
|
-
}
|
527
|
-
throw new Error('Failed to get total releasable amount: Unknown error');
|
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}`);
|
528
389
|
}
|
529
|
-
|
530
|
-
|
531
|
-
getAllVestingInfo(beneficiaryAddress) {
|
532
|
-
return __awaiter(this, void 0, void 0, function* () {
|
533
|
-
const [startTimestamp, endTimestamp, vested, releasable, releasableTotal] = yield Promise.all([
|
534
|
-
this.getVestingStart(),
|
535
|
-
this.getVestingEnd(),
|
536
|
-
this.getVestedAmount(beneficiaryAddress),
|
537
|
-
this.getReleasableAmount(beneficiaryAddress),
|
538
|
-
this.getReleasableTotalAmount(beneficiaryAddress),
|
539
|
-
]);
|
540
|
-
return {
|
541
|
-
startTimestamp,
|
542
|
-
endTimestamp,
|
543
|
-
vested,
|
544
|
-
releasable,
|
545
|
-
releasableTotal,
|
546
|
-
};
|
547
|
-
});
|
390
|
+
throw new Error('Failed to get vesting start time: Unknown error');
|
391
|
+
}
|
548
392
|
}
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
if (error instanceof Error) {
|
558
|
-
throw new Error(`Failed to get total releasable amount: ${error.message}`);
|
559
|
-
}
|
560
|
-
throw new Error('Failed to get total 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}`);
|
561
401
|
}
|
562
|
-
|
402
|
+
throw new Error('Failed to get vesting end time: Unknown error');
|
403
|
+
}
|
563
404
|
}
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
if (error instanceof Error) {
|
573
|
-
throw new Error(`Failed to get total releasable amount: ${error.message}`);
|
574
|
-
}
|
575
|
-
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}`);
|
576
413
|
}
|
577
|
-
|
414
|
+
throw new Error('Failed to get vested amount: Unknown error');
|
415
|
+
}
|
578
416
|
}
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
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}`);
|
583
425
|
}
|
584
|
-
|
585
|
-
|
586
|
-
payload
|
587
|
-
};
|
588
|
-
const signerAddress = yield this.signer.getAddress();
|
589
|
-
// Get enriched payload with nonce before signing
|
590
|
-
const enrichedPayload = yield this.getEnrichedPayload(basePayload);
|
591
|
-
// Create message to sign
|
592
|
-
const message = JSON.stringify(enrichedPayload);
|
593
|
-
// Sign the message
|
594
|
-
const signature = yield this.signer.signMessage(message);
|
595
|
-
return {
|
596
|
-
signature,
|
597
|
-
signerAddress,
|
598
|
-
payload: enrichedPayload,
|
599
|
-
};
|
600
|
-
});
|
601
|
-
}
|
602
|
-
getEnrichedPayload(payload) {
|
603
|
-
return __awaiter(this, void 0, void 0, function* () {
|
604
|
-
return this.dripApi.getNonceEnrichedPayload(payload.payload);
|
605
|
-
});
|
426
|
+
throw new Error('Failed to get releasable amount: Unknown error');
|
427
|
+
}
|
606
428
|
}
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
if (
|
614
|
-
|
615
|
-
userAddress: signerAddress.toLowerCase(),
|
616
|
-
vaultAddress: vault.vaultAddress.toLowerCase(),
|
617
|
-
});
|
618
|
-
}
|
619
|
-
else {
|
620
|
-
return this.spoolSdk.views.userInfo.getMinimumBurnRedeemBag({
|
621
|
-
userAddress: signerAddress.toLowerCase(),
|
622
|
-
vaultAddress: vault.vaultAddress.toLowerCase(),
|
623
|
-
assetsToWithdraw: [Number(amountToWithdraw)]
|
624
|
-
});
|
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}`);
|
625
437
|
}
|
626
|
-
|
438
|
+
throw new Error('Failed to get total releasable amount: Unknown error');
|
439
|
+
}
|
627
440
|
}
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
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}`);
|
632
466
|
}
|
633
|
-
|
634
|
-
|
635
|
-
return decimals;
|
636
|
-
});
|
467
|
+
throw new Error('Failed to get total releasable amount: Unknown error');
|
468
|
+
}
|
637
469
|
}
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
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}`);
|
643
479
|
}
|
480
|
+
throw new Error('Failed to get total releasable amount: Unknown error');
|
644
481
|
}
|
645
|
-
return pendingDeposits;
|
646
482
|
}
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
deposits = deposits.add(this.calculateBalanceForDNFT(nft, decimals));
|
483
|
+
async signPayload(payload) {
|
484
|
+
if (!this.signer) {
|
485
|
+
throw new Error('No signer provided');
|
651
486
|
}
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
const
|
657
|
-
|
658
|
-
|
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
|
+
});
|
659
524
|
}
|
660
|
-
return assets.mul(shares).div(1000000);
|
661
|
-
}
|
662
|
-
checkIfUserHasWithdrawsToClaim(withdrawNFTS) {
|
663
|
-
const nftIds = withdrawNFTS
|
664
|
-
//! Shares come as Strings instead of BigNumber from our Backend
|
665
|
-
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
666
|
-
.map((item) => item.nftId.toString());
|
667
|
-
const nftAmounts = withdrawNFTS
|
668
|
-
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
669
|
-
.map((item) => item.shares.toString());
|
670
|
-
return nftIds.length !== 0 || nftAmounts.length !== 0;
|
671
|
-
}
|
672
|
-
calculateAllWithdrawalBalances(wnfts, vaultAddress, decimals) {
|
673
|
-
return __awaiter(this, void 0, void 0, function* () {
|
674
|
-
if (!this.signer) {
|
675
|
-
throw Error('No signer provided');
|
676
|
-
}
|
677
|
-
let estimatedPendingWithdrawalBalance = ethers_1.BigNumber.from(0);
|
678
|
-
let estimatedWithdrawableBalance = ethers_1.BigNumber.from(0);
|
679
|
-
let withdrawals = 0;
|
680
|
-
for (const wnft of wnfts) {
|
681
|
-
// Handle burned NFTs (already withdrawn by the user)
|
682
|
-
if (wnft.assets && wnft.assets[0] && wnft.isBurned) {
|
683
|
-
withdrawals += wnft.assets[0].amount;
|
684
|
-
continue;
|
685
|
-
}
|
686
|
-
const currentBlockNumber = wnft.blockNumber - 1;
|
687
|
-
const assetsPerSvtAtBlock = yield this.dripApi.fetchAssetPerSvtAtBlock(vaultAddress.toLowerCase(), currentBlockNumber);
|
688
|
-
const estimatedValueOfNFT = ethers_1.BigNumber.from(ethers_1.ethers.utils.formatUnits(ethers_1.BigNumber.from(wnft.svtWithdrawn).mul(assetsPerSvtAtBlock), 36).split('.')[0].toString());
|
689
|
-
if (wnft.isDHWFinished) {
|
690
|
-
// Processed and Withdrawable
|
691
|
-
estimatedWithdrawableBalance = estimatedWithdrawableBalance.add(estimatedValueOfNFT);
|
692
|
-
}
|
693
|
-
else {
|
694
|
-
// Not processed, no DHW was ran => pending
|
695
|
-
estimatedPendingWithdrawalBalance = estimatedPendingWithdrawalBalance.add(estimatedValueOfNFT);
|
696
|
-
}
|
697
|
-
}
|
698
|
-
// return all values as BigNumber
|
699
|
-
withdrawals = +withdrawals.toFixed(decimals);
|
700
|
-
const estimatedWithdrawals = ethers_1.ethers.utils.parseUnits(withdrawals.toString(), decimals);
|
701
|
-
return [estimatedPendingWithdrawalBalance, estimatedWithdrawableBalance, estimatedWithdrawals];
|
702
|
-
});
|
703
525
|
}
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
return allowance;
|
712
|
-
});
|
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;
|
713
533
|
}
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
return allowance;
|
722
|
-
});
|
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;
|
723
541
|
}
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
const allowance = yield erc20Instance.allowance(signerAddress, spender);
|
732
|
-
return allowance;
|
733
|
-
});
|
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;
|
734
549
|
}
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
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;
|
746
568
|
}
|
747
569
|
}
|
748
570
|
exports.default = DripSdk;
|