@kamino-finance/klend-sdk 5.2.13 → 5.3.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/dist/classes/action.d.ts.map +1 -1
- package/dist/classes/action.js +1 -2
- package/dist/classes/action.js.map +1 -1
- package/dist/classes/manager.js +22 -5
- package/dist/classes/manager.js.map +1 -1
- package/dist/classes/obligation.d.ts +2 -0
- package/dist/classes/obligation.d.ts.map +1 -1
- package/dist/classes/obligation.js +12 -6
- package/dist/classes/obligation.js.map +1 -1
- package/dist/classes/reserve.js +14 -14
- package/dist/classes/reserve.js.map +1 -1
- package/dist/classes/shared.d.ts +2 -2
- package/dist/classes/shared.d.ts.map +1 -1
- package/dist/classes/types.d.ts +1 -1
- package/dist/classes/types.d.ts.map +1 -1
- package/dist/classes/vault.d.ts +1 -1
- package/dist/classes/vault.d.ts.map +1 -1
- package/dist/classes/vault.js +16 -3
- package/dist/classes/vault.js.map +1 -1
- package/dist/client_kamino_manager.d.ts.map +1 -1
- package/dist/client_kamino_manager.js +44 -6
- package/dist/client_kamino_manager.js.map +1 -1
- package/dist/idl.json +310 -48
- package/dist/idl_codegen/accounts/LendingMarket.d.ts +48 -3
- package/dist/idl_codegen/accounts/LendingMarket.d.ts.map +1 -1
- package/dist/idl_codegen/accounts/LendingMarket.js +35 -8
- package/dist/idl_codegen/accounts/LendingMarket.js.map +1 -1
- package/dist/idl_codegen/accounts/Obligation.d.ts +30 -0
- package/dist/idl_codegen/accounts/Obligation.d.ts.map +1 -1
- package/dist/idl_codegen/accounts/Obligation.js +23 -2
- package/dist/idl_codegen/accounts/Obligation.js.map +1 -1
- package/dist/idl_codegen/accounts/Reserve.js +1 -1
- package/dist/idl_codegen/errors/custom.d.ts +33 -1
- package/dist/idl_codegen/errors/custom.d.ts.map +1 -1
- package/dist/idl_codegen/errors/custom.js +57 -1
- package/dist/idl_codegen/errors/custom.js.map +1 -1
- package/dist/idl_codegen/instructions/index.d.ts +7 -3
- package/dist/idl_codegen/instructions/index.d.ts.map +1 -1
- package/dist/idl_codegen/instructions/index.js +7 -3
- package/dist/idl_codegen/instructions/index.js.map +1 -1
- package/dist/idl_codegen/instructions/initReferrerTokenState.d.ts +2 -5
- package/dist/idl_codegen/instructions/initReferrerTokenState.d.ts.map +1 -1
- package/dist/idl_codegen/instructions/initReferrerTokenState.js +3 -32
- package/dist/idl_codegen/instructions/initReferrerTokenState.js.map +1 -1
- package/dist/idl_codegen/instructions/markObligationForDeleveraging.d.ts +12 -0
- package/dist/idl_codegen/instructions/markObligationForDeleveraging.d.ts.map +1 -0
- package/dist/idl_codegen/instructions/markObligationForDeleveraging.js +47 -0
- package/dist/idl_codegen/instructions/markObligationForDeleveraging.js.map +1 -0
- package/dist/idl_codegen/instructions/repayAndWithdrawAndRedeem.d.ts +38 -0
- package/dist/idl_codegen/instructions/repayAndWithdrawAndRedeem.d.ts.map +1 -0
- package/dist/idl_codegen/instructions/repayAndWithdrawAndRedeem.js +159 -0
- package/dist/idl_codegen/instructions/repayAndWithdrawAndRedeem.js.map +1 -0
- package/dist/idl_codegen/instructions/withdrawObligationCollateralAndRedeemReserveCollateral.js +1 -1
- package/dist/idl_codegen/instructions/withdrawObligationCollateralAndRedeemReserveCollateral.js.map +1 -1
- package/dist/idl_codegen/types/ReserveConfig.d.ts +78 -20
- package/dist/idl_codegen/types/ReserveConfig.d.ts.map +1 -1
- package/dist/idl_codegen/types/ReserveConfig.js +45 -14
- package/dist/idl_codegen/types/ReserveConfig.js.map +1 -1
- package/dist/idl_codegen/types/ReserveLiquidity.d.ts +16 -16
- package/dist/idl_codegen/types/ReserveLiquidity.d.ts.map +1 -1
- package/dist/idl_codegen/types/ReserveLiquidity.js +16 -16
- package/dist/idl_codegen/types/ReserveLiquidity.js.map +1 -1
- package/dist/idl_codegen/types/UpdateConfigMode.d.ts +40 -14
- package/dist/idl_codegen/types/UpdateConfigMode.d.ts.map +1 -1
- package/dist/idl_codegen/types/UpdateConfigMode.js +71 -23
- package/dist/idl_codegen/types/UpdateConfigMode.js.map +1 -1
- package/dist/idl_codegen/types/UpdateLendingMarketMode.d.ts +37 -11
- package/dist/idl_codegen/types/UpdateLendingMarketMode.d.ts.map +1 -1
- package/dist/idl_codegen/types/UpdateLendingMarketMode.js +64 -16
- package/dist/idl_codegen/types/UpdateLendingMarketMode.js.map +1 -1
- package/dist/idl_codegen/types/index.d.ts +4 -4
- package/dist/idl_codegen/types/index.d.ts.map +1 -1
- package/dist/idl_codegen/types/index.js.map +1 -1
- package/dist/idl_codegen/zero_padding/ObligationZP.d.ts +4 -0
- package/dist/idl_codegen/zero_padding/ObligationZP.d.ts.map +1 -1
- package/dist/idl_codegen/zero_padding/ObligationZP.js +10 -0
- package/dist/idl_codegen/zero_padding/ObligationZP.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_calcs.d.ts +4 -2
- package/dist/lending_operations/repay_with_collateral_calcs.d.ts.map +1 -1
- package/dist/lending_operations/repay_with_collateral_calcs.js +45 -52
- package/dist/lending_operations/repay_with_collateral_calcs.js.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.d.ts +7 -0
- package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
- package/dist/lending_operations/repay_with_collateral_operations.js +13 -3
- package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
- package/dist/pyth/accounts/PriceUpdateV2.d.ts +30 -0
- package/dist/pyth/accounts/PriceUpdateV2.d.ts.map +1 -0
- package/dist/pyth/accounts/PriceUpdateV2.js +104 -0
- package/dist/pyth/accounts/PriceUpdateV2.js.map +1 -0
- package/dist/pyth/accounts/index.d.ts +3 -0
- package/dist/pyth/accounts/index.d.ts.map +1 -0
- package/dist/pyth/accounts/index.js +6 -0
- package/dist/pyth/accounts/index.js.map +1 -0
- package/dist/pyth/types/PriceFeedMessage.d.ts +58 -0
- package/dist/pyth/types/PriceFeedMessage.d.ts.map +1 -0
- package/dist/pyth/types/PriceFeedMessage.js +118 -0
- package/dist/pyth/types/PriceFeedMessage.js.map +1 -0
- package/dist/pyth/types/VerificationLevel.d.ts +45 -0
- package/dist/pyth/types/VerificationLevel.d.ts.map +1 -0
- package/dist/pyth/types/VerificationLevel.js +105 -0
- package/dist/pyth/types/VerificationLevel.js.map +1 -0
- package/dist/pyth/types/index.d.ts +7 -0
- package/dist/pyth/types/index.d.ts.map +1 -0
- package/dist/pyth/types/index.js +31 -0
- package/dist/pyth/types/index.js.map +1 -0
- package/dist/referrals/instructions.d.ts.map +1 -1
- package/dist/referrals/instructions.js +1 -2
- package/dist/referrals/instructions.js.map +1 -1
- package/dist/utils/managerTypes.d.ts.map +1 -1
- package/dist/utils/managerTypes.js +5 -4
- package/dist/utils/managerTypes.js.map +1 -1
- package/dist/utils/oracle.d.ts.map +1 -1
- package/dist/utils/oracle.js +9 -14
- package/dist/utils/oracle.js.map +1 -1
- package/package.json +3 -4
- package/src/classes/action.ts +1 -3
- package/src/classes/manager.ts +29 -6
- package/src/classes/obligation.ts +15 -6
- package/src/classes/reserve.ts +16 -16
- package/src/classes/shared.ts +2 -2
- package/src/classes/types.ts +16 -17
- package/src/classes/vault.ts +18 -4
- package/src/client_kamino_manager.ts +61 -6
- package/src/idl_codegen/accounts/LendingMarket.ts +76 -13
- package/src/idl_codegen/accounts/Obligation.ts +47 -2
- package/src/idl_codegen/accounts/Reserve.ts +1 -1
- package/src/idl_codegen/errors/custom.ts +56 -0
- package/src/idl_codegen/instructions/index.ts +13 -6
- package/src/idl_codegen/instructions/initReferrerTokenState.ts +3 -15
- package/src/idl_codegen/instructions/markObligationForDeleveraging.ts +40 -0
- package/src/idl_codegen/instructions/repayAndWithdrawAndRedeem.ts +177 -0
- package/src/idl_codegen/instructions/withdrawObligationCollateralAndRedeemReserveCollateral.ts +1 -1
- package/src/idl_codegen/programId.ts +1 -1
- package/src/idl_codegen/types/ReserveConfig.ts +100 -28
- package/src/idl_codegen/types/ReserveLiquidity.ts +25 -24
- package/src/idl_codegen/types/UpdateConfigMode.ts +86 -26
- package/src/idl_codegen/types/UpdateLendingMarketMode.ts +77 -17
- package/src/idl_codegen/types/index.ts +14 -6
- package/src/idl_codegen/zero_padding/ObligationZP.ts +10 -0
- package/src/lending_operations/repay_with_collateral_calcs.ts +55 -61
- package/src/lending_operations/repay_with_collateral_operations.ts +24 -4
- package/src/leverage/operations.ts +1 -1
- package/src/pyth/accounts/PriceUpdateV2.ts +110 -0
- package/src/pyth/accounts/index.ts +2 -0
- package/src/pyth/types/PriceFeedMessage.ts +120 -0
- package/src/pyth/types/VerificationLevel.ts +98 -0
- package/src/pyth/types/index.ts +9 -0
- package/src/referrals/instructions.ts +1 -3
- package/src/utils/managerTypes.ts +5 -5
- package/src/utils/oracle.ts +9 -15
|
@@ -29,6 +29,13 @@ export type RepayWithCollIxsResponse<QuoteResponse> = {
|
|
|
29
29
|
export type InitialInputs<QuoteResponse> = {
|
|
30
30
|
debtRepayAmountLamports: Decimal;
|
|
31
31
|
flashRepayAmountLamports: Decimal;
|
|
32
|
+
/**
|
|
33
|
+
* The amount of collateral available to withdraw, if this is less than the swap input amount, then the swap may fail due to slippage, or tokens may be debited from the user's ATA, so the caller needs to check this
|
|
34
|
+
*/
|
|
35
|
+
maxCollateralWithdrawLamports: Decimal;
|
|
36
|
+
/**
|
|
37
|
+
* The quote from the provided quoter
|
|
38
|
+
*/
|
|
32
39
|
swapQuote: SwapQuote<QuoteResponse>;
|
|
33
40
|
currentSlot: number;
|
|
34
41
|
klendAccounts: Array<PublicKey>;
|
|
@@ -93,9 +100,9 @@ export async function getRepayWithCollSwapInputs<QuoteResponse>({
|
|
|
93
100
|
}
|
|
94
101
|
const { withdrawableCollLamports } = calcMaxWithdrawCollateral(
|
|
95
102
|
kaminoMarket,
|
|
103
|
+
obligation,
|
|
96
104
|
collReserve.address,
|
|
97
105
|
debtReserve.address,
|
|
98
|
-
obligation,
|
|
99
106
|
repayAmountLamports
|
|
100
107
|
);
|
|
101
108
|
|
|
@@ -156,6 +163,7 @@ export async function getRepayWithCollSwapInputs<QuoteResponse>({
|
|
|
156
163
|
initialInputs: {
|
|
157
164
|
debtRepayAmountLamports: repayAmountLamports,
|
|
158
165
|
flashRepayAmountLamports,
|
|
166
|
+
maxCollateralWithdrawLamports: withdrawableCollLamports,
|
|
159
167
|
swapQuote,
|
|
160
168
|
currentSlot,
|
|
161
169
|
klendAccounts: uniqueKlendAccounts,
|
|
@@ -196,18 +204,30 @@ export async function getRepayWithCollIxs<QuoteResponse>({
|
|
|
196
204
|
budgetAndPriorityFeeIxs,
|
|
197
205
|
scopeRefresh,
|
|
198
206
|
});
|
|
199
|
-
const { debtRepayAmountLamports, flashRepayAmountLamports, swapQuote } = initialInputs;
|
|
207
|
+
const { debtRepayAmountLamports, flashRepayAmountLamports, maxCollateralWithdrawLamports, swapQuote } = initialInputs;
|
|
200
208
|
const { inputAmountLamports: collSwapInLamports } = swapInputs;
|
|
201
209
|
|
|
202
210
|
const collReserve = kaminoMarket.getReserveByMint(collTokenMint)!;
|
|
203
211
|
const debtReserve = kaminoMarket.getReserveByMint(debtTokenMint)!;
|
|
204
212
|
|
|
213
|
+
// the client should use these values to prevent this input, but the tx may succeed, so we don't want to fail
|
|
214
|
+
// there is also a chance that the tx will consume debt token from the user's ata which they would not expect
|
|
215
|
+
if (collSwapInLamports.greaterThan(maxCollateralWithdrawLamports)) {
|
|
216
|
+
logger(
|
|
217
|
+
`Collateral swap in amount ${collSwapInLamports} exceeds max withdrawable collateral ${maxCollateralWithdrawLamports}, tx may fail with slippage`
|
|
218
|
+
);
|
|
219
|
+
swapInputs.inputAmountLamports = maxCollateralWithdrawLamports;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const actualSwapInLamports = Decimal.min(collSwapInLamports, maxCollateralWithdrawLamports);
|
|
205
223
|
logger(
|
|
206
|
-
`Expected to swap in: ${
|
|
224
|
+
`Expected to swap in: ${actualSwapInLamports.div(collReserve.getMintFactor())} ${
|
|
207
225
|
collReserve.symbol
|
|
208
226
|
}, for: ${flashRepayAmountLamports.div(debtReserve.getMintFactor())} ${debtReserve.symbol}, quoter px: ${
|
|
209
227
|
swapQuote.priceAInB
|
|
210
|
-
} ${debtReserve.symbol}/${collReserve.symbol}
|
|
228
|
+
} ${debtReserve.symbol}/${collReserve.symbol}, required px: ${flashRepayAmountLamports
|
|
229
|
+
.div(debtReserve.getMintFactor())
|
|
230
|
+
.div(actualSwapInLamports.div(collReserve.getMintFactor()))} ${debtReserve.symbol}/${collReserve.symbol}`
|
|
211
231
|
);
|
|
212
232
|
|
|
213
233
|
const swapResponse = await swapper(swapInputs, initialInputs.klendAccounts, swapQuote);
|
|
@@ -1045,7 +1045,7 @@ export async function getAdjustLeverageSwapInputs<QuoteResponse>({
|
|
|
1045
1045
|
|
|
1046
1046
|
const swapInputAmount = toLamports(
|
|
1047
1047
|
!collIsKtoken ? calcs.borrowAmount : calcs.amountToFlashBorrowDebt,
|
|
1048
|
-
debtReserve.stats.decimals
|
|
1048
|
+
debtReserve.stats.decimals
|
|
1049
1049
|
).ceil();
|
|
1050
1050
|
|
|
1051
1051
|
const swapInputsForQuote: SwapInputs = {
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { PublicKey, Connection } from '@solana/web3.js';
|
|
2
|
+
import BN from 'bn.js'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
3
|
+
import * as borsh from '@coral-xyz/borsh'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
4
|
+
import * as types from '../types';
|
|
5
|
+
|
|
6
|
+
export const PYTH_RECEIVER_PROGRAM_ID = new PublicKey('rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ');
|
|
7
|
+
|
|
8
|
+
export interface PriceUpdateV2Fields {
|
|
9
|
+
writeAuthority: PublicKey;
|
|
10
|
+
verificationLevel: types.VerificationLevelKind;
|
|
11
|
+
priceMessage: types.PriceFeedMessageFields;
|
|
12
|
+
postedSlot: BN;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface PriceUpdateV2JSON {
|
|
16
|
+
writeAuthority: string;
|
|
17
|
+
verificationLevel: types.VerificationLevelJSON;
|
|
18
|
+
priceMessage: types.PriceFeedMessageJSON;
|
|
19
|
+
postedSlot: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class PriceUpdateV2 {
|
|
23
|
+
readonly writeAuthority: PublicKey;
|
|
24
|
+
readonly verificationLevel: types.VerificationLevelKind;
|
|
25
|
+
readonly priceMessage: types.PriceFeedMessage;
|
|
26
|
+
readonly postedSlot: BN;
|
|
27
|
+
|
|
28
|
+
// static readonly discriminator = Buffer.from([
|
|
29
|
+
// 43, 242, 204, 202, 26, 247, 59, 127,
|
|
30
|
+
// ])
|
|
31
|
+
|
|
32
|
+
static readonly layout = borsh.struct([
|
|
33
|
+
borsh.publicKey('writeAuthority'),
|
|
34
|
+
borsh.u8('verificationLevel'),
|
|
35
|
+
types.PriceFeedMessage.layout('priceMessage'),
|
|
36
|
+
borsh.u64('postedSlot'),
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
constructor(fields: PriceUpdateV2Fields) {
|
|
40
|
+
this.writeAuthority = fields.writeAuthority;
|
|
41
|
+
this.verificationLevel = fields.verificationLevel;
|
|
42
|
+
this.priceMessage = new types.PriceFeedMessage({ ...fields.priceMessage });
|
|
43
|
+
this.postedSlot = fields.postedSlot;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static async fetch(
|
|
47
|
+
c: Connection,
|
|
48
|
+
address: PublicKey,
|
|
49
|
+
programId: PublicKey = PYTH_RECEIVER_PROGRAM_ID
|
|
50
|
+
): Promise<PriceUpdateV2 | null> {
|
|
51
|
+
const info = await c.getAccountInfo(address);
|
|
52
|
+
|
|
53
|
+
if (info === null) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (!info.owner.equals(programId)) {
|
|
57
|
+
throw new Error("account doesn't belong to this program");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return this.decode(info.data);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static async fetchMultiple(
|
|
64
|
+
c: Connection,
|
|
65
|
+
addresses: PublicKey[],
|
|
66
|
+
programId: PublicKey = PYTH_RECEIVER_PROGRAM_ID
|
|
67
|
+
): Promise<Array<PriceUpdateV2 | null>> {
|
|
68
|
+
const infos = await c.getMultipleAccountsInfo(addresses);
|
|
69
|
+
|
|
70
|
+
return infos.map((info) => {
|
|
71
|
+
if (info === null) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
if (!info.owner.equals(programId)) {
|
|
75
|
+
throw new Error("account doesn't belong to this program");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return this.decode(info.data);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static decode(data: Buffer): PriceUpdateV2 {
|
|
83
|
+
const dec = PriceUpdateV2.layout.decode(data.slice(8));
|
|
84
|
+
|
|
85
|
+
return new PriceUpdateV2({
|
|
86
|
+
writeAuthority: dec.writeAuthority,
|
|
87
|
+
verificationLevel: dec.verificationLevel,
|
|
88
|
+
priceMessage: types.PriceFeedMessage.fromDecoded(dec.priceMessage),
|
|
89
|
+
postedSlot: dec.postedSlot,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
toJSON(): PriceUpdateV2JSON {
|
|
94
|
+
return {
|
|
95
|
+
writeAuthority: this.writeAuthority.toString(),
|
|
96
|
+
verificationLevel: this.verificationLevel.toJSON(),
|
|
97
|
+
priceMessage: this.priceMessage.toJSON(),
|
|
98
|
+
postedSlot: this.postedSlot.toString(),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static fromJSON(obj: PriceUpdateV2JSON): PriceUpdateV2 {
|
|
103
|
+
return new PriceUpdateV2({
|
|
104
|
+
writeAuthority: new PublicKey(obj.writeAuthority),
|
|
105
|
+
verificationLevel: types.VerificationLevel.fromJSON(obj.verificationLevel),
|
|
106
|
+
priceMessage: types.PriceFeedMessage.fromJSON(obj.priceMessage),
|
|
107
|
+
postedSlot: new BN(obj.postedSlot),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import BN from 'bn.js';
|
|
2
|
+
import * as borsh from '@coral-xyz/borsh';
|
|
3
|
+
|
|
4
|
+
export interface PriceFeedMessageFields {
|
|
5
|
+
feedId: number[];
|
|
6
|
+
price: BN;
|
|
7
|
+
conf: BN;
|
|
8
|
+
exponent: number;
|
|
9
|
+
publishTime: BN;
|
|
10
|
+
prevPublishTime: BN;
|
|
11
|
+
emaPrice: BN;
|
|
12
|
+
emaConf: BN;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface PriceFeedMessageJSON {
|
|
16
|
+
feedId: number[];
|
|
17
|
+
price: string;
|
|
18
|
+
conf: string;
|
|
19
|
+
exponent: number;
|
|
20
|
+
publishTime: string;
|
|
21
|
+
prevPublishTime: string;
|
|
22
|
+
emaPrice: string;
|
|
23
|
+
emaConf: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Reserve Withdrawal Caps State */
|
|
27
|
+
export class PriceFeedMessage {
|
|
28
|
+
readonly feedId: number[];
|
|
29
|
+
readonly price: BN;
|
|
30
|
+
readonly conf: BN;
|
|
31
|
+
readonly exponent: number;
|
|
32
|
+
readonly publishTime: BN;
|
|
33
|
+
readonly prevPublishTime: BN;
|
|
34
|
+
readonly emaPrice: BN;
|
|
35
|
+
readonly emaConf: BN;
|
|
36
|
+
|
|
37
|
+
constructor(fields: PriceFeedMessageFields) {
|
|
38
|
+
this.feedId = fields.feedId;
|
|
39
|
+
this.price = fields.price;
|
|
40
|
+
this.conf = fields.conf;
|
|
41
|
+
this.exponent = fields.exponent;
|
|
42
|
+
this.publishTime = fields.publishTime;
|
|
43
|
+
this.prevPublishTime = fields.prevPublishTime;
|
|
44
|
+
this.emaPrice = fields.emaPrice;
|
|
45
|
+
this.emaConf = fields.emaConf;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static layout(property?: string) {
|
|
49
|
+
return borsh.struct(
|
|
50
|
+
[
|
|
51
|
+
borsh.array(borsh.u8(), 32, 'feedId'),
|
|
52
|
+
borsh.i64('price'),
|
|
53
|
+
borsh.u64('conf'),
|
|
54
|
+
borsh.i32('exponent'),
|
|
55
|
+
borsh.i64('publishTime'),
|
|
56
|
+
borsh.i64('prevPublishTime'),
|
|
57
|
+
borsh.i64('emaPrice'),
|
|
58
|
+
borsh.u64('emaConf'),
|
|
59
|
+
],
|
|
60
|
+
property
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
65
|
+
static fromDecoded(obj: any) {
|
|
66
|
+
return new PriceFeedMessage({
|
|
67
|
+
feedId: obj.feedId,
|
|
68
|
+
price: obj.price,
|
|
69
|
+
conf: obj.conf,
|
|
70
|
+
exponent: obj.exponent,
|
|
71
|
+
publishTime: obj.publishTime,
|
|
72
|
+
prevPublishTime: obj.prevPublishTime,
|
|
73
|
+
emaPrice: obj.emaPrice,
|
|
74
|
+
emaConf: obj.emaConf,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static toEncodable(fields: PriceFeedMessageFields) {
|
|
79
|
+
return {
|
|
80
|
+
feedId: fields.feedId,
|
|
81
|
+
price: fields.price,
|
|
82
|
+
conf: fields.conf,
|
|
83
|
+
exponent: fields.exponent,
|
|
84
|
+
publishTime: fields.publishTime,
|
|
85
|
+
prevPublishTime: fields.prevPublishTime,
|
|
86
|
+
emaPrice: fields.emaPrice,
|
|
87
|
+
emaConf: fields.emaConf,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
toJSON(): PriceFeedMessageJSON {
|
|
92
|
+
return {
|
|
93
|
+
feedId: this.feedId,
|
|
94
|
+
price: this.price.toString(),
|
|
95
|
+
conf: this.conf.toString(),
|
|
96
|
+
exponent: this.exponent,
|
|
97
|
+
publishTime: this.publishTime.toString(),
|
|
98
|
+
prevPublishTime: this.prevPublishTime.toString(),
|
|
99
|
+
emaPrice: this.emaPrice.toString(),
|
|
100
|
+
emaConf: this.emaConf.toString(),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
static fromJSON(obj: PriceFeedMessageJSON): PriceFeedMessage {
|
|
105
|
+
return new PriceFeedMessage({
|
|
106
|
+
feedId: obj.feedId,
|
|
107
|
+
price: new BN(obj.price),
|
|
108
|
+
conf: new BN(obj.conf),
|
|
109
|
+
exponent: obj.exponent,
|
|
110
|
+
publishTime: new BN(obj.publishTime),
|
|
111
|
+
prevPublishTime: new BN(obj.prevPublishTime),
|
|
112
|
+
emaPrice: new BN(obj.emaPrice),
|
|
113
|
+
emaConf: new BN(obj.emaConf),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
toEncodable() {
|
|
118
|
+
return PriceFeedMessage.toEncodable(this);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as types from '../types';
|
|
2
|
+
import * as borsh from '@coral-xyz/borsh';
|
|
3
|
+
|
|
4
|
+
export type PartialFields = { numSignatures: number };
|
|
5
|
+
export type PartialValue = { numSignatures: number };
|
|
6
|
+
|
|
7
|
+
export interface PartialJSON {
|
|
8
|
+
kind: 'Partial';
|
|
9
|
+
value: { numSignatures: number };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class Partial {
|
|
13
|
+
static readonly discriminator = 1;
|
|
14
|
+
static readonly kind = 'Partial';
|
|
15
|
+
readonly discriminator = 1;
|
|
16
|
+
readonly kind = 'Partial';
|
|
17
|
+
readonly value: PartialValue;
|
|
18
|
+
|
|
19
|
+
constructor(value: PartialFields) {
|
|
20
|
+
this.value = { numSignatures: value.numSignatures };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
toJSON(): PartialJSON {
|
|
24
|
+
return {
|
|
25
|
+
kind: 'Partial',
|
|
26
|
+
value: {
|
|
27
|
+
numSignatures: this.value.numSignatures,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
toEncodable() {
|
|
33
|
+
return {
|
|
34
|
+
Partial: {
|
|
35
|
+
numSignatures: this.value.numSignatures,
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface FullJSON {
|
|
42
|
+
kind: 'Full';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class Full {
|
|
46
|
+
static readonly discriminator = 1;
|
|
47
|
+
static readonly kind = 'Full';
|
|
48
|
+
readonly discriminator = 1;
|
|
49
|
+
readonly kind = 'Full';
|
|
50
|
+
|
|
51
|
+
toJSON(): FullJSON {
|
|
52
|
+
return {
|
|
53
|
+
kind: 'Full',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
toEncodable() {
|
|
58
|
+
return {
|
|
59
|
+
Full: {},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
65
|
+
export function fromDecoded(obj: any): types.VerificationLevelKind {
|
|
66
|
+
if (typeof obj !== 'object') {
|
|
67
|
+
throw new Error('Invalid enum object');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if ('Partial' in obj) {
|
|
71
|
+
return new Partial({ numSignatures: obj.Partial.numSignatures });
|
|
72
|
+
}
|
|
73
|
+
if ('Full' in obj) {
|
|
74
|
+
return new Full();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
throw new Error('Invalid enum object');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function fromJSON(obj: types.VerificationLevelJSON): types.VerificationLevelKind {
|
|
81
|
+
switch (obj.kind) {
|
|
82
|
+
case 'Partial': {
|
|
83
|
+
return new Partial({ numSignatures: obj.value.numSignatures });
|
|
84
|
+
}
|
|
85
|
+
case 'Full': {
|
|
86
|
+
return new Full();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
throw new Error('Invalid enum object');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function layout(property?: string) {
|
|
93
|
+
const ret = borsh.rustEnum([borsh.struct([borsh.u8('numSignatures')], 'Partial'), borsh.struct([], 'Full')]);
|
|
94
|
+
if (property !== undefined) {
|
|
95
|
+
return ret.replicate(property);
|
|
96
|
+
}
|
|
97
|
+
return ret;
|
|
98
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { PriceFeedMessage } from './PriceFeedMessage';
|
|
2
|
+
export type { PriceFeedMessageFields, PriceFeedMessageJSON } from './PriceFeedMessage';
|
|
3
|
+
|
|
4
|
+
import * as VerificationLevel from './VerificationLevel';
|
|
5
|
+
|
|
6
|
+
export { VerificationLevel };
|
|
7
|
+
|
|
8
|
+
export type VerificationLevelKind = VerificationLevel.Partial | VerificationLevel.Full;
|
|
9
|
+
export type VerificationLevelJSON = VerificationLevel.PartialJSON | VerificationLevel.FullJSON;
|
|
@@ -41,13 +41,11 @@ export const getInitAllReferrerTokenStateIxns = async ({
|
|
|
41
41
|
|
|
42
42
|
tokenStatesToCreate.forEach(([referrerTokenStateAddress, reserveAddress]) => {
|
|
43
43
|
const initReferrerTokenStateIx = initReferrerTokenState(
|
|
44
|
-
{
|
|
45
|
-
referrer,
|
|
46
|
-
},
|
|
47
44
|
{
|
|
48
45
|
lendingMarket: kaminoMarket.getAddress(),
|
|
49
46
|
payer,
|
|
50
47
|
reserve: reserveAddress,
|
|
48
|
+
referrer,
|
|
51
49
|
referrerTokenState: referrerTokenStateAddress,
|
|
52
50
|
rent: SYSVAR_RENT_PUBKEY,
|
|
53
51
|
systemProgram: SystemProgram.programId,
|
|
@@ -277,9 +277,7 @@ export const encodeTokenName = (tokenName: string): number[] => {
|
|
|
277
277
|
for (let i = 0; i < tokenNameEncoded.length; i++) {
|
|
278
278
|
buffer[i] = tokenNameEncoded[i];
|
|
279
279
|
}
|
|
280
|
-
|
|
281
|
-
const result = [...buffer];
|
|
282
|
-
return result;
|
|
280
|
+
return [...buffer];
|
|
283
281
|
};
|
|
284
282
|
|
|
285
283
|
function buildReserveConfig(fields: {
|
|
@@ -337,13 +335,15 @@ function buildReserveConfig(fields: {
|
|
|
337
335
|
deleveragingMarginCallPeriodSecs: new BN(0),
|
|
338
336
|
borrowFactorPct: new BN(100),
|
|
339
337
|
elevationGroups: fields.configParams.elevationGroups,
|
|
340
|
-
|
|
338
|
+
deleveragingThresholdSecsPerBps: new BN(3600),
|
|
341
339
|
disableUsageAsCollOutsideEmode: 0,
|
|
342
340
|
utilizationLimitBlockBorrowingAbove: 0,
|
|
343
341
|
hostFixedInterestRateBps: 0,
|
|
342
|
+
autodeleverageEnabled: 0,
|
|
344
343
|
borrowLimitOutsideElevationGroup: new BN(0),
|
|
345
344
|
borrowLimitAgainstThisCollateralInElevationGroup: Array(32).fill(new BN(0)),
|
|
346
|
-
|
|
345
|
+
deleveragingBonusIncreaseBpsPerDay: new BN(100),
|
|
346
|
+
reserved1: Array(1).fill(0),
|
|
347
347
|
reserved2: Array(2).fill(0),
|
|
348
348
|
reserved3: Array(8).fill(0),
|
|
349
349
|
};
|
package/src/utils/oracle.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { parsePriceData } from '@pythnetwork/client';
|
|
2
1
|
import { AccountInfo, Connection, PublicKey } from '@solana/web3.js';
|
|
3
2
|
import Decimal from 'decimal.js';
|
|
4
3
|
import { OraclePrices, Scope } from '@kamino-finance/scope-sdk';
|
|
@@ -8,6 +7,7 @@ import SwitchboardProgram from '@switchboard-xyz/sbv2-lite';
|
|
|
8
7
|
import { Reserve } from '../lib';
|
|
9
8
|
import { batchFetch } from '@kamino-finance/kliquidity-sdk';
|
|
10
9
|
import BN from 'bn.js';
|
|
10
|
+
import { PriceUpdateV2 } from '../pyth/accounts';
|
|
11
11
|
|
|
12
12
|
const SWITCHBOARD_V2_PROGRAM_ID = new PublicKey('SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f');
|
|
13
13
|
|
|
@@ -166,27 +166,21 @@ export function cacheOrGetPythPrices(
|
|
|
166
166
|
const result = oracleAccounts.get(oracle);
|
|
167
167
|
if (result) {
|
|
168
168
|
try {
|
|
169
|
-
const {
|
|
170
|
-
|
|
171
|
-
);
|
|
169
|
+
const { priceMessage } = PriceUpdateV2.decode(result.data);
|
|
170
|
+
const { price, exponent, conf: confidence, publishTime: timestamp, emaPrice } = priceMessage;
|
|
172
171
|
if (price) {
|
|
173
|
-
const px = new Decimal(price);
|
|
172
|
+
const px = new Decimal(price.toString()).div(10 ** Math.abs(exponent));
|
|
174
173
|
prices.spot = {
|
|
175
174
|
price: px,
|
|
176
|
-
timestamp,
|
|
177
|
-
valid: validatePythPx(px, confidence),
|
|
178
|
-
};
|
|
179
|
-
} else {
|
|
180
|
-
prices.spot = {
|
|
181
|
-
price: new Decimal(previousPrice),
|
|
182
|
-
timestamp: previousTimestamp,
|
|
183
|
-
valid: false,
|
|
175
|
+
timestamp: BigInt(timestamp.toString()),
|
|
176
|
+
valid: validatePythPx(px, confidence.toNumber()),
|
|
184
177
|
};
|
|
185
178
|
}
|
|
186
179
|
if (emaPrice !== undefined && emaPrice !== null) {
|
|
180
|
+
const emaPx = new Decimal(emaPrice.toString()).div(10 ** Math.abs(exponent));
|
|
187
181
|
prices.twap = {
|
|
188
|
-
price:
|
|
189
|
-
timestamp,
|
|
182
|
+
price: emaPx,
|
|
183
|
+
timestamp: BigInt(timestamp.toString()),
|
|
190
184
|
valid: true,
|
|
191
185
|
};
|
|
192
186
|
}
|