@kamino-finance/klend-sdk 3.0.1 → 3.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/dist/classes/market.d.ts +1 -1
- package/dist/classes/market.js +2 -2
- package/dist/classes/market.js.map +1 -1
- package/dist/leverage/calcs.d.ts +1 -1
- package/dist/leverage/calcs.js.map +1 -1
- package/dist/leverage/operations.d.ts +1 -1
- package/dist/leverage/operations.js.map +1 -1
- package/dist/leverage/utils.d.ts +3 -3
- package/dist/leverage/utils.js.map +1 -1
- package/dist/utils/kamino.d.ts +1 -1
- package/dist/utils/kamino.js.map +1 -1
- package/dist/utils/oracle.js +2 -2
- package/dist/utils/oracle.js.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/leverage/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Kamino, StrategyWithAddress } from '@hubbleprotocol/kamino-sdk';\nimport { KaminoMarket, KaminoReserve, lamportsToNumberDecimal } from '../classes';\nimport { Connection, PublicKey, TransactionInstruction } from '@solana/web3.js';\nimport { PriceAinBProvider, SwapIxnsProvider } from './operations';\nimport Decimal from 'decimal.js';\nimport { getTokenAccountBalanceDecimal } from '../utils';\nimport { numberToLamportsDecimal } from '../classes/utils';\nimport BN from 'bn.js';\n\nexport interface KaminoSwapperIxBuilder {\n (\n input: DepositAmountsForSwap,\n tokenAMint: PublicKey,\n tokenBMint: PublicKey,\n owner: PublicKey,\n slippage: Decimal,\n allKeys: PublicKey[]\n ): Promise<[TransactionInstruction[], PublicKey[]]>;\n}\n\nexport interface DepositAmountsForSwap {\n requiredAAmountToDeposit: Decimal;\n requiredBAmountToDeposit: Decimal;\n tokenAToSwapAmount: Decimal;\n tokenBToSwapAmount: Decimal;\n}\n\nexport const getTokenToKtokenSwapper = async (\n connection: Connection,\n kaminoMarket: KaminoMarket,\n kamino: Kamino,\n depositor: PublicKey,\n swapper: SwapIxnsProvider,\n priceAinB: PriceAinBProvider,\n includeAtaIxns: boolean = true\n): Promise<SwapIxnsProvider> => {\n return async (\n amountInLamports: number,\n amountInMint: PublicKey,\n amountOutMint: PublicKey,\n slippage: number,\n amountDebtAtaBalance?: Decimal\n ) => {\n const slippageBps = new Decimal(slippage).mul('100');\n const mintInDecimals = kaminoMarket.getReserveByMint(amountInMint)!.state.liquidity.mintDecimals.toNumber();\n const amountIn = lamportsToNumberDecimal(amountInLamports, mintInDecimals);\n console.debug('Depositing token', amountInMint.toString(), ' for ', amountOutMint.toString(), 'ktoken');\n if (amountDebtAtaBalance === undefined) {\n throw Error('Amount in debt ATA balance is undefined for leverage ktoken deposit');\n }\n\n const ixWithLookup = (await getKtokenDepositIxs(\n connection,\n kamino,\n depositor,\n amountInMint,\n amountOutMint,\n amountIn,\n slippageBps,\n amountDebtAtaBalance,\n swapper,\n priceAinB,\n includeAtaIxns\n ))!;\n return [ixWithLookup.instructions, ixWithLookup.lookupTablesAddresses];\n };\n};\n\nexport async function getKtokenDepositIxs(\n connection: Connection,\n kamino: Kamino,\n depositor: PublicKey,\n depositTokenMint: PublicKey,\n ktokenMint: PublicKey,\n amountToDeposit: Decimal,\n slippageBps: Decimal,\n amountExpectedDepositAtaBalance: Decimal,\n swapper: SwapIxnsProvider,\n priceAinB: PriceAinBProvider,\n includeAtaIxns: boolean = true\n) {\n const kaminoStrategy = await kamino.getStrategyByKTokenMint(ktokenMint);\n const tokenAMint = kaminoStrategy?.strategy.tokenAMint!;\n const tokenBMint = kaminoStrategy?.strategy.tokenBMint!;\n const priceAinBDecimal = await priceAinB(tokenAMint, tokenBMint);\n\n if (tokenAMint.equals(depositTokenMint)) {\n const bBalance = await getTokenAccountBalanceDecimal(connection, tokenBMint, depositor);\n const tokensBalances = { a: amountExpectedDepositAtaBalance, b: bBalance };\n console.log('amountToDeposit', amountToDeposit);\n return await kamino.singleSidedDepositTokenA(\n kaminoStrategy!,\n amountToDeposit,\n depositor,\n slippageBps,\n undefined,\n swapProviderToKaminoSwapProvider(swapper),\n tokensBalances,\n priceAinBDecimal,\n includeAtaIxns\n );\n } else if (tokenBMint.equals(depositTokenMint)) {\n const aBalance = await getTokenAccountBalanceDecimal(connection, tokenAMint, depositor);\n const tokensBalances = { a: aBalance, b: amountExpectedDepositAtaBalance };\n return await kamino.singleSidedDepositTokenB(\n kaminoStrategy!,\n amountToDeposit,\n depositor,\n slippageBps,\n undefined,\n swapProviderToKaminoSwapProvider(swapper),\n tokensBalances,\n priceAinBDecimal,\n includeAtaIxns\n );\n } else {\n throw Error('Deposit token is neither A nor B in the strategy');\n }\n}\n\nexport const getKtokenToTokenSwapper = async (\n kaminoMarket: KaminoMarket,\n kamino: Kamino,\n depositor: PublicKey,\n swapper: SwapIxnsProvider\n): Promise<SwapIxnsProvider> => {\n return async (amountInLamports: number, amountInMint: PublicKey, amountOutMint: PublicKey, slippage: number) => {\n const amountInDecimals = kaminoMarket.getReserveByMint(amountInMint)!.state.liquidity.mintDecimals.toNumber();\n const amountToWithdraw = lamportsToNumberDecimal(amountInLamports, amountInDecimals);\n const kaminoStrategy = await kamino.getStrategyByKTokenMint(amountInMint);\n\n console.log('Withdrawing ktoken', amountInMint.toString(), ' for ', amountOutMint.toString(), 'token');\n\n const ixWithdraw = (await getKtokenWithdrawIxs(kamino, depositor, kaminoStrategy!, amountToWithdraw))!;\n\n const [estimatedAOut, estimatedBOut] = await getKtokenWithdrawEstimatesAndPrice(\n kamino,\n kaminoStrategy!,\n amountToWithdraw\n );\n\n if (amountOutMint.equals(kaminoStrategy?.strategy.tokenAMint!)) {\n const [swapIxs, swapLookupTables] = await swapper(\n estimatedBOut.toNumber(),\n kaminoStrategy?.strategy.tokenBMint!,\n kaminoStrategy?.strategy.tokenAMint!,\n slippage\n );\n\n return [[...ixWithdraw.prerequisiteIxs, ixWithdraw.withdrawIx, ...swapIxs], swapLookupTables];\n } else if (amountOutMint.equals(kaminoStrategy?.strategy.tokenBMint!)) {\n const [swapIxs, swapLookupTables] = await swapper(\n estimatedAOut.toNumber(),\n kaminoStrategy?.strategy.tokenAMint!,\n kaminoStrategy?.strategy.tokenBMint!,\n slippage\n );\n\n return [[...ixWithdraw.prerequisiteIxs, ixWithdraw.withdrawIx, ...swapIxs], swapLookupTables];\n } else {\n throw Error('Deposit token is neither A nor B in the strategy');\n }\n };\n};\n\nexport async function getKtokenWithdrawIxs(\n kamino: Kamino,\n withdrawer: PublicKey,\n kaminoStrategy: StrategyWithAddress,\n amountToWithdraw: Decimal\n) {\n return await kamino.withdrawShares(kaminoStrategy!, amountToWithdraw, withdrawer);\n}\n\nexport async function getKtokenWithdrawEstimatesAndPrice(\n kamino: Kamino,\n kaminoStrategy: StrategyWithAddress,\n amountToWithdraw: Decimal\n) {\n const sharesData = await kamino.getStrategyShareData(kaminoStrategy);\n const withdrawPct = amountToWithdraw\n .div(\n lamportsToNumberDecimal(\n new Decimal(kaminoStrategy.strategy.sharesIssued.toString()),\n kaminoStrategy.strategy.sharesMintDecimals.toNumber()\n )\n )\n .toDecimalPlaces(18);\n\n const withdrawFee = new Decimal(10_000).sub(new Decimal(kaminoStrategy.strategy.withdrawFee.toString()));\n\n // TODO: Mihai/Marius improve - currently subtracting due to decimal accuracy issues compared to yvaults SC\n // for both A and B op: .sub(0.000002)\n\n const estimatedAOut = sharesData.balance.computedHoldings.invested.a\n .add(sharesData.balance.computedHoldings.available.a)\n .mul(withdrawPct)\n .toDecimalPlaces(kaminoStrategy.strategy.tokenAMintDecimals.toNumber(), 1)\n .sub(0.000002)\n .mul(withdrawFee)\n .div(10_000)\n .toDecimalPlaces(kaminoStrategy.strategy.tokenAMintDecimals.toNumber());\n\n const estimatedAOutDecimal = numberToLamportsDecimal(\n estimatedAOut,\n kaminoStrategy.strategy.tokenAMintDecimals.toNumber()\n ).floor();\n\n const estimatedBOut = sharesData.balance.computedHoldings.invested.b\n .add(sharesData.balance.computedHoldings.available.b)\n .mul(withdrawPct)\n .toDecimalPlaces(kaminoStrategy.strategy.tokenBMintDecimals.toNumber(), 1)\n .sub(0.000002)\n .mul(withdrawFee)\n .div(10_000)\n .toDecimalPlaces(kaminoStrategy.strategy.tokenAMintDecimals.toNumber());\n\n const estimatedBOutDecimal = numberToLamportsDecimal(\n estimatedBOut,\n kaminoStrategy.strategy.tokenBMintDecimals.toNumber()\n ).floor();\n\n console.log('a-out', estimatedAOutDecimal.toString());\n console.log('b-out', estimatedBOut.toString());\n return [estimatedAOutDecimal, estimatedBOutDecimal];\n}\n\nexport function swapProviderToKaminoSwapProvider(swapper: SwapIxnsProvider): KaminoSwapperIxBuilder {\n return async (\n input: DepositAmountsForSwap,\n tokenAMint: PublicKey,\n tokenBMint: PublicKey,\n _owner: PublicKey,\n slippageBps: Decimal,\n _allKeys: PublicKey[]\n ): Promise<[TransactionInstruction[], PublicKey[]]> => {\n if (input.tokenBToSwapAmount.lt(0)) {\n return await swapper(\n input.tokenBToSwapAmount.abs().toNumber(),\n tokenBMint,\n tokenAMint,\n slippageBps.toNumber() / 100\n );\n } else if (input.tokenAToSwapAmount.lt(0)) {\n return await swapper(\n input.tokenAToSwapAmount.abs().toNumber(),\n tokenAMint,\n tokenBMint,\n slippageBps.toNumber() / 100\n );\n } else {\n throw Error('Nothing to swap');\n }\n };\n}\n\nexport const getExpectedTokenBalanceAfterBorrow = async (\n connection: Connection,\n mint: PublicKey,\n owner: PublicKey,\n amountToBorrowLamports: Decimal,\n amountToBorrowmintDecimals: number\n) => {\n const initialUserTokenABalance = await getTokenAccountBalanceDecimal(connection, mint, owner);\n\n return initialUserTokenABalance\n .add(lamportsToNumberDecimal(amountToBorrowLamports, amountToBorrowmintDecimals))\n .toDecimalPlaces(amountToBorrowmintDecimals);\n};\n\nexport const isBorrowingEnabled = (reserve: KaminoReserve) => {\n return reserve.state.config.borrowLimit.gt(new BN(0));\n};\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/leverage/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Kamino, StrategyWithAddress } from '@kamino-finance/kliquidity-sdk';\nimport { KaminoMarket, KaminoReserve, lamportsToNumberDecimal } from '../classes';\nimport { Connection, PublicKey, TransactionInstruction } from '@solana/web3.js';\nimport { PriceAinBProvider, SwapIxnsProvider } from './operations';\nimport Decimal from 'decimal.js';\nimport { getTokenAccountBalanceDecimal } from '../utils';\nimport { numberToLamportsDecimal } from '../classes/utils';\nimport BN from 'bn.js';\n\nexport interface KaminoSwapperIxBuilder {\n (\n input: DepositAmountsForSwap,\n tokenAMint: PublicKey,\n tokenBMint: PublicKey,\n owner: PublicKey,\n slippage: Decimal,\n allKeys: PublicKey[]\n ): Promise<[TransactionInstruction[], PublicKey[]]>;\n}\n\nexport interface DepositAmountsForSwap {\n requiredAAmountToDeposit: Decimal;\n requiredBAmountToDeposit: Decimal;\n tokenAToSwapAmount: Decimal;\n tokenBToSwapAmount: Decimal;\n}\n\nexport const getTokenToKtokenSwapper = async (\n connection: Connection,\n kaminoMarket: KaminoMarket,\n kamino: Kamino,\n depositor: PublicKey,\n swapper: SwapIxnsProvider,\n priceAinB: PriceAinBProvider,\n includeAtaIxns: boolean = true\n): Promise<SwapIxnsProvider> => {\n return async (\n amountInLamports: number,\n amountInMint: PublicKey,\n amountOutMint: PublicKey,\n slippage: number,\n amountDebtAtaBalance?: Decimal\n ) => {\n const slippageBps = new Decimal(slippage).mul('100');\n const mintInDecimals = kaminoMarket.getReserveByMint(amountInMint)!.state.liquidity.mintDecimals.toNumber();\n const amountIn = lamportsToNumberDecimal(amountInLamports, mintInDecimals);\n console.debug('Depositing token', amountInMint.toString(), ' for ', amountOutMint.toString(), 'ktoken');\n if (amountDebtAtaBalance === undefined) {\n throw Error('Amount in debt ATA balance is undefined for leverage ktoken deposit');\n }\n\n const ixWithLookup = (await getKtokenDepositIxs(\n connection,\n kamino,\n depositor,\n amountInMint,\n amountOutMint,\n amountIn,\n slippageBps,\n amountDebtAtaBalance,\n swapper,\n priceAinB,\n includeAtaIxns\n ))!;\n return [ixWithLookup.instructions, ixWithLookup.lookupTablesAddresses];\n };\n};\n\nexport async function getKtokenDepositIxs(\n connection: Connection,\n kamino: Kamino,\n depositor: PublicKey,\n depositTokenMint: PublicKey,\n ktokenMint: PublicKey,\n amountToDeposit: Decimal,\n slippageBps: Decimal,\n amountExpectedDepositAtaBalance: Decimal,\n swapper: SwapIxnsProvider,\n priceAinB: PriceAinBProvider,\n includeAtaIxns: boolean = true\n) {\n const kaminoStrategy = await kamino.getStrategyByKTokenMint(ktokenMint);\n const tokenAMint = kaminoStrategy?.strategy.tokenAMint!;\n const tokenBMint = kaminoStrategy?.strategy.tokenBMint!;\n const priceAinBDecimal = await priceAinB(tokenAMint, tokenBMint);\n\n if (tokenAMint.equals(depositTokenMint)) {\n const bBalance = await getTokenAccountBalanceDecimal(connection, tokenBMint, depositor);\n const tokensBalances = { a: amountExpectedDepositAtaBalance, b: bBalance };\n console.log('amountToDeposit', amountToDeposit);\n return await kamino.singleSidedDepositTokenA(\n kaminoStrategy!,\n amountToDeposit,\n depositor,\n slippageBps,\n undefined,\n swapProviderToKaminoSwapProvider(swapper),\n tokensBalances,\n priceAinBDecimal,\n includeAtaIxns\n );\n } else if (tokenBMint.equals(depositTokenMint)) {\n const aBalance = await getTokenAccountBalanceDecimal(connection, tokenAMint, depositor);\n const tokensBalances = { a: aBalance, b: amountExpectedDepositAtaBalance };\n return await kamino.singleSidedDepositTokenB(\n kaminoStrategy!,\n amountToDeposit,\n depositor,\n slippageBps,\n undefined,\n swapProviderToKaminoSwapProvider(swapper),\n tokensBalances,\n priceAinBDecimal,\n includeAtaIxns\n );\n } else {\n throw Error('Deposit token is neither A nor B in the strategy');\n }\n}\n\nexport const getKtokenToTokenSwapper = async (\n kaminoMarket: KaminoMarket,\n kamino: Kamino,\n depositor: PublicKey,\n swapper: SwapIxnsProvider\n): Promise<SwapIxnsProvider> => {\n return async (amountInLamports: number, amountInMint: PublicKey, amountOutMint: PublicKey, slippage: number) => {\n const amountInDecimals = kaminoMarket.getReserveByMint(amountInMint)!.state.liquidity.mintDecimals.toNumber();\n const amountToWithdraw = lamportsToNumberDecimal(amountInLamports, amountInDecimals);\n const kaminoStrategy = await kamino.getStrategyByKTokenMint(amountInMint);\n\n console.log('Withdrawing ktoken', amountInMint.toString(), ' for ', amountOutMint.toString(), 'token');\n\n const ixWithdraw = (await getKtokenWithdrawIxs(kamino, depositor, kaminoStrategy!, amountToWithdraw))!;\n\n const [estimatedAOut, estimatedBOut] = await getKtokenWithdrawEstimatesAndPrice(\n kamino,\n kaminoStrategy!,\n amountToWithdraw\n );\n\n if (amountOutMint.equals(kaminoStrategy?.strategy.tokenAMint!)) {\n const [swapIxs, swapLookupTables] = await swapper(\n estimatedBOut.toNumber(),\n kaminoStrategy?.strategy.tokenBMint!,\n kaminoStrategy?.strategy.tokenAMint!,\n slippage\n );\n\n return [[...ixWithdraw.prerequisiteIxs, ixWithdraw.withdrawIx, ...swapIxs], swapLookupTables];\n } else if (amountOutMint.equals(kaminoStrategy?.strategy.tokenBMint!)) {\n const [swapIxs, swapLookupTables] = await swapper(\n estimatedAOut.toNumber(),\n kaminoStrategy?.strategy.tokenAMint!,\n kaminoStrategy?.strategy.tokenBMint!,\n slippage\n );\n\n return [[...ixWithdraw.prerequisiteIxs, ixWithdraw.withdrawIx, ...swapIxs], swapLookupTables];\n } else {\n throw Error('Deposit token is neither A nor B in the strategy');\n }\n };\n};\n\nexport async function getKtokenWithdrawIxs(\n kamino: Kamino,\n withdrawer: PublicKey,\n kaminoStrategy: StrategyWithAddress,\n amountToWithdraw: Decimal\n) {\n return await kamino.withdrawShares(kaminoStrategy!, amountToWithdraw, withdrawer);\n}\n\nexport async function getKtokenWithdrawEstimatesAndPrice(\n kamino: Kamino,\n kaminoStrategy: StrategyWithAddress,\n amountToWithdraw: Decimal\n) {\n const sharesData = await kamino.getStrategyShareData(kaminoStrategy);\n const withdrawPct = amountToWithdraw\n .div(\n lamportsToNumberDecimal(\n new Decimal(kaminoStrategy.strategy.sharesIssued.toString()),\n kaminoStrategy.strategy.sharesMintDecimals.toNumber()\n )\n )\n .toDecimalPlaces(18);\n\n const withdrawFee = new Decimal(10_000).sub(new Decimal(kaminoStrategy.strategy.withdrawFee.toString()));\n\n // TODO: Mihai/Marius improve - currently subtracting due to decimal accuracy issues compared to yvaults SC\n // for both A and B op: .sub(0.000002)\n\n const estimatedAOut = sharesData.balance.computedHoldings.invested.a\n .add(sharesData.balance.computedHoldings.available.a)\n .mul(withdrawPct)\n .toDecimalPlaces(kaminoStrategy.strategy.tokenAMintDecimals.toNumber(), 1)\n .sub(0.000002)\n .mul(withdrawFee)\n .div(10_000)\n .toDecimalPlaces(kaminoStrategy.strategy.tokenAMintDecimals.toNumber());\n\n const estimatedAOutDecimal = numberToLamportsDecimal(\n estimatedAOut,\n kaminoStrategy.strategy.tokenAMintDecimals.toNumber()\n ).floor();\n\n const estimatedBOut = sharesData.balance.computedHoldings.invested.b\n .add(sharesData.balance.computedHoldings.available.b)\n .mul(withdrawPct)\n .toDecimalPlaces(kaminoStrategy.strategy.tokenBMintDecimals.toNumber(), 1)\n .sub(0.000002)\n .mul(withdrawFee)\n .div(10_000)\n .toDecimalPlaces(kaminoStrategy.strategy.tokenAMintDecimals.toNumber());\n\n const estimatedBOutDecimal = numberToLamportsDecimal(\n estimatedBOut,\n kaminoStrategy.strategy.tokenBMintDecimals.toNumber()\n ).floor();\n\n console.log('a-out', estimatedAOutDecimal.toString());\n console.log('b-out', estimatedBOut.toString());\n return [estimatedAOutDecimal, estimatedBOutDecimal];\n}\n\nexport function swapProviderToKaminoSwapProvider(swapper: SwapIxnsProvider): KaminoSwapperIxBuilder {\n return async (\n input: DepositAmountsForSwap,\n tokenAMint: PublicKey,\n tokenBMint: PublicKey,\n _owner: PublicKey,\n slippageBps: Decimal,\n _allKeys: PublicKey[]\n ): Promise<[TransactionInstruction[], PublicKey[]]> => {\n if (input.tokenBToSwapAmount.lt(0)) {\n return await swapper(\n input.tokenBToSwapAmount.abs().toNumber(),\n tokenBMint,\n tokenAMint,\n slippageBps.toNumber() / 100\n );\n } else if (input.tokenAToSwapAmount.lt(0)) {\n return await swapper(\n input.tokenAToSwapAmount.abs().toNumber(),\n tokenAMint,\n tokenBMint,\n slippageBps.toNumber() / 100\n );\n } else {\n throw Error('Nothing to swap');\n }\n };\n}\n\nexport const getExpectedTokenBalanceAfterBorrow = async (\n connection: Connection,\n mint: PublicKey,\n owner: PublicKey,\n amountToBorrowLamports: Decimal,\n amountToBorrowmintDecimals: number\n) => {\n const initialUserTokenABalance = await getTokenAccountBalanceDecimal(connection, mint, owner);\n\n return initialUserTokenABalance\n .add(lamportsToNumberDecimal(amountToBorrowLamports, amountToBorrowmintDecimals))\n .toDecimalPlaces(amountToBorrowmintDecimals);\n};\n\nexport const isBorrowingEnabled = (reserve: KaminoReserve) => {\n return reserve.state.config.borrowLimit.gt(new BN(0));\n};\n"]}
|
package/dist/utils/kamino.d.ts
CHANGED
package/dist/utils/kamino.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kamino.js","sourceRoot":"","sources":["../../src/utils/kamino.ts"],"names":[],"mappings":";;;;;;;;;;;AAIA,4BAOC;AAVD,iDAA4C;AAC5C,6CAA4C;AAE5C,SAAsB,QAAQ,CAAC,OAAkB,EAAE,MAAc;;QAC/D,MAAM,CAAC,qBAAqB,CAAC,GAAG,mBAAS,CAAC,sBAAsB,CAC9D,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,EAC9C,MAAM,CAAC,YAAY,EAAE,CACtB,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,IAAA,mBAAO,EAAC,MAAM,CAAC,aAAa,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC,aAAa,KAAK,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACzF,CAAC;CAAA","sourcesContent":["import { Kamino } from '@
|
|
1
|
+
{"version":3,"file":"kamino.js","sourceRoot":"","sources":["../../src/utils/kamino.ts"],"names":[],"mappings":";;;;;;;;;;;AAIA,4BAOC;AAVD,iDAA4C;AAC5C,6CAA4C;AAE5C,SAAsB,QAAQ,CAAC,OAAkB,EAAE,MAAc;;QAC/D,MAAM,CAAC,qBAAqB,CAAC,GAAG,mBAAS,CAAC,sBAAsB,CAC9D,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,EAC9C,MAAM,CAAC,YAAY,EAAE,CACtB,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,IAAA,mBAAO,EAAC,MAAM,CAAC,aAAa,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC,aAAa,KAAK,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACzF,CAAC;CAAA","sourcesContent":["import { Kamino } from '@kamino-finance/kliquidity-sdk';\nimport { getMint } from '@solana/spl-token';\nimport { PublicKey } from '@solana/web3.js';\n\nexport async function isKtoken(mintKey: PublicKey, kamino: Kamino): Promise<boolean> {\n const [expectedMintAuthority] = PublicKey.findProgramAddressSync(\n [Buffer.from('authority'), mintKey.toBuffer()],\n kamino.getProgramID()\n );\n const mint = await getMint(kamino.getConnection(), mintKey);\n return mint.mintAuthority !== null && mint.mintAuthority.equals(expectedMintAuthority);\n}\n"]}
|
package/dist/utils/oracle.js
CHANGED
|
@@ -26,7 +26,7 @@ const scope_sdk_1 = require("@hubbleprotocol/scope-sdk");
|
|
|
26
26
|
const pubkey_1 = require("./pubkey");
|
|
27
27
|
const classes_1 = require("../classes");
|
|
28
28
|
const sbv2_lite_1 = __importDefault(require("@switchboard-xyz/sbv2-lite"));
|
|
29
|
-
const
|
|
29
|
+
const kliquidity_sdk_1 = require("@kamino-finance/kliquidity-sdk");
|
|
30
30
|
const SWITCHBOARD_V2_PROGRAM_ID = new web3_js_1.PublicKey('SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f');
|
|
31
31
|
// validate price confidence - confidence/price ratio should be less than 2%
|
|
32
32
|
exports.MAX_CONFIDENCE_PERCENTAGE = new decimal_js_1.default('2');
|
|
@@ -108,7 +108,7 @@ function getAllOracleAccounts(connection, reserves) {
|
|
|
108
108
|
}
|
|
109
109
|
});
|
|
110
110
|
const allAccountsDeduped = dedupKeys(allAccounts);
|
|
111
|
-
const allAccs = yield (0,
|
|
111
|
+
const allAccs = yield (0, kliquidity_sdk_1.batchFetch)(allAccountsDeduped, (chunk) => connection.getMultipleAccountsInfo(chunk));
|
|
112
112
|
const allAccsMap = new pubkey_1.PubkeyHashMap();
|
|
113
113
|
allAccs.forEach((acc, i) => {
|
|
114
114
|
if (acc) {
|
package/dist/utils/oracle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oracle.js","sourceRoot":"","sources":["../../src/utils/oracle.ts"],"names":[],"mappings":"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","sourcesContent":["import { parsePriceData } from '@pythnetwork/client';\nimport { AccountInfo, Connection, PublicKey } from '@solana/web3.js';\nimport Decimal from 'decimal.js';\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { OraclePrices, Scope } from '@hubbleprotocol/scope-sdk';\nimport { isNotNullPubkey, PubkeyHashMap, PublicKeySet } from './pubkey';\nimport { parseTokenSymbol } from '../classes';\nimport SwitchboardProgram from '@switchboard-xyz/sbv2-lite';\nimport { Reserve } from '../lib';\nimport { batchFetch } from '@hubbleprotocol/kamino-sdk';\nimport BN from 'bn.js';\n\nconst SWITCHBOARD_V2_PROGRAM_ID = new PublicKey('SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f');\n\n// validate price confidence - confidence/price ratio should be less than 2%\nexport const MAX_CONFIDENCE_PERCENTAGE: Decimal = new Decimal('2');\n\n/// Confidence factor is used to scale the confidence value to a value that can be compared to the price.\nexport const CONFIDENCE_FACTOR: Decimal = new Decimal('100').div(MAX_CONFIDENCE_PERCENTAGE);\n\nconst getScopeAddress = () => {\n return 'HFn8GnPADiny6XqUoWE8uRPPxb29ikn4yTuPa9MF2fWJ';\n};\n\nexport type TokenOracleData = {\n mintAddress: PublicKey;\n decimals: Decimal;\n price: Decimal;\n timestamp: bigint;\n valid: boolean;\n};\n\nexport type CandidatePrice = {\n price: Decimal;\n timestamp: bigint;\n valid: boolean;\n};\n\nexport type ScopeRefresh = {\n includeScopeRefresh: boolean;\n scopeFeed: string;\n};\n\n// TODO: Add freshness of the latest price to match sc logic\nexport async function getTokenOracleData(\n connection: Connection,\n reserves: Reserve[]\n): Promise<Array<[Reserve, TokenOracleData | undefined]>> {\n const allOracleAccounts = await getAllOracleAccounts(connection, reserves);\n const tokenOracleDataForReserves: Array<[Reserve, TokenOracleData | undefined]> = [];\n const pythCache = new PubkeyHashMap<PublicKey, PythPrices>();\n const switchboardCache = new PubkeyHashMap<PublicKey, CandidatePrice>();\n const scopeCache = new PubkeyHashMap<PublicKey, OraclePrices>();\n let switchboardV2: SwitchboardProgram | undefined;\n for (const reserve of reserves) {\n let currentBest: CandidatePrice | undefined = undefined;\n const oracle = {\n pythAddress: reserve.config.tokenInfo.pythConfiguration.price,\n switchboardFeedAddress: reserve.config.tokenInfo.switchboardConfiguration.priceAggregator,\n switchboardTwapAddress: reserve.config.tokenInfo.switchboardConfiguration.twapAggregator,\n scopeOracleAddress: reserve.config.tokenInfo.scopeConfiguration.priceFeed,\n };\n if (isNotNullPubkey(oracle.pythAddress)) {\n const pythPrices = cacheOrGetPythPrices(oracle.pythAddress, pythCache, allOracleAccounts);\n if (pythPrices && pythPrices.spot) {\n currentBest = getBestPrice(currentBest, pythPrices.spot);\n }\n }\n if (isNotNullPubkey(oracle.switchboardFeedAddress)) {\n if (!switchboardV2) {\n switchboardV2 = await SwitchboardProgram.loadMainnet(connection);\n }\n const switchboardPrice = cacheOrGetSwitchboardPrice(\n oracle.switchboardFeedAddress,\n switchboardCache,\n allOracleAccounts,\n switchboardV2\n );\n if (switchboardPrice) {\n currentBest = getBestPrice(currentBest, switchboardPrice);\n }\n }\n\n if (isNotNullPubkey(oracle.scopeOracleAddress)) {\n const scopePrice = cacheOrGetScopePrice(\n oracle.scopeOracleAddress,\n scopeCache,\n allOracleAccounts,\n reserve.config.tokenInfo.scopeConfiguration.priceChain\n );\n if (scopePrice) {\n currentBest = getBestPrice(currentBest, scopePrice);\n }\n }\n\n if (!currentBest) {\n console.error(`No price found for reserve: ${parseTokenSymbol(reserve.config.tokenInfo.name)}`);\n tokenOracleDataForReserves.push([reserve, undefined]);\n continue;\n }\n const tokenOracleData: TokenOracleData = {\n mintAddress: reserve.liquidity.mintPubkey,\n decimals: Decimal.pow(10, reserve.liquidity.mintDecimals.toString()),\n price: new Decimal(currentBest.price),\n timestamp: currentBest.timestamp,\n valid: currentBest.valid,\n };\n tokenOracleDataForReserves.push([reserve, tokenOracleData]);\n }\n return tokenOracleDataForReserves;\n}\n\nexport type AllOracleAccounts = PubkeyHashMap<PublicKey, AccountInfo<Buffer>>;\n\nexport async function getAllOracleAccounts(connection: Connection, reserves: Reserve[]): Promise<AllOracleAccounts> {\n const allAccounts: PublicKey[] = [];\n reserves.forEach((reserve) => {\n if (isNotNullPubkey(reserve.config.tokenInfo.pythConfiguration.price)) {\n allAccounts.push(reserve.config.tokenInfo.pythConfiguration.price);\n }\n if (isNotNullPubkey(reserve.config.tokenInfo.switchboardConfiguration.priceAggregator)) {\n allAccounts.push(reserve.config.tokenInfo.switchboardConfiguration.priceAggregator);\n }\n if (isNotNullPubkey(reserve.config.tokenInfo.switchboardConfiguration.twapAggregator)) {\n allAccounts.push(reserve.config.tokenInfo.switchboardConfiguration.twapAggregator);\n }\n if (isNotNullPubkey(reserve.config.tokenInfo.scopeConfiguration.priceFeed)) {\n allAccounts.push(reserve.config.tokenInfo.scopeConfiguration.priceFeed);\n }\n });\n const allAccountsDeduped = dedupKeys(allAccounts);\n const allAccs = await batchFetch(allAccountsDeduped, (chunk) => connection.getMultipleAccountsInfo(chunk));\n const allAccsMap = new PubkeyHashMap<PublicKey, AccountInfo<Buffer>>();\n allAccs.forEach((acc, i) => {\n if (acc) {\n allAccsMap.set(allAccountsDeduped[i], acc);\n }\n });\n return allAccsMap;\n}\n\nfunction dedupKeys(keys: PublicKey[]): PublicKey[] {\n return new PublicKeySet(keys).toArray();\n}\n\nexport type PythPrices = {\n spot?: CandidatePrice;\n twap?: CandidatePrice;\n};\n\n/**\n * Get pyth price from cache or fetch if not available\n * @param oracle oracle address\n * @param cache pyth cache\n * @param oracleAccounts all oracle accounts\n */\nexport function cacheOrGetPythPrices(\n oracle: PublicKey,\n cache: Map<PublicKey, PythPrices>,\n oracleAccounts: AllOracleAccounts\n): PythPrices | null {\n const prices: PythPrices = {};\n const cached = cache.get(oracle);\n if (cached) {\n return cached;\n } else {\n const result = oracleAccounts.get(oracle);\n if (result) {\n try {\n const { price, timestamp, emaPrice, previousPrice, previousTimestamp, confidence } = parsePriceData(\n result.data\n );\n if (price) {\n const px = new Decimal(price);\n prices.spot = {\n price: px,\n timestamp,\n valid: validatePythPx(px, confidence),\n };\n } else {\n prices.spot = {\n price: new Decimal(previousPrice),\n timestamp: previousTimestamp,\n valid: false,\n };\n }\n if (emaPrice !== undefined && emaPrice !== null) {\n prices.twap = {\n price: new Decimal(emaPrice.value),\n timestamp,\n valid: true,\n };\n }\n if (prices.spot || prices.twap) {\n cache.set(oracle, prices);\n }\n } catch (error) {\n console.error(`Error parsing pyth price account ${oracle.toString()} data`, error);\n return null;\n }\n } else {\n return null;\n }\n }\n return prices;\n}\n\n/**\n * Get switchboard price from cache or fetch if not available\n * @param oracle oracle address\n * @param switchboardCache cache for oracle prices\n * @param oracleAccounts all oracle accounts\n * @param switchboardV2 loaded switchboard program\n */\nexport function cacheOrGetSwitchboardPrice(\n oracle: PublicKey,\n switchboardCache: Map<PublicKey, CandidatePrice>,\n oracleAccounts: AllOracleAccounts,\n switchboardV2: SwitchboardProgram\n): CandidatePrice | null {\n const cached = switchboardCache.get(oracle);\n if (cached) {\n return cached;\n } else {\n const info = oracleAccounts.get(oracle);\n if (info) {\n if (info.owner.equals(SWITCHBOARD_V2_PROGRAM_ID)) {\n const agg = switchboardV2.decodeAggregator(info!);\n // @ts-ignore\n const result: Big.Big | null = switchboardV2.getLatestAggregatorValue(agg);\n if (result !== undefined && result !== null) {\n const switchboardPx = new Decimal(result.toString());\n const latestRoundTimestamp: BN = agg.latestConfirmedRound.roundOpenTimestamp;\n const ts = BigInt(latestRoundTimestamp.toString());\n const valid = validateSwitchboardV2Px(agg);\n return {\n price: switchboardPx,\n timestamp: ts,\n valid,\n };\n }\n } else {\n console.error('Unrecognized switchboard owner address: ', info.owner.toString());\n return null;\n }\n }\n }\n return null;\n}\n\n/**\n * Get scope price from cache or fetch if not available\n * @param oracle oracle address\n * @param scopeCache cache for oracle prices\n * @param allOracleAccounts all oracle accounts\n * @param chain scope chain\n */\nexport function cacheOrGetScopePrice(\n oracle: PublicKey,\n scopeCache: Map<PublicKey, OraclePrices>,\n allOracleAccounts: AllOracleAccounts,\n chain: number[]\n): CandidatePrice | null {\n if (!isNotNullPubkey(oracle) || !chain || !Scope.isScopeChainValid(chain)) {\n return null;\n }\n\n const scopePrices = scopeCache.get(oracle);\n if (scopePrices) {\n return scopeChainToCandidatePrice(chain, scopePrices);\n }\n const info = allOracleAccounts.get(oracle);\n if (info) {\n const owner = info.owner.toString();\n if (owner === getScopeAddress()) {\n const prices = OraclePrices.decode(info.data);\n scopeCache.set(oracle, prices);\n return scopeChainToCandidatePrice(chain, prices);\n } else {\n console.error('Unrecognized scope owner address: ', owner);\n }\n }\n\n return null;\n}\n\nfunction getBestPrice(current: CandidatePrice | undefined, next: CandidatePrice): CandidatePrice | undefined {\n if (isBetterPrice(current, next)) {\n return next;\n }\n return current;\n}\n\nfunction isBetterPrice(current: CandidatePrice | undefined, next: CandidatePrice): boolean {\n if (!current) {\n return true;\n }\n if (current.valid && !next.valid) {\n return false;\n }\n if (!current.valid && next.valid) {\n return true;\n }\n return next.timestamp > current.timestamp;\n}\n\nfunction validatePythPx(price: Decimal, confidence: number | undefined): boolean {\n const conf50x = new Decimal(confidence || 0).mul(CONFIDENCE_FACTOR);\n return price.gt(conf50x);\n}\n\nfunction validateSwitchboardV2Px(agg: any): boolean {\n const pxMantissa = new Decimal(agg.latestConfirmedRound.result.mantissa.toString());\n const pxScale = new Decimal(agg.latestConfirmedRound.result.scale.toString());\n const stDevMantissa = new Decimal(agg.latestConfirmedRound.stdDeviation.mantissa.toString());\n const stDevScale = new Decimal(agg.latestConfirmedRound.stdDeviation.scale.toString());\n let conf50xScaled: Decimal;\n if (pxScale.gte(stDevScale)) {\n const scalingFactor = pxScale.sub(stDevScale);\n const conf50x = stDevMantissa.mul(CONFIDENCE_FACTOR);\n conf50xScaled = conf50x.mul(scalingFactor);\n } else {\n const scalingFactor = stDevScale.sub(pxScale);\n const conf50x = stDevMantissa.mul(CONFIDENCE_FACTOR);\n conf50xScaled = conf50x.div(scalingFactor);\n }\n return conf50xScaled.gte(pxMantissa);\n}\n\nfunction scopeChainToCandidatePrice(chain: number[], prices: OraclePrices): CandidatePrice {\n const scopePx = Scope.getPriceFromScopeChain(chain, prices);\n const valid = scopePx.timestamp.gt('0'); // scope prices are pre-validated\n return {\n price: scopePx.price,\n timestamp: BigInt(scopePx.timestamp.toString()),\n valid,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"oracle.js","sourceRoot":"","sources":["../../src/utils/oracle.ts"],"names":[],"mappings":"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","sourcesContent":["import { parsePriceData } from '@pythnetwork/client';\nimport { AccountInfo, Connection, PublicKey } from '@solana/web3.js';\nimport Decimal from 'decimal.js';\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { OraclePrices, Scope } from '@hubbleprotocol/scope-sdk';\nimport { isNotNullPubkey, PubkeyHashMap, PublicKeySet } from './pubkey';\nimport { parseTokenSymbol } from '../classes';\nimport SwitchboardProgram from '@switchboard-xyz/sbv2-lite';\nimport { Reserve } from '../lib';\nimport { batchFetch } from '@kamino-finance/kliquidity-sdk';\nimport BN from 'bn.js';\n\nconst SWITCHBOARD_V2_PROGRAM_ID = new PublicKey('SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f');\n\n// validate price confidence - confidence/price ratio should be less than 2%\nexport const MAX_CONFIDENCE_PERCENTAGE: Decimal = new Decimal('2');\n\n/// Confidence factor is used to scale the confidence value to a value that can be compared to the price.\nexport const CONFIDENCE_FACTOR: Decimal = new Decimal('100').div(MAX_CONFIDENCE_PERCENTAGE);\n\nconst getScopeAddress = () => {\n return 'HFn8GnPADiny6XqUoWE8uRPPxb29ikn4yTuPa9MF2fWJ';\n};\n\nexport type TokenOracleData = {\n mintAddress: PublicKey;\n decimals: Decimal;\n price: Decimal;\n timestamp: bigint;\n valid: boolean;\n};\n\nexport type CandidatePrice = {\n price: Decimal;\n timestamp: bigint;\n valid: boolean;\n};\n\nexport type ScopeRefresh = {\n includeScopeRefresh: boolean;\n scopeFeed: string;\n};\n\n// TODO: Add freshness of the latest price to match sc logic\nexport async function getTokenOracleData(\n connection: Connection,\n reserves: Reserve[]\n): Promise<Array<[Reserve, TokenOracleData | undefined]>> {\n const allOracleAccounts = await getAllOracleAccounts(connection, reserves);\n const tokenOracleDataForReserves: Array<[Reserve, TokenOracleData | undefined]> = [];\n const pythCache = new PubkeyHashMap<PublicKey, PythPrices>();\n const switchboardCache = new PubkeyHashMap<PublicKey, CandidatePrice>();\n const scopeCache = new PubkeyHashMap<PublicKey, OraclePrices>();\n let switchboardV2: SwitchboardProgram | undefined;\n for (const reserve of reserves) {\n let currentBest: CandidatePrice | undefined = undefined;\n const oracle = {\n pythAddress: reserve.config.tokenInfo.pythConfiguration.price,\n switchboardFeedAddress: reserve.config.tokenInfo.switchboardConfiguration.priceAggregator,\n switchboardTwapAddress: reserve.config.tokenInfo.switchboardConfiguration.twapAggregator,\n scopeOracleAddress: reserve.config.tokenInfo.scopeConfiguration.priceFeed,\n };\n if (isNotNullPubkey(oracle.pythAddress)) {\n const pythPrices = cacheOrGetPythPrices(oracle.pythAddress, pythCache, allOracleAccounts);\n if (pythPrices && pythPrices.spot) {\n currentBest = getBestPrice(currentBest, pythPrices.spot);\n }\n }\n if (isNotNullPubkey(oracle.switchboardFeedAddress)) {\n if (!switchboardV2) {\n switchboardV2 = await SwitchboardProgram.loadMainnet(connection);\n }\n const switchboardPrice = cacheOrGetSwitchboardPrice(\n oracle.switchboardFeedAddress,\n switchboardCache,\n allOracleAccounts,\n switchboardV2\n );\n if (switchboardPrice) {\n currentBest = getBestPrice(currentBest, switchboardPrice);\n }\n }\n\n if (isNotNullPubkey(oracle.scopeOracleAddress)) {\n const scopePrice = cacheOrGetScopePrice(\n oracle.scopeOracleAddress,\n scopeCache,\n allOracleAccounts,\n reserve.config.tokenInfo.scopeConfiguration.priceChain\n );\n if (scopePrice) {\n currentBest = getBestPrice(currentBest, scopePrice);\n }\n }\n\n if (!currentBest) {\n console.error(`No price found for reserve: ${parseTokenSymbol(reserve.config.tokenInfo.name)}`);\n tokenOracleDataForReserves.push([reserve, undefined]);\n continue;\n }\n const tokenOracleData: TokenOracleData = {\n mintAddress: reserve.liquidity.mintPubkey,\n decimals: Decimal.pow(10, reserve.liquidity.mintDecimals.toString()),\n price: new Decimal(currentBest.price),\n timestamp: currentBest.timestamp,\n valid: currentBest.valid,\n };\n tokenOracleDataForReserves.push([reserve, tokenOracleData]);\n }\n return tokenOracleDataForReserves;\n}\n\nexport type AllOracleAccounts = PubkeyHashMap<PublicKey, AccountInfo<Buffer>>;\n\nexport async function getAllOracleAccounts(connection: Connection, reserves: Reserve[]): Promise<AllOracleAccounts> {\n const allAccounts: PublicKey[] = [];\n reserves.forEach((reserve) => {\n if (isNotNullPubkey(reserve.config.tokenInfo.pythConfiguration.price)) {\n allAccounts.push(reserve.config.tokenInfo.pythConfiguration.price);\n }\n if (isNotNullPubkey(reserve.config.tokenInfo.switchboardConfiguration.priceAggregator)) {\n allAccounts.push(reserve.config.tokenInfo.switchboardConfiguration.priceAggregator);\n }\n if (isNotNullPubkey(reserve.config.tokenInfo.switchboardConfiguration.twapAggregator)) {\n allAccounts.push(reserve.config.tokenInfo.switchboardConfiguration.twapAggregator);\n }\n if (isNotNullPubkey(reserve.config.tokenInfo.scopeConfiguration.priceFeed)) {\n allAccounts.push(reserve.config.tokenInfo.scopeConfiguration.priceFeed);\n }\n });\n const allAccountsDeduped = dedupKeys(allAccounts);\n const allAccs = await batchFetch(allAccountsDeduped, (chunk) => connection.getMultipleAccountsInfo(chunk));\n const allAccsMap = new PubkeyHashMap<PublicKey, AccountInfo<Buffer>>();\n allAccs.forEach((acc, i) => {\n if (acc) {\n allAccsMap.set(allAccountsDeduped[i], acc);\n }\n });\n return allAccsMap;\n}\n\nfunction dedupKeys(keys: PublicKey[]): PublicKey[] {\n return new PublicKeySet(keys).toArray();\n}\n\nexport type PythPrices = {\n spot?: CandidatePrice;\n twap?: CandidatePrice;\n};\n\n/**\n * Get pyth price from cache or fetch if not available\n * @param oracle oracle address\n * @param cache pyth cache\n * @param oracleAccounts all oracle accounts\n */\nexport function cacheOrGetPythPrices(\n oracle: PublicKey,\n cache: Map<PublicKey, PythPrices>,\n oracleAccounts: AllOracleAccounts\n): PythPrices | null {\n const prices: PythPrices = {};\n const cached = cache.get(oracle);\n if (cached) {\n return cached;\n } else {\n const result = oracleAccounts.get(oracle);\n if (result) {\n try {\n const { price, timestamp, emaPrice, previousPrice, previousTimestamp, confidence } = parsePriceData(\n result.data\n );\n if (price) {\n const px = new Decimal(price);\n prices.spot = {\n price: px,\n timestamp,\n valid: validatePythPx(px, confidence),\n };\n } else {\n prices.spot = {\n price: new Decimal(previousPrice),\n timestamp: previousTimestamp,\n valid: false,\n };\n }\n if (emaPrice !== undefined && emaPrice !== null) {\n prices.twap = {\n price: new Decimal(emaPrice.value),\n timestamp,\n valid: true,\n };\n }\n if (prices.spot || prices.twap) {\n cache.set(oracle, prices);\n }\n } catch (error) {\n console.error(`Error parsing pyth price account ${oracle.toString()} data`, error);\n return null;\n }\n } else {\n return null;\n }\n }\n return prices;\n}\n\n/**\n * Get switchboard price from cache or fetch if not available\n * @param oracle oracle address\n * @param switchboardCache cache for oracle prices\n * @param oracleAccounts all oracle accounts\n * @param switchboardV2 loaded switchboard program\n */\nexport function cacheOrGetSwitchboardPrice(\n oracle: PublicKey,\n switchboardCache: Map<PublicKey, CandidatePrice>,\n oracleAccounts: AllOracleAccounts,\n switchboardV2: SwitchboardProgram\n): CandidatePrice | null {\n const cached = switchboardCache.get(oracle);\n if (cached) {\n return cached;\n } else {\n const info = oracleAccounts.get(oracle);\n if (info) {\n if (info.owner.equals(SWITCHBOARD_V2_PROGRAM_ID)) {\n const agg = switchboardV2.decodeAggregator(info!);\n // @ts-ignore\n const result: Big.Big | null = switchboardV2.getLatestAggregatorValue(agg);\n if (result !== undefined && result !== null) {\n const switchboardPx = new Decimal(result.toString());\n const latestRoundTimestamp: BN = agg.latestConfirmedRound.roundOpenTimestamp;\n const ts = BigInt(latestRoundTimestamp.toString());\n const valid = validateSwitchboardV2Px(agg);\n return {\n price: switchboardPx,\n timestamp: ts,\n valid,\n };\n }\n } else {\n console.error('Unrecognized switchboard owner address: ', info.owner.toString());\n return null;\n }\n }\n }\n return null;\n}\n\n/**\n * Get scope price from cache or fetch if not available\n * @param oracle oracle address\n * @param scopeCache cache for oracle prices\n * @param allOracleAccounts all oracle accounts\n * @param chain scope chain\n */\nexport function cacheOrGetScopePrice(\n oracle: PublicKey,\n scopeCache: Map<PublicKey, OraclePrices>,\n allOracleAccounts: AllOracleAccounts,\n chain: number[]\n): CandidatePrice | null {\n if (!isNotNullPubkey(oracle) || !chain || !Scope.isScopeChainValid(chain)) {\n return null;\n }\n\n const scopePrices = scopeCache.get(oracle);\n if (scopePrices) {\n return scopeChainToCandidatePrice(chain, scopePrices);\n }\n const info = allOracleAccounts.get(oracle);\n if (info) {\n const owner = info.owner.toString();\n if (owner === getScopeAddress()) {\n const prices = OraclePrices.decode(info.data);\n scopeCache.set(oracle, prices);\n return scopeChainToCandidatePrice(chain, prices);\n } else {\n console.error('Unrecognized scope owner address: ', owner);\n }\n }\n\n return null;\n}\n\nfunction getBestPrice(current: CandidatePrice | undefined, next: CandidatePrice): CandidatePrice | undefined {\n if (isBetterPrice(current, next)) {\n return next;\n }\n return current;\n}\n\nfunction isBetterPrice(current: CandidatePrice | undefined, next: CandidatePrice): boolean {\n if (!current) {\n return true;\n }\n if (current.valid && !next.valid) {\n return false;\n }\n if (!current.valid && next.valid) {\n return true;\n }\n return next.timestamp > current.timestamp;\n}\n\nfunction validatePythPx(price: Decimal, confidence: number | undefined): boolean {\n const conf50x = new Decimal(confidence || 0).mul(CONFIDENCE_FACTOR);\n return price.gt(conf50x);\n}\n\nfunction validateSwitchboardV2Px(agg: any): boolean {\n const pxMantissa = new Decimal(agg.latestConfirmedRound.result.mantissa.toString());\n const pxScale = new Decimal(agg.latestConfirmedRound.result.scale.toString());\n const stDevMantissa = new Decimal(agg.latestConfirmedRound.stdDeviation.mantissa.toString());\n const stDevScale = new Decimal(agg.latestConfirmedRound.stdDeviation.scale.toString());\n let conf50xScaled: Decimal;\n if (pxScale.gte(stDevScale)) {\n const scalingFactor = pxScale.sub(stDevScale);\n const conf50x = stDevMantissa.mul(CONFIDENCE_FACTOR);\n conf50xScaled = conf50x.mul(scalingFactor);\n } else {\n const scalingFactor = stDevScale.sub(pxScale);\n const conf50x = stDevMantissa.mul(CONFIDENCE_FACTOR);\n conf50xScaled = conf50x.div(scalingFactor);\n }\n return conf50xScaled.gte(pxMantissa);\n}\n\nfunction scopeChainToCandidatePrice(chain: number[], prices: OraclePrices): CandidatePrice {\n const scopePx = Scope.getPriceFromScopeChain(chain, prices);\n const valid = scopePx.timestamp.gt('0'); // scope prices are pre-validated\n return {\n price: scopePx.price,\n timestamp: BigInt(scopePx.timestamp.toString()),\n valid,\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kamino-finance/klend-sdk",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Typescript SDK for interacting with the Kamino Lending (klend) protocol",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"@bokuweb/zstd-wasm": "^0.0.20",
|
|
45
45
|
"@coral-xyz/anchor": "^0.28.0",
|
|
46
46
|
"@coral-xyz/borsh": "^0.28.0",
|
|
47
|
-
"@hubbleprotocol/farms-sdk": "^0.
|
|
48
|
-
"@hubbleprotocol/kamino-sdk": "^5.2.0",
|
|
47
|
+
"@hubbleprotocol/farms-sdk": "^0.11.0",
|
|
49
48
|
"@hubbleprotocol/scope-sdk": "^5.0.20",
|
|
49
|
+
"@kamino-finance/kliquidity-sdk": "^6.1.0",
|
|
50
50
|
"@pythnetwork/client": "^2.5.1",
|
|
51
51
|
"@solana/buffer-layout": "^4.0.0",
|
|
52
52
|
"@solana/spl-token": "^0.3.11",
|
|
@@ -94,8 +94,8 @@
|
|
|
94
94
|
"typescript-eslint": "^0.0.1-alpha.0"
|
|
95
95
|
},
|
|
96
96
|
"resolutions": {
|
|
97
|
-
"@
|
|
98
|
-
"@hubbleprotocol/farms-sdk": "^0.
|
|
97
|
+
"@kamino-finance/kliquidity-sdk": "^6.1.0",
|
|
98
|
+
"@hubbleprotocol/farms-sdk": "^0.11.0"
|
|
99
99
|
},
|
|
100
100
|
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
|
|
101
101
|
}
|