@kasufinance/kasu-sdk 1.0.4 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +410 -0
- package/README.md +179 -12
- package/dist/bundle.cjs.js +658 -90
- package/dist/bundle.esm.js +654 -92
- package/dist/facade/chain-configs.d.ts +11 -0
- package/dist/facade/chain-configs.js +84 -0
- package/dist/facade/chain-configs.js.map +1 -0
- package/dist/facade/deposits.d.ts +56 -0
- package/dist/facade/deposits.js +87 -0
- package/dist/facade/deposits.js.map +1 -0
- package/dist/facade/index.d.ts +6 -0
- package/dist/facade/index.js +9 -0
- package/dist/facade/index.js.map +1 -0
- package/dist/facade/kasu.d.ts +71 -0
- package/dist/facade/kasu.js +101 -0
- package/dist/facade/kasu.js.map +1 -0
- package/dist/facade/strategies.d.ts +37 -0
- package/dist/facade/strategies.js +112 -0
- package/dist/facade/strategies.js.map +1 -0
- package/dist/facade/types.d.ts +127 -0
- package/dist/facade/types.js +2 -0
- package/dist/facade/types.js.map +1 -0
- package/dist/facade/user-portfolio.d.ts +35 -0
- package/dist/facade/user-portfolio.js +53 -0
- package/dist/facade/user-portfolio.js.map +1 -0
- package/dist/index.d.ts +9 -17
- package/dist/index.js +9 -16
- package/dist/index.js.map +1 -1
- package/dist/kasu-sdk.d.ts +17 -0
- package/dist/kasu-sdk.js +17 -0
- package/dist/kasu-sdk.js.map +1 -0
- package/dist/sdk-config.d.ts +34 -4
- package/dist/sdk-config.js +9 -6
- package/dist/sdk-config.js.map +1 -1
- package/dist/services/DataService/data-service.d.ts +9 -2
- package/dist/services/DataService/data-service.js +91 -53
- package/dist/services/DataService/data-service.js.map +1 -1
- package/dist/services/DataService/queries.d.ts +0 -1
- package/dist/services/DataService/queries.js +0 -8
- package/dist/services/DataService/queries.js.map +1 -1
- package/dist/services/DataService/subgraph-types.d.ts +0 -6
- package/dist/services/DataService/types.d.ts +0 -1
- package/dist/services/Locking/locking.d.ts +9 -3
- package/dist/services/Locking/locking.js +114 -20
- package/dist/services/Locking/locking.js.map +1 -1
- package/dist/services/Locking/types.d.ts +1 -1
- package/dist/services/Portfolio/portfolio.d.ts +3 -2
- package/dist/services/Portfolio/portfolio.js +15 -7
- package/dist/services/Portfolio/portfolio.js.map +1 -1
- package/dist/services/Portfolio/types.d.ts +2 -2
- package/dist/services/UserLending/user-lending.d.ts +3 -1
- package/dist/services/UserLending/user-lending.js +9 -3
- package/dist/services/UserLending/user-lending.js.map +1 -1
- package/dist/tests/facade.test.d.ts +1 -0
- package/dist/tests/facade.test.js +196 -0
- package/dist/tests/facade.test.js.map +1 -0
- package/dist/tests/sample.test.js +19 -14
- package/dist/tests/sample.test.js.map +1 -1
- package/dist/utils/deployment-mode.d.ts +6 -0
- package/dist/utils/deployment-mode.js +8 -0
- package/dist/utils/deployment-mode.js.map +1 -0
- package/package.json +2 -2
- package/src/facade/chain-configs.ts +93 -0
- package/src/facade/deposits.ts +102 -0
- package/src/facade/index.ts +26 -0
- package/src/facade/kasu.ts +144 -0
- package/src/facade/strategies.ts +119 -0
- package/src/facade/types.ts +168 -0
- package/src/facade/user-portfolio.ts +73 -0
- package/src/index.ts +59 -25
- package/src/kasu-sdk.ts +27 -0
- package/src/sdk-config.ts +43 -15
- package/src/services/DataService/data-service.ts +106 -66
- package/src/services/DataService/queries.ts +0 -9
- package/src/services/DataService/subgraph-types.ts +0 -7
- package/src/services/DataService/types.ts +0 -1
- package/src/services/Locking/locking.ts +141 -25
- package/src/services/Locking/types.ts +1 -1
- package/src/services/Portfolio/portfolio.ts +21 -11
- package/src/services/Portfolio/types.ts +2 -2
- package/src/services/UserLending/user-lending.ts +13 -4
- package/src/tests/facade.test.ts +245 -0
- package/src/tests/sample.test.ts +7 -9
- package/src/utils/deployment-mode.ts +9 -0
|
@@ -57,29 +57,37 @@ import {
|
|
|
57
57
|
|
|
58
58
|
export class KSULocking {
|
|
59
59
|
private readonly _contractAbi: IKSULockingAbi;
|
|
60
|
-
private readonly _kasuToken: IERC20MetadataAbi;
|
|
60
|
+
private readonly _kasuToken: IERC20MetadataAbi | null;
|
|
61
61
|
private readonly _kasuBonusAddress: string;
|
|
62
62
|
private readonly _graph: GraphQLClient;
|
|
63
63
|
private readonly _userManagerAbi: IUserManagerAbi;
|
|
64
64
|
private readonly _systemVariablesAbi: ISystemVariablesAbi;
|
|
65
65
|
private readonly _ksuPriceAbi: IKsuPriceAbi;
|
|
66
66
|
private readonly _userLoyaltyRewardsAbi: IUserLoyaltyRewardsAbi;
|
|
67
|
+
private readonly _isLiteDeployment: boolean;
|
|
67
68
|
private readonly apyBonuses: number[] = [0, 0.001, 0.002];
|
|
68
|
-
|
|
69
|
-
*
|
|
70
|
-
*/
|
|
69
|
+
|
|
71
70
|
constructor(
|
|
72
71
|
private _kasuConfig: SdkConfig,
|
|
73
72
|
signerOrProvider: Signer | Provider,
|
|
74
73
|
) {
|
|
74
|
+
this._isLiteDeployment = _kasuConfig.isLiteDeployment;
|
|
75
|
+
|
|
75
76
|
this._contractAbi = IKSULockingAbi__factory.connect(
|
|
76
77
|
_kasuConfig.contracts.IKSULocking,
|
|
77
78
|
signerOrProvider,
|
|
78
79
|
);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
|
|
81
|
+
// Only initialize KSU token contract if not a Lite deployment and address is provided
|
|
82
|
+
if (!this._isLiteDeployment && _kasuConfig.contracts.KSUToken) {
|
|
83
|
+
this._kasuToken = IERC20MetadataAbi__factory.connect(
|
|
84
|
+
_kasuConfig.contracts.KSUToken,
|
|
85
|
+
signerOrProvider,
|
|
86
|
+
);
|
|
87
|
+
} else {
|
|
88
|
+
this._kasuToken = null;
|
|
89
|
+
}
|
|
90
|
+
|
|
83
91
|
this._userManagerAbi = IUserManagerAbi__factory.connect(
|
|
84
92
|
_kasuConfig.contracts.UserManager,
|
|
85
93
|
signerOrProvider,
|
|
@@ -100,10 +108,20 @@ export class KSULocking {
|
|
|
100
108
|
);
|
|
101
109
|
}
|
|
102
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Check if this is a Lite deployment (no KSU token functionality)
|
|
113
|
+
*/
|
|
114
|
+
get isLiteDeployment(): boolean {
|
|
115
|
+
return this._isLiteDeployment;
|
|
116
|
+
}
|
|
117
|
+
|
|
103
118
|
async lockKSUTokens(
|
|
104
119
|
amount: BigNumber,
|
|
105
120
|
lockPeriod: BigNumber,
|
|
106
121
|
): Promise<ContractTransaction> {
|
|
122
|
+
if (this._isLiteDeployment) {
|
|
123
|
+
throw new Error('Locking is not available on Lite deployments');
|
|
124
|
+
}
|
|
107
125
|
return this._contractAbi.lock(amount, lockPeriod);
|
|
108
126
|
}
|
|
109
127
|
|
|
@@ -112,6 +130,10 @@ export class KSULocking {
|
|
|
112
130
|
lockPeriod: number,
|
|
113
131
|
permit: RSVDeadlineValue,
|
|
114
132
|
): Promise<ContractTransaction> {
|
|
133
|
+
if (this._isLiteDeployment) {
|
|
134
|
+
throw new Error('Locking is not available on Lite deployments');
|
|
135
|
+
}
|
|
136
|
+
|
|
115
137
|
const amountBN = BigNumber.from(amount);
|
|
116
138
|
const lockPeriodBN = BigNumber.from(lockPeriod);
|
|
117
139
|
|
|
@@ -134,13 +156,27 @@ export class KSULocking {
|
|
|
134
156
|
amount: BigNumber,
|
|
135
157
|
userLockId: BigNumber,
|
|
136
158
|
): Promise<ContractTransaction> {
|
|
159
|
+
if (this._isLiteDeployment) {
|
|
160
|
+
throw new Error('Locking is not available on Lite deployments');
|
|
161
|
+
}
|
|
137
162
|
return this._contractAbi.unlock(amount, userLockId);
|
|
138
163
|
}
|
|
139
164
|
|
|
140
165
|
async claimFees(): Promise<ContractTransaction> {
|
|
166
|
+
if (this._isLiteDeployment) {
|
|
167
|
+
throw new Error('Fee claiming is not available on Lite deployments');
|
|
168
|
+
}
|
|
141
169
|
return await this._contractAbi.claimFees();
|
|
142
170
|
}
|
|
171
|
+
|
|
143
172
|
async lockDetails(lockPeriod: BigNumber): Promise<LockPeriodInterface> {
|
|
173
|
+
if (this._isLiteDeployment) {
|
|
174
|
+
return {
|
|
175
|
+
rKsuMultiplier: 0,
|
|
176
|
+
ksuBonusMultiplier: 0,
|
|
177
|
+
isActive: false,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
144
180
|
const result = await this._contractAbi.lockDetails(lockPeriod);
|
|
145
181
|
return {
|
|
146
182
|
rKsuMultiplier: result[0].toNumber(),
|
|
@@ -150,6 +186,9 @@ export class KSULocking {
|
|
|
150
186
|
}
|
|
151
187
|
|
|
152
188
|
async userTotalDeposits(userAddress: string): Promise<BigNumber> {
|
|
189
|
+
if (this._isLiteDeployment) {
|
|
190
|
+
return BigNumber.from(0);
|
|
191
|
+
}
|
|
153
192
|
return await this._contractAbi.userTotalDeposits(userAddress);
|
|
154
193
|
}
|
|
155
194
|
|
|
@@ -158,7 +197,7 @@ export class KSULocking {
|
|
|
158
197
|
KSULocked: number,
|
|
159
198
|
lockPeriod: BigNumber,
|
|
160
199
|
): Promise<number> {
|
|
161
|
-
if (KSULocked === 0) {
|
|
200
|
+
if (this._isLiteDeployment || KSULocked === 0) {
|
|
162
201
|
return 0;
|
|
163
202
|
}
|
|
164
203
|
|
|
@@ -232,22 +271,26 @@ export class KSULocking {
|
|
|
232
271
|
}
|
|
233
272
|
|
|
234
273
|
async getUserLocks(userAddress: string): Promise<UserLock[]> {
|
|
274
|
+
if (this._isLiteDeployment) {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
|
|
235
278
|
const result: GQLUserLocks = await this._graph.request(userLocksQuery, {
|
|
236
279
|
userAddress: userAddress.toLowerCase(),
|
|
237
280
|
});
|
|
238
281
|
const resultPromises = result.userLocks.map(async (userLock) => {
|
|
239
282
|
const [, id] = userLock.id.split('-');
|
|
240
|
-
const
|
|
283
|
+
const rKSUtoStableRatio = await this.getRKSUvsStableRatio(
|
|
241
284
|
userLock.rKSUAmount,
|
|
242
285
|
userAddress,
|
|
243
286
|
);
|
|
244
287
|
const loyaltyStatus =
|
|
245
|
-
this.getLoyaltyLevelAndApyBonusFromRatio(
|
|
288
|
+
this.getLoyaltyLevelAndApyBonusFromRatio(rKSUtoStableRatio);
|
|
246
289
|
return {
|
|
247
290
|
id: BigNumber.from(id),
|
|
248
291
|
lockedAmount: userLock.ksuAmount,
|
|
249
292
|
rKSUAmount: userLock.rKSUAmount,
|
|
250
|
-
|
|
293
|
+
rKSUtoStableRatio: rKSUtoStableRatio,
|
|
251
294
|
apyBonus: loyaltyStatus.apyBonus,
|
|
252
295
|
loyaltyLevel: loyaltyStatus.loyaltyLevel,
|
|
253
296
|
startTime: parseFloat(userLock.startTimestamp),
|
|
@@ -261,8 +304,14 @@ export class KSULocking {
|
|
|
261
304
|
}
|
|
262
305
|
|
|
263
306
|
async getUserBonusData(userAddress: string): Promise<UserBonusData> {
|
|
264
|
-
|
|
265
|
-
|
|
307
|
+
if (this._isLiteDeployment) {
|
|
308
|
+
return {
|
|
309
|
+
ksuBonusAndRewards: '0',
|
|
310
|
+
ksuBonusAndRewardsLifetime: '0',
|
|
311
|
+
protocolFeesEarned: '0',
|
|
312
|
+
totalLockedAmount: '0',
|
|
313
|
+
};
|
|
314
|
+
}
|
|
266
315
|
|
|
267
316
|
const DECIMALS = 18;
|
|
268
317
|
|
|
@@ -318,22 +367,31 @@ export class KSULocking {
|
|
|
318
367
|
};
|
|
319
368
|
}
|
|
320
369
|
|
|
321
|
-
getLoyaltyLevelAndApyBonusFromRatio(
|
|
370
|
+
getLoyaltyLevelAndApyBonusFromRatio(rKSUtoStableRatio: number): {
|
|
322
371
|
loyaltyLevel: number;
|
|
323
372
|
apyBonus: number;
|
|
324
373
|
} {
|
|
325
|
-
|
|
374
|
+
// On Lite deployments, always return level 0 with no bonus
|
|
375
|
+
if (this._isLiteDeployment) {
|
|
376
|
+
return { loyaltyLevel: 0, apyBonus: 0 };
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (rKSUtoStableRatio < 0.01) {
|
|
326
380
|
return { loyaltyLevel: 0, apyBonus: this.apyBonuses[0] };
|
|
327
|
-
} else if (
|
|
381
|
+
} else if (rKSUtoStableRatio < 0.05) {
|
|
328
382
|
return { loyaltyLevel: 1, apyBonus: this.apyBonuses[1] };
|
|
329
383
|
}
|
|
330
384
|
return { loyaltyLevel: 2, apyBonus: this.apyBonuses[2] };
|
|
331
385
|
}
|
|
332
386
|
|
|
333
|
-
async
|
|
387
|
+
async getRKSUvsStableRatio(
|
|
334
388
|
rKSUAmount: string,
|
|
335
389
|
userAddress: string,
|
|
336
390
|
): Promise<number> {
|
|
391
|
+
if (this._isLiteDeployment) {
|
|
392
|
+
return 0;
|
|
393
|
+
}
|
|
394
|
+
|
|
337
395
|
const [depositedAmount, pendingAmount]: [BigNumber, BigNumber] =
|
|
338
396
|
await this._userManagerAbi.userTotalPendingAndActiveDepositedAmountForCurrentEpoch(
|
|
339
397
|
userAddress,
|
|
@@ -345,18 +403,31 @@ export class KSULocking {
|
|
|
345
403
|
18,
|
|
346
404
|
);
|
|
347
405
|
|
|
348
|
-
const
|
|
406
|
+
const totalUserStableAmount =
|
|
349
407
|
depositedAmount.toNumber() + pendingAmount.toNumber();
|
|
350
408
|
|
|
351
|
-
|
|
409
|
+
// Convert rKSU value to stable asset units: rKSU * ksuPrice / 1e18 / 1e(18 - stableDecimals)
|
|
410
|
+
const decimalDiff = 18 - this._kasuConfig.stableAssetDecimals;
|
|
411
|
+
const rKSUInStable = rKSUAmountBignumber
|
|
352
412
|
.mul(ksuPrice)
|
|
353
413
|
.div(ethers.utils.parseUnits('1', 18))
|
|
354
|
-
.div(ethers.utils.parseUnits('1',
|
|
414
|
+
.div(ethers.utils.parseUnits('1', decimalDiff));
|
|
415
|
+
|
|
416
|
+
return rKSUInStable.toNumber() / totalUserStableAmount;
|
|
417
|
+
}
|
|
355
418
|
|
|
356
|
-
|
|
419
|
+
/** @deprecated Use `getRKSUvsStableRatio` instead. */
|
|
420
|
+
async getRKSUvsUSDCRatio(
|
|
421
|
+
rKSUAmount: string,
|
|
422
|
+
userAddress: string,
|
|
423
|
+
): Promise<number> {
|
|
424
|
+
return this.getRKSUvsStableRatio(rKSUAmount, userAddress);
|
|
357
425
|
}
|
|
358
426
|
|
|
359
427
|
async getClaimableRewards(userAddress: string): Promise<BigNumber> {
|
|
428
|
+
if (this._isLiteDeployment) {
|
|
429
|
+
return BigNumber.from(0);
|
|
430
|
+
}
|
|
360
431
|
const result = await this._contractAbi.rewards(userAddress);
|
|
361
432
|
return result;
|
|
362
433
|
}
|
|
@@ -364,6 +435,7 @@ export class KSULocking {
|
|
|
364
435
|
async getKasuTokenPrice(): Promise<{ price: BigNumber; decimals: number }> {
|
|
365
436
|
const decimals = 18;
|
|
366
437
|
|
|
438
|
+
// Price can still be queried on Lite deployments (set to 0 or configured value)
|
|
367
439
|
return Promise.resolve({
|
|
368
440
|
price: await this._ksuPriceAbi.ksuTokenPrice(),
|
|
369
441
|
decimals,
|
|
@@ -387,6 +459,10 @@ export class KSULocking {
|
|
|
387
459
|
rewardDecimals: number,
|
|
388
460
|
claimableRewards?: BigNumber,
|
|
389
461
|
): Promise<BigNumber> {
|
|
462
|
+
if (this._isLiteDeployment) {
|
|
463
|
+
return BigNumber.from(0);
|
|
464
|
+
}
|
|
465
|
+
|
|
390
466
|
const result: GQLClaimedFeesForAddress = await this._graph.request(
|
|
391
467
|
claimedFeesQuery,
|
|
392
468
|
{
|
|
@@ -408,6 +484,10 @@ export class KSULocking {
|
|
|
408
484
|
bonusMultiplier: number,
|
|
409
485
|
bonusTokensLeft: BigNumber,
|
|
410
486
|
): BigNumber {
|
|
487
|
+
if (this._isLiteDeployment) {
|
|
488
|
+
return BigNumber.from(0);
|
|
489
|
+
}
|
|
490
|
+
|
|
411
491
|
const bonusMultiplierBN = ethers.utils.parseUnits(
|
|
412
492
|
bonusMultiplier.toFixed(2),
|
|
413
493
|
2,
|
|
@@ -422,6 +502,10 @@ export class KSULocking {
|
|
|
422
502
|
}
|
|
423
503
|
|
|
424
504
|
async getUserStakedKsu(userAddress: string): Promise<string> {
|
|
505
|
+
if (this._isLiteDeployment) {
|
|
506
|
+
return '0';
|
|
507
|
+
}
|
|
508
|
+
|
|
425
509
|
const result: GQLStakedAmountForAddress = await this._graph.request(
|
|
426
510
|
userStakedKsuQuery,
|
|
427
511
|
{
|
|
@@ -435,6 +519,10 @@ export class KSULocking {
|
|
|
435
519
|
}
|
|
436
520
|
|
|
437
521
|
async getUserEarnedrKsu(userAddress: string): Promise<string> {
|
|
522
|
+
if (this._isLiteDeployment) {
|
|
523
|
+
return '0';
|
|
524
|
+
}
|
|
525
|
+
|
|
438
526
|
const result: GQLEarnedRKsuForAddress = await this._graph.request(
|
|
439
527
|
userEarnedrKsuQuery,
|
|
440
528
|
{
|
|
@@ -449,6 +537,10 @@ export class KSULocking {
|
|
|
449
537
|
}
|
|
450
538
|
|
|
451
539
|
async getUserTotalBonusAmount(userAddress: string): Promise<string> {
|
|
540
|
+
if (this._isLiteDeployment) {
|
|
541
|
+
return '0';
|
|
542
|
+
}
|
|
543
|
+
|
|
452
544
|
const result: GQLTotalBonusAmountForAddress = await this._graph.request(
|
|
453
545
|
userTotalBonusAmountQuery,
|
|
454
546
|
{
|
|
@@ -465,7 +557,14 @@ export class KSULocking {
|
|
|
465
557
|
async getLockingRewards(
|
|
466
558
|
userAddress: string,
|
|
467
559
|
): Promise<{ claimableRewards: string; lifeTimeRewards: string }> {
|
|
468
|
-
|
|
560
|
+
if (this._isLiteDeployment) {
|
|
561
|
+
return {
|
|
562
|
+
claimableRewards: '0',
|
|
563
|
+
lifeTimeRewards: '0',
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
const rewardDecimals = this._kasuConfig.stableAssetDecimals;
|
|
469
568
|
|
|
470
569
|
const claimableRewards = await this.getClaimableRewards(userAddress);
|
|
471
570
|
|
|
@@ -486,18 +585,26 @@ export class KSULocking {
|
|
|
486
585
|
}
|
|
487
586
|
|
|
488
587
|
async getAvailableKsuBonus(): Promise<string> {
|
|
489
|
-
|
|
588
|
+
if (this._isLiteDeployment || !this._kasuToken) {
|
|
589
|
+
return '0';
|
|
590
|
+
}
|
|
490
591
|
|
|
592
|
+
const amount = await this._kasuToken.balanceOf(this._kasuBonusAddress);
|
|
491
593
|
return formatEther(amount);
|
|
492
594
|
}
|
|
493
595
|
|
|
494
596
|
async getUserKsuBalance(userAddress: string): Promise<string> {
|
|
597
|
+
if (this._isLiteDeployment || !this._kasuToken) {
|
|
598
|
+
return '0';
|
|
599
|
+
}
|
|
600
|
+
|
|
495
601
|
const balance = await this._kasuToken.balanceOf(
|
|
496
602
|
userAddress.toLowerCase(),
|
|
497
603
|
);
|
|
498
604
|
|
|
499
605
|
return formatEther(balance);
|
|
500
606
|
}
|
|
607
|
+
|
|
501
608
|
async getNextEpochDate(): Promise<EpochTimeStamp> {
|
|
502
609
|
return (
|
|
503
610
|
await this._systemVariablesAbi.nextEpochStartTimestamp()
|
|
@@ -526,6 +633,10 @@ export class KSULocking {
|
|
|
526
633
|
}
|
|
527
634
|
|
|
528
635
|
async getActiveLockPeriods(): Promise<LockPeriod[]> {
|
|
636
|
+
if (this._isLiteDeployment) {
|
|
637
|
+
return [];
|
|
638
|
+
}
|
|
639
|
+
|
|
529
640
|
const data: GQLGetLockingPeriods =
|
|
530
641
|
await this._graph.request(lockingPeriodsQuery);
|
|
531
642
|
return data.lockPeriods;
|
|
@@ -535,7 +646,12 @@ export class KSULocking {
|
|
|
535
646
|
return '10.00';
|
|
536
647
|
}
|
|
537
648
|
|
|
538
|
-
|
|
649
|
+
getProjectedStableAmount(): string {
|
|
539
650
|
return '20.00';
|
|
540
651
|
}
|
|
652
|
+
|
|
653
|
+
/** @deprecated Use `getProjectedStableAmount` instead. */
|
|
654
|
+
getProjectedUSDC(): string {
|
|
655
|
+
return this.getProjectedStableAmount();
|
|
656
|
+
}
|
|
541
657
|
}
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
IUserLoyaltyRewardsAbi__factory,
|
|
12
12
|
} from '../../contracts';
|
|
13
13
|
import { SdkConfig } from '../../sdk-config';
|
|
14
|
+
import { isLiteDeployment } from '../../utils/deployment-mode';
|
|
14
15
|
import { DataService } from '../DataService/data-service';
|
|
15
16
|
import {
|
|
16
17
|
getAllTrancheConfigurationsQuery,
|
|
@@ -53,8 +54,9 @@ export class Portfolio {
|
|
|
53
54
|
private _userLoyaltyRewardsAbi: ReturnType<
|
|
54
55
|
typeof IUserLoyaltyRewardsAbi__factory.connect
|
|
55
56
|
>;
|
|
56
|
-
private _kasuNftContract: IKasuNFTsAbi;
|
|
57
|
+
private _kasuNftContract: IKasuNFTsAbi | null;
|
|
57
58
|
readonly _signerOrProvider: Signer | Provider;
|
|
59
|
+
private _isLiteDeployment: boolean;
|
|
58
60
|
|
|
59
61
|
constructor(
|
|
60
62
|
private _kasuConfig: SdkConfig,
|
|
@@ -75,10 +77,13 @@ export class Portfolio {
|
|
|
75
77
|
_kasuConfig,
|
|
76
78
|
signerOrProvider,
|
|
77
79
|
);
|
|
78
|
-
this.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
this._isLiteDeployment = isLiteDeployment(_kasuConfig);
|
|
81
|
+
this._kasuNftContract = _kasuConfig.contracts.KasuNFTs
|
|
82
|
+
? IKasuNFTsAbi__factory.connect(
|
|
83
|
+
_kasuConfig.contracts.KasuNFTs,
|
|
84
|
+
signerOrProvider,
|
|
85
|
+
)
|
|
86
|
+
: null;
|
|
82
87
|
this._graph = new GraphQLClient(_kasuConfig.subgraphUrl);
|
|
83
88
|
}
|
|
84
89
|
|
|
@@ -155,8 +160,8 @@ export class Portfolio {
|
|
|
155
160
|
}
|
|
156
161
|
|
|
157
162
|
/**
|
|
158
|
-
* Calculate the user's weekly protocol fee share (
|
|
159
|
-
* system variables and locking summary. All inputs are expected to be pre-fetched.
|
|
163
|
+
* Calculate the user's weekly protocol fee share (in stable asset units) given tranche
|
|
164
|
+
* balances/configs, system variables and locking summary. All inputs are expected to be pre-fetched.
|
|
160
165
|
*/
|
|
161
166
|
public calculateWeeklyProtocolFees(params: {
|
|
162
167
|
trancheBalances: TrancheSubgraphResult;
|
|
@@ -240,13 +245,13 @@ export class Portfolio {
|
|
|
240
245
|
|
|
241
246
|
if (totalUserDeposits.isZero()) return 0;
|
|
242
247
|
|
|
243
|
-
const
|
|
248
|
+
const rKSUtoStableRatio = await this._lockingService.getRKSUvsStableRatio(
|
|
244
249
|
userRksuAmount,
|
|
245
250
|
userAddress,
|
|
246
251
|
);
|
|
247
252
|
const { loyaltyLevel } =
|
|
248
253
|
this._lockingService.getLoyaltyLevelAndApyBonusFromRatio(
|
|
249
|
-
|
|
254
|
+
rKSUtoStableRatio,
|
|
250
255
|
);
|
|
251
256
|
|
|
252
257
|
const loyaltyRewardRate =
|
|
@@ -284,15 +289,20 @@ export class Portfolio {
|
|
|
284
289
|
},
|
|
285
290
|
protocolFees: {
|
|
286
291
|
claimableBalance: {
|
|
287
|
-
|
|
292
|
+
stableAmount: lockingRewards.claimableRewards,
|
|
288
293
|
},
|
|
289
|
-
lifeTime: {
|
|
294
|
+
lifeTime: { stableAmount: lockingRewards.lifeTimeRewards },
|
|
290
295
|
},
|
|
291
296
|
ksuLaunchBonus: { lifeTime: { ksuAmount: ksuLaunchBonus } },
|
|
292
297
|
};
|
|
293
298
|
}
|
|
294
299
|
|
|
295
300
|
async getUserNfts(userAddress: string): Promise<number[]> {
|
|
301
|
+
// NFTs are not available on Lite deployments
|
|
302
|
+
if (this._isLiteDeployment || !this._kasuNftContract) {
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
|
|
296
306
|
const usernfts = await this._kasuNftContract.tokensOfOwner(userAddress);
|
|
297
307
|
|
|
298
308
|
return usernfts.map((nft) => nft.toNumber());
|
|
@@ -287,17 +287,17 @@ export class UserLending {
|
|
|
287
287
|
);
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
async
|
|
290
|
+
async requestWithdrawalInAsset(
|
|
291
291
|
lendingPool: string,
|
|
292
292
|
tranche: string,
|
|
293
|
-
|
|
293
|
+
assetAmount: BigNumberish,
|
|
294
294
|
): Promise<ContractTransaction> {
|
|
295
295
|
const trancheContract: ILendingPoolTrancheAbi =
|
|
296
296
|
ILendingPoolTrancheAbi__factory.connect(
|
|
297
297
|
tranche,
|
|
298
298
|
this._signerOrProvider,
|
|
299
299
|
);
|
|
300
|
-
const shareAmount = await trancheContract.convertToShares(
|
|
300
|
+
const shareAmount = await trancheContract.convertToShares(assetAmount);
|
|
301
301
|
|
|
302
302
|
return await this._lendingPoolManagerAbi.requestWithdrawal(
|
|
303
303
|
lendingPool,
|
|
@@ -306,6 +306,15 @@ export class UserLending {
|
|
|
306
306
|
);
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
/** @deprecated Use `requestWithdrawalInAsset` instead. */
|
|
310
|
+
async requestWithdrawalInUSDC(
|
|
311
|
+
lendingPool: string,
|
|
312
|
+
tranche: string,
|
|
313
|
+
amount: BigNumberish,
|
|
314
|
+
): Promise<ContractTransaction> {
|
|
315
|
+
return this.requestWithdrawalInAsset(lendingPool, tranche, amount);
|
|
316
|
+
}
|
|
317
|
+
|
|
309
318
|
async requestWithdrawalMax(
|
|
310
319
|
lendingPool: string,
|
|
311
320
|
tranche: string,
|
|
@@ -775,7 +784,7 @@ export class UserLending {
|
|
|
775
784
|
return {
|
|
776
785
|
poolId: lendingPool.id,
|
|
777
786
|
yieldEarned:
|
|
778
|
-
parseFloat(ethers.utils.formatUnits(balance,
|
|
787
|
+
parseFloat(ethers.utils.formatUnits(balance, this._kasuConfig.stableAssetDecimals)) -
|
|
779
788
|
parseFloat(totalAcceptedDeposits) -
|
|
780
789
|
-parseFloat(totalAcceptedWithdrawnAmount),
|
|
781
790
|
balance,
|