carbon-js-sdk 0.2.13-dev.2 → 0.2.13-dev.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.
@@ -13,10 +13,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.CDPModule = void 0;
16
+ const codec_1 = require("../codec");
17
+ const query_1 = require("../codec/cdp/query");
16
18
  const tx_1 = require("../codec/cdp/tx");
19
+ const query_2 = require("../codec/cosmos/bank/v1beta1/query");
17
20
  const util_1 = require("../util");
21
+ const number_1 = require("../util/number");
22
+ const bignumber_js_1 = require("bignumber.js");
23
+ const query_3 = require("./../codec/cdp/query");
18
24
  const base_1 = __importDefault(require("./base"));
19
25
  class CDPModule extends base_1.default {
26
+ constructor() {
27
+ super(...arguments);
28
+ this.cdpModuleAddress = "";
29
+ this.collateralsAddress = "";
30
+ }
20
31
  supplyAsset(params, opts) {
21
32
  return __awaiter(this, void 0, void 0, function* () {
22
33
  const wallet = this.getWallet();
@@ -203,6 +214,326 @@ class CDPModule extends base_1.default {
203
214
  }, opts);
204
215
  });
205
216
  }
217
+ // start of cdp calculations
218
+ getAccountData(account) {
219
+ return __awaiter(this, void 0, void 0, function* () {
220
+ const sdk = this.sdkProvider;
221
+ const debtInfoResponse = yield sdk.query.cdp.TokenDebtsAll(query_3.QueryTokenDebtsAllRequest.fromPartial({}));
222
+ const debtInfos = debtInfoResponse.debtInfosAll;
223
+ const collateralsRsp = yield sdk.query.cdp.AccountCollaterals(query_3.QueryAccountCollateralsRequest.fromPartial({ account }));
224
+ const collaterals = collateralsRsp.collaterals;
225
+ const assetParamsRsp = yield sdk.query.cdp.AssetsAll(query_3.QueryAssetsAllRequest.fromPartial({}));
226
+ const assetParams = assetParamsRsp.assetParamsAll;
227
+ let totalCollateralsUsd = number_1.BN_ZERO;
228
+ let availableBorrowsUsd = number_1.BN_ZERO;
229
+ let currLiquidationThreshold = number_1.BN_ZERO;
230
+ for (let i = 0; i < collaterals.length; i++) {
231
+ const amount = (0, number_1.bnOrZero)(collaterals[i].collateralAmount);
232
+ if (amount.isZero()) {
233
+ continue;
234
+ }
235
+ const denom = collaterals[i].denom;
236
+ const debtInfo = debtInfos.find(d => d.denom === denom);
237
+ if (!debtInfo) {
238
+ return;
239
+ }
240
+ const collateralUsdVal = yield this.getCdpTokenUsdVal(collaterals[i].cdpDenom, amount);
241
+ if (!collateralUsdVal) {
242
+ return;
243
+ }
244
+ const assetParam = assetParams.find(a => a.denom === denom);
245
+ if (!assetParam) {
246
+ return;
247
+ }
248
+ const ltv = (0, number_1.bnOrZero)(assetParam.loanToValue).div(number_1.BN_10000);
249
+ const availableBorrowUsd = collateralUsdVal.times(ltv);
250
+ const liquidationThreshold = (0, number_1.bnOrZero)(assetParam.liquidationThreshold).div(number_1.BN_10000);
251
+ const liquidationThresholdVal = collateralUsdVal.times(liquidationThreshold);
252
+ totalCollateralsUsd = totalCollateralsUsd.plus(collateralUsdVal);
253
+ availableBorrowsUsd = availableBorrowsUsd.plus(availableBorrowUsd);
254
+ currLiquidationThreshold = currLiquidationThreshold.plus(liquidationThresholdVal);
255
+ }
256
+ // add token debts
257
+ const debtsRsp = yield sdk.query.cdp.AccountDebts(query_1.QueryAccountDebtsRequest.fromPartial({ account }));
258
+ const debts = debtsRsp.debts;
259
+ let totalDebtsUsd = number_1.BN_ZERO;
260
+ for (let i = 0; i < debts.length; i++) {
261
+ const amount = (0, number_1.bnOrZero)(debts[i].principalDebt);
262
+ const denom = debts[i].denom;
263
+ if (amount.isZero()) {
264
+ continue;
265
+ }
266
+ const debtInfo = debtInfos.find(d => d.denom === denom);
267
+ if (!debtInfo) {
268
+ return;
269
+ }
270
+ const tokenDebtUsdVal = yield this.getTotalAccountTokenDebtUsdVal(account, denom, debts[i], debtInfo);
271
+ if (!tokenDebtUsdVal) {
272
+ return;
273
+ }
274
+ totalDebtsUsd = totalDebtsUsd.plus(tokenDebtUsdVal);
275
+ }
276
+ // add stablecoin debt
277
+ const accountStablecoin = yield sdk.query.cdp.AccountStablecoin({ account: account });
278
+ const stablecoinDecimals = yield this.sdkProvider.getTokenClient().getDecimals("usc");
279
+ if (!stablecoinDecimals) {
280
+ return;
281
+ }
282
+ const stablecoinDebt = new bignumber_js_1.BigNumber(accountStablecoin.principalDebt).plus(accountStablecoin.interestDebt);
283
+ totalDebtsUsd = totalDebtsUsd.plus(stablecoinDebt.shiftedBy(-stablecoinDecimals));
284
+ const healthFactor = currLiquidationThreshold.div(totalDebtsUsd);
285
+ return {
286
+ TotalCollateralsUsd: totalCollateralsUsd,
287
+ AvailableBorrowsUsd: availableBorrowsUsd,
288
+ CurrLiquidationThreshold: currLiquidationThreshold,
289
+ TotalDebtsUsd: totalDebtsUsd,
290
+ HealthFactor: healthFactor,
291
+ };
292
+ });
293
+ }
294
+ getCdpToActualRatio(cdpDenom) {
295
+ return __awaiter(this, void 0, void 0, function* () {
296
+ const sdk = this.sdkProvider;
297
+ const denom = this.getUnderlyingDenom(cdpDenom);
298
+ if (!denom) {
299
+ return;
300
+ }
301
+ const supplyRsp = yield sdk.query.bank.SupplyOf(query_2.QuerySupplyOfRequest.fromPartial({ denom: cdpDenom }));
302
+ const cdpAmountRsp = supplyRsp.amount;
303
+ if (!cdpAmountRsp) {
304
+ return;
305
+ }
306
+ const cdpAmount = (0, number_1.bnOrZero)(cdpAmountRsp.amount);
307
+ if (!this.cdpModuleAddress) {
308
+ const moduleAddressRsp = yield sdk.query.misc.ModuleAddress(codec_1.QueryModuleAddressRequest.fromPartial({ module: "cdp" }));
309
+ this.cdpModuleAddress = moduleAddressRsp.address;
310
+ }
311
+ const balanceRsp = yield sdk.query.bank.Balance(query_2.QueryBalanceRequest.fromPartial({ address: this.cdpModuleAddress, denom }));
312
+ if (!balanceRsp.balance) {
313
+ return;
314
+ }
315
+ let actualAmount = (0, number_1.bnOrZero)(balanceRsp.balance.amount);
316
+ const owedAmount = yield this.getTotalTokenDebt(denom);
317
+ if (!owedAmount) {
318
+ return;
319
+ }
320
+ actualAmount = actualAmount.plus(owedAmount);
321
+ const ratio = cdpAmount.div(actualAmount);
322
+ return ratio;
323
+ });
324
+ }
325
+ getTotalAccountTokenDebtUsdVal(account, denom, debt, debtInfo) {
326
+ return __awaiter(this, void 0, void 0, function* () {
327
+ const amount = yield this.getTotalAccountTokenDebt(account, denom, debt, debtInfo).catch((err) => console.log(err));
328
+ if (!amount) {
329
+ return;
330
+ }
331
+ const tokenDebtUsdVal = yield this.getTokenUsdVal(denom, amount).catch((err) => console.log(err));
332
+ return tokenDebtUsdVal;
333
+ });
334
+ }
335
+ getModuleTotalDebtUsdVal() {
336
+ return __awaiter(this, void 0, void 0, function* () {
337
+ let totalDebt = new bignumber_js_1.BigNumber(0);
338
+ // get token debts
339
+ const allDebtsRes = yield this.sdkProvider.query.cdp.TokenDebtsAll({});
340
+ const allDebts = allDebtsRes.debtInfosAll;
341
+ for (let i = 0; i < allDebts.length; i++) {
342
+ const denom = allDebts[i].denom;
343
+ const initialCIM = allDebts[i].initialCumulativeInterestMultiplier;
344
+ const principal = allDebts[i].totalPrincipal;
345
+ const CIM = yield this.recalculateCIM(denom, allDebts[i]);
346
+ const debtAmt = CIM.div(initialCIM).multipliedBy(principal);
347
+ const debtUsdVal = yield this.getTokenUsdVal(denom, debtAmt);
348
+ if (!debtUsdVal) {
349
+ return;
350
+ }
351
+ totalDebt = totalDebt.plus(debtUsdVal);
352
+ }
353
+ // get stablecoin debts
354
+ const stablecoinDebtRes = yield this.sdkProvider.query.cdp.StablecoinDebt({});
355
+ const stablecoinDebt = stablecoinDebtRes.stablecoinDebtInfo;
356
+ if (!stablecoinDebt) {
357
+ return;
358
+ }
359
+ const CIM = new bignumber_js_1.BigNumber(stablecoinDebt.cumulativeInterestMultiplier);
360
+ const initialCIM = new bignumber_js_1.BigNumber(stablecoinDebt.initialCumulativeInterestMultiplier);
361
+ const debtAmt = CIM.div(initialCIM).multipliedBy(stablecoinDebt.totalPrincipal);
362
+ const stablecoinDecimals = yield this.sdkProvider.getTokenClient().getDecimals(stablecoinDebt.denom);
363
+ if (!stablecoinDecimals) {
364
+ return;
365
+ }
366
+ const debtUsdVal = debtAmt.shiftedBy(-stablecoinDecimals);
367
+ totalDebt = totalDebt.plus(debtUsdVal);
368
+ return totalDebt;
369
+ });
370
+ }
371
+ getModuleTotalCollateralUsdVal() {
372
+ return __awaiter(this, void 0, void 0, function* () {
373
+ const allCollaterals = yield this.sdkProvider.query.cdp.CollateralsAll({});
374
+ let allCollateralsUsdValue = new bignumber_js_1.BigNumber(0);
375
+ for (let i = 0; i < allCollaterals.collaterals.length; i++) {
376
+ const denom = allCollaterals.collaterals[i].denom;
377
+ const amount = new bignumber_js_1.BigNumber(allCollaterals.collaterals[i].amount);
378
+ const collateralUsdValue = yield this.getCdpTokenUsdVal(denom, amount);
379
+ if (!collateralUsdValue) {
380
+ return;
381
+ }
382
+ allCollateralsUsdValue = allCollateralsUsdValue.plus(collateralUsdValue);
383
+ }
384
+ return allCollateralsUsdValue;
385
+ });
386
+ }
387
+ getCdpTokenUsdVal(cdpDenom, amount) {
388
+ return __awaiter(this, void 0, void 0, function* () {
389
+ const denom = this.getUnderlyingDenom(cdpDenom);
390
+ if (!denom) {
391
+ return;
392
+ }
393
+ const ratio = yield this.getCdpToActualRatio(cdpDenom);
394
+ if (!ratio) {
395
+ return;
396
+ }
397
+ const actualTokenAmount = amount.div(ratio);
398
+ const cdpTokenUsdVal = yield this.getTokenUsdVal(denom, actualTokenAmount);
399
+ return cdpTokenUsdVal;
400
+ });
401
+ }
402
+ getTokenUsdVal(denom, amount) {
403
+ return __awaiter(this, void 0, void 0, function* () {
404
+ const sdk = this.sdkProvider;
405
+ const decimals = yield this.sdkProvider.getTokenClient().getDecimals(denom);
406
+ if (!decimals) {
407
+ return;
408
+ }
409
+ const price = yield sdk.query.pricing.TokenPrice(codec_1.QueryTokenPriceRequest.fromPartial({ denom }));
410
+ if (!price.tokenPrice) {
411
+ return;
412
+ }
413
+ const twap = (0, number_1.bnOrZero)(price.tokenPrice.twap).shiftedBy(18 * (-1));
414
+ return amount.times(twap).shiftedBy(decimals * (-1));
415
+ });
416
+ }
417
+ getTotalTokenDebt(denom, debtInfo) {
418
+ return __awaiter(this, void 0, void 0, function* () {
419
+ if (!debtInfo) {
420
+ const debtInfoRsp = yield this.sdkProvider.query.cdp.TokenDebt(query_1.QueryTokenDebtRequest.fromPartial({ denom }));
421
+ debtInfo = debtInfoRsp.debtInfo;
422
+ }
423
+ if (!debtInfo) {
424
+ return;
425
+ }
426
+ const cim = yield this.recalculateCIM(denom, debtInfo);
427
+ if (!cim) {
428
+ return;
429
+ }
430
+ const principalAmount = (0, number_1.bnOrZero)(debtInfo.totalPrincipal);
431
+ const initialCIM = (0, number_1.bnOrZero)(debtInfo.initialCumulativeInterestMultiplier);
432
+ return principalAmount.times(cim).div(initialCIM);
433
+ });
434
+ }
435
+ getTotalAccountTokenDebt(account, denom, debt, debtInfo) {
436
+ return __awaiter(this, void 0, void 0, function* () {
437
+ const sdk = this.sdkProvider;
438
+ if (!debtInfo) {
439
+ const debtInfoRsp = yield sdk.query.cdp.TokenDebt(query_1.QueryTokenDebtRequest.fromPartial({ denom }));
440
+ debtInfo = debtInfoRsp.debtInfo;
441
+ }
442
+ if (!debtInfo) {
443
+ return;
444
+ }
445
+ if (!debt) {
446
+ const debtRes = yield sdk.query.cdp.AccountDebt({ account: account, denom: denom });
447
+ debt = debtRes.debt;
448
+ }
449
+ if (!debt) {
450
+ return;
451
+ }
452
+ const principalAmount = (0, number_1.bnOrZero)(debt.principalDebt);
453
+ const initialCIM = (0, number_1.bnOrZero)(debt.initialCumulativeInterestMultiplier);
454
+ const cim = yield this.recalculateCIM(denom, debtInfo);
455
+ if (!cim) {
456
+ return;
457
+ }
458
+ // TODO: change to round up
459
+ const totalAmountTokenDebt = principalAmount.times(cim).dividedToIntegerBy(initialCIM);
460
+ return totalAmountTokenDebt;
461
+ });
462
+ }
463
+ calculateAPY(denom, debtInfo, assetParams, rateStrategyParams) {
464
+ return __awaiter(this, void 0, void 0, function* () {
465
+ const sdk = this.sdkProvider;
466
+ if (!debtInfo) {
467
+ const debtInfoResponse = yield sdk.query.cdp.TokenDebt(query_1.QueryTokenDebtRequest.fromPartial({ denom }));
468
+ debtInfo = debtInfoResponse.debtInfo;
469
+ if (!debtInfo) {
470
+ return;
471
+ }
472
+ }
473
+ if (!assetParams) {
474
+ const assetResponse = yield sdk.query.cdp.Asset(query_1.QueryAssetRequest.fromPartial({ denom }));
475
+ assetParams = assetResponse.assetParams;
476
+ if (!assetParams) {
477
+ return;
478
+ }
479
+ }
480
+ if (!rateStrategyParams) {
481
+ const rateStrategyParamsResponse = yield sdk.query.cdp.RateStrategy(query_1.QueryRateStrategyRequest.fromPartial({
482
+ name: assetParams.rateStrategyName
483
+ }));
484
+ rateStrategyParams = rateStrategyParamsResponse.rateStrategyParams;
485
+ if (!rateStrategyParams) {
486
+ return;
487
+ }
488
+ }
489
+ const utilizationRate = (0, number_1.bnOrZero)(debtInfo.utilizationRate).shiftedBy(-18);
490
+ const optimalUsage = (0, number_1.bnOrZero)(rateStrategyParams.optimalUsage).div(number_1.BN_10000);
491
+ const variableRate1 = (0, number_1.bnOrZero)(rateStrategyParams.variableRateSlope1).div(number_1.BN_10000);
492
+ const variableRate2 = (0, number_1.bnOrZero)(rateStrategyParams.variableRateSlope2).div(number_1.BN_10000);
493
+ const baseVariableBorrowRate = (0, number_1.bnOrZero)(rateStrategyParams.baseVariableBorrowRate).div(number_1.BN_10000);
494
+ if (utilizationRate.lte(optimalUsage)) {
495
+ return utilizationRate.times(variableRate1).div(optimalUsage).plus(baseVariableBorrowRate);
496
+ }
497
+ else {
498
+ const ratio = utilizationRate.minus(optimalUsage).div(number_1.BN_ONE.minus(optimalUsage));
499
+ return ratio.times(variableRate2).plus(variableRate1).plus(baseVariableBorrowRate);
500
+ }
501
+ });
502
+ }
503
+ calculateInterestForTimePeriod(apy, start, end) {
504
+ if (end <= start) {
505
+ return number_1.BN_ZERO;
506
+ }
507
+ const duration = (0, number_1.bnOrZero)(end.valueOf() - start.valueOf());
508
+ const millisecondsAYear = (0, number_1.bnOrZero)(31536000000);
509
+ const interest = duration.div(millisecondsAYear).times(apy);
510
+ return interest;
511
+ }
512
+ recalculateCIM(denom, debtInfo) {
513
+ var _a;
514
+ return __awaiter(this, void 0, void 0, function* () {
515
+ const sdk = this.sdkProvider;
516
+ if (!debtInfo) {
517
+ const debtInfoResponse = yield sdk.query.cdp.TokenDebt(query_1.QueryTokenDebtRequest.fromPartial({ denom }));
518
+ debtInfo = debtInfoResponse.debtInfo;
519
+ if (!debtInfo) {
520
+ return number_1.BN_ZERO;
521
+ }
522
+ }
523
+ const cim = (0, number_1.bnOrZero)(debtInfo.cumulativeInterestMultiplier);
524
+ const apy = yield this.calculateAPY(denom, debtInfo);
525
+ if (!apy) {
526
+ return number_1.BN_ZERO;
527
+ }
528
+ const interest = this.calculateInterestForTimePeriod(apy, (_a = debtInfo.lastUpdatedTime) !== null && _a !== void 0 ? _a : new Date(0), new Date());
529
+ const newCIM = cim.times(interest.plus(1));
530
+ return newCIM;
531
+ });
532
+ }
533
+ getUnderlyingDenom(cdpDenom) {
534
+ var _a;
535
+ return (_a = this.sdkProvider.getTokenClient().getCdpUnderlyingToken(cdpDenom)) === null || _a === void 0 ? void 0 : _a.denom;
536
+ }
206
537
  }
207
538
  exports.CDPModule = CDPModule;
208
539
  ;
@@ -1,6 +1,7 @@
1
1
  import BigNumber from "bignumber.js";
2
2
  export declare const BN_ONE: BigNumber;
3
3
  export declare const BN_ZERO: BigNumber;
4
+ export declare const BN_10000: BigNumber;
4
5
  export declare const parseBN: (input?: string | number | BigNumber | null | undefined, defaultValue?: BigNumber | undefined) => BigNumber | undefined;
5
6
  export declare const bnOrZero: (input?: string | number | BigNumber | null | undefined, defaultValue?: BigNumber) => BigNumber;
6
7
  export declare const toHuman: (value?: string | number | BigNumber | null | undefined, decimals?: string | number | BigNumber | null | undefined) => BigNumber | undefined;
@@ -3,10 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generateNonce = exports.toUnitless = exports.toHuman = exports.bnOrZero = exports.parseBN = exports.BN_ZERO = exports.BN_ONE = void 0;
6
+ exports.generateNonce = exports.toUnitless = exports.toHuman = exports.bnOrZero = exports.parseBN = exports.BN_10000 = exports.BN_ZERO = exports.BN_ONE = void 0;
7
7
  const bignumber_js_1 = __importDefault(require("bignumber.js"));
8
8
  exports.BN_ONE = new bignumber_js_1.default(1);
9
9
  exports.BN_ZERO = new bignumber_js_1.default(0);
10
+ exports.BN_10000 = new bignumber_js_1.default(10000);
10
11
  const parseBN = (input, defaultValue) => {
11
12
  if (!input && input !== 0)
12
13
  return defaultValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "carbon-js-sdk",
3
- "version": "0.2.13-dev.2",
3
+ "version": "0.2.13-dev.3+306c777561d7",
4
4
  "description": "TypeScript SDK for Carbon blockchain",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",