@dripfi/drip-sdk 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DripApi.d.ts +19 -0
- package/dist/DripApi.js +139 -0
- package/dist/DripConfig.d.ts +11 -0
- package/dist/DripConfig.js +42 -0
- package/dist/DripSdk.d.ts +36 -0
- package/dist/DripSdk.js +457 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +10 -0
- package/dist/types/QLFastRedeem.d.ts +15 -0
- package/dist/types/QLFastRedeem.js +2 -0
- package/dist/types/SwapInfo.d.ts +5 -0
- package/dist/types/SwapInfo.js +2 -0
- package/dist/types/UserBalance.d.ts +7 -0
- package/dist/types/UserBalance.js +2 -0
- package/dist/types/Vault.d.ts +66 -0
- package/dist/types/Vault.js +2 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +14 -0
- package/package.json +11 -5
- package/DripApi.ts +0 -133
- package/DripConfig.ts +0 -38
- package/DripSdk.ts +0 -516
- package/index.ts +0 -5
- package/types/QLFastRedeem.ts +0 -15
- package/types/SwapInfo.ts +0 -5
- package/types/UserBalance.ts +0 -7
- package/types/Vault.ts +0 -68
- package/utils.ts +0 -12
package/dist/DripSdk.js
ADDED
@@ -0,0 +1,457 @@
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
+
const web3_token_1 = __importDefault(require("web3-token"));
|
16
|
+
const spool_v2_sdk_1 = require("@spool.fi/spool-v2-sdk");
|
17
|
+
const ethers_1 = require("ethers");
|
18
|
+
const utils_1 = require("./utils");
|
19
|
+
const DripApi_1 = __importDefault(require("./DripApi"));
|
20
|
+
const KASU_USDC_VAULT_ADDRESS = "0xd8aa8099a53eddebe6a49c98ca12746ff19aa502";
|
21
|
+
class DripSdk {
|
22
|
+
constructor(dripConfig, signer) {
|
23
|
+
this.signer = signer;
|
24
|
+
this.dripConfig = dripConfig;
|
25
|
+
if (signer) {
|
26
|
+
this.spoolSdk = new spool_v2_sdk_1.SpoolSdk(dripConfig.internalConfig, signer);
|
27
|
+
}
|
28
|
+
this.dripApi = new DripApi_1.default(dripConfig.dripRoute);
|
29
|
+
}
|
30
|
+
getAllVaults() {
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
32
|
+
return this.dripApi.fetchAllVaults();
|
33
|
+
});
|
34
|
+
}
|
35
|
+
getVaultDetails(vaultAddress) {
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
37
|
+
return this.dripApi.fetchVaultDetails(vaultAddress);
|
38
|
+
});
|
39
|
+
}
|
40
|
+
getUserBalance(vault) {
|
41
|
+
return __awaiter(this, void 0, void 0, function* () {
|
42
|
+
if (!this.signer)
|
43
|
+
throw Error('No signer provided');
|
44
|
+
const userAddress = yield this.signer.getAddress();
|
45
|
+
const token = yield this.generateToken();
|
46
|
+
const dnfts = yield this.dripApi.fetchAllUserDNFTForVault(vault.vaultAddress, userAddress, token);
|
47
|
+
const wnfts = yield this.dripApi.fetchAllUserWNFTForVault(vault.vaultAddress, userAddress, token);
|
48
|
+
const decimals = yield this.getERC20Precission(vault.depositToken.tokenAddress);
|
49
|
+
if (this.shouldUseNewWithdrawLogic(userAddress, vault)) {
|
50
|
+
const [estimatedPendingWithdrawalBalance, estimatedWithdrawableBalance] = yield this.calculateAllWithdrawalBalances(wnfts, vault.vaultAddress, decimals);
|
51
|
+
const hasWithdrawsToClaim = this.checkIfUserHasWithdrawsToClaim(wnfts);
|
52
|
+
const pendingDeposits = this.calculatePendingDeposits(dnfts, decimals);
|
53
|
+
const userBalance = this.calculateAllDeposits(dnfts, decimals).sub(pendingDeposits);
|
54
|
+
return {
|
55
|
+
hasWithdrawsToClaim,
|
56
|
+
userBalance: ethers_1.ethers.utils.formatUnits(userBalance, decimals),
|
57
|
+
pendingUserBalance: ethers_1.ethers.utils.formatUnits(pendingDeposits, decimals),
|
58
|
+
pendingWithdrawalBalance: ethers_1.ethers.utils.formatUnits(estimatedPendingWithdrawalBalance, decimals),
|
59
|
+
withdrawableBalance: ethers_1.ethers.utils.formatUnits(estimatedWithdrawableBalance, decimals),
|
60
|
+
};
|
61
|
+
}
|
62
|
+
else {
|
63
|
+
const allDeposits = this.calculateDepositsOld(dnfts, decimals);
|
64
|
+
const pendingDeposits = this.calculatePendingDepositsOld(dnfts, decimals);
|
65
|
+
const [estimatedPendingWithdrawalBalance, estimatedWithdrawableBalance, estimatedWithdrawals] = yield this.calculateAllWithdrawalBalances(wnfts, vault.vaultAddress, decimals);
|
66
|
+
const fastWithdrawBalance = yield this.calculateFastWithdrawBalancesOld(vault.vaultAddress, userAddress, decimals);
|
67
|
+
const hasWithdrawsToClaim = this.checkIfUserHasWithdrawsToClaim(wnfts);
|
68
|
+
let balance = allDeposits
|
69
|
+
.sub(estimatedWithdrawals)
|
70
|
+
.sub(estimatedWithdrawableBalance)
|
71
|
+
.sub(estimatedPendingWithdrawalBalance)
|
72
|
+
.sub(fastWithdrawBalance);
|
73
|
+
return {
|
74
|
+
hasWithdrawsToClaim,
|
75
|
+
userBalance: ethers_1.ethers.utils.formatUnits(balance, decimals),
|
76
|
+
pendingUserBalance: ethers_1.ethers.utils.formatUnits(pendingDeposits, decimals),
|
77
|
+
pendingWithdrawalBalance: ethers_1.ethers.utils.formatUnits(estimatedPendingWithdrawalBalance, decimals),
|
78
|
+
withdrawableBalance: ethers_1.ethers.utils.formatUnits(estimatedWithdrawableBalance, decimals),
|
79
|
+
};
|
80
|
+
}
|
81
|
+
});
|
82
|
+
}
|
83
|
+
fastWithdraw(vault, amountToWithdraw) {
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
85
|
+
var _a, _b;
|
86
|
+
if (!this.signer)
|
87
|
+
throw Error('No signer provided');
|
88
|
+
try {
|
89
|
+
const signerAddress = yield this.signer.getAddress();
|
90
|
+
if (!signerAddress)
|
91
|
+
throw Error('Error fetching address');
|
92
|
+
const redeemBagStruct = this.shouldUseNewWithdrawLogic(signerAddress, vault)
|
93
|
+
? yield this.generateNewRedeemBagStruct(vault, signerAddress, amountToWithdraw)
|
94
|
+
: yield this.generateOldRedeemBagStruct(vault, signerAddress, amountToWithdraw);
|
95
|
+
const currentBlockNumber = yield ((_a = this.signer.provider) === null || _a === void 0 ? void 0 : _a.getBlockNumber());
|
96
|
+
if (!currentBlockNumber)
|
97
|
+
throw Error('Error fetching block number');
|
98
|
+
const redeemTx = yield ((_b = this.spoolSdk) === null || _b === void 0 ? void 0 : _b.redeemFast(redeemBagStruct, signerAddress.toLowerCase(), currentBlockNumber));
|
99
|
+
const redeemTxReceipt = yield redeemTx.wait();
|
100
|
+
}
|
101
|
+
catch (error) {
|
102
|
+
console.log(error);
|
103
|
+
}
|
104
|
+
});
|
105
|
+
}
|
106
|
+
deposit(tokenAddress, vaultAddress, amount) {
|
107
|
+
return __awaiter(this, void 0, void 0, function* () {
|
108
|
+
if (!this.signer)
|
109
|
+
throw Error('No signer provided');
|
110
|
+
const currentTokenAllowance = yield this.getTokenAllowanceForDeposit(tokenAddress);
|
111
|
+
const decimals = yield this.getERC20Precission(tokenAddress);
|
112
|
+
let amountToWithdrawFixedDecimals = parseFloat(amount).toFixed(decimals);
|
113
|
+
const amountToDeposit = ethers_1.ethers.utils.parseUnits(amountToWithdrawFixedDecimals, decimals);
|
114
|
+
if (amountToDeposit.gt(currentTokenAllowance)) {
|
115
|
+
const requiredTokenAllowance = amountToDeposit.sub(currentTokenAllowance);
|
116
|
+
yield this.approveTokenForDeposit(tokenAddress, requiredTokenAllowance);
|
117
|
+
}
|
118
|
+
const signerAddress = yield this.signer.getAddress();
|
119
|
+
if (!signerAddress)
|
120
|
+
throw Error('Error fetching address');
|
121
|
+
const depositBagStruct = {
|
122
|
+
smartVault: vaultAddress,
|
123
|
+
assets: [amountToDeposit],
|
124
|
+
receiver: signerAddress,
|
125
|
+
referral: ethers_1.ethers.constants.AddressZero,
|
126
|
+
doFlush: false,
|
127
|
+
};
|
128
|
+
const depositTx = yield this.spoolSdk.deposit(depositBagStruct);
|
129
|
+
yield depositTx.wait();
|
130
|
+
});
|
131
|
+
}
|
132
|
+
swapAndDeposit(fromTokenAddress, toTokenAddress, fromTokenAmount, vaultAddress, ethAmount) {
|
133
|
+
return __awaiter(this, void 0, void 0, function* () {
|
134
|
+
var _a, _b;
|
135
|
+
if (!this.signer)
|
136
|
+
throw Error('No signer provided');
|
137
|
+
const decimals = yield this.getERC20Precission(fromTokenAddress);
|
138
|
+
const amountToWithdrawFixedDecimals = parseFloat(fromTokenAmount).toFixed(decimals);
|
139
|
+
const fromToken = ethers_1.ethers.utils.parseUnits(amountToWithdrawFixedDecimals, decimals);
|
140
|
+
const signerAddress = yield this.signer.getAddress();
|
141
|
+
if (fromToken.gt(ethers_1.BigNumber.from(0))) {
|
142
|
+
const currentTokenAllowance = yield this.getTokenAllowanceForSwapAndDepositContractAddress(fromTokenAddress);
|
143
|
+
if (fromToken.gt(currentTokenAllowance)) {
|
144
|
+
yield this.approveTokenForSwapAndDepositContract(fromTokenAddress, fromToken.sub(currentTokenAllowance));
|
145
|
+
}
|
146
|
+
}
|
147
|
+
const swapInfo = yield this.dripApi.getSwapInfo(fromTokenAddress, toTokenAddress, fromToken, signerAddress);
|
148
|
+
const swapDepositBagStruct = {
|
149
|
+
inTokens: [fromTokenAddress],
|
150
|
+
inAmounts: [fromToken],
|
151
|
+
smartVault: vaultAddress,
|
152
|
+
swapInfo,
|
153
|
+
receiver: signerAddress,
|
154
|
+
referral: ethers_1.ethers.constants.AddressZero,
|
155
|
+
doFlush: false,
|
156
|
+
};
|
157
|
+
let swapAndDepositRequest;
|
158
|
+
if (ethAmount) {
|
159
|
+
const eth = ethers_1.ethers.utils.parseEther(ethAmount);
|
160
|
+
swapAndDepositRequest = yield ((_a = this.spoolSdk) === null || _a === void 0 ? void 0 : _a.swapAndDeposit(swapDepositBagStruct, { value: eth }));
|
161
|
+
}
|
162
|
+
else {
|
163
|
+
swapAndDepositRequest = yield ((_b = this.spoolSdk) === null || _b === void 0 ? void 0 : _b.swapAndDeposit(swapDepositBagStruct));
|
164
|
+
}
|
165
|
+
yield (swapAndDepositRequest === null || swapAndDepositRequest === void 0 ? void 0 : swapAndDepositRequest.wait());
|
166
|
+
});
|
167
|
+
}
|
168
|
+
withdraw(vault, amountToWithdraw) {
|
169
|
+
return __awaiter(this, void 0, void 0, function* () {
|
170
|
+
if (!this.signer)
|
171
|
+
throw Error('No signer provided');
|
172
|
+
try {
|
173
|
+
const signerAddress = yield this.signer.getAddress();
|
174
|
+
if (!signerAddress)
|
175
|
+
throw Error('Error fetching address');
|
176
|
+
const redeemBagStruct = this.shouldUseNewWithdrawLogic(signerAddress, vault)
|
177
|
+
? yield this.generateNewRedeemBagStruct(vault, signerAddress, amountToWithdraw)
|
178
|
+
: yield this.generateOldRedeemBagStruct(vault, signerAddress, amountToWithdraw);
|
179
|
+
const redeemTx = yield this.spoolSdk.redeem(redeemBagStruct, signerAddress.toLowerCase(), false);
|
180
|
+
const redeemTxReceipt = yield redeemTx.wait();
|
181
|
+
}
|
182
|
+
catch (error) {
|
183
|
+
console.log(error);
|
184
|
+
}
|
185
|
+
});
|
186
|
+
}
|
187
|
+
generateOldRedeemBagStruct(vault, signerAddress, amountToWithdraw) {
|
188
|
+
return __awaiter(this, void 0, void 0, function* () {
|
189
|
+
const token = yield this.generateToken();
|
190
|
+
const dnfts = yield this.dripApi.fetchEnrichedUserDNFTForVault(vault.vaultAddress, signerAddress, token);
|
191
|
+
const userBalance = yield this.dripApi.fetchUserBalance(vault.vaultAddress, signerAddress, token);
|
192
|
+
const totalTokenBalance = ethers_1.BigNumber.from(userBalance[vault.depositToken.tokenAddress]);
|
193
|
+
const totalSharesFetched = yield this.dripApi.fetchUserSVTBalance(vault.vaultAddress, signerAddress, token);
|
194
|
+
const totalShares = ethers_1.BigNumber.from(totalSharesFetched);
|
195
|
+
const decimals = yield this.getERC20Precission(vault.depositToken.tokenAddress);
|
196
|
+
let sharesToWithdraw = ethers_1.BigNumber.from(0);
|
197
|
+
if (!amountToWithdraw) {
|
198
|
+
sharesToWithdraw = totalShares;
|
199
|
+
}
|
200
|
+
else {
|
201
|
+
//! Not a MAX Withdraw (calculate the shares to withdraw)
|
202
|
+
let amountToWithdrawFixedDecimals = parseFloat(amountToWithdraw).toFixed(decimals);
|
203
|
+
sharesToWithdraw = ethers_1.ethers.utils
|
204
|
+
.parseUnits(amountToWithdrawFixedDecimals, decimals)
|
205
|
+
.mul(totalShares)
|
206
|
+
.div(totalTokenBalance);
|
207
|
+
if (sharesToWithdraw.gt(totalShares)) {
|
208
|
+
sharesToWithdraw = totalShares;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
const nftIds = dnfts
|
212
|
+
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
213
|
+
.map((item) => item.nftId.toString());
|
214
|
+
const nftAmounts = dnfts
|
215
|
+
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
216
|
+
.map((item) => item.shares.toString());
|
217
|
+
return {
|
218
|
+
smartVault: vault.vaultAddress,
|
219
|
+
shares: sharesToWithdraw,
|
220
|
+
nftIds,
|
221
|
+
nftAmounts,
|
222
|
+
};
|
223
|
+
});
|
224
|
+
}
|
225
|
+
generateNewRedeemBagStruct(vault, signerAddress, amountToWithdraw) {
|
226
|
+
return __awaiter(this, void 0, void 0, function* () {
|
227
|
+
const token = yield this.generateToken();
|
228
|
+
const decimals = yield this.getERC20Precission(vault.depositToken.tokenAddress.toLowerCase());
|
229
|
+
const withdrawAll = (!amountToWithdraw);
|
230
|
+
const initialAmountToWithdraw = ethers_1.ethers.utils.parseUnits(amountToWithdraw || '0', decimals);
|
231
|
+
let totalAmountToWithdraw = initialAmountToWithdraw;
|
232
|
+
let dnfts = yield this.dripApi.fetchEnrichedUserDNFTForVault(vault.vaultAddress.toLowerCase(), signerAddress, token);
|
233
|
+
dnfts = yield this.getAllSvts(vault.vaultAddress.toLowerCase(), signerAddress, dnfts);
|
234
|
+
let shares = ethers_1.BigNumber.from(0);
|
235
|
+
let nftIds = [];
|
236
|
+
let nftAmounts = [];
|
237
|
+
let index = 0;
|
238
|
+
while (dnfts[index] && (totalAmountToWithdraw.gt(0) || withdrawAll)) {
|
239
|
+
const dnft = dnfts[index];
|
240
|
+
const userBalance = this.calculateBalanceForDNFT(dnft, decimals);
|
241
|
+
if (userBalance.gt(0)) {
|
242
|
+
let amountToWithdraw = totalAmountToWithdraw;
|
243
|
+
const userSvts = dnft.svts;
|
244
|
+
let svtsToWithdraw = ethers_1.BigNumber.from(0);
|
245
|
+
let nftAmount = ethers_1.BigNumber.from(0);
|
246
|
+
if (amountToWithdraw.gte(userBalance) || withdrawAll) {
|
247
|
+
nftAmount = dnft.shares;
|
248
|
+
svtsToWithdraw = userSvts;
|
249
|
+
if (!withdrawAll)
|
250
|
+
totalAmountToWithdraw = totalAmountToWithdraw.sub(userBalance);
|
251
|
+
}
|
252
|
+
else {
|
253
|
+
nftAmount = amountToWithdraw.mul(dnft.shares).div(userBalance);
|
254
|
+
svtsToWithdraw = nftAmount.mul(userSvts).div(dnft.shares);
|
255
|
+
totalAmountToWithdraw = totalAmountToWithdraw.sub(amountToWithdraw);
|
256
|
+
}
|
257
|
+
shares = shares.add(svtsToWithdraw);
|
258
|
+
nftIds.push(dnft.nftId);
|
259
|
+
nftAmounts.push(nftAmount);
|
260
|
+
}
|
261
|
+
index++;
|
262
|
+
}
|
263
|
+
return {
|
264
|
+
smartVault: vault.vaultAddress.toLowerCase(),
|
265
|
+
shares: shares,
|
266
|
+
nftIds,
|
267
|
+
nftAmounts
|
268
|
+
};
|
269
|
+
});
|
270
|
+
}
|
271
|
+
getAllSvts(vaultAddress, userAddress, dnfts) {
|
272
|
+
return __awaiter(this, void 0, void 0, function* () {
|
273
|
+
const token = yield this.generateToken();
|
274
|
+
const svts = yield this.dripApi.fetchUserSVTFromNfts(vaultAddress, userAddress, dnfts.map((element) => parseInt(element.nftId)), token);
|
275
|
+
const result = dnfts.map((element, index) => { return { nftId: element.nftId, assets: element.assets, shares: element.shares, svts: svts[index] }; });
|
276
|
+
return result;
|
277
|
+
});
|
278
|
+
}
|
279
|
+
getERC20Precission(tokenAddress) {
|
280
|
+
return __awaiter(this, void 0, void 0, function* () {
|
281
|
+
if (!this.signer)
|
282
|
+
throw Error('No signer provided');
|
283
|
+
const signerAddress = yield this.signer.getAddress();
|
284
|
+
if (!signerAddress)
|
285
|
+
throw Error('Error fetching address');
|
286
|
+
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
287
|
+
const decimals = yield erc20Instance.decimals();
|
288
|
+
return decimals;
|
289
|
+
});
|
290
|
+
}
|
291
|
+
calculateFastWithdrawBalancesOld(vaultAddress, userAddress, decimals) {
|
292
|
+
return __awaiter(this, void 0, void 0, function* () {
|
293
|
+
const token = yield this.generateToken();
|
294
|
+
const fastWithdrawNFTs = yield this.dripApi.fetchFastWithdrawNFTs(vaultAddress, userAddress, token);
|
295
|
+
let fastWithdrawBalance = 0;
|
296
|
+
for (const wnft of fastWithdrawNFTs) {
|
297
|
+
if (wnft.assetsWithdrawn[0].asset && wnft.assetsWithdrawn[0].claimed) {
|
298
|
+
const value = +(0, utils_1.insertDot)(wnft.assetsWithdrawn[0].claimed, decimals);
|
299
|
+
fastWithdrawBalance += value;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
return ethers_1.ethers.utils.parseUnits(fastWithdrawBalance.toFixed(decimals), decimals);
|
303
|
+
});
|
304
|
+
}
|
305
|
+
calculatePendingDepositsOld(dnfts, decimals) {
|
306
|
+
let pendingDeposits = 0;
|
307
|
+
for (const nft of dnfts) {
|
308
|
+
if (nft['assets'] && nft['assets'][0] && !nft.isDHWFinished) {
|
309
|
+
pendingDeposits += nft['assets'][0];
|
310
|
+
}
|
311
|
+
}
|
312
|
+
pendingDeposits = +pendingDeposits.toFixed(decimals);
|
313
|
+
return ethers_1.ethers.utils.parseUnits(pendingDeposits.toString(), decimals);
|
314
|
+
}
|
315
|
+
calculateDepositsOld(dnfts, decimals) {
|
316
|
+
let deposits = 0;
|
317
|
+
for (const nft of dnfts) {
|
318
|
+
if (nft['assets'] && nft['assets'][0] && nft.isDHWFinished) {
|
319
|
+
deposits += nft['assets'][0];
|
320
|
+
}
|
321
|
+
}
|
322
|
+
deposits = +deposits.toFixed(decimals);
|
323
|
+
return ethers_1.ethers.utils.parseUnits(deposits.toString(), decimals);
|
324
|
+
}
|
325
|
+
calculatePendingDeposits(dnfts, decimals) {
|
326
|
+
let pendingDeposits = ethers_1.BigNumber.from(0);
|
327
|
+
for (const nft of dnfts) {
|
328
|
+
if (nft['assets'] && nft['assets'][0] && !nft.isDHWFinished) {
|
329
|
+
pendingDeposits = pendingDeposits.add(ethers_1.ethers.utils.parseUnits(nft['assets'][0].toString(), decimals));
|
330
|
+
}
|
331
|
+
}
|
332
|
+
return pendingDeposits;
|
333
|
+
}
|
334
|
+
calculateAllDeposits(dnfts, decimals) {
|
335
|
+
let deposits = ethers_1.BigNumber.from(0);
|
336
|
+
for (const nft of dnfts) {
|
337
|
+
deposits = deposits.add(this.calculateBalanceForDNFT(nft, decimals));
|
338
|
+
}
|
339
|
+
return deposits;
|
340
|
+
}
|
341
|
+
calculateBalanceForDNFT(dnft, decimals) {
|
342
|
+
const assets = ethers_1.BigNumber.from(ethers_1.ethers.utils.parseUnits(dnft.assets[0].toString(), decimals));
|
343
|
+
const shares = ethers_1.BigNumber.from(dnft.shares);
|
344
|
+
if (shares.eq(0)) {
|
345
|
+
return ethers_1.BigNumber.from(0);
|
346
|
+
}
|
347
|
+
return assets.mul(shares).div(1000000);
|
348
|
+
}
|
349
|
+
checkIfUserHasWithdrawsToClaim(withdrawNFTS) {
|
350
|
+
const nftIds = withdrawNFTS
|
351
|
+
//! Shares come as Strings instead of BigNumber from our Backend
|
352
|
+
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
353
|
+
.map((item) => item.nftId.toString());
|
354
|
+
const nftAmounts = withdrawNFTS
|
355
|
+
.filter((item) => !item.isBurned && ethers_1.BigNumber.from(item.shares).gt(ethers_1.BigNumber.from('0')) && item.isDHWFinished)
|
356
|
+
.map((item) => item.shares.toString());
|
357
|
+
return nftIds.length !== 0 || nftAmounts.length !== 0;
|
358
|
+
}
|
359
|
+
shouldUseNewWithdrawLogic(userAddress, vault) {
|
360
|
+
// Users that already withdrew using the old approach should keep using the same
|
361
|
+
const usersWhoAlreadyWithdraw = {
|
362
|
+
'0x5ae62d2bc40e9119aee9cd4ed50e3d9378c9a191': KASU_USDC_VAULT_ADDRESS
|
363
|
+
};
|
364
|
+
if (usersWhoAlreadyWithdraw[userAddress.toLowerCase()] && usersWhoAlreadyWithdraw[userAddress.toLowerCase()] === vault.vaultAddress.toLowerCase()) {
|
365
|
+
return false;
|
366
|
+
}
|
367
|
+
return vault.newWithdraw;
|
368
|
+
}
|
369
|
+
generateToken() {
|
370
|
+
return __awaiter(this, void 0, void 0, function* () {
|
371
|
+
if (!this.signer)
|
372
|
+
throw Error('No signer provided');
|
373
|
+
const token = yield web3_token_1.default.sign((msg) => __awaiter(this, void 0, void 0, function* () { return yield this.signer.signMessage(msg); }), '1d');
|
374
|
+
return token;
|
375
|
+
});
|
376
|
+
}
|
377
|
+
calculateAllWithdrawalBalances(wnfts, vaultAddress, decimals) {
|
378
|
+
return __awaiter(this, void 0, void 0, function* () {
|
379
|
+
if (!this.signer)
|
380
|
+
throw Error('No signer provided');
|
381
|
+
const userAddress = yield this.signer.getAddress();
|
382
|
+
let estimatedPendingWithdrawalBalance = ethers_1.BigNumber.from(0);
|
383
|
+
let estimatedWithdrawableBalance = ethers_1.BigNumber.from(0);
|
384
|
+
let withdrawals = 0;
|
385
|
+
for (const wnft of wnfts) {
|
386
|
+
// Handle burned NFTs (already withdrawn by the user)
|
387
|
+
if (wnft.assets && wnft.assets[0] && wnft.isBurned) {
|
388
|
+
withdrawals += wnft.assets[0].amount;
|
389
|
+
continue;
|
390
|
+
}
|
391
|
+
const currentBlockNumber = wnft.blockNumber - 1;
|
392
|
+
const token = yield this.generateToken();
|
393
|
+
const assetsPerSvtAtBlock = yield this.dripApi.fetchAssetPerSvtAtBlock(vaultAddress, currentBlockNumber, token);
|
394
|
+
const estimatedValueOfNFT = ethers_1.BigNumber.from(parseInt(ethers_1.ethers.utils.formatUnits(ethers_1.BigNumber.from(wnft.svtWithdrawn).mul(assetsPerSvtAtBlock), 36)).toString());
|
395
|
+
if (wnft.isDHWFinished) {
|
396
|
+
// Processed and Withdrawable
|
397
|
+
estimatedWithdrawableBalance = estimatedWithdrawableBalance.add(estimatedValueOfNFT);
|
398
|
+
}
|
399
|
+
else {
|
400
|
+
// Not processed, no DHW was ran => pending
|
401
|
+
estimatedPendingWithdrawalBalance = estimatedPendingWithdrawalBalance.add(estimatedValueOfNFT);
|
402
|
+
}
|
403
|
+
}
|
404
|
+
// return all values as BigNumber
|
405
|
+
withdrawals = +withdrawals.toFixed(decimals);
|
406
|
+
const estimatedWithdrawals = ethers_1.ethers.utils.parseUnits(withdrawals.toString(), decimals);
|
407
|
+
return [estimatedPendingWithdrawalBalance, estimatedWithdrawableBalance, estimatedWithdrawals];
|
408
|
+
});
|
409
|
+
}
|
410
|
+
getTokenAllowanceForSwapAndDepositContractAddress(tokenAddress) {
|
411
|
+
return __awaiter(this, void 0, void 0, function* () {
|
412
|
+
if (!this.signer)
|
413
|
+
throw Error('No signer provided');
|
414
|
+
const signerAddress = yield this.signer.getAddress();
|
415
|
+
if (!signerAddress)
|
416
|
+
throw Error('Error fetching address');
|
417
|
+
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
418
|
+
const swapAndDepositAddress = yield this.dripConfig.getSwapAndDepositContractAddress(this.signer);
|
419
|
+
const allowance = yield erc20Instance.allowance(signerAddress, swapAndDepositAddress);
|
420
|
+
return allowance;
|
421
|
+
});
|
422
|
+
}
|
423
|
+
approveTokenForSwapAndDepositContract(tokenAddress, amount) {
|
424
|
+
return __awaiter(this, void 0, void 0, function* () {
|
425
|
+
if (!this.signer)
|
426
|
+
throw Error('No signer provided');
|
427
|
+
const swapAndDepositContractAddress = yield this.dripConfig.getSwapAndDepositContractAddress(this.signer);
|
428
|
+
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
429
|
+
const approveTx = yield erc20Instance.approve(swapAndDepositContractAddress, amount);
|
430
|
+
yield approveTx.wait();
|
431
|
+
});
|
432
|
+
}
|
433
|
+
getTokenAllowanceForDeposit(tokenAddress) {
|
434
|
+
return __awaiter(this, void 0, void 0, function* () {
|
435
|
+
if (!this.signer)
|
436
|
+
throw Error('No signer provided');
|
437
|
+
const signerAddress = yield this.signer.getAddress();
|
438
|
+
if (!signerAddress)
|
439
|
+
throw Error('Error fetching address');
|
440
|
+
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
441
|
+
const smartVaultManagerAddress = yield this.dripConfig.getSmartVaultManagerAddress(this.signer);
|
442
|
+
const allowance = yield erc20Instance.allowance(signerAddress, smartVaultManagerAddress);
|
443
|
+
return allowance;
|
444
|
+
});
|
445
|
+
}
|
446
|
+
approveTokenForDeposit(tokenAddress, amount) {
|
447
|
+
return __awaiter(this, void 0, void 0, function* () {
|
448
|
+
if (!this.signer)
|
449
|
+
throw Error('No signer provided');
|
450
|
+
const smartVaultManagerAddress = yield this.dripConfig.getSmartVaultManagerAddress(this.signer);
|
451
|
+
const erc20Instance = spool_v2_sdk_1.ERC20__factory.connect(tokenAddress, this.signer);
|
452
|
+
const approveTx = yield erc20Instance.approve(smartVaultManagerAddress, amount);
|
453
|
+
yield approveTx.wait();
|
454
|
+
});
|
455
|
+
}
|
456
|
+
}
|
457
|
+
exports.default = DripSdk;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.DripConfig = exports.DripSdk = void 0;
|
7
|
+
const DripSdk_1 = __importDefault(require("./DripSdk"));
|
8
|
+
exports.DripSdk = DripSdk_1.default;
|
9
|
+
const DripConfig_1 = require("./DripConfig");
|
10
|
+
Object.defineProperty(exports, "DripConfig", { enumerable: true, get: function () { return DripConfig_1.DripConfig; } });
|
@@ -0,0 +1,66 @@
|
|
1
|
+
export type Vault = {
|
2
|
+
vaultName: string;
|
3
|
+
vaultAddress: string;
|
4
|
+
apy: number;
|
5
|
+
tvr: number;
|
6
|
+
protocols: string[];
|
7
|
+
projectName: string;
|
8
|
+
depositToken: VaultDepositToken;
|
9
|
+
type: VaultType;
|
10
|
+
rewards: VaultReward[];
|
11
|
+
liveUntil: string;
|
12
|
+
liveUntilFormatted: string;
|
13
|
+
hasPoolEnded: boolean;
|
14
|
+
boosters: NFTBoost[];
|
15
|
+
stretchGoals: StretchGoal[];
|
16
|
+
strategies: Strategy[];
|
17
|
+
newWithdraw: boolean;
|
18
|
+
tgePrice?: number;
|
19
|
+
maxAmountOfTokens?: number;
|
20
|
+
rewardsInformation: RewardsInformation;
|
21
|
+
};
|
22
|
+
export type VaultType = 'launch' | 'earn' | 'airdrop';
|
23
|
+
export type VaultDepositToken = {
|
24
|
+
name: string;
|
25
|
+
symbol: string;
|
26
|
+
roundingDecimals: number;
|
27
|
+
precisionDecimals: number;
|
28
|
+
tokenAddress: string;
|
29
|
+
};
|
30
|
+
export type VaultReward = {
|
31
|
+
type: 'token' | 'points';
|
32
|
+
name: string;
|
33
|
+
symbol: string;
|
34
|
+
decimals: number;
|
35
|
+
tokenAddress: string;
|
36
|
+
monthlyEmissionRate?: number;
|
37
|
+
};
|
38
|
+
export type NFTBoost = {
|
39
|
+
url: string;
|
40
|
+
tokenAddress: string;
|
41
|
+
multiplier: number;
|
42
|
+
nftAddress: string;
|
43
|
+
network: string;
|
44
|
+
initialBlock: number;
|
45
|
+
imagePath: string;
|
46
|
+
};
|
47
|
+
export interface StretchGoal {
|
48
|
+
threshhold: number;
|
49
|
+
threshholdDescription: string;
|
50
|
+
rewardTooltip: string;
|
51
|
+
rewardDescription: string;
|
52
|
+
amountOfTokens: number;
|
53
|
+
}
|
54
|
+
export type RewardsInformation = {
|
55
|
+
[tokenAddress: string]: {
|
56
|
+
blockNumber: string;
|
57
|
+
rewardrate: string;
|
58
|
+
timestamp: string;
|
59
|
+
endTime: string;
|
60
|
+
};
|
61
|
+
};
|
62
|
+
export type Strategy = {
|
63
|
+
address: string;
|
64
|
+
lastDoHardWorkTime: number | null;
|
65
|
+
lastDoHardWorkBlock: number | null;
|
66
|
+
};
|
package/dist/utils.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export declare function insertDot(numberString: string, decimals: number): string;
|
package/dist/utils.js
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.insertDot = void 0;
|
4
|
+
function insertDot(numberString, decimals) {
|
5
|
+
if (numberString.length < decimals + 1) {
|
6
|
+
numberString = '0'.repeat(decimals + 1 - numberString.length) + numberString;
|
7
|
+
}
|
8
|
+
const indexToInsertDot = numberString.length - decimals;
|
9
|
+
// Ensure there is a part before the dot, even if it's 0
|
10
|
+
const beforeDecimal = indexToInsertDot > 0 ? numberString.slice(0, indexToInsertDot) : '0';
|
11
|
+
const afterDecimal = numberString.slice(indexToInsertDot);
|
12
|
+
return `${beforeDecimal}.${afterDecimal}`;
|
13
|
+
}
|
14
|
+
exports.insertDot = insertDot;
|
package/package.json
CHANGED
@@ -1,16 +1,22 @@
|
|
1
1
|
{
|
2
2
|
"name": "@dripfi/drip-sdk",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.3",
|
4
4
|
"description": "Drip SDK",
|
5
|
-
"main": "index.js",
|
5
|
+
"main": "dist/index.js",
|
6
|
+
"types": "dist/index.d.ts",
|
6
7
|
"scripts": {
|
8
|
+
"prepublish": "npm run build",
|
9
|
+
"build": "tsc",
|
7
10
|
"test": "echo \"Error: no test specified\" && exit 1"
|
8
11
|
},
|
9
12
|
"dependencies": {
|
10
13
|
"@spool.fi/spool-v2-sdk": "1.0.14",
|
11
|
-
"
|
12
|
-
"
|
14
|
+
"ethers": "^5.7.2",
|
15
|
+
"web3-token": "^1.0.6"
|
13
16
|
},
|
14
17
|
"author": "",
|
15
|
-
"license": "ISC"
|
18
|
+
"license": "ISC",
|
19
|
+
"devDependencies": {
|
20
|
+
"typescript": "^5.4.5"
|
21
|
+
}
|
16
22
|
}
|