@kamino-finance/klend-sdk 6.0.5-beta.20 → 6.0.5-beta.22
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/classes/manager.d.ts.map +1 -1
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/obligation.d.ts +32 -2
- package/dist/classes/obligation.d.ts.map +1 -1
- package/dist/classes/obligation.js +150 -24
- package/dist/classes/obligation.js.map +1 -1
- package/dist/classes/reserve.d.ts +5 -0
- package/dist/classes/reserve.d.ts.map +1 -1
- package/dist/classes/reserve.js +13 -0
- package/dist/classes/reserve.js.map +1 -1
- package/package.json +2 -2
- package/src/classes/manager.ts +0 -1
- package/src/classes/obligation.ts +201 -36
- package/src/classes/reserve.ts +16 -0
|
@@ -39,6 +39,11 @@ export type Position = {
|
|
|
39
39
|
marketValueRefreshed: Decimal;
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
+
export type PositionChange = {
|
|
43
|
+
reserveAddress: PublicKey;
|
|
44
|
+
amountChangeLamports: Decimal;
|
|
45
|
+
};
|
|
46
|
+
|
|
42
47
|
export type ObligationStats = {
|
|
43
48
|
userTotalDeposit: Decimal;
|
|
44
49
|
userTotalCollateralDeposit: Decimal;
|
|
@@ -491,19 +496,20 @@ export class KaminoObligation {
|
|
|
491
496
|
|
|
492
497
|
simulateDepositChange(
|
|
493
498
|
obligationDeposits: ObligationCollateral[],
|
|
494
|
-
|
|
495
|
-
changeReserve: PublicKey,
|
|
499
|
+
depositChange: PositionChange,
|
|
496
500
|
collateralExchangeRates: Map<PublicKey, Decimal>
|
|
497
501
|
): ObligationCollateral[] {
|
|
498
502
|
const newDeposits: ObligationCollateral[] = [];
|
|
499
|
-
const depositIndex = obligationDeposits.findIndex((deposit) =>
|
|
503
|
+
const depositIndex = obligationDeposits.findIndex((deposit) =>
|
|
504
|
+
deposit.depositReserve.equals(depositChange.reserveAddress)
|
|
505
|
+
);
|
|
500
506
|
|
|
501
507
|
// Always copy the previous deposits and modify the changeReserve one if it exists
|
|
502
508
|
for (let i = 0; i < obligationDeposits.length; i++) {
|
|
503
|
-
if (obligationDeposits[i].depositReserve.equals(
|
|
509
|
+
if (obligationDeposits[i].depositReserve.equals(depositChange.reserveAddress)) {
|
|
504
510
|
const coll: ObligationCollateralFields = { ...obligationDeposits[i] };
|
|
505
|
-
const exchangeRate = collateralExchangeRates.get(
|
|
506
|
-
const changeInCollateral = new Decimal(
|
|
511
|
+
const exchangeRate = collateralExchangeRates.get(depositChange.reserveAddress)!;
|
|
512
|
+
const changeInCollateral = new Decimal(depositChange.amountChangeLamports).mul(exchangeRate).toFixed(0);
|
|
507
513
|
const updatedDeposit = new Decimal(obligationDeposits[i].depositedAmount.toNumber()).add(changeInCollateral);
|
|
508
514
|
coll.depositedAmount = new BN(positiveOrZero(updatedDeposit).toString());
|
|
509
515
|
newDeposits.push(new ObligationCollateral(coll));
|
|
@@ -523,10 +529,10 @@ export class KaminoObligation {
|
|
|
523
529
|
}
|
|
524
530
|
|
|
525
531
|
const coll: ObligationCollateralFields = { ...obligationDeposits[firstBorrowIndexAvailable] };
|
|
526
|
-
const exchangeRate = collateralExchangeRates.get(
|
|
527
|
-
const changeInCollateral = new Decimal(
|
|
532
|
+
const exchangeRate = collateralExchangeRates.get(depositChange.reserveAddress)!;
|
|
533
|
+
const changeInCollateral = new Decimal(depositChange.amountChangeLamports).mul(exchangeRate).toFixed(0);
|
|
528
534
|
coll.depositedAmount = new BN(positiveOrZero(new Decimal(changeInCollateral)).toString());
|
|
529
|
-
coll.depositReserve =
|
|
535
|
+
coll.depositReserve = depositChange.reserveAddress;
|
|
530
536
|
|
|
531
537
|
newDeposits[firstBorrowIndexAvailable] = new ObligationCollateral(coll);
|
|
532
538
|
}
|
|
@@ -536,18 +542,21 @@ export class KaminoObligation {
|
|
|
536
542
|
|
|
537
543
|
simulateBorrowChange(
|
|
538
544
|
obligationBorrows: ObligationLiquidity[],
|
|
539
|
-
|
|
540
|
-
changeReserve: PublicKey,
|
|
545
|
+
borrowChange: PositionChange,
|
|
541
546
|
cumulativeBorrowRate: Decimal
|
|
542
547
|
): ObligationLiquidity[] {
|
|
543
548
|
const newBorrows: ObligationLiquidity[] = [];
|
|
544
|
-
const borrowIndex = obligationBorrows.findIndex((borrow) =>
|
|
549
|
+
const borrowIndex = obligationBorrows.findIndex((borrow) =>
|
|
550
|
+
borrow.borrowReserve.equals(borrowChange.reserveAddress)
|
|
551
|
+
);
|
|
545
552
|
|
|
546
553
|
// Always copy the previous borrows and modify the changeReserve one if it exists
|
|
547
554
|
for (let i = 0; i < obligationBorrows.length; i++) {
|
|
548
|
-
if (obligationBorrows[i].borrowReserve.equals(
|
|
555
|
+
if (obligationBorrows[i].borrowReserve.equals(borrowChange.reserveAddress)) {
|
|
549
556
|
const borrow: ObligationLiquidityFields = { ...obligationBorrows[borrowIndex] };
|
|
550
|
-
const newBorrowedAmount: Decimal = new Fraction(borrow.borrowedAmountSf)
|
|
557
|
+
const newBorrowedAmount: Decimal = new Fraction(borrow.borrowedAmountSf)
|
|
558
|
+
.toDecimal()
|
|
559
|
+
.add(borrowChange.amountChangeLamports);
|
|
551
560
|
const newBorrowedAmountSf = Fraction.fromDecimal(positiveOrZero(newBorrowedAmount)).getValue();
|
|
552
561
|
borrow.borrowedAmountSf = newBorrowedAmountSf;
|
|
553
562
|
|
|
@@ -568,8 +577,8 @@ export class KaminoObligation {
|
|
|
568
577
|
}
|
|
569
578
|
|
|
570
579
|
const borrow: ObligationLiquidityFields = { ...obligationBorrows[firstBorrowIndexAvailable] };
|
|
571
|
-
borrow.borrowedAmountSf = Fraction.fromDecimal(new Decimal(
|
|
572
|
-
borrow.borrowReserve =
|
|
580
|
+
borrow.borrowedAmountSf = Fraction.fromDecimal(new Decimal(borrowChange.amountChangeLamports)).getValue();
|
|
581
|
+
borrow.borrowReserve = borrowChange.reserveAddress;
|
|
573
582
|
borrow.cumulativeBorrowRateBsf = {
|
|
574
583
|
padding: [],
|
|
575
584
|
value: [Fraction.fromDecimal(cumulativeBorrowRate).getValue(), new BN(0), new BN(0), new BN(0)],
|
|
@@ -643,8 +652,10 @@ export class KaminoObligation {
|
|
|
643
652
|
}
|
|
644
653
|
newObligationDeposits = this.simulateDepositChange(
|
|
645
654
|
this.state.deposits,
|
|
646
|
-
|
|
647
|
-
|
|
655
|
+
{
|
|
656
|
+
reserveAddress: collateralReservePk!,
|
|
657
|
+
amountChangeLamports: amountCollateral,
|
|
658
|
+
},
|
|
648
659
|
collateralExchangeRates
|
|
649
660
|
);
|
|
650
661
|
break;
|
|
@@ -656,8 +667,10 @@ export class KaminoObligation {
|
|
|
656
667
|
|
|
657
668
|
newObligationBorrows = this.simulateBorrowChange(
|
|
658
669
|
this.state.borrows,
|
|
659
|
-
|
|
660
|
-
|
|
670
|
+
{
|
|
671
|
+
reserveAddress: debtReservePk!,
|
|
672
|
+
amountChangeLamports: amountDebt,
|
|
673
|
+
},
|
|
661
674
|
debtReserveCumulativeBorrowRate!
|
|
662
675
|
);
|
|
663
676
|
break;
|
|
@@ -669,8 +682,10 @@ export class KaminoObligation {
|
|
|
669
682
|
|
|
670
683
|
newObligationBorrows = this.simulateBorrowChange(
|
|
671
684
|
this.state.borrows,
|
|
672
|
-
|
|
673
|
-
|
|
685
|
+
{
|
|
686
|
+
reserveAddress: debtReservePk!,
|
|
687
|
+
amountChangeLamports: amountDebt.neg(),
|
|
688
|
+
},
|
|
674
689
|
debtReserveCumulativeBorrowRate!
|
|
675
690
|
);
|
|
676
691
|
|
|
@@ -683,8 +698,10 @@ export class KaminoObligation {
|
|
|
683
698
|
}
|
|
684
699
|
newObligationDeposits = this.simulateDepositChange(
|
|
685
700
|
this.state.deposits,
|
|
686
|
-
|
|
687
|
-
|
|
701
|
+
{
|
|
702
|
+
reserveAddress: collateralReservePk!,
|
|
703
|
+
amountChangeLamports: amountCollateral.neg(),
|
|
704
|
+
},
|
|
688
705
|
collateralExchangeRates
|
|
689
706
|
);
|
|
690
707
|
break;
|
|
@@ -700,15 +717,19 @@ export class KaminoObligation {
|
|
|
700
717
|
}
|
|
701
718
|
newObligationDeposits = this.simulateDepositChange(
|
|
702
719
|
this.state.deposits,
|
|
703
|
-
|
|
704
|
-
|
|
720
|
+
{
|
|
721
|
+
reserveAddress: collateralReservePk!,
|
|
722
|
+
amountChangeLamports: amountCollateral,
|
|
723
|
+
},
|
|
705
724
|
collateralExchangeRates
|
|
706
725
|
);
|
|
707
726
|
|
|
708
727
|
newObligationBorrows = this.simulateBorrowChange(
|
|
709
728
|
this.state.borrows,
|
|
710
|
-
|
|
711
|
-
|
|
729
|
+
{
|
|
730
|
+
reserveAddress: debtReservePk!,
|
|
731
|
+
amountChangeLamports: amountDebt,
|
|
732
|
+
},
|
|
712
733
|
debtReserveCumulativeBorrowRate!
|
|
713
734
|
);
|
|
714
735
|
break;
|
|
@@ -724,14 +745,18 @@ export class KaminoObligation {
|
|
|
724
745
|
}
|
|
725
746
|
newObligationDeposits = this.simulateDepositChange(
|
|
726
747
|
this.state.deposits,
|
|
727
|
-
|
|
728
|
-
|
|
748
|
+
{
|
|
749
|
+
reserveAddress: collateralReservePk!,
|
|
750
|
+
amountChangeLamports: amountCollateral.neg(),
|
|
751
|
+
},
|
|
729
752
|
collateralExchangeRates
|
|
730
753
|
);
|
|
731
754
|
newObligationBorrows = this.simulateBorrowChange(
|
|
732
755
|
this.state.borrows,
|
|
733
|
-
|
|
734
|
-
|
|
756
|
+
{
|
|
757
|
+
reserveAddress: debtReservePk!,
|
|
758
|
+
amountChangeLamports: amountDebt.neg(),
|
|
759
|
+
},
|
|
735
760
|
debtReserveCumulativeBorrowRate!
|
|
736
761
|
);
|
|
737
762
|
break;
|
|
@@ -803,14 +828,18 @@ export class KaminoObligation {
|
|
|
803
828
|
let newObligationDeposits = this.state.deposits;
|
|
804
829
|
newObligationDeposits = this.simulateDepositChange(
|
|
805
830
|
newObligationDeposits,
|
|
806
|
-
|
|
807
|
-
|
|
831
|
+
{
|
|
832
|
+
reserveAddress: withdrawReserveAddress,
|
|
833
|
+
amountChangeLamports: withdrawAmountLamports.neg(),
|
|
834
|
+
},
|
|
808
835
|
collateralExchangeRates
|
|
809
836
|
);
|
|
810
837
|
newObligationDeposits = this.simulateDepositChange(
|
|
811
838
|
newObligationDeposits,
|
|
812
|
-
|
|
813
|
-
|
|
839
|
+
{
|
|
840
|
+
reserveAddress: depositReserveAddress,
|
|
841
|
+
amountChangeLamports: depositAmountLamports,
|
|
842
|
+
},
|
|
814
843
|
collateralExchangeRates
|
|
815
844
|
);
|
|
816
845
|
|
|
@@ -947,6 +976,7 @@ export class KaminoObligation {
|
|
|
947
976
|
} else {
|
|
948
977
|
exchangeRate = reserve.getCollateralExchangeRate();
|
|
949
978
|
}
|
|
979
|
+
|
|
950
980
|
const supplyAmount = new Decimal(deposit.depositedAmount.toString()).div(exchangeRate);
|
|
951
981
|
|
|
952
982
|
const depositValueUsd = supplyAmount.mul(getPx(reserve)).div(reserve.getMintFactor());
|
|
@@ -1074,6 +1104,73 @@ export class KaminoObligation {
|
|
|
1074
1104
|
return borrowLimit.div(userTotalCollateralDeposit);
|
|
1075
1105
|
}
|
|
1076
1106
|
|
|
1107
|
+
/**
|
|
1108
|
+
* Creates a new KaminoObligation with simulated position changes applied.
|
|
1109
|
+
* This allows you to model what the obligation would look like with deposits/borrows
|
|
1110
|
+
* without actually executing those transactions.
|
|
1111
|
+
*
|
|
1112
|
+
* @param market - The KaminoMarket instance
|
|
1113
|
+
* @param slot - The slot number for rate calculations
|
|
1114
|
+
* @param depositChanges - Optional array of deposit changes to apply
|
|
1115
|
+
* @param borrowChanges - Optional array of borrow changes to apply
|
|
1116
|
+
* @returns A new KaminoObligation instance with the changes applied
|
|
1117
|
+
*/
|
|
1118
|
+
withPositionChanges(
|
|
1119
|
+
market: KaminoMarket,
|
|
1120
|
+
slot: number,
|
|
1121
|
+
depositChanges?: PositionChange[],
|
|
1122
|
+
borrowChanges?: PositionChange[]
|
|
1123
|
+
): KaminoObligation {
|
|
1124
|
+
const reservesToRefresh: PublicKey[] = [];
|
|
1125
|
+
|
|
1126
|
+
if (depositChanges) {
|
|
1127
|
+
reservesToRefresh.push(...depositChanges.map((change) => change.reserveAddress));
|
|
1128
|
+
}
|
|
1129
|
+
if (borrowChanges) {
|
|
1130
|
+
reservesToRefresh.push(...borrowChanges.map((change) => change.reserveAddress));
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
const { collateralExchangeRates, cumulativeBorrowRates } = KaminoObligation.getRatesForObligation(
|
|
1134
|
+
market,
|
|
1135
|
+
this.state,
|
|
1136
|
+
slot,
|
|
1137
|
+
reservesToRefresh
|
|
1138
|
+
);
|
|
1139
|
+
|
|
1140
|
+
let newDeposits: ObligationCollateral[] = this.state.deposits;
|
|
1141
|
+
if (depositChanges) {
|
|
1142
|
+
for (const depositChange of depositChanges) {
|
|
1143
|
+
newDeposits = this.simulateDepositChange(newDeposits, depositChange, collateralExchangeRates);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
let newBorrows: ObligationLiquidity[] = this.state.borrows;
|
|
1148
|
+
if (borrowChanges) {
|
|
1149
|
+
for (const borrowChange of borrowChanges) {
|
|
1150
|
+
const reserve = market.getReserveByAddress(borrowChange.reserveAddress);
|
|
1151
|
+
if (!reserve) {
|
|
1152
|
+
throw new Error(`Reserve not found: ${borrowChange.reserveAddress}`);
|
|
1153
|
+
}
|
|
1154
|
+
newBorrows = this.simulateBorrowChange(newBorrows, borrowChange, reserve.getCumulativeBorrowRate());
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// Create a deep copy of the obligation state and override deposits/borrows
|
|
1159
|
+
const newObligationState = new Obligation({
|
|
1160
|
+
...this.state,
|
|
1161
|
+
deposits: newDeposits,
|
|
1162
|
+
borrows: newBorrows,
|
|
1163
|
+
});
|
|
1164
|
+
|
|
1165
|
+
return new KaminoObligation(
|
|
1166
|
+
market,
|
|
1167
|
+
this.obligationAddress,
|
|
1168
|
+
newObligationState,
|
|
1169
|
+
collateralExchangeRates,
|
|
1170
|
+
cumulativeBorrowRates
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1077
1174
|
/*
|
|
1078
1175
|
How much of a given token can a user borrow extra given an elevation group,
|
|
1079
1176
|
regardless of caps and liquidity or assuming infinite liquidity and infinite caps,
|
|
@@ -1196,6 +1293,36 @@ export class KaminoObligation {
|
|
|
1196
1293
|
}
|
|
1197
1294
|
}
|
|
1198
1295
|
|
|
1296
|
+
/*
|
|
1297
|
+
Same as getMaxBorrowAmountV2 but assumes a deposit is made first, calculating
|
|
1298
|
+
the new borrow power after the deposit, without overriding the obligation itself.
|
|
1299
|
+
|
|
1300
|
+
* @param market - The KaminoMarket instance.
|
|
1301
|
+
* @param liquidityMint - The liquidity mint Address.
|
|
1302
|
+
* @param slot - The slot number.
|
|
1303
|
+
* @param elevationGroup - The elevation group number (default: this.state.elevationGroup).
|
|
1304
|
+
* @returns The maximum borrow amount as a Decimal.
|
|
1305
|
+
* @throws Error if the reserve is not found.
|
|
1306
|
+
*/
|
|
1307
|
+
getMaxBorrowAmountV2WithDeposit(
|
|
1308
|
+
market: KaminoMarket,
|
|
1309
|
+
liquidityMint: PublicKey,
|
|
1310
|
+
slot: number,
|
|
1311
|
+
elevationGroup: number = this.state.elevationGroup,
|
|
1312
|
+
depositAmountLamports: Decimal,
|
|
1313
|
+
depositReserveAddress: PublicKey
|
|
1314
|
+
): Decimal {
|
|
1315
|
+
const depositChanges = [
|
|
1316
|
+
{
|
|
1317
|
+
reserveAddress: depositReserveAddress,
|
|
1318
|
+
amountChangeLamports: depositAmountLamports,
|
|
1319
|
+
},
|
|
1320
|
+
];
|
|
1321
|
+
const obligationWithDeposit = this.withPositionChanges(market, slot, depositChanges);
|
|
1322
|
+
|
|
1323
|
+
return obligationWithDeposit.getMaxBorrowAmountV2(market, liquidityMint, slot, elevationGroup);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1199
1326
|
/*
|
|
1200
1327
|
Returns true if the loan is eligible for the elevation group, including for the default one.
|
|
1201
1328
|
* @param market - The KaminoMarket object representing the market.
|
|
@@ -1447,6 +1574,44 @@ export class KaminoObligation {
|
|
|
1447
1574
|
);
|
|
1448
1575
|
}
|
|
1449
1576
|
|
|
1577
|
+
/**
|
|
1578
|
+
* Same as getMaxWithdrawAmount but assumes a repay is made first, calculating
|
|
1579
|
+
* the new withdraw power after the repay, without overriding the obligation itself.
|
|
1580
|
+
*
|
|
1581
|
+
* @param market - The KaminoMarket instance.
|
|
1582
|
+
* @param tokenMint - The liquidity mint Address.
|
|
1583
|
+
* @param slot - The slot number.
|
|
1584
|
+
* @param repayAmountLamports - The amount to repay in lamports (use U64_MAX for full repay).
|
|
1585
|
+
* @param repayReserveAddress - The reserve address of the borrow being repaid.
|
|
1586
|
+
* @returns The maximum withdraw amount as a Decimal.
|
|
1587
|
+
* @throws Error if the reserve is not found.
|
|
1588
|
+
*/
|
|
1589
|
+
getMaxWithdrawAmountWithRepay(
|
|
1590
|
+
market: KaminoMarket,
|
|
1591
|
+
tokenMint: PublicKey,
|
|
1592
|
+
slot: number,
|
|
1593
|
+
repayAmountLamports: Decimal,
|
|
1594
|
+
repayReserveAddress: PublicKey
|
|
1595
|
+
): Decimal {
|
|
1596
|
+
const repayReserve = market.getReserveByAddress(repayReserveAddress);
|
|
1597
|
+
if (!repayReserve) {
|
|
1598
|
+
throw new Error('Reserve not found');
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
const repayAmount = repayAmountLamports.equals(U64_MAX)
|
|
1602
|
+
? this.getBorrowAmountByReserve(repayReserve)
|
|
1603
|
+
: repayAmountLamports;
|
|
1604
|
+
const borrowChanges = [
|
|
1605
|
+
{
|
|
1606
|
+
reserveAddress: repayReserveAddress,
|
|
1607
|
+
amountChangeLamports: repayAmount.neg(), // as it's a repay
|
|
1608
|
+
},
|
|
1609
|
+
];
|
|
1610
|
+
const obligationWithRepay = this.withPositionChanges(market, slot, undefined, borrowChanges);
|
|
1611
|
+
|
|
1612
|
+
return obligationWithRepay.getMaxWithdrawAmount(market, tokenMint, slot);
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1450
1615
|
getObligationLiquidityByReserve(reserveAddress: PublicKey): ObligationLiquidity {
|
|
1451
1616
|
const obligationLiquidity = this.state.borrows.find((borrow) => borrow.borrowReserve.equals(reserveAddress));
|
|
1452
1617
|
|
package/src/classes/reserve.ts
CHANGED
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
|
41
41
|
import { aprToApy, KaminoPrices } from '@kamino-finance/kliquidity-sdk';
|
|
42
42
|
import { FarmState, RewardInfo } from '@kamino-finance/farms-sdk';
|
|
43
|
+
import { Scope, ScopeEntryMetadata } from '@kamino-finance/scope-sdk';
|
|
43
44
|
|
|
44
45
|
export const DEFAULT_RECENT_SLOT_DURATION_MS = 450;
|
|
45
46
|
|
|
@@ -56,6 +57,8 @@ export class KaminoReserve {
|
|
|
56
57
|
private connection: Connection;
|
|
57
58
|
private readonly recentSlotDurationMs: number;
|
|
58
59
|
|
|
60
|
+
private metadata?: ScopeEntryMetadata[];
|
|
61
|
+
|
|
59
62
|
constructor(
|
|
60
63
|
state: Reserve,
|
|
61
64
|
address: PublicKey,
|
|
@@ -96,6 +99,19 @@ export class KaminoReserve {
|
|
|
96
99
|
return parseTokenSymbol(this.state.config.tokenInfo.name);
|
|
97
100
|
}
|
|
98
101
|
|
|
102
|
+
/**
|
|
103
|
+
* @returns list of logo names and human readable oracle type descriptions
|
|
104
|
+
*/
|
|
105
|
+
async getOracleMetadata(): Promise<[string, string][]> {
|
|
106
|
+
if (this.metadata === undefined) {
|
|
107
|
+
const scope = new Scope('mainnet-beta', this.connection);
|
|
108
|
+
const { priceFeed, priceChain } = this.state.config.tokenInfo.scopeConfiguration;
|
|
109
|
+
this.metadata = await scope.getChainMetadata({ prices: priceFeed }, priceChain);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return (this.metadata || []).map((chainMetadata) => [chainMetadata.provider, chainMetadata.name]);
|
|
113
|
+
}
|
|
114
|
+
|
|
99
115
|
/**
|
|
100
116
|
* @returns the total borrowed amount of the reserve in lamports
|
|
101
117
|
*/
|