From 2f630a0c8ac47d80bc38b4dc812784eb887195d2 Mon Sep 17 00:00:00 2001 From: 0xodia <0xodia@solend.fi> Date: Tue, 2 Apr 2024 16:53:12 -0400 Subject: [PATCH] restore config files --- solend-lite/src/stores/pools.ts | 2 +- solend-sdk/README.md | 4 +- solend-sdk/__tests__/flash_loan.test.ts | 78 - solend-sdk/__tests__/market.test.ts | 191 --- solend-sdk/__tests__/obligation.test.ts | 55 - solend-sdk/__tests__/rpc.test.ts | 28 - solend-sdk/docs/.nojekyll | 1 - solend-sdk/docs/CNAME | 1 - solend-sdk/docs/assets/highlight.css | 85 - solend-sdk/docs/assets/icons.css | 1043 ------------- solend-sdk/docs/assets/icons.png | Bin 9615 -> 0 bytes solend-sdk/docs/assets/icons@2x.png | Bin 28144 -> 0 bytes solend-sdk/docs/assets/main.js | 52 - solend-sdk/docs/assets/search.js | 1 - solend-sdk/docs/assets/style.css | 1388 ----------------- solend-sdk/docs/assets/widgets.png | Bin 480 -> 0 bytes solend-sdk/docs/assets/widgets@2x.png | Bin 855 -> 0 bytes solend-sdk/docs/classes/SolendAction.html | 1 - solend-sdk/docs/classes/SolendClaim.html | 1 - solend-sdk/docs/classes/SolendMarket.html | 1 - solend-sdk/docs/classes/SolendObligation.html | 1 - solend-sdk/docs/classes/SolendReserve.html | 1 - solend-sdk/docs/classes/SolendWallet.html | 1 - solend-sdk/docs/index.html | 66 - solend-sdk/docs/interfaces/LastUpdate.html | 1 - solend-sdk/docs/interfaces/LendingMarket.html | 1 - solend-sdk/docs/interfaces/Obligation.html | 1 - .../docs/interfaces/ObligationCollateral.html | 1 - .../docs/interfaces/ObligationLiquidity.html | 1 - .../docs/interfaces/ProtoObligation.html | 1 - solend-sdk/docs/interfaces/Reserve.html | 1 - .../docs/interfaces/ReserveCollateral.html | 1 - solend-sdk/docs/interfaces/ReserveConfig.html | 1 - .../docs/interfaces/ReserveLiquidity.html | 1 - solend-sdk/docs/modules.html | 18 - solend-sdk/package.json | 19 +- solend-sdk/src/classes/action.ts | 912 ----------- solend-sdk/src/classes/claim.ts | 179 --- solend-sdk/src/classes/constants.ts | 32 - solend-sdk/src/classes/index.ts | 8 - solend-sdk/src/classes/market.ts | 269 ---- solend-sdk/src/classes/obligation.ts | 144 -- solend-sdk/src/classes/utils.ts | 100 -- solend-sdk/src/classes/wallet.ts | 380 ----- .../src/core/{action/action.ts => actions.ts} | 26 +- solend-sdk/src/core/constants.ts | 61 + solend-sdk/src/core/index.ts | 3 +- solend-sdk/src/core/margin.ts | 869 +++++++++++ solend-sdk/src/core/types.ts | 3 + solend-sdk/src/core/utils/config.ts | 10 +- solend-sdk/src/core/utils/index.ts | 3 +- solend-sdk/src/core/utils/metadata.ts | 37 - solend-sdk/src/core/utils/obligations.ts | 242 ++- solend-sdk/src/core/utils/pools.ts | 31 +- solend-sdk/src/core/utils/prices.ts | 2 +- solend-sdk/src/core/utils/wallet.ts | 91 -- .../src/experimental/break_flash_loans.ts | 137 -- solend-sdk/src/hooks/margin.tsx | 35 + solend-sdk/src/hooks/obligation.tsx | 29 + solend-sdk/src/hooks/reserve.tsx | 35 + .../instructions/borrowObligationLiquidity.ts | 2 +- .../depositObligationCollateral.ts | 2 +- .../instructions/depositReserveLiquidity.ts | 2 +- ...ReserveLiquidityAndObligationCollateral.ts | 2 +- .../flashBorrowReserveLiquidity.ts | 2 +- .../flashRepayReserveLiquidity.ts | 2 +- solend-sdk/src/instructions/forgiveDebt.ts | 2 +- solend-sdk/src/instructions/index.ts | 2 + .../src/instructions/initLendingMarket.ts | 2 +- solend-sdk/src/instructions/initReserve.ts | 2 +- .../instructions/redeemReserveCollateral.ts | 2 +- .../instructions/repayObligationLiquidity.ts | 2 +- .../setLendingMarketOwnerAndConfig.ts | 2 +- .../src/instructions/updateReserveConfig.ts | 2 +- .../withdrawObligationCollateral.ts | 2 +- ...tionCollateralAndRedeemReserveLiquidity.ts | 2 +- solend-sdk/src/{utils => }/layout.ts | 0 solend-sdk/src/lib.ts | 1 - solend-sdk/src/state/lastUpdate.ts | 2 +- solend-sdk/src/state/lendingMarket.ts | 2 +- solend-sdk/src/state/obligation.ts | 3 +- solend-sdk/src/state/rateLimiter.ts | 2 +- solend-sdk/src/state/reserve.ts | 2 +- solend-sdk/src/utils/merkle_distributor.ts | 492 ------ solend-sdk/src/utils/rpc/cached.ts | 303 ---- solend-sdk/src/utils/rpc/index.ts | 5 - solend-sdk/src/utils/rpc/instrumented.ts | 214 --- solend-sdk/src/utils/rpc/interface.ts | 95 -- solend-sdk/src/utils/rpc/multi.ts | 248 --- solend-sdk/src/utils/rpc/retry.ts | 185 --- 90 files changed, 1280 insertions(+), 6992 deletions(-) delete mode 100644 solend-sdk/__tests__/flash_loan.test.ts delete mode 100644 solend-sdk/__tests__/market.test.ts delete mode 100644 solend-sdk/__tests__/obligation.test.ts delete mode 100644 solend-sdk/__tests__/rpc.test.ts delete mode 100644 solend-sdk/docs/.nojekyll delete mode 100644 solend-sdk/docs/CNAME delete mode 100644 solend-sdk/docs/assets/highlight.css delete mode 100644 solend-sdk/docs/assets/icons.css delete mode 100644 solend-sdk/docs/assets/icons.png delete mode 100644 solend-sdk/docs/assets/icons@2x.png delete mode 100644 solend-sdk/docs/assets/main.js delete mode 100644 solend-sdk/docs/assets/search.js delete mode 100644 solend-sdk/docs/assets/style.css delete mode 100644 solend-sdk/docs/assets/widgets.png delete mode 100644 solend-sdk/docs/assets/widgets@2x.png delete mode 100644 solend-sdk/docs/classes/SolendAction.html delete mode 100644 solend-sdk/docs/classes/SolendClaim.html delete mode 100644 solend-sdk/docs/classes/SolendMarket.html delete mode 100644 solend-sdk/docs/classes/SolendObligation.html delete mode 100644 solend-sdk/docs/classes/SolendReserve.html delete mode 100644 solend-sdk/docs/classes/SolendWallet.html delete mode 100644 solend-sdk/docs/index.html delete mode 100644 solend-sdk/docs/interfaces/LastUpdate.html delete mode 100644 solend-sdk/docs/interfaces/LendingMarket.html delete mode 100644 solend-sdk/docs/interfaces/Obligation.html delete mode 100644 solend-sdk/docs/interfaces/ObligationCollateral.html delete mode 100644 solend-sdk/docs/interfaces/ObligationLiquidity.html delete mode 100644 solend-sdk/docs/interfaces/ProtoObligation.html delete mode 100644 solend-sdk/docs/interfaces/Reserve.html delete mode 100644 solend-sdk/docs/interfaces/ReserveCollateral.html delete mode 100644 solend-sdk/docs/interfaces/ReserveConfig.html delete mode 100644 solend-sdk/docs/interfaces/ReserveLiquidity.html delete mode 100644 solend-sdk/docs/modules.html delete mode 100644 solend-sdk/src/classes/action.ts delete mode 100644 solend-sdk/src/classes/claim.ts delete mode 100644 solend-sdk/src/classes/constants.ts delete mode 100644 solend-sdk/src/classes/index.ts delete mode 100644 solend-sdk/src/classes/market.ts delete mode 100644 solend-sdk/src/classes/obligation.ts delete mode 100644 solend-sdk/src/classes/utils.ts delete mode 100644 solend-sdk/src/classes/wallet.ts rename solend-sdk/src/core/{action/action.ts => actions.ts} (97%) create mode 100644 solend-sdk/src/core/margin.ts delete mode 100644 solend-sdk/src/core/utils/metadata.ts delete mode 100644 solend-sdk/src/core/utils/wallet.ts delete mode 100644 solend-sdk/src/experimental/break_flash_loans.ts create mode 100644 solend-sdk/src/hooks/margin.tsx create mode 100644 solend-sdk/src/hooks/obligation.tsx create mode 100644 solend-sdk/src/hooks/reserve.tsx rename solend-sdk/src/{utils => }/layout.ts (100%) delete mode 100644 solend-sdk/src/utils/merkle_distributor.ts delete mode 100644 solend-sdk/src/utils/rpc/cached.ts delete mode 100644 solend-sdk/src/utils/rpc/index.ts delete mode 100644 solend-sdk/src/utils/rpc/instrumented.ts delete mode 100644 solend-sdk/src/utils/rpc/interface.ts delete mode 100644 solend-sdk/src/utils/rpc/multi.ts delete mode 100644 solend-sdk/src/utils/rpc/retry.ts diff --git a/solend-lite/src/stores/pools.ts b/solend-lite/src/stores/pools.ts index 8a9cc3d0..82c94f52 100644 --- a/solend-lite/src/stores/pools.ts +++ b/solend-lite/src/stores/pools.ts @@ -14,12 +14,12 @@ import { configAtom } from './config'; import BigNumber from 'bignumber.js'; import { createObligationAddress, - ReserveType, fetchPools, getReservesOfPool, parseLendingMarket, parseRateLimiter, PoolType, + ReserveType } from '@solendprotocol/solend-sdk'; import { DEBUG_MODE, PROGRAM_ID } from 'common/config'; import { atomWithRefresh } from './shared'; diff --git a/solend-sdk/README.md b/solend-sdk/README.md index 5290241d..e5435023 100644 --- a/solend-sdk/README.md +++ b/solend-sdk/README.md @@ -75,7 +75,8 @@ const { wallet } = useWallet(); const solendWallet = await SolendWallet.initialize(wallet, connection); // Claim rewards -const mndeRewards = solendWallet.rewards["MNDEFzGvMt87ueuHvVU9VcTqsAP5b3fTGPsHuuPA5ey"]; +const mndeRewards = + solendWallet.rewards["MNDEFzGvMt87ueuHvVU9VcTqsAP5b3fTGPsHuuPA5ey"]; console.log( "Claimable rewards:", mndeRewards.claimableAmount / 10 ** mndeRewards.decimals @@ -118,6 +119,7 @@ Due to transaction size limits of Solana, a user with a high amount of positions Partner rewards and liquidity mining are not present on devnet. ## Publishing + `package.json` is configured for monorepo development alongside other packages. To publish the sdk, use `yarn release` to run scripts optimizing for release. Package has been marked private to prevent accidently publish with `yarn publish`. ``` diff --git a/solend-sdk/__tests__/flash_loan.test.ts b/solend-sdk/__tests__/flash_loan.test.ts deleted file mode 100644 index 2fb945df..00000000 --- a/solend-sdk/__tests__/flash_loan.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Connection, Keypair, Transaction, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js'; -import { SolendAction, SolendMarket, SolendWallet } from "../src"; -import * as anchor from '@project-serum/anchor'; -import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token'; -import { flashBorrowReserveLiquidityInstruction } from '../src/instructions/flashBorrowReserveLiquidity'; -import { flashRepayReserveLiquidityInstruction } from '../src/instructions/flashRepayReserveLiquidity'; -import {SOLEND_DEVNET_PROGRAM_ID} from '../src/classes/constants'; - -jest.setTimeout(120_000); - -describe("flash loan", () => { - it("empty flash loan", async () => { - const connection = new Connection('https://api.devnet.solana.com', { - commitment: "finalized", - }); - const payer = Keypair.generate(); - { - const sig = await connection.requestAirdrop(payer.publicKey, LAMPORTS_PER_SOL * 2); - await connection.confirmTransaction(sig); - } - - - const market = await SolendMarket.initialize( - connection, - 'devnet', - "AAGH44cPMYSq51JZ1rth2AzBqSVass8bxwFxtEQy2L9x" - ); - - const reserve = market.reserves.find(res => res.config.liquidityToken.symbol === 'SOL'); - if (reserve == null) { - throw 'can\'t find reserve!'; - } - - console.log(`reserve: ${JSON.stringify(reserve?.config.liquidityToken.mint)}`); - - const token = new Token(connection, new PublicKey(reserve!.config.liquidityToken.mint), TOKEN_PROGRAM_ID, payer); - const tokenAccount = await token.createAccount(payer.publicKey); - - const delegate = Keypair.generate(); - await token.approve(tokenAccount, delegate.publicKey, payer, [], 10); - - let tx = new Transaction(); - tx.add( - flashBorrowReserveLiquidityInstruction( - 100, - new PublicKey(reserve.config.liquidityAddress), - tokenAccount, - new PublicKey(reserve.config.address), - new PublicKey(market.config!.address), - SOLEND_DEVNET_PROGRAM_ID - ), - flashRepayReserveLiquidityInstruction( - 100, - 0, - tokenAccount, - new PublicKey(reserve.config.liquidityAddress), - new PublicKey(reserve.config.liquidityFeeReceiverAddress), - tokenAccount, - new PublicKey(reserve.config.address), - new PublicKey(market.config!.address), - delegate.publicKey, - SOLEND_DEVNET_PROGRAM_ID - ) - ); - - // hard to make this succeed bc i need tokens to pay off the flash loan fee. - try { - await connection.sendTransaction(tx, [payer, delegate]); - } - catch (e) { - console.log("Error found"); - console.log(e); - return; - } - - throw 'expected a failure!' - }); -}); diff --git a/solend-sdk/__tests__/market.test.ts b/solend-sdk/__tests__/market.test.ts deleted file mode 100644 index 2ee5145c..00000000 --- a/solend-sdk/__tests__/market.test.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { Connection, Keypair, Transaction, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js'; -import BN from 'bn.js'; -import * as anchor from '@project-serum/anchor'; -import { parseReserve, SolendAction, SolendMarket, SolendWallet } from "../src"; - -jest.setTimeout(50_000); - -describe("calculate", function () { - it ('parses reserves', async function() { - - const connection = new Connection('https://api.mainnet-beta.solana.com', { - commitment: "finalized", - }); - - const reserve = await connection.getAccountInfo(new PublicKey('CCpirWrgNuBVLdkP2haxLTbD6XqEgaYuVXixbbpxUB6')); - - const parsedReserveData = parseReserve(new PublicKey('CCpirWrgNuBVLdkP2haxLTbD6XqEgaYuVXixbbpxUB6'), reserve!); - expect(parsedReserveData!.info.liquidity.pythOracle).not.toBeUndefined(); - expect(parsedReserveData!.info.liquidity.switchboardOracle).not.toBeUndefined(); - }); - - it("reads wallet", async function () { - const connection = new Connection('https://api.mainnet-beta.solana.com', { - commitment: "finalized", - }); - - const keypair = Keypair.generate(); - const wallet = new anchor.Wallet(keypair); - const solendWallet = await SolendWallet.initialize( - wallet, - connection, - ); - - const [setupIxs, claimIxs] = await solendWallet.getClaimAllIxs(); - - expect([...setupIxs, ...claimIxs].length).toEqual(0); - }); - - it("reads solend main market", async function () { - const connection = new Connection('https://api.mainnet-beta.solana.com', { - commitment: "finalized", - }); - - const market = await SolendMarket.initialize( - connection - ); - await market.loadReserves(); - await market.loadRewards(); - const reserve = market.reserves.find(res => res.config.liquidityToken.symbol === 'USDC'); - - expect(reserve!.stats!.decimals).toEqual(6); - expect(reserve!.stats!.protocolTakeRate).toBeLessThanOrEqual(1); - }); - - it("reads solend devnet", async function () { - const connection = new Connection('https://api.devnet.solana.com', { - commitment: "finalized", - }); - - const market = await SolendMarket.initialize( - connection, - 'devnet' - ); - await market.loadReserves(); - await market.loadRewards(); - const reserve = market.reserves.find(res => res.config.liquidityToken.symbol === 'USDC'); - - expect(reserve!.stats!.decimals).toEqual(6); - expect(reserve!.stats!.protocolTakeRate).toBeLessThanOrEqual(1); - }); - - it("reads solend invictus market", async function () { - const connection = new Connection('https://api.mainnet-beta.solana.com', { - commitment: "finalized", - }); - - const market = await SolendMarket.initialize( - connection, - 'production', - '5i8SzwX2LjpGUxLZRJ8EiYohpuKgW2FYDFhVjhGj66P1', - ); - await market.loadReserves(); - await market.loadRewards(); - const reserve = market.reserves.find(res => res.config.liquidityToken.symbol === 'USDC'); - expect((await reserve!.totalBorrowAPY()).rewards).toEqual([]); - expect(reserve!.stats!.optimalUtilizationRate).toEqual(0.8); - }); - - it("reads permissionless", async function () { - const connection = new Connection('https://api.mainnet-beta.solana.com', { - commitment: "finalized", - }); - - const market = await SolendMarket.initialize( - connection, - 'production', - 'Ckya2fwCXDqTUg9fnWbajR6YLcSfQmPxxy5MyAoZXgyb', - ); - await market.loadReserves(); - await market.loadRewards(); - const reserve = market.reserves.find(res => res.config.liquidityToken.symbol === 'SLND'); - expect((await reserve!.totalBorrowAPY()).rewards).toEqual([]); - expect(reserve!.stats!.optimalUtilizationRate).toEqual(0.8); - }); - - it("performs a deposit", async function () { - const connection = new Connection('https://api.devnet.solana.com', { - commitment: "finalized", - }); - - const depositAmount = new BN("1000"); - - const account = Keypair.generate(); - - const signature = await connection.requestAirdrop(account.publicKey, LAMPORTS_PER_SOL); - await connection.confirmTransaction(signature); - - const solendAction = await SolendAction.buildDepositTxns( - connection, - depositAmount, - "SOL", - account.publicKey, - "devnet" - ); - - const sendTransaction = async (txn: Transaction, connection: Connection) => { - const { blockhash } = await connection.getRecentBlockhash(); - txn.recentBlockhash = blockhash; - txn.feePayer = account.publicKey; - txn.sign(account); - return connection.sendRawTransaction(txn.serialize()); - } - - const txHash = await solendAction.sendTransactions(sendTransaction); - - await connection.confirmTransaction(txHash, 'finalized'); - - const market = await SolendMarket.initialize( - connection, - 'devnet', - ); - - const obligation = await market.fetchObligationByWallet(account.publicKey); - - expect(obligation!.deposits[0].amount === depositAmount) - }); - - // TODO update to a non-primary pool after another pool deployed to devnet - it("performs a deposit to specific pool", async function () { - const connection = new Connection('https://api.devnet.solana.com', { - commitment: "finalized", - }); - - const depositAmount = new BN("1000"); - - const account = Keypair.generate(); - - const signature = await connection.requestAirdrop(account.publicKey, LAMPORTS_PER_SOL); - await connection.confirmTransaction(signature); - - const solendAction = await SolendAction.buildDepositTxns( - connection, - depositAmount, - "SOL", - account.publicKey, - "devnet", - new PublicKey("GvjoVKNjBvQcFaSKUW1gTE7DxhSpjHbE69umVR5nPuQp"), - ); - - const sendTransaction = async (txn: Transaction, connection: Connection) => { - const { blockhash } = await connection.getRecentBlockhash(); - txn.recentBlockhash = blockhash; - txn.feePayer = account.publicKey; - txn.sign(account); - return connection.sendRawTransaction(txn.serialize()); - } - - const txHash = await solendAction.sendTransactions(sendTransaction); - - await connection.confirmTransaction(txHash, 'finalized'); - - const market = await SolendMarket.initialize( - connection, - 'devnet', - ); - - const obligation = await market.fetchObligationByWallet(account.publicKey); - - expect(obligation!.deposits[0].amount === depositAmount) - }); -}); diff --git a/solend-sdk/__tests__/obligation.test.ts b/solend-sdk/__tests__/obligation.test.ts deleted file mode 100644 index ffc5c8b7..00000000 --- a/solend-sdk/__tests__/obligation.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { - Connection, - Keypair, - Transaction, - LAMPORTS_PER_SOL, - PublicKey, -} from "@solana/web3.js"; -import BN from "bn.js"; -import * as anchor from "@project-serum/anchor"; -import { parseObligation } from "../src"; - -jest.setTimeout(50_000); - -describe("check", function () { - it("parses obligation in both formats", async function () { - const zstdEncodedObligationData = Buffer.from( - "KLUv/QBYLQoAdBEBWZHIBwAAAAABM7MexO/4+iia6oyVTAFjLi12SQjOVE1oZb3vERv/YSsChcZ+Ktz1mRBrkyRk1BwBK+MRLDs2kN6sQJrkE/068ae2QKj1GoAIagEAUiLO4HOtZQD9iDA+OBRghg/ZNGo1t+NsujMBAQFsp+C1qN6toMtzc12/wVf8DODwcnh4K7b1j6DEElE6V8esAGvgw8KAVqMAbcvwdUngHTQhP3KK2EcTtbcXhy+sOBPKuWOvMSyN283/9ZTFWnxCDgDvyiK06ZHhKd04ANAh+wRuI+ENjqkOBTFIeS9ID9NTKr93sO+769EA4idmIqc8x1Enq7K/tz3DwaHWY5RMvzQOIJZ5G4lBjXXPHRJX7vzRwA8SAM1yFQDEt5APgChdqyVY2VtAAS80LATg+oCsBCUWCFQgLRhoqHwAcXWBMw==", - "base64" - ); - const base64EncodedObligationData = Buffer.from( - "AVmRyAcAAAAAATOzHsTv+PoomuqMlUwBYy4tdkkIzlRNaGW97xEb/2ErAoXGfirc9ZkQa5MkZNQcASvjESw7NpDerECa5BP9OvGntkCo9RqACGoBAAAAAAAAUiLO4HOtZQAAAAAAAAAAAP2IMD44FGCGDwEAAAAAAADZNGo1t+NsujMBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBbKfgtajeraDLc3Ndv8FX/Azg8HJ4eCu29Y+gxBJROlfHrAAAAAAAAGvgw8KAVqMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG3L8HVJ4B00IT9yithHE7W3F4cvrDgTyrljrzEsjdvN//WUxVp8Qg4AAAAAAAAAAO/KIrTpkeEp3TgAAAAAAABSIs7gc61lAAAAAAAAAAAAAAAAAAAAAABty/B1SeAdNCE/corYRxO1txeHL6w4E8q5Y68xLI3bzf/1lMVafEIOAAAAAAAAAADvyiK06ZHhKd04AAAAAAAAUiLO4HOtZQAAAAAAAAAAANAh+wQAAAAAbiPhDY6pDgUxAQAAAAAAAAAAAAAAAAAASHkvSA/TUyq/d7Dvu+vRAOInZiKnPMdRJ6uyv7c9w8Gh1mOUTL80DgAAAAAAAAAAIJZ5G4lBjXXPIfsEAAAAAB0SV+780cAPMQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", - "base64" - ); - - const obligationPubkey = new PublicKey( - "FfRLBU1gHm3MyqJ3KX6dBnsxxJtwVGCwKFwJrfDnceWN" - ); - const connection = new Connection("https://api.mainnet-beta.solana.com", { - commitment: "finalized", - }); - - const zstdEncodedObligation = await connection.getAccountInfo( - obligationPubkey - ); - zstdEncodedObligation!.data = zstdEncodedObligationData; - const base64EncodedObligation = await connection.getAccountInfo( - obligationPubkey - ); - base64EncodedObligation!.data = base64EncodedObligationData; - - const parsedzstdEncodedObligation = parseObligation( - obligationPubkey, - zstdEncodedObligation!, - "base64+zstd" - ); - const parsedbase64EncodedObligation = parseObligation( - obligationPubkey, - base64EncodedObligation! - ); - - expect(parsedzstdEncodedObligation!).toMatchObject( - parsedbase64EncodedObligation! - ); - }); -}); diff --git a/solend-sdk/__tests__/rpc.test.ts b/solend-sdk/__tests__/rpc.test.ts deleted file mode 100644 index b6c18580..00000000 --- a/solend-sdk/__tests__/rpc.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Connection } from '@solana/web3.js'; -import { StatsD } from 'hot-shots'; -import { InstrumentedConnection, MultiConnection, RetryConnection, SolendRPCConnection } from '../src/utils/rpc'; - -jest.setTimeout(1_000); - -describe("calculate", function () { - it("checks interface fulfillment", async function () { - const connection = new Connection('https://api.mainnet-beta.solana.com', { - commitment: "finalized", - }); - const multiConnection = new MultiConnection([connection]); - _checkInterface(multiConnection); - - const retryConection = new RetryConnection(connection, 10); - _checkInterface(retryConection); - - const stats = new StatsD({mock: true}); - const instrumentedConnection = new InstrumentedConnection(connection, stats, ''); - _checkInterface(instrumentedConnection); - }); -}); - -// You can't check if a class implements an interface at runtime, so we can -// just do it at compile time here with a function that does nothing. -function _checkInterface(connection: SolendRPCConnection) { - return; -} diff --git a/solend-sdk/docs/.nojekyll b/solend-sdk/docs/.nojekyll deleted file mode 100644 index e2ac6616..00000000 --- a/solend-sdk/docs/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/solend-sdk/docs/CNAME b/solend-sdk/docs/CNAME deleted file mode 100644 index 1164f5b2..00000000 --- a/solend-sdk/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -sdk.solend.fi \ No newline at end of file diff --git a/solend-sdk/docs/assets/highlight.css b/solend-sdk/docs/assets/highlight.css deleted file mode 100644 index f93a4bfa..00000000 --- a/solend-sdk/docs/assets/highlight.css +++ /dev/null @@ -1,85 +0,0 @@ -:root { - --light-hl-0: #001080; - --dark-hl-0: #9CDCFE; - --light-hl-1: #000000; - --dark-hl-1: #D4D4D4; - --light-hl-2: #008000; - --dark-hl-2: #6A9955; - --light-hl-3: #0000FF; - --dark-hl-3: #569CD6; - --light-hl-4: #0070C1; - --dark-hl-4: #4FC1FF; - --light-hl-5: #AF00DB; - --dark-hl-5: #C586C0; - --light-hl-6: #795E26; - --dark-hl-6: #DCDCAA; - --light-hl-7: #A31515; - --dark-hl-7: #CE9178; - --light-hl-8: #098658; - --dark-hl-8: #B5CEA8; - --light-code-background: #FFFFFF; - --dark-code-background: #1E1E1E; -} - -@media (prefers-color-scheme: light) { :root { - --hl-0: var(--light-hl-0); - --hl-1: var(--light-hl-1); - --hl-2: var(--light-hl-2); - --hl-3: var(--light-hl-3); - --hl-4: var(--light-hl-4); - --hl-5: var(--light-hl-5); - --hl-6: var(--light-hl-6); - --hl-7: var(--light-hl-7); - --hl-8: var(--light-hl-8); - --code-background: var(--light-code-background); -} } - -@media (prefers-color-scheme: dark) { :root { - --hl-0: var(--dark-hl-0); - --hl-1: var(--dark-hl-1); - --hl-2: var(--dark-hl-2); - --hl-3: var(--dark-hl-3); - --hl-4: var(--dark-hl-4); - --hl-5: var(--dark-hl-5); - --hl-6: var(--dark-hl-6); - --hl-7: var(--dark-hl-7); - --hl-8: var(--dark-hl-8); - --code-background: var(--dark-code-background); -} } - -body.light { - --hl-0: var(--light-hl-0); - --hl-1: var(--light-hl-1); - --hl-2: var(--light-hl-2); - --hl-3: var(--light-hl-3); - --hl-4: var(--light-hl-4); - --hl-5: var(--light-hl-5); - --hl-6: var(--light-hl-6); - --hl-7: var(--light-hl-7); - --hl-8: var(--light-hl-8); - --code-background: var(--light-code-background); -} - -body.dark { - --hl-0: var(--dark-hl-0); - --hl-1: var(--dark-hl-1); - --hl-2: var(--dark-hl-2); - --hl-3: var(--dark-hl-3); - --hl-4: var(--dark-hl-4); - --hl-5: var(--dark-hl-5); - --hl-6: var(--dark-hl-6); - --hl-7: var(--dark-hl-7); - --hl-8: var(--dark-hl-8); - --code-background: var(--dark-code-background); -} - -.hl-0 { color: var(--hl-0); } -.hl-1 { color: var(--hl-1); } -.hl-2 { color: var(--hl-2); } -.hl-3 { color: var(--hl-3); } -.hl-4 { color: var(--hl-4); } -.hl-5 { color: var(--hl-5); } -.hl-6 { color: var(--hl-6); } -.hl-7 { color: var(--hl-7); } -.hl-8 { color: var(--hl-8); } -pre, code { background: var(--code-background); } diff --git a/solend-sdk/docs/assets/icons.css b/solend-sdk/docs/assets/icons.css deleted file mode 100644 index 776a3562..00000000 --- a/solend-sdk/docs/assets/icons.css +++ /dev/null @@ -1,1043 +0,0 @@ -.tsd-kind-icon { - display: block; - position: relative; - padding-left: 20px; - text-indent: -20px; -} -.tsd-kind-icon:before { - content: ""; - display: inline-block; - vertical-align: middle; - width: 17px; - height: 17px; - margin: 0 3px 2px 0; - background-image: url(./icons.png); -} -@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { - .tsd-kind-icon:before { - background-image: url(./icons@2x.png); - background-size: 238px 204px; - } -} - -.tsd-signature.tsd-kind-icon:before { - background-position: 0 -153px; -} - -.tsd-kind-object-literal > .tsd-kind-icon:before { - background-position: 0px -17px; -} -.tsd-kind-object-literal.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -17px; -} -.tsd-kind-object-literal.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -17px; -} - -.tsd-kind-class > .tsd-kind-icon:before { - background-position: 0px -34px; -} -.tsd-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -34px; -} -.tsd-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -34px; -} - -.tsd-kind-class.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: 0px -51px; -} -.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -17px -51px; -} -.tsd-kind-class.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -51px; -} - -.tsd-kind-interface > .tsd-kind-icon:before { - background-position: 0px -68px; -} -.tsd-kind-interface.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -68px; -} -.tsd-kind-interface.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -68px; -} - -.tsd-kind-interface.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: 0px -85px; -} -.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -17px -85px; -} -.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private - > .tsd-kind-icon:before { - background-position: -34px -85px; -} - -.tsd-kind-namespace > .tsd-kind-icon:before { - background-position: 0px -102px; -} -.tsd-kind-namespace.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -102px; -} -.tsd-kind-namespace.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -102px; -} - -.tsd-kind-module > .tsd-kind-icon:before { - background-position: 0px -102px; -} -.tsd-kind-module.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -102px; -} -.tsd-kind-module.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -102px; -} - -.tsd-kind-enum > .tsd-kind-icon:before { - background-position: 0px -119px; -} -.tsd-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -119px; -} -.tsd-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -119px; -} - -.tsd-kind-enum-member > .tsd-kind-icon:before { - background-position: 0px -136px; -} -.tsd-kind-enum-member.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -136px; -} -.tsd-kind-enum-member.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -136px; -} - -.tsd-kind-signature > .tsd-kind-icon:before { - background-position: 0px -153px; -} -.tsd-kind-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -153px; -} -.tsd-kind-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -153px; -} - -.tsd-kind-type-alias > .tsd-kind-icon:before { - background-position: 0px -170px; -} -.tsd-kind-type-alias.tsd-is-protected > .tsd-kind-icon:before { - background-position: -17px -170px; -} -.tsd-kind-type-alias.tsd-is-private > .tsd-kind-icon:before { - background-position: -34px -170px; -} - -.tsd-kind-type-alias.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: 0px -187px; -} -.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -17px -187px; -} -.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-private - > .tsd-kind-icon:before { - background-position: -34px -187px; -} - -.tsd-kind-variable > .tsd-kind-icon:before { - background-position: -136px -0px; -} -.tsd-kind-variable.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -0px; -} -.tsd-kind-variable.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -0px; -} -.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-variable.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -0px; -} -.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -0px; -} -.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-variable.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -0px; -} -.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -0px; -} - -.tsd-kind-property > .tsd-kind-icon:before { - background-position: -136px -0px; -} -.tsd-kind-property.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -0px; -} -.tsd-kind-property.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-property.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -0px; -} -.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -0px; -} -.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -0px; -} -.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -0px; -} -.tsd-kind-property.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-property.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -0px; -} -.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -0px; -} -.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -0px; -} -.tsd-kind-property.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -0px; -} -.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -0px; -} - -.tsd-kind-get-signature > .tsd-kind-icon:before { - background-position: -136px -17px; -} -.tsd-kind-get-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -17px; -} -.tsd-kind-get-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -17px; -} -.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -17px; -} - -.tsd-kind-set-signature > .tsd-kind-icon:before { - background-position: -136px -34px; -} -.tsd-kind-set-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -34px; -} -.tsd-kind-set-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -34px; -} -.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -34px; -} - -.tsd-kind-accessor > .tsd-kind-icon:before { - background-position: -136px -51px; -} -.tsd-kind-accessor.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -51px; -} -.tsd-kind-accessor.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -51px; -} -.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -51px; -} - -.tsd-kind-function > .tsd-kind-icon:before { - background-position: -136px -68px; -} -.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -68px; -} -.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -68px; -} -.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -68px; -} -.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -68px; -} -.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -68px; -} -.tsd-kind-function.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -68px; -} -.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -68px; -} -.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -68px; -} -.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -68px; -} - -.tsd-kind-method > .tsd-kind-icon:before { - background-position: -136px -68px; -} -.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -68px; -} -.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -68px; -} -.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -68px; -} -.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -68px; -} -.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -68px; -} -.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -68px; -} -.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -68px; -} -.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -68px; -} -.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -68px; -} - -.tsd-kind-call-signature > .tsd-kind-icon:before { - background-position: -136px -68px; -} -.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -68px; -} -.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -68px; -} -.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -68px; -} - -.tsd-kind-function.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: -136px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -153px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class - > .tsd-kind-icon:before { - background-position: -51px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum - > .tsd-kind-icon:before { - background-position: -170px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface - > .tsd-kind-icon:before { - background-position: -204px -85px; -} -.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -85px; -} - -.tsd-kind-method.tsd-has-type-parameter > .tsd-kind-icon:before { - background-position: -136px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -153px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class - > .tsd-kind-icon:before { - background-position: -51px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum - > .tsd-kind-icon:before { - background-position: -170px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface - > .tsd-kind-icon:before { - background-position: -204px -85px; -} -.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -85px; -} - -.tsd-kind-constructor > .tsd-kind-icon:before { - background-position: -136px -102px; -} -.tsd-kind-constructor.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -102px; -} -.tsd-kind-constructor.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -102px; -} -.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -102px; -} - -.tsd-kind-constructor-signature > .tsd-kind-icon:before { - background-position: -136px -102px; -} -.tsd-kind-constructor-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -102px; -} -.tsd-kind-constructor-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-interface - > .tsd-kind-icon:before { - background-position: -204px -102px; -} -.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -102px; -} - -.tsd-kind-index-signature > .tsd-kind-icon:before { - background-position: -136px -119px; -} -.tsd-kind-index-signature.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -119px; -} -.tsd-kind-index-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -119px; -} -.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -119px; -} - -.tsd-kind-event > .tsd-kind-icon:before { - background-position: -136px -136px; -} -.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -136px; -} -.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -136px; -} -.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -136px; -} -.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -136px; -} -.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -136px; -} -.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -136px; -} -.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -136px; -} -.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -136px; -} -.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -136px; -} -.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -136px; -} -.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -136px; -} -.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -136px; -} - -.tsd-is-static > .tsd-kind-icon:before { - background-position: -136px -153px; -} -.tsd-is-static.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -153px; -} -.tsd-is-static.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -153px; -} -.tsd-is-static.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -153px; -} -.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { - background-position: -68px -153px; -} -.tsd-is-static.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { - background-position: -85px -153px; -} -.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -153px; -} -.tsd-is-static.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -153px; -} -.tsd-is-static.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -153px; -} -.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { - background-position: -187px -153px; -} -.tsd-is-static.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -153px; -} -.tsd-is-static.tsd-parent-kind-interface > .tsd-kind-icon:before { - background-position: -204px -153px; -} -.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -153px; -} - -.tsd-is-static.tsd-kind-function > .tsd-kind-icon:before { - background-position: -136px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface - > .tsd-kind-icon:before { - background-position: -204px -170px; -} -.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -170px; -} - -.tsd-is-static.tsd-kind-method > .tsd-kind-icon:before { - background-position: -136px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface - > .tsd-kind-icon:before { - background-position: -204px -170px; -} -.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -170px; -} - -.tsd-is-static.tsd-kind-call-signature > .tsd-kind-icon:before { - background-position: -136px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -153px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class - > .tsd-kind-icon:before { - background-position: -51px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum - > .tsd-kind-icon:before { - background-position: -170px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface - > .tsd-kind-icon:before { - background-position: -204px -170px; -} -.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -170px; -} - -.tsd-is-static.tsd-kind-event > .tsd-kind-icon:before { - background-position: -136px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { - background-position: -153px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { - background-position: -119px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { - background-position: -51px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -68px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -85px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -102px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { - background-position: -170px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected - > .tsd-kind-icon:before { - background-position: -187px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private - > .tsd-kind-icon:before { - background-position: -119px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface - > .tsd-kind-icon:before { - background-position: -204px -187px; -} -.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited - > .tsd-kind-icon:before { - background-position: -221px -187px; -} diff --git a/solend-sdk/docs/assets/icons.png b/solend-sdk/docs/assets/icons.png deleted file mode 100644 index 3836d5fe46e48bbe186116855aae879c23935327..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9615 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 NZmR35l_G4O{0}dcmS_L~ diff --git a/solend-sdk/docs/assets/icons@2x.png b/solend-sdk/docs/assets/icons@2x.png deleted file mode 100644 index 5a209e2f6d7f915cc9cb6fe7a4264c8be4db87b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28144 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 Ce=Object.create;var J=Object.defineProperty;var Pe=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var Re=Object.getPrototypeOf,_e=Object.prototype.hasOwnProperty;var Me=t=>J(t,"__esModule",{value:!0});var Fe=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var De=(t,e,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Oe(e))!_e.call(t,n)&&n!=="default"&&J(t,n,{get:()=>e[n],enumerable:!(r=Pe(e,n))||r.enumerable});return t},Ae=t=>De(Me(J(t!=null?Ce(Re(t)):{},"default",t&&t.__esModule&&"default"in t?{get:()=>t.default,enumerable:!0}:{value:t,enumerable:!0})),t);var de=Fe((ue,he)=>{(function(){var t=function(e){var r=new t.Builder;return r.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),r.searchPipeline.add(t.stemmer),e.call(r,r),r.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(r){e.console&&console.warn&&console.warn(r)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var r=Object.create(null),n=Object.keys(e),i=0;i0){var h=t.utils.clone(r)||{};h.position=[a,l],h.index=s.length,s.push(new t.Token(n.slice(a,o),h))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,r){r in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+r),e.label=r,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var r=e.label&&e.label in this.registeredFunctions;r||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. -`,e)},t.Pipeline.load=function(e){var r=new t.Pipeline;return e.forEach(function(n){var i=t.Pipeline.registeredFunctions[n];if(i)r.add(i);else throw new Error("Cannot load unregistered function: "+n)}),r},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(r){t.Pipeline.warnIfFunctionNotRegistered(r),this._stack.push(r)},this)},t.Pipeline.prototype.after=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");n=n+1,this._stack.splice(n,0,r)},t.Pipeline.prototype.before=function(e,r){t.Pipeline.warnIfFunctionNotRegistered(r);var n=this._stack.indexOf(e);if(n==-1)throw new Error("Cannot find existingFn");this._stack.splice(n,0,r)},t.Pipeline.prototype.remove=function(e){var r=this._stack.indexOf(e);r!=-1&&this._stack.splice(r,1)},t.Pipeline.prototype.run=function(e){for(var r=this._stack.length,n=0;n1&&(oe&&(n=s),o!=e);)i=n-r,s=r+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(oc?h+=2:a==c&&(r+=n[l+1]*i[h+1],l+=2,h+=2);return r},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),r=1,n=0;r0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}if(s.str.length==0&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}s.str.length==1&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var h=s.str.charAt(0),f=s.str.charAt(1),v;f in s.node.edges?v=s.node.edges[f]:(v=new t.TokenSet,s.node.edges[f]=v),s.str.length==1&&(v.final=!0),i.push({node:v,editsRemaining:s.editsRemaining-1,str:h+s.str.slice(2)})}}}return n},t.TokenSet.fromString=function(e){for(var r=new t.TokenSet,n=r,i=0,s=e.length;i=e;r--){var n=this.uncheckedNodes[r],i=n.child.toString();i in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[i]:(n.child._str=i,this.minimizedNodes[i]=n.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(r){var n=new t.QueryParser(e,r);n.parse()})},t.Index.prototype.query=function(e){for(var r=new t.Query(this.fields),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),c=0;c1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,r){var n=e[this._ref],i=Object.keys(this._fields);this._documents[n]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,r;do e=this.next(),r=e.charCodeAt(0);while(r>47&&r<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var r=e.next();if(r==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(r.charCodeAt(0)==92){e.escapeCharacter();continue}if(r==":")return t.QueryLexer.lexField;if(r=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(r=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(r=="+"&&e.width()===1||r=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(r.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,r){this.lexer=new t.QueryLexer(e),this.query=r,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var r=e.peekLexeme();if(r!=null)switch(r.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(n+=" with value '"+r.str+"'"),new t.QueryParseError(n,r.start,r.end)}},t.QueryParser.parsePresence=function(e){var r=e.consumeLexeme();if(r!=null){switch(r.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+r.str+"'";throw new t.QueryParseError(n,r.start,r.end)}var i=e.peekLexeme();if(i==null){var n="expecting term or field, found nothing";throw new t.QueryParseError(n,r.start,r.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var n="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(n,i.start,i.end)}}},t.QueryParser.parseField=function(e){var r=e.consumeLexeme();if(r!=null){if(e.query.allFields.indexOf(r.str)==-1){var n=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+r.str+"', possible fields: "+n;throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.fields=[r.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,r.start,r.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var r=e.consumeLexeme();if(r!=null){e.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(n==null){e.nextClause();return}switch(n.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+n.type+"'";throw new t.QueryParseError(i,n.start,n.end)}}},t.QueryParser.parseEditDistance=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="edit distance must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.editDistance=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var r=e.consumeLexeme();if(r!=null){var n=parseInt(r.str,10);if(isNaN(n)){var i="boost must be numeric";throw new t.QueryParseError(i,r.start,r.end)}e.currentClause.boost=n;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,r){typeof define=="function"&&define.amd?define(r):typeof ue=="object"?he.exports=r():e.lunr=r()}(this,function(){return t})})()});var le=[];function N(t,e){le.push({selector:e,constructor:t})}var X=class{constructor(){this.createComponents(document.body)}createComponents(e){le.forEach(r=>{e.querySelectorAll(r.selector).forEach(n=>{n.dataset.hasInstance||(new r.constructor({el:n}),n.dataset.hasInstance=String(!0))})})}};var Q=class{constructor(e){this.el=e.el}};var Z=class{constructor(){this.listeners={}}addEventListener(e,r){e in this.listeners||(this.listeners[e]=[]),this.listeners[e].push(r)}removeEventListener(e,r){if(!(e in this.listeners))return;let n=this.listeners[e];for(let i=0,s=n.length;i{let r=Date.now();return(...n)=>{r+e-Date.now()<0&&(t(...n),r=Date.now())}};var ee=class extends Z{constructor(){super();this.scrollTop=0;this.lastY=0;this.width=0;this.height=0;this.showToolbar=!0;this.toolbar=document.querySelector(".tsd-page-toolbar"),this.secondaryNav=document.querySelector(".tsd-navigation.secondary"),window.addEventListener("scroll",K(()=>this.onScroll(),10)),window.addEventListener("resize",K(()=>this.onResize(),10)),this.onResize(),this.onScroll()}triggerResize(){let e=new CustomEvent("resize",{detail:{width:this.width,height:this.height}});this.dispatchEvent(e)}onResize(){this.width=window.innerWidth||0,this.height=window.innerHeight||0;let e=new CustomEvent("resize",{detail:{width:this.width,height:this.height}});this.dispatchEvent(e)}onScroll(){this.scrollTop=window.scrollY||0;let e=new CustomEvent("scroll",{detail:{scrollTop:this.scrollTop}});this.dispatchEvent(e),this.hideShowToolbar()}hideShowToolbar(){var r;let e=this.showToolbar;this.showToolbar=this.lastY>=this.scrollTop||this.scrollTop<=0,e!==this.showToolbar&&(this.toolbar.classList.toggle("tsd-page-toolbar--hide"),(r=this.secondaryNav)==null||r.classList.toggle("tsd-navigation--toolbar-hide")),this.lastY=this.scrollTop}},I=ee;I.instance=new ee;var te=class extends Q{constructor(e){super(e);this.anchors=[];this.index=-1;I.instance.addEventListener("resize",()=>this.onResize()),I.instance.addEventListener("scroll",r=>this.onScroll(r)),this.createAnchors()}createAnchors(){let e=window.location.href;e.indexOf("#")!=-1&&(e=e.substr(0,e.indexOf("#"))),this.el.querySelectorAll("a").forEach(r=>{let n=r.href;if(n.indexOf("#")==-1||n.substr(0,e.length)!=e)return;let i=n.substr(n.indexOf("#")+1),s=document.querySelector("a.tsd-anchor[name="+i+"]"),o=r.parentNode;!s||!o||this.anchors.push({link:o,anchor:s,position:0})}),this.onResize()}onResize(){let e;for(let n=0,i=this.anchors.length;nn.position-i.position);let r=new CustomEvent("scroll",{detail:{scrollTop:I.instance.scrollTop}});this.onScroll(r)}onScroll(e){let r=e.detail.scrollTop+5,n=this.anchors,i=n.length-1,s=this.index;for(;s>-1&&n[s].position>r;)s-=1;for(;s-1&&this.anchors[this.index].link.classList.remove("focus"),this.index=s,this.index>-1&&this.anchors[this.index].link.classList.add("focus"))}};var ce=(t,e=100)=>{let r;return(...n)=>{clearTimeout(r),r=setTimeout(()=>t(n),e)}};var pe=Ae(de());function fe(){let t=document.getElementById("tsd-search");if(!t)return;let e=document.getElementById("search-script");t.classList.add("loading"),e&&(e.addEventListener("error",()=>{t.classList.remove("loading"),t.classList.add("failure")}),e.addEventListener("load",()=>{t.classList.remove("loading"),t.classList.add("ready")}),window.searchData&&t.classList.remove("loading"));let r=document.querySelector("#tsd-search input"),n=document.querySelector("#tsd-search .results");if(!r||!n)throw new Error("The input field or the result list wrapper was not found");let i=!1;n.addEventListener("mousedown",()=>i=!0),n.addEventListener("mouseup",()=>{i=!1,t.classList.remove("has-focus")}),r.addEventListener("focus",()=>t.classList.add("has-focus")),r.addEventListener("blur",()=>{i||(i=!1,t.classList.remove("has-focus"))});let s={base:t.dataset.base+"/"};Ve(t,n,r,s)}function Ve(t,e,r,n){r.addEventListener("input",ce(()=>{ze(t,e,r,n)},200));let i=!1;r.addEventListener("keydown",s=>{i=!0,s.key=="Enter"?Ne(e,r):s.key=="Escape"?r.blur():s.key=="ArrowUp"?me(e,-1):s.key==="ArrowDown"?me(e,1):i=!1}),r.addEventListener("keypress",s=>{i&&s.preventDefault()}),document.body.addEventListener("keydown",s=>{s.altKey||s.ctrlKey||s.metaKey||!r.matches(":focus")&&s.key==="/"&&(r.focus(),s.preventDefault())})}function He(t,e){t.index||window.searchData&&(e.classList.remove("loading"),e.classList.add("ready"),t.data=window.searchData,t.index=pe.Index.load(window.searchData.index))}function ze(t,e,r,n){if(He(n,t),!n.index||!n.data)return;e.textContent="";let i=r.value.trim(),s=n.index.search(`*${i}*`);for(let o=0,a=Math.min(10,s.length);o${ve(c.parent,i)}.${l}`);let h=document.createElement("li");h.classList.value=c.classes;let f=document.createElement("a");f.href=n.base+c.url,f.classList.add("tsd-kind-icon"),f.innerHTML=l,h.append(f),e.appendChild(h)}}function me(t,e){let r=t.querySelector(".current");if(!r)r=t.querySelector(e==1?"li:first-child":"li:last-child"),r&&r.classList.add("current");else{let n=r;if(e===1)do n=n.nextElementSibling;while(n instanceof HTMLElement&&n.offsetParent==null);else do n=n.previousElementSibling;while(n instanceof HTMLElement&&n.offsetParent==null);n&&(r.classList.remove("current"),n.classList.add("current"))}}function Ne(t,e){let r=t.querySelector(".current");if(r||(r=t.querySelector("li:first-child")),r){let n=r.querySelector("a");n&&(window.location.href=n.href),e.blur()}}function ve(t,e){if(e==="")return t;let r=t.toLocaleLowerCase(),n=e.toLocaleLowerCase(),i=[],s=0,o=r.indexOf(n);for(;o!=-1;)i.push(re(t.substring(s,o)),`${re(t.substring(o,o+n.length))}`),s=o+n.length,o=r.indexOf(n,s);return i.push(re(t.substring(s))),i.join("")}var je={"&":"&","<":"<",">":">","'":"'",'"':"""};function re(t){return t.replace(/[&<>"'"]/g,e=>je[e])}var ge=class{constructor(e,r){this.signature=e,this.description=r}addClass(e){return this.signature.classList.add(e),this.description.classList.add(e),this}removeClass(e){return this.signature.classList.remove(e),this.description.classList.remove(e),this}},ne=class extends Q{constructor(e){super(e);this.groups=[];this.index=-1;this.createGroups(),this.container&&(this.el.classList.add("active"),Array.from(this.el.children).forEach(r=>{r.addEventListener("touchstart",n=>this.onClick(n)),r.addEventListener("click",n=>this.onClick(n))}),this.container.classList.add("active"),this.setIndex(0))}setIndex(e){if(e<0&&(e=0),e>this.groups.length-1&&(e=this.groups.length-1),this.index==e)return;let r=this.groups[e];if(this.index>-1){let n=this.groups[this.index];n.removeClass("current").addClass("fade-out"),r.addClass("current"),r.addClass("fade-in"),I.instance.triggerResize(),setTimeout(()=>{n.removeClass("fade-out"),r.removeClass("fade-in")},300)}else r.addClass("current"),I.instance.triggerResize();this.index=e}createGroups(){let e=this.el.children;if(e.length<2)return;this.container=this.el.nextElementSibling;let r=this.container.children;this.groups=[];for(let n=0;n{r.signature===e.currentTarget&&this.setIndex(n)})}};var C="mousedown",ye="mousemove",_="mouseup",G={x:0,y:0},xe=!1,ie=!1,Be=!1,A=!1,Le=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(Le?"is-mobile":"not-mobile");Le&&"ontouchstart"in document.documentElement&&(Be=!0,C="touchstart",ye="touchmove",_="touchend");document.addEventListener(C,t=>{ie=!0,A=!1;let e=C=="touchstart"?t.targetTouches[0]:t;G.y=e.pageY||0,G.x=e.pageX||0});document.addEventListener(ye,t=>{if(!!ie&&!A){let e=C=="touchstart"?t.targetTouches[0]:t,r=G.x-(e.pageX||0),n=G.y-(e.pageY||0);A=Math.sqrt(r*r+n*n)>10}});document.addEventListener(_,()=>{ie=!1});document.addEventListener("click",t=>{xe&&(t.preventDefault(),t.stopImmediatePropagation(),xe=!1)});var se=class extends Q{constructor(e){super(e);this.className=this.el.dataset.toggle||"",this.el.addEventListener(_,r=>this.onPointerUp(r)),this.el.addEventListener("click",r=>r.preventDefault()),document.addEventListener(C,r=>this.onDocumentPointerDown(r)),document.addEventListener(_,r=>this.onDocumentPointerUp(r))}setActive(e){if(this.active==e)return;this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);let r=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(r),setTimeout(()=>document.documentElement.classList.remove(r),500)}onPointerUp(e){A||(this.setActive(!0),e.preventDefault())}onDocumentPointerDown(e){if(this.active){if(e.target.closest(".col-menu, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(e){if(!A&&this.active&&e.target.closest(".col-menu")){let r=e.target.closest("a");if(r){let n=window.location.href;n.indexOf("#")!=-1&&(n=n.substr(0,n.indexOf("#"))),r.href.substr(0,n.length)==n&&setTimeout(()=>this.setActive(!1),250)}}}};var oe=class{constructor(e,r){this.key=e,this.value=r,this.defaultValue=r,this.initialize(),window.localStorage[this.key]&&this.setValue(this.fromLocalStorage(window.localStorage[this.key]))}initialize(){}setValue(e){if(this.value==e)return;let r=this.value;this.value=e,window.localStorage[this.key]=this.toLocalStorage(e),this.handleValueChange(r,e)}},ae=class extends oe{initialize(){let e=document.querySelector("#tsd-filter-"+this.key);!e||(this.checkbox=e,this.checkbox.addEventListener("change",()=>{this.setValue(this.checkbox.checked)}))}handleValueChange(e,r){!this.checkbox||(this.checkbox.checked=this.value,document.documentElement.classList.toggle("toggle-"+this.key,this.value!=this.defaultValue))}fromLocalStorage(e){return e=="true"}toLocalStorage(e){return e?"true":"false"}},Ee=class extends oe{initialize(){document.documentElement.classList.add("toggle-"+this.key+this.value);let e=document.querySelector("#tsd-filter-"+this.key);if(!e)return;this.select=e;let r=()=>{this.select.classList.add("active")},n=()=>{this.select.classList.remove("active")};this.select.addEventListener(C,r),this.select.addEventListener("mouseover",r),this.select.addEventListener("mouseleave",n),this.select.querySelectorAll("li").forEach(i=>{i.addEventListener(_,s=>{e.classList.remove("active"),this.setValue(s.target.dataset.value||"")})}),document.addEventListener(C,i=>{this.select.contains(i.target)||this.select.classList.remove("active")})}handleValueChange(e,r){this.select.querySelectorAll("li.selected").forEach(s=>{s.classList.remove("selected")});let n=this.select.querySelector('li[data-value="'+r+'"]'),i=this.select.querySelector(".tsd-select-label");n&&i&&(n.classList.add("selected"),i.textContent=n.textContent),document.documentElement.classList.remove("toggle-"+e),document.documentElement.classList.add("toggle-"+r)}fromLocalStorage(e){return e}toLocalStorage(e){return e}},Y=class extends Q{constructor(e){super(e);this.optionVisibility=new Ee("visibility","private"),this.optionInherited=new ae("inherited",!0),this.optionExternals=new ae("externals",!0)}static isSupported(){try{return typeof window.localStorage!="undefined"}catch{return!1}}};function be(t){let e=localStorage.getItem("tsd-theme")||"os";t.value=e,we(e),t.addEventListener("change",()=>{localStorage.setItem("tsd-theme",t.value),we(t.value)})}function we(t){switch(t){case"os":document.body.classList.remove("light","dark");break;case"light":document.body.classList.remove("dark"),document.body.classList.add("light");break;case"dark":document.body.classList.remove("light"),document.body.classList.add("dark");break}}fe();N(te,".menu-highlight");N(ne,".tsd-signatures");N(se,"a[data-toggle]");Y.isSupported()?N(Y,"#tsd-filter"):document.documentElement.classList.add("no-filter");var Te=document.getElementById("theme");Te&&be(Te);var qe=new X;Object.defineProperty(window,"app",{value:qe});})(); -/*! - * lunr.Builder - * Copyright (C) 2020 Oliver Nightingale - */ -/*! - * lunr.Index - * Copyright (C) 2020 Oliver Nightingale - */ -/*! - * lunr.Pipeline - * Copyright (C) 2020 Oliver Nightingale - */ -/*! - * lunr.Set - * Copyright (C) 2020 Oliver Nightingale - */ -/*! - * lunr.TokenSet - * Copyright (C) 2020 Oliver Nightingale - */ -/*! - * lunr.Vector - * Copyright (C) 2020 Oliver Nightingale - */ -/*! - * lunr.stemmer - * Copyright (C) 2020 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - */ -/*! - * lunr.stopWordFilter - * Copyright (C) 2020 Oliver Nightingale - */ -/*! - * lunr.tokenizer - * Copyright (C) 2020 Oliver Nightingale - */ -/*! - * lunr.trimmer - * Copyright (C) 2020 Oliver Nightingale - */ -/*! - * lunr.utils - * Copyright (C) 2020 Oliver Nightingale - */ -/** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - */ diff --git a/solend-sdk/docs/assets/search.js b/solend-sdk/docs/assets/search.js deleted file mode 100644 index 7e203875..00000000 --- a/solend-sdk/docs/assets/search.js +++ /dev/null @@ -1 +0,0 @@ -window.searchData = {"kinds":{"32":"Variable","64":"Function","128":"Class","256":"Interface","512":"Constructor","1024":"Property","2048":"Method","65536":"Type literal","4194304":"Type alias"},"rows":[{"id":0,"kind":64,"name":"borrowObligationLiquidityInstruction","url":"modules.html#borrowObligationLiquidityInstruction","classes":"tsd-kind-function"},{"id":1,"kind":64,"name":"depositObligationCollateralInstruction","url":"modules.html#depositObligationCollateralInstruction","classes":"tsd-kind-function"},{"id":2,"kind":64,"name":"depositReserveLiquidityInstruction","url":"modules.html#depositReserveLiquidityInstruction","classes":"tsd-kind-function"},{"id":3,"kind":64,"name":"initObligationInstruction","url":"modules.html#initObligationInstruction","classes":"tsd-kind-function"},{"id":4,"kind":64,"name":"redeemReserveCollateralInstruction","url":"modules.html#redeemReserveCollateralInstruction","classes":"tsd-kind-function"},{"id":5,"kind":64,"name":"refreshObligationInstruction","url":"modules.html#refreshObligationInstruction","classes":"tsd-kind-function"},{"id":6,"kind":64,"name":"refreshReserveInstruction","url":"modules.html#refreshReserveInstruction","classes":"tsd-kind-function"},{"id":7,"kind":64,"name":"repayObligationLiquidityInstruction","url":"modules.html#repayObligationLiquidityInstruction","classes":"tsd-kind-function"},{"id":8,"kind":64,"name":"withdrawObligationCollateralInstruction","url":"modules.html#withdrawObligationCollateralInstruction","classes":"tsd-kind-function"},{"id":9,"kind":64,"name":"depositReserveLiquidityAndObligationCollateralInstruction","url":"modules.html#depositReserveLiquidityAndObligationCollateralInstruction","classes":"tsd-kind-function"},{"id":10,"kind":64,"name":"withdrawObligationCollateralAndRedeemReserveLiquidity","url":"modules.html#withdrawObligationCollateralAndRedeemReserveLiquidity","classes":"tsd-kind-function"},{"id":11,"kind":64,"name":"syncNative","url":"modules.html#syncNative","classes":"tsd-kind-function"},{"id":12,"kind":64,"name":"initLendingMarketInstruction","url":"modules.html#initLendingMarketInstruction","classes":"tsd-kind-function"},{"id":13,"kind":64,"name":"initReserveInstruction","url":"modules.html#initReserveInstruction","classes":"tsd-kind-function"},{"id":14,"kind":64,"name":"updateReserveConfig","url":"modules.html#updateReserveConfig","classes":"tsd-kind-function"},{"id":15,"kind":64,"name":"flashBorrowReserveLiquidityInstruction","url":"modules.html#flashBorrowReserveLiquidityInstruction","classes":"tsd-kind-function"},{"id":16,"kind":64,"name":"flashRepayReserveLiquidityInstruction","url":"modules.html#flashRepayReserveLiquidityInstruction","classes":"tsd-kind-function"},{"id":17,"kind":32,"name":"LastUpdateLayout","url":"modules.html#LastUpdateLayout","classes":"tsd-kind-variable"},{"id":18,"kind":256,"name":"LastUpdate","url":"interfaces/LastUpdate.html","classes":"tsd-kind-interface"},{"id":19,"kind":1024,"name":"slot","url":"interfaces/LastUpdate.html#slot","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"LastUpdate"},{"id":20,"kind":1024,"name":"stale","url":"interfaces/LastUpdate.html#stale","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"LastUpdate"},{"id":21,"kind":256,"name":"LendingMarket","url":"interfaces/LendingMarket.html","classes":"tsd-kind-interface"},{"id":22,"kind":1024,"name":"version","url":"interfaces/LendingMarket.html#version","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"LendingMarket"},{"id":23,"kind":1024,"name":"isInitialized","url":"interfaces/LendingMarket.html#isInitialized","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"LendingMarket"},{"id":24,"kind":1024,"name":"quoteTokenMint","url":"interfaces/LendingMarket.html#quoteTokenMint","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"LendingMarket"},{"id":25,"kind":1024,"name":"tokenProgramId","url":"interfaces/LendingMarket.html#tokenProgramId","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"LendingMarket"},{"id":26,"kind":32,"name":"LendingMarketLayout","url":"modules.html#LendingMarketLayout","classes":"tsd-kind-variable"},{"id":27,"kind":32,"name":"LENDING_MARKET_SIZE","url":"modules.html#LENDING_MARKET_SIZE","classes":"tsd-kind-variable"},{"id":28,"kind":64,"name":"isLendingMarket","url":"modules.html#isLendingMarket","classes":"tsd-kind-function"},{"id":29,"kind":64,"name":"parseLendingMarket","url":"modules.html#parseLendingMarket","classes":"tsd-kind-function"},{"id":30,"kind":64,"name":"reserveToString","url":"modules.html#reserveToString","classes":"tsd-kind-function"},{"id":31,"kind":256,"name":"Reserve","url":"interfaces/Reserve.html","classes":"tsd-kind-interface"},{"id":32,"kind":1024,"name":"version","url":"interfaces/Reserve.html#version","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Reserve"},{"id":33,"kind":1024,"name":"lastUpdate","url":"interfaces/Reserve.html#lastUpdate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Reserve"},{"id":34,"kind":1024,"name":"lendingMarket","url":"interfaces/Reserve.html#lendingMarket","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Reserve"},{"id":35,"kind":1024,"name":"liquidity","url":"interfaces/Reserve.html#liquidity","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Reserve"},{"id":36,"kind":1024,"name":"collateral","url":"interfaces/Reserve.html#collateral","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Reserve"},{"id":37,"kind":1024,"name":"config","url":"interfaces/Reserve.html#config","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Reserve"},{"id":38,"kind":256,"name":"ReserveLiquidity","url":"interfaces/ReserveLiquidity.html","classes":"tsd-kind-interface"},{"id":39,"kind":1024,"name":"mintPubkey","url":"interfaces/ReserveLiquidity.html#mintPubkey","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":40,"kind":1024,"name":"mintDecimals","url":"interfaces/ReserveLiquidity.html#mintDecimals","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":41,"kind":1024,"name":"supplyPubkey","url":"interfaces/ReserveLiquidity.html#supplyPubkey","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":42,"kind":1024,"name":"oracleOption","url":"interfaces/ReserveLiquidity.html#oracleOption","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":43,"kind":1024,"name":"pythOraclePubkey","url":"interfaces/ReserveLiquidity.html#pythOraclePubkey","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":44,"kind":1024,"name":"switchboardOraclePubkey","url":"interfaces/ReserveLiquidity.html#switchboardOraclePubkey","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":45,"kind":1024,"name":"availableAmount","url":"interfaces/ReserveLiquidity.html#availableAmount","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":46,"kind":1024,"name":"borrowedAmountWads","url":"interfaces/ReserveLiquidity.html#borrowedAmountWads","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":47,"kind":1024,"name":"cumulativeBorrowRateWads","url":"interfaces/ReserveLiquidity.html#cumulativeBorrowRateWads","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":48,"kind":1024,"name":"marketPrice","url":"interfaces/ReserveLiquidity.html#marketPrice","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveLiquidity"},{"id":49,"kind":256,"name":"ReserveCollateral","url":"interfaces/ReserveCollateral.html","classes":"tsd-kind-interface"},{"id":50,"kind":1024,"name":"mintPubkey","url":"interfaces/ReserveCollateral.html#mintPubkey","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveCollateral"},{"id":51,"kind":1024,"name":"mintTotalSupply","url":"interfaces/ReserveCollateral.html#mintTotalSupply","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveCollateral"},{"id":52,"kind":1024,"name":"supplyPubkey","url":"interfaces/ReserveCollateral.html#supplyPubkey","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveCollateral"},{"id":53,"kind":256,"name":"ReserveConfig","url":"interfaces/ReserveConfig.html","classes":"tsd-kind-interface"},{"id":54,"kind":1024,"name":"optimalUtilizationRate","url":"interfaces/ReserveConfig.html#optimalUtilizationRate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":55,"kind":1024,"name":"loanToValueRatio","url":"interfaces/ReserveConfig.html#loanToValueRatio","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":56,"kind":1024,"name":"liquidationBonus","url":"interfaces/ReserveConfig.html#liquidationBonus","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":57,"kind":1024,"name":"liquidationThreshold","url":"interfaces/ReserveConfig.html#liquidationThreshold","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":58,"kind":1024,"name":"minBorrowRate","url":"interfaces/ReserveConfig.html#minBorrowRate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":59,"kind":1024,"name":"optimalBorrowRate","url":"interfaces/ReserveConfig.html#optimalBorrowRate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":60,"kind":1024,"name":"maxBorrowRate","url":"interfaces/ReserveConfig.html#maxBorrowRate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":61,"kind":1024,"name":"fees","url":"interfaces/ReserveConfig.html#fees","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":62,"kind":65536,"name":"__type","url":"interfaces/ReserveConfig.html#__type","classes":"tsd-kind-type-literal tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":63,"kind":1024,"name":"borrowFeeWad","url":"interfaces/ReserveConfig.html#__type.borrowFeeWad","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfig.__type"},{"id":64,"kind":1024,"name":"flashLoanFeeWad","url":"interfaces/ReserveConfig.html#__type.flashLoanFeeWad","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfig.__type"},{"id":65,"kind":1024,"name":"hostFeePercentage","url":"interfaces/ReserveConfig.html#__type.hostFeePercentage","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfig.__type"},{"id":66,"kind":1024,"name":"depositLimit","url":"interfaces/ReserveConfig.html#depositLimit","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":67,"kind":1024,"name":"borrowLimit","url":"interfaces/ReserveConfig.html#borrowLimit","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":68,"kind":1024,"name":"feeReceiver","url":"interfaces/ReserveConfig.html#feeReceiver","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":69,"kind":1024,"name":"protocolLiquidationFee","url":"interfaces/ReserveConfig.html#protocolLiquidationFee","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":70,"kind":1024,"name":"protocolTakeRate","url":"interfaces/ReserveConfig.html#protocolTakeRate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ReserveConfig"},{"id":71,"kind":32,"name":"ReserveConfigLayout","url":"modules.html#ReserveConfigLayout","classes":"tsd-kind-variable"},{"id":72,"kind":32,"name":"ReserveLayout","url":"modules.html#ReserveLayout","classes":"tsd-kind-variable"},{"id":73,"kind":32,"name":"RESERVE_SIZE","url":"modules.html#RESERVE_SIZE","classes":"tsd-kind-variable"},{"id":74,"kind":64,"name":"isReserve","url":"modules.html#isReserve","classes":"tsd-kind-function"},{"id":75,"kind":64,"name":"parseReserve","url":"modules.html#parseReserve","classes":"tsd-kind-function"},{"id":76,"kind":64,"name":"obligationToString","url":"modules.html#obligationToString","classes":"tsd-kind-function"},{"id":77,"kind":256,"name":"Obligation","url":"interfaces/Obligation.html","classes":"tsd-kind-interface"},{"id":78,"kind":1024,"name":"version","url":"interfaces/Obligation.html#version","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":79,"kind":1024,"name":"lastUpdate","url":"interfaces/Obligation.html#lastUpdate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":80,"kind":1024,"name":"lendingMarket","url":"interfaces/Obligation.html#lendingMarket","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":81,"kind":1024,"name":"owner","url":"interfaces/Obligation.html#owner","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":82,"kind":1024,"name":"deposits","url":"interfaces/Obligation.html#deposits","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":83,"kind":1024,"name":"borrows","url":"interfaces/Obligation.html#borrows","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":84,"kind":1024,"name":"depositedValue","url":"interfaces/Obligation.html#depositedValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":85,"kind":1024,"name":"borrowedValue","url":"interfaces/Obligation.html#borrowedValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":86,"kind":1024,"name":"allowedBorrowValue","url":"interfaces/Obligation.html#allowedBorrowValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":87,"kind":1024,"name":"unhealthyBorrowValue","url":"interfaces/Obligation.html#unhealthyBorrowValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"Obligation"},{"id":88,"kind":256,"name":"ObligationCollateral","url":"interfaces/ObligationCollateral.html","classes":"tsd-kind-interface"},{"id":89,"kind":1024,"name":"depositReserve","url":"interfaces/ObligationCollateral.html#depositReserve","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ObligationCollateral"},{"id":90,"kind":1024,"name":"depositedAmount","url":"interfaces/ObligationCollateral.html#depositedAmount","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ObligationCollateral"},{"id":91,"kind":1024,"name":"marketValue","url":"interfaces/ObligationCollateral.html#marketValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ObligationCollateral"},{"id":92,"kind":256,"name":"ObligationLiquidity","url":"interfaces/ObligationLiquidity.html","classes":"tsd-kind-interface"},{"id":93,"kind":1024,"name":"borrowReserve","url":"interfaces/ObligationLiquidity.html#borrowReserve","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ObligationLiquidity"},{"id":94,"kind":1024,"name":"cumulativeBorrowRateWads","url":"interfaces/ObligationLiquidity.html#cumulativeBorrowRateWads","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ObligationLiquidity"},{"id":95,"kind":1024,"name":"borrowedAmountWads","url":"interfaces/ObligationLiquidity.html#borrowedAmountWads","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ObligationLiquidity"},{"id":96,"kind":1024,"name":"marketValue","url":"interfaces/ObligationLiquidity.html#marketValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ObligationLiquidity"},{"id":97,"kind":32,"name":"ObligationLayout","url":"modules.html#ObligationLayout","classes":"tsd-kind-variable"},{"id":98,"kind":32,"name":"ObligationCollateralLayout","url":"modules.html#ObligationCollateralLayout","classes":"tsd-kind-variable"},{"id":99,"kind":32,"name":"ObligationLiquidityLayout","url":"modules.html#ObligationLiquidityLayout","classes":"tsd-kind-variable"},{"id":100,"kind":32,"name":"OBLIGATION_SIZE","url":"modules.html#OBLIGATION_SIZE","classes":"tsd-kind-variable"},{"id":101,"kind":64,"name":"isObligation","url":"modules.html#isObligation","classes":"tsd-kind-function"},{"id":102,"kind":256,"name":"ProtoObligation","url":"interfaces/ProtoObligation.html","classes":"tsd-kind-interface"},{"id":103,"kind":1024,"name":"version","url":"interfaces/ProtoObligation.html#version","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":104,"kind":1024,"name":"lastUpdate","url":"interfaces/ProtoObligation.html#lastUpdate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":105,"kind":1024,"name":"lendingMarket","url":"interfaces/ProtoObligation.html#lendingMarket","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":106,"kind":1024,"name":"owner","url":"interfaces/ProtoObligation.html#owner","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":107,"kind":1024,"name":"depositedValue","url":"interfaces/ProtoObligation.html#depositedValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":108,"kind":1024,"name":"borrowedValue","url":"interfaces/ProtoObligation.html#borrowedValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":109,"kind":1024,"name":"allowedBorrowValue","url":"interfaces/ProtoObligation.html#allowedBorrowValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":110,"kind":1024,"name":"unhealthyBorrowValue","url":"interfaces/ProtoObligation.html#unhealthyBorrowValue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":111,"kind":1024,"name":"depositsLen","url":"interfaces/ProtoObligation.html#depositsLen","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":112,"kind":1024,"name":"borrowsLen","url":"interfaces/ProtoObligation.html#borrowsLen","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":113,"kind":1024,"name":"dataFlat","url":"interfaces/ProtoObligation.html#dataFlat","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"ProtoObligation"},{"id":114,"kind":64,"name":"parseObligation","url":"modules.html#parseObligation","classes":"tsd-kind-function"},{"id":115,"kind":32,"name":"POSITION_LIMIT","url":"modules.html#POSITION_LIMIT","classes":"tsd-kind-variable"},{"id":116,"kind":4194304,"name":"ActionType","url":"modules.html#ActionType","classes":"tsd-kind-type-alias"},{"id":117,"kind":128,"name":"SolendAction","url":"classes/SolendAction.html","classes":"tsd-kind-class"},{"id":118,"kind":2048,"name":"initialize","url":"classes/SolendAction.html#initialize","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendAction"},{"id":119,"kind":2048,"name":"buildDepositTxns","url":"classes/SolendAction.html#buildDepositTxns","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendAction"},{"id":120,"kind":2048,"name":"buildBorrowTxns","url":"classes/SolendAction.html#buildBorrowTxns","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendAction"},{"id":121,"kind":2048,"name":"buildDepositReserveLiquidityTxns","url":"classes/SolendAction.html#buildDepositReserveLiquidityTxns","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendAction"},{"id":122,"kind":2048,"name":"buildRedeemReserveCollateralTxns","url":"classes/SolendAction.html#buildRedeemReserveCollateralTxns","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendAction"},{"id":123,"kind":2048,"name":"buildDepositObligationCollateralTxns","url":"classes/SolendAction.html#buildDepositObligationCollateralTxns","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendAction"},{"id":124,"kind":2048,"name":"buildWithdrawTxns","url":"classes/SolendAction.html#buildWithdrawTxns","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendAction"},{"id":125,"kind":2048,"name":"buildRepayTxns","url":"classes/SolendAction.html#buildRepayTxns","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendAction"},{"id":126,"kind":512,"name":"constructor","url":"classes/SolendAction.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class tsd-is-private","parent":"SolendAction"},{"id":127,"kind":1024,"name":"programId","url":"classes/SolendAction.html#programId","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":128,"kind":1024,"name":"connection","url":"classes/SolendAction.html#connection","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":129,"kind":1024,"name":"reserve","url":"classes/SolendAction.html#reserve","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":130,"kind":1024,"name":"lendingMarket","url":"classes/SolendAction.html#lendingMarket","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":131,"kind":1024,"name":"publicKey","url":"classes/SolendAction.html#publicKey","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":132,"kind":1024,"name":"obligationAddress","url":"classes/SolendAction.html#obligationAddress","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":133,"kind":1024,"name":"obligationAccountInfo","url":"classes/SolendAction.html#obligationAccountInfo","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":134,"kind":1024,"name":"userTokenAccountAddress","url":"classes/SolendAction.html#userTokenAccountAddress","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":135,"kind":1024,"name":"userCollateralAccountAddress","url":"classes/SolendAction.html#userCollateralAccountAddress","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":136,"kind":1024,"name":"seed","url":"classes/SolendAction.html#seed","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":137,"kind":1024,"name":"symbol","url":"classes/SolendAction.html#symbol","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":138,"kind":1024,"name":"positions","url":"classes/SolendAction.html#positions","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":139,"kind":1024,"name":"amount","url":"classes/SolendAction.html#amount","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":140,"kind":1024,"name":"hostAta","url":"classes/SolendAction.html#hostAta","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":141,"kind":1024,"name":"setupIxs","url":"classes/SolendAction.html#setupIxs","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":142,"kind":1024,"name":"lendingIxs","url":"classes/SolendAction.html#lendingIxs","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":143,"kind":1024,"name":"cleanupIxs","url":"classes/SolendAction.html#cleanupIxs","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":144,"kind":1024,"name":"preTxnIxs","url":"classes/SolendAction.html#preTxnIxs","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":145,"kind":1024,"name":"postTxnIxs","url":"classes/SolendAction.html#postTxnIxs","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":146,"kind":1024,"name":"depositReserves","url":"classes/SolendAction.html#depositReserves","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":147,"kind":1024,"name":"borrowReserves","url":"classes/SolendAction.html#borrowReserves","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendAction"},{"id":148,"kind":2048,"name":"getTransactions","url":"classes/SolendAction.html#getTransactions","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":149,"kind":2048,"name":"sendTransactions","url":"classes/SolendAction.html#sendTransactions","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":150,"kind":2048,"name":"sendSingleTransaction","url":"classes/SolendAction.html#sendSingleTransaction","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendAction"},{"id":151,"kind":2048,"name":"addDepositIx","url":"classes/SolendAction.html#addDepositIx","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":152,"kind":2048,"name":"addDepositReserveLiquidityIx","url":"classes/SolendAction.html#addDepositReserveLiquidityIx","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":153,"kind":2048,"name":"addRedeemReserveCollateralIx","url":"classes/SolendAction.html#addRedeemReserveCollateralIx","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":154,"kind":2048,"name":"addDepositObligationCollateralIx","url":"classes/SolendAction.html#addDepositObligationCollateralIx","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":155,"kind":2048,"name":"addBorrowIx","url":"classes/SolendAction.html#addBorrowIx","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":156,"kind":2048,"name":"addWithdrawIx","url":"classes/SolendAction.html#addWithdrawIx","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":157,"kind":2048,"name":"addRepayIx","url":"classes/SolendAction.html#addRepayIx","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":158,"kind":2048,"name":"addSupportIxs","url":"classes/SolendAction.html#addSupportIxs","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendAction"},{"id":159,"kind":2048,"name":"addRefreshIxs","url":"classes/SolendAction.html#addRefreshIxs","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendAction"},{"id":160,"kind":2048,"name":"addObligationIxs","url":"classes/SolendAction.html#addObligationIxs","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendAction"},{"id":161,"kind":2048,"name":"addAtaIxs","url":"classes/SolendAction.html#addAtaIxs","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendAction"},{"id":162,"kind":2048,"name":"updateWSOLAccount","url":"classes/SolendAction.html#updateWSOLAccount","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendAction"},{"id":163,"kind":128,"name":"SolendMarket","url":"classes/SolendMarket.html","classes":"tsd-kind-class"},{"id":164,"kind":2048,"name":"initialize","url":"classes/SolendMarket.html#initialize","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendMarket"},{"id":165,"kind":512,"name":"constructor","url":"classes/SolendMarket.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class tsd-is-private","parent":"SolendMarket"},{"id":166,"kind":1024,"name":"connection","url":"classes/SolendMarket.html#connection","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"SolendMarket"},{"id":167,"kind":1024,"name":"reserves","url":"classes/SolendMarket.html#reserves","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendMarket"},{"id":168,"kind":1024,"name":"rewardsData","url":"classes/SolendMarket.html#rewardsData","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendMarket"},{"id":169,"kind":1024,"name":"config","url":"classes/SolendMarket.html#config","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendMarket"},{"id":170,"kind":1024,"name":"programId","url":"classes/SolendMarket.html#programId","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendMarket"},{"id":171,"kind":2048,"name":"fetchObligationByWallet","url":"classes/SolendMarket.html#fetchObligationByWallet","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendMarket"},{"id":172,"kind":2048,"name":"loadAll","url":"classes/SolendMarket.html#loadAll","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendMarket"},{"id":173,"kind":2048,"name":"loadExternalRewardData","url":"classes/SolendMarket.html#loadExternalRewardData","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendMarket"},{"id":174,"kind":2048,"name":"loadPriceData","url":"classes/SolendMarket.html#loadPriceData","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendMarket"},{"id":175,"kind":2048,"name":"getLatestRewardRate","url":"classes/SolendMarket.html#getLatestRewardRate","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendMarket"},{"id":176,"kind":2048,"name":"loadRewards","url":"classes/SolendMarket.html#loadRewards","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendMarket"},{"id":177,"kind":2048,"name":"loadReserves","url":"classes/SolendMarket.html#loadReserves","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendMarket"},{"id":178,"kind":2048,"name":"refreshAll","url":"classes/SolendMarket.html#refreshAll","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendMarket"},{"id":179,"kind":4194304,"name":"ClaimType","url":"modules.html#ClaimType","classes":"tsd-kind-type-alias"},{"id":180,"kind":65536,"name":"__type","url":"modules.html#ClaimType.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"ClaimType"},{"id":181,"kind":1024,"name":"obligationID","url":"modules.html#ClaimType.__type.obligationID","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":182,"kind":1024,"name":"lotNumber","url":"modules.html#ClaimType.__type.lotNumber","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":183,"kind":1024,"name":"index","url":"modules.html#ClaimType.__type.index","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":184,"kind":1024,"name":"quantity","url":"modules.html#ClaimType.__type.quantity","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":185,"kind":1024,"name":"root","url":"modules.html#ClaimType.__type.root","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":186,"kind":1024,"name":"proof","url":"modules.html#ClaimType.__type.proof","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":187,"kind":1024,"name":"distributorPublicKey","url":"modules.html#ClaimType.__type.distributorPublicKey","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":188,"kind":1024,"name":"name","url":"modules.html#ClaimType.__type.name","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":189,"kind":1024,"name":"incentivizer","url":"modules.html#ClaimType.__type.incentivizer","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":190,"kind":1024,"name":"optionMarketKey","url":"modules.html#ClaimType.__type.optionMarketKey","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ClaimType.__type"},{"id":191,"kind":4194304,"name":"EnrichedClaimType","url":"modules.html#EnrichedClaimType","classes":"tsd-kind-type-alias"},{"id":192,"kind":4194304,"name":"SolendReward","url":"modules.html#SolendReward","classes":"tsd-kind-type-alias"},{"id":193,"kind":65536,"name":"__type","url":"modules.html#SolendReward.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"SolendReward"},{"id":194,"kind":1024,"name":"lifetimeAmount","url":"modules.html#SolendReward.__type.lifetimeAmount","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"SolendReward.__type"},{"id":195,"kind":1024,"name":"symbol","url":"modules.html#SolendReward.__type.symbol","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"SolendReward.__type"},{"id":196,"kind":1024,"name":"claimedAmount","url":"modules.html#SolendReward.__type.claimedAmount","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"SolendReward.__type"},{"id":197,"kind":1024,"name":"claimableAmount","url":"modules.html#SolendReward.__type.claimableAmount","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"SolendReward.__type"},{"id":198,"kind":1024,"name":"rewardClaims","url":"modules.html#SolendReward.__type.rewardClaims","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"SolendReward.__type"},{"id":199,"kind":128,"name":"SolendWallet","url":"classes/SolendWallet.html","classes":"tsd-kind-class"},{"id":200,"kind":2048,"name":"initialize","url":"classes/SolendWallet.html#initialize","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SolendWallet"},{"id":201,"kind":512,"name":"constructor","url":"classes/SolendWallet.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class tsd-is-private","parent":"SolendWallet"},{"id":202,"kind":1024,"name":"config","url":"classes/SolendWallet.html#config","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendWallet"},{"id":203,"kind":1024,"name":"rewards","url":"classes/SolendWallet.html#rewards","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendWallet"},{"id":204,"kind":65536,"name":"__type","url":"classes/SolendWallet.html#__type","classes":"tsd-kind-type-literal tsd-parent-kind-class","parent":"SolendWallet"},{"id":205,"kind":1024,"name":"provider","url":"classes/SolendWallet.html#provider","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendWallet"},{"id":206,"kind":1024,"name":"programId","url":"classes/SolendWallet.html#programId","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendWallet"},{"id":207,"kind":2048,"name":"loadRewards","url":"classes/SolendWallet.html#loadRewards","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendWallet"},{"id":208,"kind":2048,"name":"getClaimAllIxs","url":"classes/SolendWallet.html#getClaimAllIxs","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendWallet"},{"id":209,"kind":128,"name":"SolendClaim","url":"classes/SolendClaim.html","classes":"tsd-kind-class"},{"id":210,"kind":512,"name":"constructor","url":"classes/SolendClaim.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"SolendClaim"},{"id":211,"kind":1024,"name":"metadata","url":"classes/SolendClaim.html#metadata","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendClaim"},{"id":212,"kind":1024,"name":"provider","url":"classes/SolendClaim.html#provider","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendClaim"},{"id":213,"kind":2048,"name":"getExerciseIxs","url":"classes/SolendClaim.html#getExerciseIxs","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendClaim"},{"id":214,"kind":2048,"name":"getClaimIxs","url":"classes/SolendClaim.html#getClaimIxs","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendClaim"},{"id":215,"kind":2048,"name":"claim","url":"classes/SolendClaim.html#claim","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendClaim"},{"id":216,"kind":128,"name":"SolendReserve","url":"classes/SolendReserve.html","classes":"tsd-kind-class"},{"id":217,"kind":512,"name":"constructor","url":"classes/SolendReserve.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"SolendReserve"},{"id":218,"kind":1024,"name":"config","url":"classes/SolendReserve.html#config","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendReserve"},{"id":219,"kind":1024,"name":"rewardsData","url":"classes/SolendReserve.html#rewardsData","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"SolendReserve"},{"id":220,"kind":1024,"name":"buffer","url":"classes/SolendReserve.html#buffer","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"SolendReserve"},{"id":221,"kind":1024,"name":"stats","url":"classes/SolendReserve.html#stats","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendReserve"},{"id":222,"kind":1024,"name":"connection","url":"classes/SolendReserve.html#connection","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"SolendReserve"},{"id":223,"kind":2048,"name":"calculateSupplyAPY","url":"classes/SolendReserve.html#calculateSupplyAPY","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendReserve"},{"id":224,"kind":2048,"name":"calculateBorrowAPY","url":"classes/SolendReserve.html#calculateBorrowAPY","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendReserve"},{"id":225,"kind":2048,"name":"calculateSupplyAPR","url":"classes/SolendReserve.html#calculateSupplyAPR","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendReserve"},{"id":226,"kind":2048,"name":"calculateUtilizationRatio","url":"classes/SolendReserve.html#calculateUtilizationRatio","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendReserve"},{"id":227,"kind":2048,"name":"calculateBorrowAPR","url":"classes/SolendReserve.html#calculateBorrowAPR","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendReserve"},{"id":228,"kind":2048,"name":"setBuffer","url":"classes/SolendReserve.html#setBuffer","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendReserve"},{"id":229,"kind":2048,"name":"load","url":"classes/SolendReserve.html#load","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendReserve"},{"id":230,"kind":2048,"name":"calculateRewardAPY","url":"classes/SolendReserve.html#calculateRewardAPY","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendReserve"},{"id":231,"kind":2048,"name":"totalSupplyAPY","url":"classes/SolendReserve.html#totalSupplyAPY","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendReserve"},{"id":232,"kind":2048,"name":"totalBorrowAPY","url":"classes/SolendReserve.html#totalBorrowAPY","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SolendReserve"},{"id":233,"kind":2048,"name":"formatReserveData","url":"classes/SolendReserve.html#formatReserveData","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendReserve"},{"id":234,"kind":4194304,"name":"Position","url":"modules.html#Position","classes":"tsd-kind-type-alias"},{"id":235,"kind":65536,"name":"__type","url":"modules.html#Position.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"Position"},{"id":236,"kind":1024,"name":"mintAddress","url":"modules.html#Position.__type.mintAddress","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"Position.__type"},{"id":237,"kind":1024,"name":"amount","url":"modules.html#Position.__type.amount","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"Position.__type"},{"id":238,"kind":4194304,"name":"ObligationStats","url":"modules.html#ObligationStats","classes":"tsd-kind-type-alias"},{"id":239,"kind":65536,"name":"__type","url":"modules.html#ObligationStats.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"ObligationStats"},{"id":240,"kind":1024,"name":"liquidationThreshold","url":"modules.html#ObligationStats.__type.liquidationThreshold","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ObligationStats.__type"},{"id":241,"kind":1024,"name":"userTotalDeposit","url":"modules.html#ObligationStats.__type.userTotalDeposit","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ObligationStats.__type"},{"id":242,"kind":1024,"name":"userTotalBorrow","url":"modules.html#ObligationStats.__type.userTotalBorrow","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ObligationStats.__type"},{"id":243,"kind":1024,"name":"borrowLimit","url":"modules.html#ObligationStats.__type.borrowLimit","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ObligationStats.__type"},{"id":244,"kind":1024,"name":"borrowUtilization","url":"modules.html#ObligationStats.__type.borrowUtilization","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ObligationStats.__type"},{"id":245,"kind":1024,"name":"netAccountValue","url":"modules.html#ObligationStats.__type.netAccountValue","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ObligationStats.__type"},{"id":246,"kind":1024,"name":"positions","url":"modules.html#ObligationStats.__type.positions","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ObligationStats.__type"},{"id":247,"kind":128,"name":"SolendObligation","url":"classes/SolendObligation.html","classes":"tsd-kind-class"},{"id":248,"kind":512,"name":"constructor","url":"classes/SolendObligation.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"SolendObligation"},{"id":249,"kind":1024,"name":"walletAddress","url":"classes/SolendObligation.html#walletAddress","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendObligation"},{"id":250,"kind":1024,"name":"obligationAddress","url":"classes/SolendObligation.html#obligationAddress","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendObligation"},{"id":251,"kind":1024,"name":"deposits","url":"classes/SolendObligation.html#deposits","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendObligation"},{"id":252,"kind":1024,"name":"borrows","url":"classes/SolendObligation.html#borrows","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendObligation"},{"id":253,"kind":1024,"name":"obligationStats","url":"classes/SolendObligation.html#obligationStats","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SolendObligation"},{"id":254,"kind":2048,"name":"calculatePositions","url":"classes/SolendObligation.html#calculatePositions","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"SolendObligation"},{"id":255,"kind":4194304,"name":"RewardInfoType","url":"modules.html#RewardInfoType","classes":"tsd-kind-type-alias"},{"id":256,"kind":65536,"name":"__type","url":"modules.html#RewardInfoType.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"RewardInfoType"},{"id":257,"kind":1024,"name":"rewardRate","url":"modules.html#RewardInfoType.__type.rewardRate","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"RewardInfoType.__type"},{"id":258,"kind":1024,"name":"rewardMint","url":"modules.html#RewardInfoType.__type.rewardMint","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"RewardInfoType.__type"},{"id":259,"kind":1024,"name":"rewardSymbol","url":"modules.html#RewardInfoType.__type.rewardSymbol","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"RewardInfoType.__type"},{"id":260,"kind":1024,"name":"price","url":"modules.html#RewardInfoType.__type.price","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"RewardInfoType.__type"},{"id":261,"kind":4194304,"name":"RewardsDataType","url":"modules.html#RewardsDataType","classes":"tsd-kind-type-alias"},{"id":262,"kind":65536,"name":"__type","url":"modules.html#RewardsDataType.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"RewardsDataType"},{"id":263,"kind":4194304,"name":"RewardResponseType","url":"modules.html#RewardResponseType","classes":"tsd-kind-type-alias"},{"id":264,"kind":65536,"name":"__type","url":"modules.html#RewardResponseType.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"RewardResponseType"},{"id":265,"kind":1024,"name":"supply","url":"modules.html#RewardResponseType.__type.supply","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"RewardResponseType.__type"},{"id":266,"kind":1024,"name":"borrow","url":"modules.html#RewardResponseType.__type.borrow","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"RewardResponseType.__type"},{"id":267,"kind":4194304,"name":"RewardStatType","url":"modules.html#RewardStatType","classes":"tsd-kind-type-alias"},{"id":268,"kind":4194304,"name":"ExternalRewardStatType","url":"modules.html#ExternalRewardStatType","classes":"tsd-kind-type-alias"},{"id":269,"kind":4194304,"name":"ConfigType","url":"modules.html#ConfigType","classes":"tsd-kind-type-alias"},{"id":270,"kind":4194304,"name":"ReserveConfigType","url":"modules.html#ReserveConfigType","classes":"tsd-kind-type-alias"},{"id":271,"kind":65536,"name":"__type","url":"modules.html#ReserveConfigType.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"ReserveConfigType"},{"id":272,"kind":1024,"name":"liquidityToken","url":"modules.html#ReserveConfigType.__type.liquidityToken","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":273,"kind":65536,"name":"__type","url":"modules.html#ReserveConfigType.__type.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":274,"kind":1024,"name":"coingeckoID","url":"modules.html#ReserveConfigType.__type.__type-1.coingeckoID","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type.__type"},{"id":275,"kind":1024,"name":"decimals","url":"modules.html#ReserveConfigType.__type.__type-1.decimals","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type.__type"},{"id":276,"kind":1024,"name":"logo","url":"modules.html#ReserveConfigType.__type.__type-1.logo","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type.__type"},{"id":277,"kind":1024,"name":"mint","url":"modules.html#ReserveConfigType.__type.__type-1.mint","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type.__type"},{"id":278,"kind":1024,"name":"name","url":"modules.html#ReserveConfigType.__type.__type-1.name","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type.__type"},{"id":279,"kind":1024,"name":"symbol","url":"modules.html#ReserveConfigType.__type.__type-1.symbol","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type.__type"},{"id":280,"kind":1024,"name":"volume24h","url":"modules.html#ReserveConfigType.__type.__type-1.volume24h","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type.__type"},{"id":281,"kind":1024,"name":"pythOracle","url":"modules.html#ReserveConfigType.__type.pythOracle","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":282,"kind":1024,"name":"switchboardOracle","url":"modules.html#ReserveConfigType.__type.switchboardOracle","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":283,"kind":1024,"name":"address","url":"modules.html#ReserveConfigType.__type.address","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":284,"kind":1024,"name":"collateralMintAddress","url":"modules.html#ReserveConfigType.__type.collateralMintAddress","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":285,"kind":1024,"name":"collateralSupplyAddress","url":"modules.html#ReserveConfigType.__type.collateralSupplyAddress","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":286,"kind":1024,"name":"liquidityAddress","url":"modules.html#ReserveConfigType.__type.liquidityAddress","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":287,"kind":1024,"name":"liquidityFeeReceiverAddress","url":"modules.html#ReserveConfigType.__type.liquidityFeeReceiverAddress","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":288,"kind":1024,"name":"userSupplyCap","url":"modules.html#ReserveConfigType.__type.userSupplyCap","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":289,"kind":1024,"name":"userBorrowCap","url":"modules.html#ReserveConfigType.__type.userBorrowCap","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveConfigType.__type"},{"id":290,"kind":4194304,"name":"MarketConfigType","url":"modules.html#MarketConfigType","classes":"tsd-kind-type-alias"},{"id":291,"kind":65536,"name":"__type","url":"modules.html#MarketConfigType.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"MarketConfigType"},{"id":292,"kind":1024,"name":"name","url":"modules.html#MarketConfigType.__type.name","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"MarketConfigType.__type"},{"id":293,"kind":1024,"name":"isPrimary","url":"modules.html#MarketConfigType.__type.isPrimary","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"MarketConfigType.__type"},{"id":294,"kind":1024,"name":"description","url":"modules.html#MarketConfigType.__type.description","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"MarketConfigType.__type"},{"id":295,"kind":1024,"name":"creator","url":"modules.html#MarketConfigType.__type.creator","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"MarketConfigType.__type"},{"id":296,"kind":1024,"name":"address","url":"modules.html#MarketConfigType.__type.address","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"MarketConfigType.__type"},{"id":297,"kind":1024,"name":"hidden","url":"modules.html#MarketConfigType.__type.hidden","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"MarketConfigType.__type"},{"id":298,"kind":1024,"name":"authorityAddress","url":"modules.html#MarketConfigType.__type.authorityAddress","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"MarketConfigType.__type"},{"id":299,"kind":1024,"name":"reserves","url":"modules.html#MarketConfigType.__type.reserves","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"MarketConfigType.__type"},{"id":300,"kind":4194304,"name":"ReserveDataType","url":"modules.html#ReserveDataType","classes":"tsd-kind-type-alias"},{"id":301,"kind":65536,"name":"__type","url":"modules.html#ReserveDataType.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias","parent":"ReserveDataType"},{"id":302,"kind":1024,"name":"optimalUtilizationRate","url":"modules.html#ReserveDataType.__type.optimalUtilizationRate","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":303,"kind":1024,"name":"loanToValueRatio","url":"modules.html#ReserveDataType.__type.loanToValueRatio","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":304,"kind":1024,"name":"liquidationBonus","url":"modules.html#ReserveDataType.__type.liquidationBonus","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":305,"kind":1024,"name":"liquidationThreshold","url":"modules.html#ReserveDataType.__type.liquidationThreshold","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":306,"kind":1024,"name":"minBorrowRate","url":"modules.html#ReserveDataType.__type.minBorrowRate","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":307,"kind":1024,"name":"optimalBorrowRate","url":"modules.html#ReserveDataType.__type.optimalBorrowRate","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":308,"kind":1024,"name":"maxBorrowRate","url":"modules.html#ReserveDataType.__type.maxBorrowRate","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":309,"kind":1024,"name":"borrowFeePercentage","url":"modules.html#ReserveDataType.__type.borrowFeePercentage","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":310,"kind":1024,"name":"hostFeePercentage","url":"modules.html#ReserveDataType.__type.hostFeePercentage","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":311,"kind":1024,"name":"depositLimit","url":"modules.html#ReserveDataType.__type.depositLimit","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":312,"kind":1024,"name":"reserveBorrowLimit","url":"modules.html#ReserveDataType.__type.reserveBorrowLimit","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":313,"kind":1024,"name":"name","url":"modules.html#ReserveDataType.__type.name","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":314,"kind":1024,"name":"symbol","url":"modules.html#ReserveDataType.__type.symbol","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":315,"kind":1024,"name":"decimals","url":"modules.html#ReserveDataType.__type.decimals","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":316,"kind":1024,"name":"mintAddress","url":"modules.html#ReserveDataType.__type.mintAddress","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":317,"kind":1024,"name":"totalDepositsWads","url":"modules.html#ReserveDataType.__type.totalDepositsWads","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":318,"kind":1024,"name":"totalBorrowsWads","url":"modules.html#ReserveDataType.__type.totalBorrowsWads","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":319,"kind":1024,"name":"totalLiquidityWads","url":"modules.html#ReserveDataType.__type.totalLiquidityWads","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":320,"kind":1024,"name":"supplyInterestAPY","url":"modules.html#ReserveDataType.__type.supplyInterestAPY","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":321,"kind":1024,"name":"borrowInterestAPY","url":"modules.html#ReserveDataType.__type.borrowInterestAPY","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":322,"kind":1024,"name":"assetPriceUSD","url":"modules.html#ReserveDataType.__type.assetPriceUSD","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":323,"kind":1024,"name":"protocolTakeRate","url":"modules.html#ReserveDataType.__type.protocolTakeRate","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":324,"kind":1024,"name":"userDepositLimit","url":"modules.html#ReserveDataType.__type.userDepositLimit","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":325,"kind":1024,"name":"cumulativeBorrowRateWads","url":"modules.html#ReserveDataType.__type.cumulativeBorrowRateWads","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":326,"kind":1024,"name":"cTokenExchangeRate","url":"modules.html#ReserveDataType.__type.cTokenExchangeRate","classes":"tsd-kind-property tsd-parent-kind-type-literal","parent":"ReserveDataType.__type"},{"id":327,"kind":64,"name":"getProgramId","url":"modules.html#getProgramId","classes":"tsd-kind-function"},{"id":328,"kind":32,"name":"WAD","url":"modules.html#WAD","classes":"tsd-kind-variable"},{"id":329,"kind":32,"name":"WANG","url":"modules.html#WANG","classes":"tsd-kind-variable"},{"id":330,"kind":32,"name":"U64_MAX","url":"modules.html#U64_MAX","classes":"tsd-kind-variable"},{"id":331,"kind":32,"name":"SLOTS_PER_YEAR","url":"modules.html#SLOTS_PER_YEAR","classes":"tsd-kind-variable"},{"id":332,"kind":32,"name":"SOLEND_PRODUCTION_PROGRAM_ID","url":"modules.html#SOLEND_PRODUCTION_PROGRAM_ID","classes":"tsd-kind-variable"},{"id":333,"kind":32,"name":"SOLEND_DEVNET_PROGRAM_ID","url":"modules.html#SOLEND_DEVNET_PROGRAM_ID","classes":"tsd-kind-variable"},{"id":334,"kind":32,"name":"SOLEND_BETA_PROGRAM_ID","url":"modules.html#SOLEND_BETA_PROGRAM_ID","classes":"tsd-kind-variable"}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,54.116]],["parent/0",[]],["name/1",[1,54.116]],["parent/1",[]],["name/2",[2,54.116]],["parent/2",[]],["name/3",[3,54.116]],["parent/3",[]],["name/4",[4,54.116]],["parent/4",[]],["name/5",[5,54.116]],["parent/5",[]],["name/6",[6,54.116]],["parent/6",[]],["name/7",[7,54.116]],["parent/7",[]],["name/8",[8,54.116]],["parent/8",[]],["name/9",[9,54.116]],["parent/9",[]],["name/10",[10,54.116]],["parent/10",[]],["name/11",[11,54.116]],["parent/11",[]],["name/12",[12,54.116]],["parent/12",[]],["name/13",[13,54.116]],["parent/13",[]],["name/14",[14,54.116]],["parent/14",[]],["name/15",[15,54.116]],["parent/15",[]],["name/16",[16,54.116]],["parent/16",[]],["name/17",[17,54.116]],["parent/17",[]],["name/18",[18,39.453]],["parent/18",[]],["name/19",[19,54.116]],["parent/19",[18,3.529]],["name/20",[20,54.116]],["parent/20",[18,3.529]],["name/21",[21,35.658]],["parent/21",[]],["name/22",[22,43.13]],["parent/22",[21,3.189]],["name/23",[23,54.116]],["parent/23",[21,3.189]],["name/24",[24,54.116]],["parent/24",[21,3.189]],["name/25",[25,54.116]],["parent/25",[21,3.189]],["name/26",[26,54.116]],["parent/26",[]],["name/27",[27,54.116]],["parent/27",[]],["name/28",[28,54.116]],["parent/28",[]],["name/29",[29,54.116]],["parent/29",[]],["name/30",[30,54.116]],["parent/30",[]],["name/31",[31,36.77]],["parent/31",[]],["name/32",[22,43.13]],["parent/32",[31,3.289]],["name/33",[18,39.453]],["parent/33",[31,3.289]],["name/34",[21,35.658]],["parent/34",[31,3.289]],["name/35",[32,54.116]],["parent/35",[31,3.289]],["name/36",[33,54.116]],["parent/36",[31,3.289]],["name/37",[34,43.13]],["parent/37",[31,3.289]],["name/38",[35,33.748]],["parent/38",[]],["name/39",[36,49.008]],["parent/39",[35,3.019]],["name/40",[37,54.116]],["parent/40",[35,3.019]],["name/41",[38,49.008]],["parent/41",[35,3.019]],["name/42",[39,54.116]],["parent/42",[35,3.019]],["name/43",[40,54.116]],["parent/43",[35,3.019]],["name/44",[41,54.116]],["parent/44",[35,3.019]],["name/45",[42,54.116]],["parent/45",[35,3.019]],["name/46",[43,49.008]],["parent/46",[35,3.019]],["name/47",[44,45.643]],["parent/47",[35,3.019]],["name/48",[45,54.116]],["parent/48",[35,3.019]],["name/49",[46,43.13]],["parent/49",[]],["name/50",[36,49.008]],["parent/50",[46,3.858]],["name/51",[47,54.116]],["parent/51",[46,3.858]],["name/52",[38,49.008]],["parent/52",[46,3.858]],["name/53",[48,30.763]],["parent/53",[]],["name/54",[49,49.008]],["parent/54",[48,2.752]],["name/55",[50,49.008]],["parent/55",[48,2.752]],["name/56",[51,49.008]],["parent/56",[48,2.752]],["name/57",[52,45.643]],["parent/57",[48,2.752]],["name/58",[53,49.008]],["parent/58",[48,2.752]],["name/59",[54,49.008]],["parent/59",[48,2.752]],["name/60",[55,49.008]],["parent/60",[48,2.752]],["name/61",[56,54.116]],["parent/61",[48,2.752]],["name/62",[57,32.144]],["parent/62",[48,2.752]],["name/63",[58,54.116]],["parent/63",[59,4.083]],["name/64",[60,54.116]],["parent/64",[59,4.083]],["name/65",[61,49.008]],["parent/65",[59,4.083]],["name/66",[62,49.008]],["parent/66",[48,2.752]],["name/67",[63,49.008]],["parent/67",[48,2.752]],["name/68",[64,54.116]],["parent/68",[48,2.752]],["name/69",[65,54.116]],["parent/69",[48,2.752]],["name/70",[66,49.008]],["parent/70",[48,2.752]],["name/71",[67,54.116]],["parent/71",[]],["name/72",[68,54.116]],["parent/72",[]],["name/73",[69,54.116]],["parent/73",[]],["name/74",[70,54.116]],["parent/74",[]],["name/75",[71,54.116]],["parent/75",[]],["name/76",[72,54.116]],["parent/76",[]],["name/77",[73,33.748]],["parent/77",[]],["name/78",[22,43.13]],["parent/78",[73,3.019]],["name/79",[18,39.453]],["parent/79",[73,3.019]],["name/80",[21,35.658]],["parent/80",[73,3.019]],["name/81",[74,49.008]],["parent/81",[73,3.019]],["name/82",[75,49.008]],["parent/82",[73,3.019]],["name/83",[76,49.008]],["parent/83",[73,3.019]],["name/84",[77,49.008]],["parent/84",[73,3.019]],["name/85",[78,49.008]],["parent/85",[73,3.019]],["name/86",[79,49.008]],["parent/86",[73,3.019]],["name/87",[80,49.008]],["parent/87",[73,3.019]],["name/88",[81,43.13]],["parent/88",[]],["name/89",[82,54.116]],["parent/89",[81,3.858]],["name/90",[83,54.116]],["parent/90",[81,3.858]],["name/91",[84,49.008]],["parent/91",[81,3.858]],["name/92",[85,41.124]],["parent/92",[]],["name/93",[86,54.116]],["parent/93",[85,3.678]],["name/94",[44,45.643]],["parent/94",[85,3.678]],["name/95",[43,49.008]],["parent/95",[85,3.678]],["name/96",[84,49.008]],["parent/96",[85,3.678]],["name/97",[87,54.116]],["parent/97",[]],["name/98",[88,54.116]],["parent/98",[]],["name/99",[89,54.116]],["parent/99",[]],["name/100",[90,54.116]],["parent/100",[]],["name/101",[91,54.116]],["parent/101",[]],["name/102",[92,32.914]],["parent/102",[]],["name/103",[22,43.13]],["parent/103",[92,2.944]],["name/104",[18,39.453]],["parent/104",[92,2.944]],["name/105",[21,35.658]],["parent/105",[92,2.944]],["name/106",[74,49.008]],["parent/106",[92,2.944]],["name/107",[77,49.008]],["parent/107",[92,2.944]],["name/108",[78,49.008]],["parent/108",[92,2.944]],["name/109",[79,49.008]],["parent/109",[92,2.944]],["name/110",[80,49.008]],["parent/110",[92,2.944]],["name/111",[93,54.116]],["parent/111",[92,2.944]],["name/112",[94,54.116]],["parent/112",[92,2.944]],["name/113",[95,54.116]],["parent/113",[92,2.944]],["name/114",[96,54.116]],["parent/114",[]],["name/115",[97,54.116]],["parent/115",[]],["name/116",[98,54.116]],["parent/116",[]],["name/117",[99,19.777]],["parent/117",[]],["name/118",[100,45.643]],["parent/118",[99,1.769]],["name/119",[101,54.116]],["parent/119",[99,1.769]],["name/120",[102,54.116]],["parent/120",[99,1.769]],["name/121",[103,54.116]],["parent/121",[99,1.769]],["name/122",[104,54.116]],["parent/122",[99,1.769]],["name/123",[105,54.116]],["parent/123",[99,1.769]],["name/124",[106,54.116]],["parent/124",[99,1.769]],["name/125",[107,54.116]],["parent/125",[99,1.769]],["name/126",[108,39.453]],["parent/126",[99,1.769]],["name/127",[109,45.643]],["parent/127",[99,1.769]],["name/128",[110,45.643]],["parent/128",[99,1.769]],["name/129",[31,36.77]],["parent/129",[99,1.769]],["name/130",[21,35.658]],["parent/130",[99,1.769]],["name/131",[111,54.116]],["parent/131",[99,1.769]],["name/132",[112,49.008]],["parent/132",[99,1.769]],["name/133",[113,54.116]],["parent/133",[99,1.769]],["name/134",[114,54.116]],["parent/134",[99,1.769]],["name/135",[115,54.116]],["parent/135",[99,1.769]],["name/136",[116,54.116]],["parent/136",[99,1.769]],["name/137",[117,43.13]],["parent/137",[99,1.769]],["name/138",[118,49.008]],["parent/138",[99,1.769]],["name/139",[119,49.008]],["parent/139",[99,1.769]],["name/140",[120,54.116]],["parent/140",[99,1.769]],["name/141",[121,54.116]],["parent/141",[99,1.769]],["name/142",[122,54.116]],["parent/142",[99,1.769]],["name/143",[123,54.116]],["parent/143",[99,1.769]],["name/144",[124,54.116]],["parent/144",[99,1.769]],["name/145",[125,54.116]],["parent/145",[99,1.769]],["name/146",[126,54.116]],["parent/146",[99,1.769]],["name/147",[127,54.116]],["parent/147",[99,1.769]],["name/148",[128,54.116]],["parent/148",[99,1.769]],["name/149",[129,54.116]],["parent/149",[99,1.769]],["name/150",[130,54.116]],["parent/150",[99,1.769]],["name/151",[131,54.116]],["parent/151",[99,1.769]],["name/152",[132,54.116]],["parent/152",[99,1.769]],["name/153",[133,54.116]],["parent/153",[99,1.769]],["name/154",[134,54.116]],["parent/154",[99,1.769]],["name/155",[135,54.116]],["parent/155",[99,1.769]],["name/156",[136,54.116]],["parent/156",[99,1.769]],["name/157",[137,54.116]],["parent/157",[99,1.769]],["name/158",[138,54.116]],["parent/158",[99,1.769]],["name/159",[139,54.116]],["parent/159",[99,1.769]],["name/160",[140,54.116]],["parent/160",[99,1.769]],["name/161",[141,54.116]],["parent/161",[99,1.769]],["name/162",[142,54.116]],["parent/162",[99,1.769]],["name/163",[143,30.138]],["parent/163",[]],["name/164",[100,45.643]],["parent/164",[143,2.696]],["name/165",[108,39.453]],["parent/165",[143,2.696]],["name/166",[110,45.643]],["parent/166",[143,2.696]],["name/167",[144,49.008]],["parent/167",[143,2.696]],["name/168",[145,49.008]],["parent/168",[143,2.696]],["name/169",[34,43.13]],["parent/169",[143,2.696]],["name/170",[109,45.643]],["parent/170",[143,2.696]],["name/171",[146,54.116]],["parent/171",[143,2.696]],["name/172",[147,54.116]],["parent/172",[143,2.696]],["name/173",[148,54.116]],["parent/173",[143,2.696]],["name/174",[149,54.116]],["parent/174",[143,2.696]],["name/175",[150,54.116]],["parent/175",[143,2.696]],["name/176",[151,49.008]],["parent/176",[143,2.696]],["name/177",[152,54.116]],["parent/177",[143,2.696]],["name/178",[153,54.116]],["parent/178",[143,2.696]],["name/179",[154,49.008]],["parent/179",[]],["name/180",[57,32.144]],["parent/180",[154,4.384]],["name/181",[155,54.116]],["parent/181",[156,3.1]],["name/182",[157,54.116]],["parent/182",[156,3.1]],["name/183",[158,54.116]],["parent/183",[156,3.1]],["name/184",[159,54.116]],["parent/184",[156,3.1]],["name/185",[160,54.116]],["parent/185",[156,3.1]],["name/186",[161,54.116]],["parent/186",[156,3.1]],["name/187",[162,54.116]],["parent/187",[156,3.1]],["name/188",[163,43.13]],["parent/188",[156,3.1]],["name/189",[164,54.116]],["parent/189",[156,3.1]],["name/190",[165,54.116]],["parent/190",[156,3.1]],["name/191",[166,54.116]],["parent/191",[]],["name/192",[167,49.008]],["parent/192",[]],["name/193",[57,32.144]],["parent/193",[167,4.384]],["name/194",[168,54.116]],["parent/194",[169,3.678]],["name/195",[117,43.13]],["parent/195",[169,3.678]],["name/196",[170,54.116]],["parent/196",[169,3.678]],["name/197",[171,54.116]],["parent/197",[169,3.678]],["name/198",[172,54.116]],["parent/198",[169,3.678]],["name/199",[173,34.657]],["parent/199",[]],["name/200",[100,45.643]],["parent/200",[173,3.1]],["name/201",[108,39.453]],["parent/201",[173,3.1]],["name/202",[34,43.13]],["parent/202",[173,3.1]],["name/203",[174,54.116]],["parent/203",[173,3.1]],["name/204",[57,32.144]],["parent/204",[173,3.1]],["name/205",[175,49.008]],["parent/205",[173,3.1]],["name/206",[109,45.643]],["parent/206",[173,3.1]],["name/207",[151,49.008]],["parent/207",[173,3.1]],["name/208",[176,54.116]],["parent/208",[173,3.1]],["name/209",[177,38.022]],["parent/209",[]],["name/210",[108,39.453]],["parent/210",[177,3.401]],["name/211",[178,54.116]],["parent/211",[177,3.401]],["name/212",[175,49.008]],["parent/212",[177,3.401]],["name/213",[179,54.116]],["parent/213",[177,3.401]],["name/214",[180,54.116]],["parent/214",[177,3.401]],["name/215",[181,54.116]],["parent/215",[177,3.401]],["name/216",[182,28.993]],["parent/216",[]],["name/217",[108,39.453]],["parent/217",[182,2.593]],["name/218",[34,43.13]],["parent/218",[182,2.593]],["name/219",[145,49.008]],["parent/219",[182,2.593]],["name/220",[183,54.116]],["parent/220",[182,2.593]],["name/221",[184,54.116]],["parent/221",[182,2.593]],["name/222",[110,45.643]],["parent/222",[182,2.593]],["name/223",[185,54.116]],["parent/223",[182,2.593]],["name/224",[186,54.116]],["parent/224",[182,2.593]],["name/225",[187,54.116]],["parent/225",[182,2.593]],["name/226",[188,54.116]],["parent/226",[182,2.593]],["name/227",[189,54.116]],["parent/227",[182,2.593]],["name/228",[190,54.116]],["parent/228",[182,2.593]],["name/229",[191,54.116]],["parent/229",[182,2.593]],["name/230",[192,54.116]],["parent/230",[182,2.593]],["name/231",[193,54.116]],["parent/231",[182,2.593]],["name/232",[194,54.116]],["parent/232",[182,2.593]],["name/233",[195,54.116]],["parent/233",[182,2.593]],["name/234",[196,49.008]],["parent/234",[]],["name/235",[57,32.144]],["parent/235",[196,4.384]],["name/236",[197,49.008]],["parent/236",[198,4.384]],["name/237",[119,49.008]],["parent/237",[198,4.384]],["name/238",[199,45.643]],["parent/238",[]],["name/239",[57,32.144]],["parent/239",[199,4.083]],["name/240",[52,45.643]],["parent/240",[200,3.401]],["name/241",[201,54.116]],["parent/241",[200,3.401]],["name/242",[202,54.116]],["parent/242",[200,3.401]],["name/243",[63,49.008]],["parent/243",[200,3.401]],["name/244",[203,54.116]],["parent/244",[200,3.401]],["name/245",[204,54.116]],["parent/245",[200,3.401]],["name/246",[118,49.008]],["parent/246",[200,3.401]],["name/247",[205,36.77]],["parent/247",[]],["name/248",[108,39.453]],["parent/248",[205,3.289]],["name/249",[206,54.116]],["parent/249",[205,3.289]],["name/250",[112,49.008]],["parent/250",[205,3.289]],["name/251",[75,49.008]],["parent/251",[205,3.289]],["name/252",[76,49.008]],["parent/252",[205,3.289]],["name/253",[199,45.643]],["parent/253",[205,3.289]],["name/254",[207,54.116]],["parent/254",[205,3.289]],["name/255",[208,49.008]],["parent/255",[]],["name/256",[57,32.144]],["parent/256",[208,4.384]],["name/257",[209,54.116]],["parent/257",[210,3.858]],["name/258",[211,54.116]],["parent/258",[210,3.858]],["name/259",[212,54.116]],["parent/259",[210,3.858]],["name/260",[213,54.116]],["parent/260",[210,3.858]],["name/261",[214,49.008]],["parent/261",[]],["name/262",[57,32.144]],["parent/262",[214,4.384]],["name/263",[215,49.008]],["parent/263",[]],["name/264",[57,32.144]],["parent/264",[215,4.384]],["name/265",[216,54.116]],["parent/265",[217,4.384]],["name/266",[218,54.116]],["parent/266",[217,4.384]],["name/267",[219,54.116]],["parent/267",[]],["name/268",[220,54.116]],["parent/268",[]],["name/269",[221,54.116]],["parent/269",[]],["name/270",[222,49.008]],["parent/270",[]],["name/271",[57,32.144]],["parent/271",[222,4.384]],["name/272",[223,54.116]],["parent/272",[224,3.019]],["name/273",[57,32.144]],["parent/273",[224,3.019]],["name/274",[225,54.116]],["parent/274",[226,3.401]],["name/275",[227,49.008]],["parent/275",[226,3.401]],["name/276",[228,54.116]],["parent/276",[226,3.401]],["name/277",[229,54.116]],["parent/277",[226,3.401]],["name/278",[163,43.13]],["parent/278",[226,3.401]],["name/279",[117,43.13]],["parent/279",[226,3.401]],["name/280",[230,54.116]],["parent/280",[226,3.401]],["name/281",[231,54.116]],["parent/281",[224,3.019]],["name/282",[232,54.116]],["parent/282",[224,3.019]],["name/283",[233,49.008]],["parent/283",[224,3.019]],["name/284",[234,54.116]],["parent/284",[224,3.019]],["name/285",[235,54.116]],["parent/285",[224,3.019]],["name/286",[236,54.116]],["parent/286",[224,3.019]],["name/287",[237,54.116]],["parent/287",[224,3.019]],["name/288",[238,54.116]],["parent/288",[224,3.019]],["name/289",[239,54.116]],["parent/289",[224,3.019]],["name/290",[240,49.008]],["parent/290",[]],["name/291",[57,32.144]],["parent/291",[240,4.384]],["name/292",[163,43.13]],["parent/292",[241,3.289]],["name/293",[242,54.116]],["parent/293",[241,3.289]],["name/294",[243,54.116]],["parent/294",[241,3.289]],["name/295",[244,54.116]],["parent/295",[241,3.289]],["name/296",[233,49.008]],["parent/296",[241,3.289]],["name/297",[245,54.116]],["parent/297",[241,3.289]],["name/298",[246,54.116]],["parent/298",[241,3.289]],["name/299",[144,49.008]],["parent/299",[241,3.289]],["name/300",[247,49.008]],["parent/300",[]],["name/301",[57,32.144]],["parent/301",[247,4.384]],["name/302",[49,49.008]],["parent/302",[248,2.306]],["name/303",[50,49.008]],["parent/303",[248,2.306]],["name/304",[51,49.008]],["parent/304",[248,2.306]],["name/305",[52,45.643]],["parent/305",[248,2.306]],["name/306",[53,49.008]],["parent/306",[248,2.306]],["name/307",[54,49.008]],["parent/307",[248,2.306]],["name/308",[55,49.008]],["parent/308",[248,2.306]],["name/309",[249,54.116]],["parent/309",[248,2.306]],["name/310",[61,49.008]],["parent/310",[248,2.306]],["name/311",[62,49.008]],["parent/311",[248,2.306]],["name/312",[250,54.116]],["parent/312",[248,2.306]],["name/313",[163,43.13]],["parent/313",[248,2.306]],["name/314",[117,43.13]],["parent/314",[248,2.306]],["name/315",[227,49.008]],["parent/315",[248,2.306]],["name/316",[197,49.008]],["parent/316",[248,2.306]],["name/317",[251,54.116]],["parent/317",[248,2.306]],["name/318",[252,54.116]],["parent/318",[248,2.306]],["name/319",[253,54.116]],["parent/319",[248,2.306]],["name/320",[254,54.116]],["parent/320",[248,2.306]],["name/321",[255,54.116]],["parent/321",[248,2.306]],["name/322",[256,54.116]],["parent/322",[248,2.306]],["name/323",[66,49.008]],["parent/323",[248,2.306]],["name/324",[257,54.116]],["parent/324",[248,2.306]],["name/325",[44,45.643]],["parent/325",[248,2.306]],["name/326",[258,54.116]],["parent/326",[248,2.306]],["name/327",[259,54.116]],["parent/327",[]],["name/328",[260,54.116]],["parent/328",[]],["name/329",[261,54.116]],["parent/329",[]],["name/330",[262,54.116]],["parent/330",[]],["name/331",[263,54.116]],["parent/331",[]],["name/332",[264,54.116]],["parent/332",[]],["name/333",[265,54.116]],["parent/333",[]],["name/334",[266,54.116]],["parent/334",[]]],"invertedIndex":[["__type",{"_index":57,"name":{"62":{},"180":{},"193":{},"204":{},"235":{},"239":{},"256":{},"262":{},"264":{},"271":{},"273":{},"291":{},"301":{}},"parent":{}}],["actiontype",{"_index":98,"name":{"116":{}},"parent":{}}],["addataixs",{"_index":141,"name":{"161":{}},"parent":{}}],["addborrowix",{"_index":135,"name":{"155":{}},"parent":{}}],["adddepositix",{"_index":131,"name":{"151":{}},"parent":{}}],["adddepositobligationcollateralix",{"_index":134,"name":{"154":{}},"parent":{}}],["adddepositreserveliquidityix",{"_index":132,"name":{"152":{}},"parent":{}}],["addobligationixs",{"_index":140,"name":{"160":{}},"parent":{}}],["addredeemreservecollateralix",{"_index":133,"name":{"153":{}},"parent":{}}],["addrefreshixs",{"_index":139,"name":{"159":{}},"parent":{}}],["addrepayix",{"_index":137,"name":{"157":{}},"parent":{}}],["address",{"_index":233,"name":{"283":{},"296":{}},"parent":{}}],["addsupportixs",{"_index":138,"name":{"158":{}},"parent":{}}],["addwithdrawix",{"_index":136,"name":{"156":{}},"parent":{}}],["allowedborrowvalue",{"_index":79,"name":{"86":{},"109":{}},"parent":{}}],["amount",{"_index":119,"name":{"139":{},"237":{}},"parent":{}}],["assetpriceusd",{"_index":256,"name":{"322":{}},"parent":{}}],["authorityaddress",{"_index":246,"name":{"298":{}},"parent":{}}],["availableamount",{"_index":42,"name":{"45":{}},"parent":{}}],["borrow",{"_index":218,"name":{"266":{}},"parent":{}}],["borrowedamountwads",{"_index":43,"name":{"46":{},"95":{}},"parent":{}}],["borrowedvalue",{"_index":78,"name":{"85":{},"108":{}},"parent":{}}],["borrowfeepercentage",{"_index":249,"name":{"309":{}},"parent":{}}],["borrowfeewad",{"_index":58,"name":{"63":{}},"parent":{}}],["borrowinterestapy",{"_index":255,"name":{"321":{}},"parent":{}}],["borrowlimit",{"_index":63,"name":{"67":{},"243":{}},"parent":{}}],["borrowobligationliquidityinstruction",{"_index":0,"name":{"0":{}},"parent":{}}],["borrowreserve",{"_index":86,"name":{"93":{}},"parent":{}}],["borrowreserves",{"_index":127,"name":{"147":{}},"parent":{}}],["borrows",{"_index":76,"name":{"83":{},"252":{}},"parent":{}}],["borrowslen",{"_index":94,"name":{"112":{}},"parent":{}}],["borrowutilization",{"_index":203,"name":{"244":{}},"parent":{}}],["buffer",{"_index":183,"name":{"220":{}},"parent":{}}],["buildborrowtxns",{"_index":102,"name":{"120":{}},"parent":{}}],["builddepositobligationcollateraltxns",{"_index":105,"name":{"123":{}},"parent":{}}],["builddepositreserveliquiditytxns",{"_index":103,"name":{"121":{}},"parent":{}}],["builddeposittxns",{"_index":101,"name":{"119":{}},"parent":{}}],["buildredeemreservecollateraltxns",{"_index":104,"name":{"122":{}},"parent":{}}],["buildrepaytxns",{"_index":107,"name":{"125":{}},"parent":{}}],["buildwithdrawtxns",{"_index":106,"name":{"124":{}},"parent":{}}],["calculateborrowapr",{"_index":189,"name":{"227":{}},"parent":{}}],["calculateborrowapy",{"_index":186,"name":{"224":{}},"parent":{}}],["calculatepositions",{"_index":207,"name":{"254":{}},"parent":{}}],["calculaterewardapy",{"_index":192,"name":{"230":{}},"parent":{}}],["calculatesupplyapr",{"_index":187,"name":{"225":{}},"parent":{}}],["calculatesupplyapy",{"_index":185,"name":{"223":{}},"parent":{}}],["calculateutilizationratio",{"_index":188,"name":{"226":{}},"parent":{}}],["claim",{"_index":181,"name":{"215":{}},"parent":{}}],["claimableamount",{"_index":171,"name":{"197":{}},"parent":{}}],["claimedamount",{"_index":170,"name":{"196":{}},"parent":{}}],["claimtype",{"_index":154,"name":{"179":{}},"parent":{"180":{}}}],["claimtype.__type",{"_index":156,"name":{},"parent":{"181":{},"182":{},"183":{},"184":{},"185":{},"186":{},"187":{},"188":{},"189":{},"190":{}}}],["cleanupixs",{"_index":123,"name":{"143":{}},"parent":{}}],["coingeckoid",{"_index":225,"name":{"274":{}},"parent":{}}],["collateral",{"_index":33,"name":{"36":{}},"parent":{}}],["collateralmintaddress",{"_index":234,"name":{"284":{}},"parent":{}}],["collateralsupplyaddress",{"_index":235,"name":{"285":{}},"parent":{}}],["config",{"_index":34,"name":{"37":{},"169":{},"202":{},"218":{}},"parent":{}}],["configtype",{"_index":221,"name":{"269":{}},"parent":{}}],["connection",{"_index":110,"name":{"128":{},"166":{},"222":{}},"parent":{}}],["constructor",{"_index":108,"name":{"126":{},"165":{},"201":{},"210":{},"217":{},"248":{}},"parent":{}}],["creator",{"_index":244,"name":{"295":{}},"parent":{}}],["ctokenexchangerate",{"_index":258,"name":{"326":{}},"parent":{}}],["cumulativeborrowratewads",{"_index":44,"name":{"47":{},"94":{},"325":{}},"parent":{}}],["dataflat",{"_index":95,"name":{"113":{}},"parent":{}}],["decimals",{"_index":227,"name":{"275":{},"315":{}},"parent":{}}],["depositedamount",{"_index":83,"name":{"90":{}},"parent":{}}],["depositedvalue",{"_index":77,"name":{"84":{},"107":{}},"parent":{}}],["depositlimit",{"_index":62,"name":{"66":{},"311":{}},"parent":{}}],["depositobligationcollateralinstruction",{"_index":1,"name":{"1":{}},"parent":{}}],["depositreserve",{"_index":82,"name":{"89":{}},"parent":{}}],["depositreserveliquidityandobligationcollateralinstruction",{"_index":9,"name":{"9":{}},"parent":{}}],["depositreserveliquidityinstruction",{"_index":2,"name":{"2":{}},"parent":{}}],["depositreserves",{"_index":126,"name":{"146":{}},"parent":{}}],["deposits",{"_index":75,"name":{"82":{},"251":{}},"parent":{}}],["depositslen",{"_index":93,"name":{"111":{}},"parent":{}}],["description",{"_index":243,"name":{"294":{}},"parent":{}}],["distributorpublickey",{"_index":162,"name":{"187":{}},"parent":{}}],["enrichedclaimtype",{"_index":166,"name":{"191":{}},"parent":{}}],["externalrewardstattype",{"_index":220,"name":{"268":{}},"parent":{}}],["feereceiver",{"_index":64,"name":{"68":{}},"parent":{}}],["fees",{"_index":56,"name":{"61":{}},"parent":{}}],["fetchobligationbywallet",{"_index":146,"name":{"171":{}},"parent":{}}],["flashborrowreserveliquidityinstruction",{"_index":15,"name":{"15":{}},"parent":{}}],["flashloanfeewad",{"_index":60,"name":{"64":{}},"parent":{}}],["flashrepayreserveliquidityinstruction",{"_index":16,"name":{"16":{}},"parent":{}}],["formatreservedata",{"_index":195,"name":{"233":{}},"parent":{}}],["getclaimallixs",{"_index":176,"name":{"208":{}},"parent":{}}],["getclaimixs",{"_index":180,"name":{"214":{}},"parent":{}}],["getexerciseixs",{"_index":179,"name":{"213":{}},"parent":{}}],["getlatestrewardrate",{"_index":150,"name":{"175":{}},"parent":{}}],["getprogramid",{"_index":259,"name":{"327":{}},"parent":{}}],["gettransactions",{"_index":128,"name":{"148":{}},"parent":{}}],["hidden",{"_index":245,"name":{"297":{}},"parent":{}}],["hostata",{"_index":120,"name":{"140":{}},"parent":{}}],["hostfeepercentage",{"_index":61,"name":{"65":{},"310":{}},"parent":{}}],["incentivizer",{"_index":164,"name":{"189":{}},"parent":{}}],["index",{"_index":158,"name":{"183":{}},"parent":{}}],["initialize",{"_index":100,"name":{"118":{},"164":{},"200":{}},"parent":{}}],["initlendingmarketinstruction",{"_index":12,"name":{"12":{}},"parent":{}}],["initobligationinstruction",{"_index":3,"name":{"3":{}},"parent":{}}],["initreserveinstruction",{"_index":13,"name":{"13":{}},"parent":{}}],["isinitialized",{"_index":23,"name":{"23":{}},"parent":{}}],["islendingmarket",{"_index":28,"name":{"28":{}},"parent":{}}],["isobligation",{"_index":91,"name":{"101":{}},"parent":{}}],["isprimary",{"_index":242,"name":{"293":{}},"parent":{}}],["isreserve",{"_index":70,"name":{"74":{}},"parent":{}}],["lastupdate",{"_index":18,"name":{"18":{},"33":{},"79":{},"104":{}},"parent":{"19":{},"20":{}}}],["lastupdatelayout",{"_index":17,"name":{"17":{}},"parent":{}}],["lending_market_size",{"_index":27,"name":{"27":{}},"parent":{}}],["lendingixs",{"_index":122,"name":{"142":{}},"parent":{}}],["lendingmarket",{"_index":21,"name":{"21":{},"34":{},"80":{},"105":{},"130":{}},"parent":{"22":{},"23":{},"24":{},"25":{}}}],["lendingmarketlayout",{"_index":26,"name":{"26":{}},"parent":{}}],["lifetimeamount",{"_index":168,"name":{"194":{}},"parent":{}}],["liquidationbonus",{"_index":51,"name":{"56":{},"304":{}},"parent":{}}],["liquidationthreshold",{"_index":52,"name":{"57":{},"240":{},"305":{}},"parent":{}}],["liquidity",{"_index":32,"name":{"35":{}},"parent":{}}],["liquidityaddress",{"_index":236,"name":{"286":{}},"parent":{}}],["liquidityfeereceiveraddress",{"_index":237,"name":{"287":{}},"parent":{}}],["liquiditytoken",{"_index":223,"name":{"272":{}},"parent":{}}],["load",{"_index":191,"name":{"229":{}},"parent":{}}],["loadall",{"_index":147,"name":{"172":{}},"parent":{}}],["loadexternalrewarddata",{"_index":148,"name":{"173":{}},"parent":{}}],["loadpricedata",{"_index":149,"name":{"174":{}},"parent":{}}],["loadreserves",{"_index":152,"name":{"177":{}},"parent":{}}],["loadrewards",{"_index":151,"name":{"176":{},"207":{}},"parent":{}}],["loantovalueratio",{"_index":50,"name":{"55":{},"303":{}},"parent":{}}],["logo",{"_index":228,"name":{"276":{}},"parent":{}}],["lotnumber",{"_index":157,"name":{"182":{}},"parent":{}}],["marketconfigtype",{"_index":240,"name":{"290":{}},"parent":{"291":{}}}],["marketconfigtype.__type",{"_index":241,"name":{},"parent":{"292":{},"293":{},"294":{},"295":{},"296":{},"297":{},"298":{},"299":{}}}],["marketprice",{"_index":45,"name":{"48":{}},"parent":{}}],["marketvalue",{"_index":84,"name":{"91":{},"96":{}},"parent":{}}],["maxborrowrate",{"_index":55,"name":{"60":{},"308":{}},"parent":{}}],["metadata",{"_index":178,"name":{"211":{}},"parent":{}}],["minborrowrate",{"_index":53,"name":{"58":{},"306":{}},"parent":{}}],["mint",{"_index":229,"name":{"277":{}},"parent":{}}],["mintaddress",{"_index":197,"name":{"236":{},"316":{}},"parent":{}}],["mintdecimals",{"_index":37,"name":{"40":{}},"parent":{}}],["mintpubkey",{"_index":36,"name":{"39":{},"50":{}},"parent":{}}],["minttotalsupply",{"_index":47,"name":{"51":{}},"parent":{}}],["name",{"_index":163,"name":{"188":{},"278":{},"292":{},"313":{}},"parent":{}}],["netaccountvalue",{"_index":204,"name":{"245":{}},"parent":{}}],["obligation",{"_index":73,"name":{"77":{}},"parent":{"78":{},"79":{},"80":{},"81":{},"82":{},"83":{},"84":{},"85":{},"86":{},"87":{}}}],["obligation_size",{"_index":90,"name":{"100":{}},"parent":{}}],["obligationaccountinfo",{"_index":113,"name":{"133":{}},"parent":{}}],["obligationaddress",{"_index":112,"name":{"132":{},"250":{}},"parent":{}}],["obligationcollateral",{"_index":81,"name":{"88":{}},"parent":{"89":{},"90":{},"91":{}}}],["obligationcollaterallayout",{"_index":88,"name":{"98":{}},"parent":{}}],["obligationid",{"_index":155,"name":{"181":{}},"parent":{}}],["obligationlayout",{"_index":87,"name":{"97":{}},"parent":{}}],["obligationliquidity",{"_index":85,"name":{"92":{}},"parent":{"93":{},"94":{},"95":{},"96":{}}}],["obligationliquiditylayout",{"_index":89,"name":{"99":{}},"parent":{}}],["obligationstats",{"_index":199,"name":{"238":{},"253":{}},"parent":{"239":{}}}],["obligationstats.__type",{"_index":200,"name":{},"parent":{"240":{},"241":{},"242":{},"243":{},"244":{},"245":{},"246":{}}}],["obligationtostring",{"_index":72,"name":{"76":{}},"parent":{}}],["optimalborrowrate",{"_index":54,"name":{"59":{},"307":{}},"parent":{}}],["optimalutilizationrate",{"_index":49,"name":{"54":{},"302":{}},"parent":{}}],["optionmarketkey",{"_index":165,"name":{"190":{}},"parent":{}}],["oracleoption",{"_index":39,"name":{"42":{}},"parent":{}}],["owner",{"_index":74,"name":{"81":{},"106":{}},"parent":{}}],["parselendingmarket",{"_index":29,"name":{"29":{}},"parent":{}}],["parseobligation",{"_index":96,"name":{"114":{}},"parent":{}}],["parsereserve",{"_index":71,"name":{"75":{}},"parent":{}}],["position",{"_index":196,"name":{"234":{}},"parent":{"235":{}}}],["position.__type",{"_index":198,"name":{},"parent":{"236":{},"237":{}}}],["position_limit",{"_index":97,"name":{"115":{}},"parent":{}}],["positions",{"_index":118,"name":{"138":{},"246":{}},"parent":{}}],["posttxnixs",{"_index":125,"name":{"145":{}},"parent":{}}],["pretxnixs",{"_index":124,"name":{"144":{}},"parent":{}}],["price",{"_index":213,"name":{"260":{}},"parent":{}}],["programid",{"_index":109,"name":{"127":{},"170":{},"206":{}},"parent":{}}],["proof",{"_index":161,"name":{"186":{}},"parent":{}}],["protocolliquidationfee",{"_index":65,"name":{"69":{}},"parent":{}}],["protocoltakerate",{"_index":66,"name":{"70":{},"323":{}},"parent":{}}],["protoobligation",{"_index":92,"name":{"102":{}},"parent":{"103":{},"104":{},"105":{},"106":{},"107":{},"108":{},"109":{},"110":{},"111":{},"112":{},"113":{}}}],["provider",{"_index":175,"name":{"205":{},"212":{}},"parent":{}}],["publickey",{"_index":111,"name":{"131":{}},"parent":{}}],["pythoracle",{"_index":231,"name":{"281":{}},"parent":{}}],["pythoraclepubkey",{"_index":40,"name":{"43":{}},"parent":{}}],["quantity",{"_index":159,"name":{"184":{}},"parent":{}}],["quotetokenmint",{"_index":24,"name":{"24":{}},"parent":{}}],["redeemreservecollateralinstruction",{"_index":4,"name":{"4":{}},"parent":{}}],["refreshall",{"_index":153,"name":{"178":{}},"parent":{}}],["refreshobligationinstruction",{"_index":5,"name":{"5":{}},"parent":{}}],["refreshreserveinstruction",{"_index":6,"name":{"6":{}},"parent":{}}],["repayobligationliquidityinstruction",{"_index":7,"name":{"7":{}},"parent":{}}],["reserve",{"_index":31,"name":{"31":{},"129":{}},"parent":{"32":{},"33":{},"34":{},"35":{},"36":{},"37":{}}}],["reserve_size",{"_index":69,"name":{"73":{}},"parent":{}}],["reserveborrowlimit",{"_index":250,"name":{"312":{}},"parent":{}}],["reservecollateral",{"_index":46,"name":{"49":{}},"parent":{"50":{},"51":{},"52":{}}}],["reserveconfig",{"_index":48,"name":{"53":{}},"parent":{"54":{},"55":{},"56":{},"57":{},"58":{},"59":{},"60":{},"61":{},"62":{},"66":{},"67":{},"68":{},"69":{},"70":{}}}],["reserveconfig.__type",{"_index":59,"name":{},"parent":{"63":{},"64":{},"65":{}}}],["reserveconfiglayout",{"_index":67,"name":{"71":{}},"parent":{}}],["reserveconfigtype",{"_index":222,"name":{"270":{}},"parent":{"271":{}}}],["reserveconfigtype.__type",{"_index":224,"name":{},"parent":{"272":{},"273":{},"281":{},"282":{},"283":{},"284":{},"285":{},"286":{},"287":{},"288":{},"289":{}}}],["reserveconfigtype.__type.__type",{"_index":226,"name":{},"parent":{"274":{},"275":{},"276":{},"277":{},"278":{},"279":{},"280":{}}}],["reservedatatype",{"_index":247,"name":{"300":{}},"parent":{"301":{}}}],["reservedatatype.__type",{"_index":248,"name":{},"parent":{"302":{},"303":{},"304":{},"305":{},"306":{},"307":{},"308":{},"309":{},"310":{},"311":{},"312":{},"313":{},"314":{},"315":{},"316":{},"317":{},"318":{},"319":{},"320":{},"321":{},"322":{},"323":{},"324":{},"325":{},"326":{}}}],["reservelayout",{"_index":68,"name":{"72":{}},"parent":{}}],["reserveliquidity",{"_index":35,"name":{"38":{}},"parent":{"39":{},"40":{},"41":{},"42":{},"43":{},"44":{},"45":{},"46":{},"47":{},"48":{}}}],["reserves",{"_index":144,"name":{"167":{},"299":{}},"parent":{}}],["reservetostring",{"_index":30,"name":{"30":{}},"parent":{}}],["rewardclaims",{"_index":172,"name":{"198":{}},"parent":{}}],["rewardinfotype",{"_index":208,"name":{"255":{}},"parent":{"256":{}}}],["rewardinfotype.__type",{"_index":210,"name":{},"parent":{"257":{},"258":{},"259":{},"260":{}}}],["rewardmint",{"_index":211,"name":{"258":{}},"parent":{}}],["rewardrate",{"_index":209,"name":{"257":{}},"parent":{}}],["rewardresponsetype",{"_index":215,"name":{"263":{}},"parent":{"264":{}}}],["rewardresponsetype.__type",{"_index":217,"name":{},"parent":{"265":{},"266":{}}}],["rewards",{"_index":174,"name":{"203":{}},"parent":{}}],["rewardsdata",{"_index":145,"name":{"168":{},"219":{}},"parent":{}}],["rewardsdatatype",{"_index":214,"name":{"261":{}},"parent":{"262":{}}}],["rewardstattype",{"_index":219,"name":{"267":{}},"parent":{}}],["rewardsymbol",{"_index":212,"name":{"259":{}},"parent":{}}],["root",{"_index":160,"name":{"185":{}},"parent":{}}],["seed",{"_index":116,"name":{"136":{}},"parent":{}}],["sendsingletransaction",{"_index":130,"name":{"150":{}},"parent":{}}],["sendtransactions",{"_index":129,"name":{"149":{}},"parent":{}}],["setbuffer",{"_index":190,"name":{"228":{}},"parent":{}}],["setupixs",{"_index":121,"name":{"141":{}},"parent":{}}],["slot",{"_index":19,"name":{"19":{}},"parent":{}}],["slots_per_year",{"_index":263,"name":{"331":{}},"parent":{}}],["solend_beta_program_id",{"_index":266,"name":{"334":{}},"parent":{}}],["solend_devnet_program_id",{"_index":265,"name":{"333":{}},"parent":{}}],["solend_production_program_id",{"_index":264,"name":{"332":{}},"parent":{}}],["solendaction",{"_index":99,"name":{"117":{}},"parent":{"118":{},"119":{},"120":{},"121":{},"122":{},"123":{},"124":{},"125":{},"126":{},"127":{},"128":{},"129":{},"130":{},"131":{},"132":{},"133":{},"134":{},"135":{},"136":{},"137":{},"138":{},"139":{},"140":{},"141":{},"142":{},"143":{},"144":{},"145":{},"146":{},"147":{},"148":{},"149":{},"150":{},"151":{},"152":{},"153":{},"154":{},"155":{},"156":{},"157":{},"158":{},"159":{},"160":{},"161":{},"162":{}}}],["solendclaim",{"_index":177,"name":{"209":{}},"parent":{"210":{},"211":{},"212":{},"213":{},"214":{},"215":{}}}],["solendmarket",{"_index":143,"name":{"163":{}},"parent":{"164":{},"165":{},"166":{},"167":{},"168":{},"169":{},"170":{},"171":{},"172":{},"173":{},"174":{},"175":{},"176":{},"177":{},"178":{}}}],["solendobligation",{"_index":205,"name":{"247":{}},"parent":{"248":{},"249":{},"250":{},"251":{},"252":{},"253":{},"254":{}}}],["solendreserve",{"_index":182,"name":{"216":{}},"parent":{"217":{},"218":{},"219":{},"220":{},"221":{},"222":{},"223":{},"224":{},"225":{},"226":{},"227":{},"228":{},"229":{},"230":{},"231":{},"232":{},"233":{}}}],["solendreward",{"_index":167,"name":{"192":{}},"parent":{"193":{}}}],["solendreward.__type",{"_index":169,"name":{},"parent":{"194":{},"195":{},"196":{},"197":{},"198":{}}}],["solendwallet",{"_index":173,"name":{"199":{}},"parent":{"200":{},"201":{},"202":{},"203":{},"204":{},"205":{},"206":{},"207":{},"208":{}}}],["stale",{"_index":20,"name":{"20":{}},"parent":{}}],["stats",{"_index":184,"name":{"221":{}},"parent":{}}],["supply",{"_index":216,"name":{"265":{}},"parent":{}}],["supplyinterestapy",{"_index":254,"name":{"320":{}},"parent":{}}],["supplypubkey",{"_index":38,"name":{"41":{},"52":{}},"parent":{}}],["switchboardoracle",{"_index":232,"name":{"282":{}},"parent":{}}],["switchboardoraclepubkey",{"_index":41,"name":{"44":{}},"parent":{}}],["symbol",{"_index":117,"name":{"137":{},"195":{},"279":{},"314":{}},"parent":{}}],["syncnative",{"_index":11,"name":{"11":{}},"parent":{}}],["tokenprogramid",{"_index":25,"name":{"25":{}},"parent":{}}],["totalborrowapy",{"_index":194,"name":{"232":{}},"parent":{}}],["totalborrowswads",{"_index":252,"name":{"318":{}},"parent":{}}],["totaldepositswads",{"_index":251,"name":{"317":{}},"parent":{}}],["totalliquiditywads",{"_index":253,"name":{"319":{}},"parent":{}}],["totalsupplyapy",{"_index":193,"name":{"231":{}},"parent":{}}],["u64_max",{"_index":262,"name":{"330":{}},"parent":{}}],["unhealthyborrowvalue",{"_index":80,"name":{"87":{},"110":{}},"parent":{}}],["updatereserveconfig",{"_index":14,"name":{"14":{}},"parent":{}}],["updatewsolaccount",{"_index":142,"name":{"162":{}},"parent":{}}],["userborrowcap",{"_index":239,"name":{"289":{}},"parent":{}}],["usercollateralaccountaddress",{"_index":115,"name":{"135":{}},"parent":{}}],["userdepositlimit",{"_index":257,"name":{"324":{}},"parent":{}}],["usersupplycap",{"_index":238,"name":{"288":{}},"parent":{}}],["usertokenaccountaddress",{"_index":114,"name":{"134":{}},"parent":{}}],["usertotalborrow",{"_index":202,"name":{"242":{}},"parent":{}}],["usertotaldeposit",{"_index":201,"name":{"241":{}},"parent":{}}],["version",{"_index":22,"name":{"22":{},"32":{},"78":{},"103":{}},"parent":{}}],["volume24h",{"_index":230,"name":{"280":{}},"parent":{}}],["wad",{"_index":260,"name":{"328":{}},"parent":{}}],["walletaddress",{"_index":206,"name":{"249":{}},"parent":{}}],["wang",{"_index":261,"name":{"329":{}},"parent":{}}],["withdrawobligationcollateralandredeemreserveliquidity",{"_index":10,"name":{"10":{}},"parent":{}}],["withdrawobligationcollateralinstruction",{"_index":8,"name":{"8":{}},"parent":{}}]],"pipeline":[]}} \ No newline at end of file diff --git a/solend-sdk/docs/assets/style.css b/solend-sdk/docs/assets/style.css deleted file mode 100644 index 28f90b67..00000000 --- a/solend-sdk/docs/assets/style.css +++ /dev/null @@ -1,1388 +0,0 @@ -@import url("./icons.css"); - -:root { - /* Light */ - --light-color-background: #fcfcfc; - --light-color-secondary-background: #fff; - --light-color-text: #222; - --light-color-text-aside: #707070; - --light-color-link: #4da6ff; - --light-color-menu-divider: #eee; - --light-color-menu-divider-focus: #000; - --light-color-menu-label: #707070; - --light-color-panel: var(--light-color-secondary-background); - --light-color-panel-divider: #eee; - --light-color-comment-tag: #707070; - --light-color-comment-tag-text: #fff; - --light-color-ts: #9600ff; - --light-color-ts-interface: #647f1b; - --light-color-ts-enum: #937210; - --light-color-ts-class: #0672de; - --light-color-ts-private: #707070; - --light-color-toolbar: #fff; - --light-color-toolbar-text: #333; - --light-icon-filter: invert(0); - --light-external-icon: url("data:image/svg+xml;utf8,"); - - /* Dark */ - --dark-color-background: #36393f; - --dark-color-secondary-background: #2f3136; - --dark-color-text: #ffffff; - --dark-color-text-aside: #e6e4e4; - --dark-color-link: #00aff4; - --dark-color-menu-divider: #eee; - --dark-color-menu-divider-focus: #000; - --dark-color-menu-label: #707070; - --dark-color-panel: var(--dark-color-secondary-background); - --dark-color-panel-divider: #818181; - --dark-color-comment-tag: #dcddde; - --dark-color-comment-tag-text: #2f3136; - --dark-color-ts: #c97dff; - --dark-color-ts-interface: #9cbe3c; - --dark-color-ts-enum: #d6ab29; - --dark-color-ts-class: #3695f3; - --dark-color-ts-private: #e2e2e2; - --dark-color-toolbar: #34373c; - --dark-color-toolbar-text: #ffffff; - --dark-icon-filter: invert(1); - --dark-external-icon: url("data:image/svg+xml;utf8,"); -} - -@media (prefers-color-scheme: light) { - :root { - --color-background: var(--light-color-background); - --color-secondary-background: var(--light-color-secondary-background); - --color-text: var(--light-color-text); - --color-text-aside: var(--light-color-text-aside); - --color-link: var(--light-color-link); - --color-menu-divider: var(--light-color-menu-divider); - --color-menu-divider-focus: var(--light-color-menu-divider-focus); - --color-menu-label: var(--light-color-menu-label); - --color-panel: var(--light-color-panel); - --color-panel-divider: var(--light-color-panel-divider); - --color-comment-tag: var(--light-color-comment-tag); - --color-comment-tag-text: var(--light-color-comment-tag-text); - --color-ts: var(--light-color-ts); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-class: var(--light-color-ts-class); - --color-ts-private: var(--light-color-ts-private); - --color-toolbar: var(--light-color-toolbar); - --color-toolbar-text: var(--light-color-toolbar-text); - --icon-filter: var(--light-icon-filter); - --external-icon: var(--light-external-icon); - } -} - -@media (prefers-color-scheme: dark) { - :root { - --color-background: var(--dark-color-background); - --color-secondary-background: var(--dark-color-secondary-background); - --color-text: var(--dark-color-text); - --color-text-aside: var(--dark-color-text-aside); - --color-link: var(--dark-color-link); - --color-menu-divider: var(--dark-color-menu-divider); - --color-menu-divider-focus: var(--dark-color-menu-divider-focus); - --color-menu-label: var(--dark-color-menu-label); - --color-panel: var(--dark-color-panel); - --color-panel-divider: var(--dark-color-panel-divider); - --color-comment-tag: var(--dark-color-comment-tag); - --color-comment-tag-text: var(--dark-color-comment-tag-text); - --color-ts: var(--dark-color-ts); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-private: var(--dark-color-ts-private); - --color-toolbar: var(--dark-color-toolbar); - --color-toolbar-text: var(--dark-color-toolbar-text); - --icon-filter: var(--dark-icon-filter); - --external-icon: var(--dark-external-icon); - } -} - -body { - margin: 0; -} - -body.light { - --color-background: var(--light-color-background); - --color-secondary-background: var(--light-color-secondary-background); - --color-text: var(--light-color-text); - --color-text-aside: var(--light-color-text-aside); - --color-link: var(--light-color-link); - --color-menu-divider: var(--light-color-menu-divider); - --color-menu-divider-focus: var(--light-color-menu-divider-focus); - --color-menu-label: var(--light-color-menu-label); - --color-panel: var(--light-color-panel); - --color-panel-divider: var(--light-color-panel-divider); - --color-comment-tag: var(--light-color-comment-tag); - --color-comment-tag-text: var(--light-color-comment-tag-text); - --color-ts: var(--light-color-ts); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-class: var(--light-color-ts-class); - --color-ts-private: var(--light-color-ts-private); - --color-toolbar: var(--light-color-toolbar); - --color-toolbar-text: var(--light-color-toolbar-text); - --icon-filter: var(--light-icon-filter); - --external-icon: var(--light-external-icon); -} - -body.dark { - --color-background: var(--dark-color-background); - --color-secondary-background: var(--dark-color-secondary-background); - --color-text: var(--dark-color-text); - --color-text-aside: var(--dark-color-text-aside); - --color-link: var(--dark-color-link); - --color-menu-divider: var(--dark-color-menu-divider); - --color-menu-divider-focus: var(--dark-color-menu-divider-focus); - --color-menu-label: var(--dark-color-menu-label); - --color-panel: var(--dark-color-panel); - --color-panel-divider: var(--dark-color-panel-divider); - --color-comment-tag: var(--dark-color-comment-tag); - --color-comment-tag-text: var(--dark-color-comment-tag-text); - --color-ts: var(--dark-color-ts); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-private: var(--dark-color-ts-private); - --color-toolbar: var(--dark-color-toolbar); - --color-toolbar-text: var(--dark-color-toolbar-text); - --icon-filter: var(--dark-icon-filter); - --external-icon: var(--dark-external-icon); -} - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -h2 { - font-size: 1.5em; - margin: 0.83em 0; -} - -h3 { - font-size: 1.17em; - margin: 1em 0; -} - -h4, -.tsd-index-panel h3 { - font-size: 1em; - margin: 1.33em 0; -} - -h5 { - font-size: 0.83em; - margin: 1.67em 0; -} - -h6 { - font-size: 0.67em; - margin: 2.33em 0; -} - -pre { - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word; -} - -dl, -menu, -ol, -ul { - margin: 1em 0; -} - -dd { - margin: 0 0 0 40px; -} - -.container { - max-width: 1200px; - margin: 0 auto; - padding: 0 40px; -} -@media (max-width: 640px) { - .container { - padding: 0 20px; - } -} - -.container-main { - padding-bottom: 200px; -} - -.row { - display: flex; - position: relative; - margin: 0 -10px; -} -.row:after { - visibility: hidden; - display: block; - content: ""; - clear: both; - height: 0; -} - -.col-4, -.col-8 { - box-sizing: border-box; - float: left; - padding: 0 10px; -} - -.col-4 { - width: 33.3333333333%; -} -.col-8 { - width: 66.6666666667%; -} - -ul.tsd-descriptions > li > :first-child, -.tsd-panel > :first-child, -.col-8 > :first-child, -.col-4 > :first-child, -ul.tsd-descriptions > li > :first-child > :first-child, -.tsd-panel > :first-child > :first-child, -.col-8 > :first-child > :first-child, -.col-4 > :first-child > :first-child, -ul.tsd-descriptions > li > :first-child > :first-child > :first-child, -.tsd-panel > :first-child > :first-child > :first-child, -.col-8 > :first-child > :first-child > :first-child, -.col-4 > :first-child > :first-child > :first-child { - margin-top: 0; -} -ul.tsd-descriptions > li > :last-child, -.tsd-panel > :last-child, -.col-8 > :last-child, -.col-4 > :last-child, -ul.tsd-descriptions > li > :last-child > :last-child, -.tsd-panel > :last-child > :last-child, -.col-8 > :last-child > :last-child, -.col-4 > :last-child > :last-child, -ul.tsd-descriptions > li > :last-child > :last-child > :last-child, -.tsd-panel > :last-child > :last-child > :last-child, -.col-8 > :last-child > :last-child > :last-child, -.col-4 > :last-child > :last-child > :last-child { - margin-bottom: 0; -} - -@keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } -} -@keyframes fade-out { - from { - opacity: 1; - visibility: visible; - } - to { - opacity: 0; - } -} -@keyframes fade-in-delayed { - 0% { - opacity: 0; - } - 33% { - opacity: 0; - } - 100% { - opacity: 1; - } -} -@keyframes fade-out-delayed { - 0% { - opacity: 1; - visibility: visible; - } - 66% { - opacity: 0; - } - 100% { - opacity: 0; - } -} -@keyframes shift-to-left { - from { - transform: translate(0, 0); - } - to { - transform: translate(-25%, 0); - } -} -@keyframes unshift-to-left { - from { - transform: translate(-25%, 0); - } - to { - transform: translate(0, 0); - } -} -@keyframes pop-in-from-right { - from { - transform: translate(100%, 0); - } - to { - transform: translate(0, 0); - } -} -@keyframes pop-out-to-right { - from { - transform: translate(0, 0); - visibility: visible; - } - to { - transform: translate(100%, 0); - } -} -body { - background: var(--color-background); - font-family: "Segoe UI", sans-serif; - font-size: 16px; - color: var(--color-text); -} - -a { - color: var(--color-link); - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -a.external[target="_blank"] { - background-image: var(--external-icon); - background-position: top 3px right; - background-repeat: no-repeat; - padding-right: 13px; -} - -code, -pre { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - padding: 0.2em; - margin: 0; - font-size: 14px; -} - -pre { - padding: 10px; -} -pre code { - padding: 0; - font-size: 100%; -} - -blockquote { - margin: 1em 0; - padding-left: 1em; - border-left: 4px solid gray; -} - -.tsd-typography { - line-height: 1.333em; -} -.tsd-typography ul { - list-style: square; - padding: 0 0 0 20px; - margin: 0; -} -.tsd-typography h4, -.tsd-typography .tsd-index-panel h3, -.tsd-index-panel .tsd-typography h3, -.tsd-typography h5, -.tsd-typography h6 { - font-size: 1em; - margin: 0; -} -.tsd-typography h5, -.tsd-typography h6 { - font-weight: normal; -} -.tsd-typography p, -.tsd-typography ul, -.tsd-typography ol { - margin: 1em 0; -} - -@media (min-width: 901px) and (max-width: 1024px) { - html .col-content { - width: 72%; - } - html .col-menu { - width: 28%; - } - html .tsd-navigation { - padding-left: 10px; - } -} -@media (max-width: 900px) { - html .col-content { - float: none; - width: 100%; - } - html .col-menu { - position: fixed !important; - overflow: auto; - -webkit-overflow-scrolling: touch; - z-index: 1024; - top: 0 !important; - bottom: 0 !important; - left: auto !important; - right: 0 !important; - width: 100%; - padding: 20px 20px 0 0; - max-width: 450px; - visibility: hidden; - background-color: var(--color-panel); - transform: translate(100%, 0); - } - html .col-menu > *:last-child { - padding-bottom: 20px; - } - html .overlay { - content: ""; - display: block; - position: fixed; - z-index: 1023; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.75); - visibility: hidden; - } - - .to-has-menu .overlay { - animation: fade-in 0.4s; - } - - .to-has-menu :is(header, footer, .col-content) { - animation: shift-to-left 0.4s; - } - - .to-has-menu .col-menu { - animation: pop-in-from-right 0.4s; - } - - .from-has-menu .overlay { - animation: fade-out 0.4s; - } - - .from-has-menu :is(header, footer, .col-content) { - animation: unshift-to-left 0.4s; - } - - .from-has-menu .col-menu { - animation: pop-out-to-right 0.4s; - } - - .has-menu body { - overflow: hidden; - } - .has-menu .overlay { - visibility: visible; - } - .has-menu :is(header, footer, .col-content) { - transform: translate(-25%, 0); - } - .has-menu .col-menu { - visibility: visible; - transform: translate(0, 0); - display: grid; - grid-template-rows: auto 1fr; - max-height: 100vh; - } - .has-menu .tsd-navigation { - max-height: 100%; - } -} - -.tsd-page-title { - padding: 70px 0 20px 0; - margin: 0 0 40px 0; - background: var(--color-panel); - box-shadow: 0 0 5px rgba(0, 0, 0, 0.35); -} -.tsd-page-title h1 { - margin: 0; -} - -.tsd-breadcrumb { - margin: 0; - padding: 0; - color: var(--color-text-aside); -} -.tsd-breadcrumb a { - color: var(--color-text-aside); - text-decoration: none; -} -.tsd-breadcrumb a:hover { - text-decoration: underline; -} -.tsd-breadcrumb li { - display: inline; -} -.tsd-breadcrumb li:after { - content: " / "; -} - -dl.tsd-comment-tags { - overflow: hidden; -} -dl.tsd-comment-tags dt { - float: left; - padding: 1px 5px; - margin: 0 10px 0 0; - border-radius: 4px; - border: 1px solid var(--color-comment-tag); - color: var(--color-comment-tag); - font-size: 0.8em; - font-weight: normal; -} -dl.tsd-comment-tags dd { - margin: 0 0 10px 0; -} -dl.tsd-comment-tags dd:before, -dl.tsd-comment-tags dd:after { - display: table; - content: " "; -} -dl.tsd-comment-tags dd pre, -dl.tsd-comment-tags dd:after { - clear: both; -} -dl.tsd-comment-tags p { - margin: 0; -} - -.tsd-panel.tsd-comment .lead { - font-size: 1.1em; - line-height: 1.333em; - margin-bottom: 2em; -} -.tsd-panel.tsd-comment .lead:last-child { - margin-bottom: 0; -} - -.toggle-protected .tsd-is-private { - display: none; -} - -.toggle-public .tsd-is-private, -.toggle-public .tsd-is-protected, -.toggle-public .tsd-is-private-protected { - display: none; -} - -.toggle-inherited .tsd-is-inherited { - display: none; -} - -.toggle-externals .tsd-is-external { - display: none; -} - -#tsd-filter { - position: relative; - display: inline-block; - height: 40px; - vertical-align: bottom; -} -.no-filter #tsd-filter { - display: none; -} -#tsd-filter .tsd-filter-group { - display: inline-block; - height: 40px; - vertical-align: bottom; - white-space: nowrap; -} -#tsd-filter input { - display: none; -} -@media (max-width: 900px) { - #tsd-filter .tsd-filter-group { - display: block; - position: absolute; - top: 40px; - right: 20px; - height: auto; - background-color: var(--color-panel); - visibility: hidden; - transform: translate(50%, 0); - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); - } - .has-options #tsd-filter .tsd-filter-group { - visibility: visible; - } - .to-has-options #tsd-filter .tsd-filter-group { - animation: fade-in 0.2s; - } - .from-has-options #tsd-filter .tsd-filter-group { - animation: fade-out 0.2s; - } - #tsd-filter label, - #tsd-filter .tsd-select { - display: block; - padding-right: 20px; - } -} - -footer { - border-top: 1px solid var(--color-panel-divider); - background-color: var(--color-panel); -} -footer:after { - content: ""; - display: table; -} -footer.with-border-bottom { - border-bottom: 1px solid var(--color-panel-divider); -} -footer .tsd-legend-group { - font-size: 0; -} -footer .tsd-legend { - display: inline-block; - width: 25%; - padding: 0; - font-size: 16px; - list-style: none; - line-height: 1.333em; - vertical-align: top; -} -@media (max-width: 900px) { - footer .tsd-legend { - width: 50%; - } -} - -.tsd-hierarchy { - list-style: square; - padding: 0 0 0 20px; - margin: 0; -} -.tsd-hierarchy .target { - font-weight: bold; -} - -.tsd-index-panel .tsd-index-content { - margin-bottom: -30px !important; -} -.tsd-index-panel .tsd-index-section { - margin-bottom: 30px !important; -} -.tsd-index-panel h3 { - margin: 0 -20px 10px -20px; - padding: 0 20px 10px 20px; - border-bottom: 1px solid var(--color-panel-divider); -} -.tsd-index-panel ul.tsd-index-list { - -webkit-column-count: 3; - -moz-column-count: 3; - -ms-column-count: 3; - -o-column-count: 3; - column-count: 3; - -webkit-column-gap: 20px; - -moz-column-gap: 20px; - -ms-column-gap: 20px; - -o-column-gap: 20px; - column-gap: 20px; - padding: 0; - list-style: none; - line-height: 1.333em; -} -@media (max-width: 900px) { - .tsd-index-panel ul.tsd-index-list { - -webkit-column-count: 1; - -moz-column-count: 1; - -ms-column-count: 1; - -o-column-count: 1; - column-count: 1; - } -} -@media (min-width: 901px) and (max-width: 1024px) { - .tsd-index-panel ul.tsd-index-list { - -webkit-column-count: 2; - -moz-column-count: 2; - -ms-column-count: 2; - -o-column-count: 2; - column-count: 2; - } -} -.tsd-index-panel ul.tsd-index-list li { - -webkit-page-break-inside: avoid; - -moz-page-break-inside: avoid; - -ms-page-break-inside: avoid; - -o-page-break-inside: avoid; - page-break-inside: avoid; -} -.tsd-index-panel a, -.tsd-index-panel .tsd-parent-kind-module a { - color: var(--color-ts); -} -.tsd-index-panel .tsd-parent-kind-interface a { - color: var(--color-ts-interface); -} -.tsd-index-panel .tsd-parent-kind-enum a { - color: var(--color-ts-enum); -} -.tsd-index-panel .tsd-parent-kind-class a { - color: var(--color-ts-class); -} -.tsd-index-panel .tsd-kind-module a { - color: var(--color-ts); -} -.tsd-index-panel .tsd-kind-interface a { - color: var(--color-ts-interface); -} -.tsd-index-panel .tsd-kind-enum a { - color: var(--color-ts-enum); -} -.tsd-index-panel .tsd-kind-class a { - color: var(--color-ts-class); -} -.tsd-index-panel .tsd-is-private a { - color: var(--color-ts-private); -} - -.tsd-flag { - display: inline-block; - padding: 1px 5px; - border-radius: 4px; - color: var(--color-comment-tag-text); - background-color: var(--color-comment-tag); - text-indent: 0; - font-size: 14px; - font-weight: normal; -} - -.tsd-anchor { - position: absolute; - top: -100px; -} - -.tsd-member { - position: relative; -} -.tsd-member .tsd-anchor + h3 { - margin-top: 0; - margin-bottom: 0; - border-bottom: none; -} -.tsd-member [data-tsd-kind] { - color: var(--color-ts); -} -.tsd-member [data-tsd-kind="Interface"] { - color: var(--color-ts-interface); -} -.tsd-member [data-tsd-kind="Enum"] { - color: var(--color-ts-enum); -} -.tsd-member [data-tsd-kind="Class"] { - color: var(--color-ts-class); -} -.tsd-member [data-tsd-kind="Private"] { - color: var(--color-ts-private); -} - -.tsd-navigation { - margin: 0 0 0 40px; -} -.tsd-navigation a { - display: block; - padding-top: 2px; - padding-bottom: 2px; - border-left: 2px solid transparent; - color: var(--color-text); - text-decoration: none; - transition: border-left-color 0.1s; -} -.tsd-navigation a:hover { - text-decoration: underline; -} -.tsd-navigation ul { - margin: 0; - padding: 0; - list-style: none; -} -.tsd-navigation li { - padding: 0; -} - -.tsd-navigation.primary { - padding-bottom: 40px; -} -.tsd-navigation.primary a { - display: block; - padding-top: 6px; - padding-bottom: 6px; -} -.tsd-navigation.primary ul li a { - padding-left: 5px; -} -.tsd-navigation.primary ul li li a { - padding-left: 25px; -} -.tsd-navigation.primary ul li li li a { - padding-left: 45px; -} -.tsd-navigation.primary ul li li li li a { - padding-left: 65px; -} -.tsd-navigation.primary ul li li li li li a { - padding-left: 85px; -} -.tsd-navigation.primary ul li li li li li li a { - padding-left: 105px; -} -.tsd-navigation.primary > ul { - border-bottom: 1px solid var(--color-panel-divider); -} -.tsd-navigation.primary li { - border-top: 1px solid var(--color-panel-divider); -} -.tsd-navigation.primary li.current > a { - font-weight: bold; -} -.tsd-navigation.primary li.label span { - display: block; - padding: 20px 0 6px 5px; - color: var(--color-menu-label); -} -.tsd-navigation.primary li.globals + li > span, -.tsd-navigation.primary li.globals + li > a { - padding-top: 20px; -} - -.tsd-navigation.secondary { - max-height: calc(100vh - 1rem - 40px); - overflow: auto; - position: sticky; - top: calc(0.5rem + 40px); - transition: 0.3s; -} -.tsd-navigation.secondary.tsd-navigation--toolbar-hide { - max-height: calc(100vh - 1rem); - top: 0.5rem; -} -.tsd-navigation.secondary ul { - transition: opacity 0.2s; -} -.tsd-navigation.secondary ul li a { - padding-left: 25px; -} -.tsd-navigation.secondary ul li li a { - padding-left: 45px; -} -.tsd-navigation.secondary ul li li li a { - padding-left: 65px; -} -.tsd-navigation.secondary ul li li li li a { - padding-left: 85px; -} -.tsd-navigation.secondary ul li li li li li a { - padding-left: 105px; -} -.tsd-navigation.secondary ul li li li li li li a { - padding-left: 125px; -} -.tsd-navigation.secondary ul.current a { - border-left-color: var(--color-panel-divider); -} -.tsd-navigation.secondary li.focus > a, -.tsd-navigation.secondary ul.current li.focus > a { - border-left-color: var(--color-menu-divider-focus); -} -.tsd-navigation.secondary li.current { - margin-top: 20px; - margin-bottom: 20px; - border-left-color: var(--color-panel-divider); -} -.tsd-navigation.secondary li.current > a { - font-weight: bold; -} - -@media (min-width: 901px) { - .menu-sticky-wrap { - position: static; - } -} - -.tsd-panel { - margin: 20px 0; - padding: 20px; - background-color: var(--color-panel); - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); -} -.tsd-panel:empty { - display: none; -} -.tsd-panel > h1, -.tsd-panel > h2, -.tsd-panel > h3 { - margin: 1.5em -20px 10px -20px; - padding: 0 20px 10px 20px; - border-bottom: 1px solid var(--color-panel-divider); -} -.tsd-panel > h1.tsd-before-signature, -.tsd-panel > h2.tsd-before-signature, -.tsd-panel > h3.tsd-before-signature { - margin-bottom: 0; - border-bottom: 0; -} -.tsd-panel table { - display: block; - width: 100%; - overflow: auto; - margin-top: 10px; - word-break: normal; - word-break: keep-all; - border-collapse: collapse; -} -.tsd-panel table th { - font-weight: bold; -} -.tsd-panel table th, -.tsd-panel table td { - padding: 6px 13px; - border: 1px solid var(--color-panel-divider); -} -.tsd-panel table tr { - background: var(--color-background); -} -.tsd-panel table tr:nth-child(even) { - background: var(--color-secondary-background); -} - -.tsd-panel-group { - margin: 60px 0; -} -.tsd-panel-group > h1, -.tsd-panel-group > h2, -.tsd-panel-group > h3 { - padding-left: 20px; - padding-right: 20px; -} - -#tsd-search { - transition: background-color 0.2s; -} -#tsd-search .title { - position: relative; - z-index: 2; -} -#tsd-search .field { - position: absolute; - left: 0; - top: 0; - right: 40px; - height: 40px; -} -#tsd-search .field input { - box-sizing: border-box; - position: relative; - top: -50px; - z-index: 1; - width: 100%; - padding: 0 10px; - opacity: 0; - outline: 0; - border: 0; - background: transparent; - color: var(--color-text); -} -#tsd-search .field label { - position: absolute; - overflow: hidden; - right: -40px; -} -#tsd-search .field input, -#tsd-search .title { - transition: opacity 0.2s; -} -#tsd-search .results { - position: absolute; - visibility: hidden; - top: 40px; - width: 100%; - margin: 0; - padding: 0; - list-style: none; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); -} -#tsd-search .results li { - padding: 0 10px; - background-color: var(--color-background); -} -#tsd-search .results li:nth-child(even) { - background-color: var(--color-panel); -} -#tsd-search .results li.state { - display: none; -} -#tsd-search .results li.current, -#tsd-search .results li:hover { - background-color: var(--color-panel-divider); -} -#tsd-search .results a { - display: block; -} -#tsd-search .results a:before { - top: 10px; -} -#tsd-search .results span.parent { - color: var(--color-text-aside); - font-weight: normal; -} -#tsd-search.has-focus { - background-color: var(--color-panel-divider); -} -#tsd-search.has-focus .field input { - top: 0; - opacity: 1; -} -#tsd-search.has-focus .title { - z-index: 0; - opacity: 0; -} -#tsd-search.has-focus .results { - visibility: visible; -} -#tsd-search.loading .results li.state.loading { - display: block; -} -#tsd-search.failure .results li.state.failure { - display: block; -} - -.tsd-signature { - margin: 0 0 1em 0; - padding: 10px; - border: 1px solid var(--color-panel-divider); - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - font-size: 14px; - overflow-x: auto; -} -.tsd-signature.tsd-kind-icon { - padding-left: 30px; -} -.tsd-signature.tsd-kind-icon:before { - top: 10px; - left: 10px; -} -.tsd-panel > .tsd-signature { - margin-left: -20px; - margin-right: -20px; - border-width: 1px 0; -} -.tsd-panel > .tsd-signature.tsd-kind-icon { - padding-left: 40px; -} -.tsd-panel > .tsd-signature.tsd-kind-icon:before { - left: 20px; -} - -.tsd-signature-symbol { - color: var(--color-text-aside); - font-weight: normal; -} - -.tsd-signature-type { - font-style: italic; - font-weight: normal; -} - -.tsd-signatures { - padding: 0; - margin: 0 0 1em 0; - border: 1px solid var(--color-panel-divider); -} -.tsd-signatures .tsd-signature { - margin: 0; - border-width: 1px 0 0 0; - transition: background-color 0.1s; -} -.tsd-signatures .tsd-signature:first-child { - border-top-width: 0; -} -.tsd-signatures .tsd-signature.current { - background-color: var(--color-panel-divider); -} -.tsd-signatures.active > .tsd-signature { - cursor: pointer; -} -.tsd-panel > .tsd-signatures { - margin-left: -20px; - margin-right: -20px; - border-width: 1px 0; -} -.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon { - padding-left: 40px; -} -.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon:before { - left: 20px; -} -.tsd-panel > a.anchor + .tsd-signatures { - border-top-width: 0; - margin-top: -20px; -} - -ul.tsd-descriptions { - position: relative; - overflow: hidden; - padding: 0; - list-style: none; -} -ul.tsd-descriptions.active > .tsd-description { - display: none; -} -ul.tsd-descriptions.active > .tsd-description.current { - display: block; -} -ul.tsd-descriptions.active > .tsd-description.fade-in { - animation: fade-in-delayed 0.3s; -} -ul.tsd-descriptions.active > .tsd-description.fade-out { - animation: fade-out-delayed 0.3s; - position: absolute; - display: block; - top: 0; - left: 0; - right: 0; - opacity: 0; - visibility: hidden; -} -ul.tsd-descriptions h4, -ul.tsd-descriptions .tsd-index-panel h3, -.tsd-index-panel ul.tsd-descriptions h3 { - font-size: 16px; - margin: 1em 0 0.5em 0; -} - -ul.tsd-parameters, -ul.tsd-type-parameters { - list-style: square; - margin: 0; - padding-left: 20px; -} -ul.tsd-parameters > li.tsd-parameter-signature, -ul.tsd-type-parameters > li.tsd-parameter-signature { - list-style: none; - margin-left: -20px; -} -ul.tsd-parameters h5, -ul.tsd-type-parameters h5 { - font-size: 16px; - margin: 1em 0 0.5em 0; -} -ul.tsd-parameters .tsd-comment, -ul.tsd-type-parameters .tsd-comment { - margin-top: -0.5em; -} - -.tsd-sources { - font-size: 14px; - color: var(--color-text-aside); - margin: 0 0 1em 0; -} -.tsd-sources a { - color: var(--color-text-aside); - text-decoration: underline; -} -.tsd-sources ul, -.tsd-sources p { - margin: 0 !important; -} -.tsd-sources ul { - list-style: none; - padding: 0; -} - -.tsd-page-toolbar { - position: fixed; - z-index: 1; - top: 0; - left: 0; - width: 100%; - height: 40px; - color: var(--color-toolbar-text); - background: var(--color-toolbar); - border-bottom: 1px solid var(--color-panel-divider); - transition: transform 0.3s linear; -} -.tsd-page-toolbar a { - color: var(--color-toolbar-text); - text-decoration: none; -} -.tsd-page-toolbar a.title { - font-weight: bold; -} -.tsd-page-toolbar a.title:hover { - text-decoration: underline; -} -.tsd-page-toolbar .table-wrap { - display: table; - width: 100%; - height: 40px; -} -.tsd-page-toolbar .table-cell { - display: table-cell; - position: relative; - white-space: nowrap; - line-height: 40px; -} -.tsd-page-toolbar .table-cell:first-child { - width: 100%; -} - -.tsd-page-toolbar--hide { - transform: translateY(-100%); -} - -.tsd-select .tsd-select-list li:before, -.tsd-select .tsd-select-label:before, -.tsd-widget:before { - content: ""; - display: inline-block; - width: 40px; - height: 40px; - margin: 0 -8px 0 0; - background-image: url(./widgets.png); - background-repeat: no-repeat; - text-indent: -1024px; - vertical-align: bottom; - filter: var(--icon-filter); -} -@media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { - .tsd-select .tsd-select-list li:before, - .tsd-select .tsd-select-label:before, - .tsd-widget:before { - background-image: url(./widgets@2x.png); - background-size: 320px 40px; - } -} - -.tsd-widget { - display: inline-block; - overflow: hidden; - opacity: 0.8; - height: 40px; - transition: opacity 0.1s, background-color 0.2s; - vertical-align: bottom; - cursor: pointer; -} -.tsd-widget:hover { - opacity: 0.9; -} -.tsd-widget.active { - opacity: 1; - background-color: var(--color-panel-divider); -} -.tsd-widget.no-caption { - width: 40px; -} -.tsd-widget.no-caption:before { - margin: 0; -} -.tsd-widget.search:before { - background-position: 0 0; -} -.tsd-widget.menu:before { - background-position: -40px 0; -} -.tsd-widget.options:before { - background-position: -80px 0; -} -.tsd-widget.options, -.tsd-widget.menu { - display: none; -} -@media (max-width: 900px) { - .tsd-widget.options, - .tsd-widget.menu { - display: inline-block; - } -} -input[type="checkbox"] + .tsd-widget:before { - background-position: -120px 0; -} -input[type="checkbox"]:checked + .tsd-widget:before { - background-position: -160px 0; -} - -.tsd-select { - position: relative; - display: inline-block; - height: 40px; - transition: opacity 0.1s, background-color 0.2s; - vertical-align: bottom; - cursor: pointer; -} -.tsd-select .tsd-select-label { - opacity: 0.6; - transition: opacity 0.2s; -} -.tsd-select .tsd-select-label:before { - background-position: -240px 0; -} -.tsd-select.active .tsd-select-label { - opacity: 0.8; -} -.tsd-select.active .tsd-select-list { - visibility: visible; - opacity: 1; - transition-delay: 0s; -} -.tsd-select .tsd-select-list { - position: absolute; - visibility: hidden; - top: 40px; - left: 0; - margin: 0; - padding: 0; - opacity: 0; - list-style: none; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); - transition: visibility 0s 0.2s, opacity 0.2s; -} -.tsd-select .tsd-select-list li { - padding: 0 20px 0 0; - background-color: var(--color-background); -} -.tsd-select .tsd-select-list li:before { - background-position: 40px 0; -} -.tsd-select .tsd-select-list li:nth-child(even) { - background-color: var(--color-panel); -} -.tsd-select .tsd-select-list li:hover { - background-color: var(--color-panel-divider); -} -.tsd-select .tsd-select-list li.selected:before { - background-position: -200px 0; -} -@media (max-width: 900px) { - .tsd-select .tsd-select-list { - top: 0; - left: auto; - right: 100%; - margin-right: -5px; - } - .tsd-select .tsd-select-label:before { - background-position: -280px 0; - } -} - -img { - max-width: 100%; -} diff --git a/solend-sdk/docs/assets/widgets.png b/solend-sdk/docs/assets/widgets.png deleted file mode 100644 index c7380532ac1b45400620011c37c4dcb7aec27a4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 480 zcmeAS@N?(olHy`uVBq!ia0y~yU~~YoH8@y+q^jrZML>b&o-U3d6^w6h1+IPUz|;DW zIZ;96kdsD>Qv^q=09&hp0GpEni<1IR%gvP3v%OR9*{MuRTKWHZyIbuBt)Ci`cU_&% z1T+i^Y)o{%281-<3TpPAUTzw5v;RY=>1rvxmPl96#kYc9hX!6V^nB|ad#(S+)}?8C zr_H+lT3B#So$T=?$(w3-{rbQ4R<@nsf$}$hwSO)A$8&`(j+wQf=Jwhb0`CvhR5DCf z^OgI)KQemrUFPH+UynC$Y~QHG%DbTVh-Skz{enNU)cV_hPu~{TD7TPZl>0&K>iuE| z7AYn$7)Jrb9GE&SfQW4q&G*@N|4cHI`VakFa5-C!ov&XD)J(qp$rJJ*9e z-sHv}#g*T7Cv048d1v~BEAzM5FztAse#q78WWC^BUCzQ U&wLp6h6BX&boFyt=akR{0G%$)mH+?% diff --git a/solend-sdk/docs/assets/widgets@2x.png b/solend-sdk/docs/assets/widgets@2x.png deleted file mode 100644 index 4bbbd57272f3b28f47527d4951ad10f950b8ad43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 855 zcmeAS@N?(olHy`uVBq!ia0y~yU}^xe12~w0Jcmn z@(X6T|9^jgLcx21{)7exgY)a>N6m2F0<`Rqr;B4q1>>88jUdw-7W`c)zLE*mq8W2H z-<&Jl_Hco5BuC5n@AbF5GD82~-e8-v=#zCyUX0F-o}8pPfAv`!GN$ff+TL<~@kgt} z62eO?_|&+>xBmM$@p|z`tIKEdpPf8%qI>4r7@jn<=eta*{3~?g(zz{Ke9zc-G^gr? z-7foa?LcS!hmbwzru}ICvbWLlW8;+l-}!^=c32!^nV`+`C*;0-*Y%l94pC;Cb3GXz zzSf%a!{gVr{Y_lVuUj+a)*Ca+!-Hu%xmP&&X-2CuANY8^i{D7Kg6qzP zXz_ps9+lN8ESH{K4`yu&b~I>N9xGlE&;2u*b?+Go!AhN?m-bxlLvtC#MzDF2kFzfHJ1W7ybqdefSqVhbOykd*Yi%EDuhs z4wF{ft^bv2+DDnKb8gj1FuvcV`M}luS>lO<^)8x>y1#R;a=-ZKwWTQQb)ioBbi;zh zD!f5V)8581to1LL7c9!l^PSC$NBPYif!_vAZhmL4)v4U)4UsrLYiH_9rmQDd?)(e5 z^pcH>qvBg*i0dus2r*mp4;zKvu=P#s-ti;2obl`NjjwoYd>e(oo#j_uyRb<7Pv^If zzZ|mGHmV)8^tbO%^>eqMw(@7(&3g{jEp-Najo7V75xI_ZHK*FA`elF{r5}E*d7+j_R diff --git a/solend-sdk/docs/classes/SolendAction.html b/solend-sdk/docs/classes/SolendAction.html deleted file mode 100644 index d81d9839..00000000 --- a/solend-sdk/docs/classes/SolendAction.html +++ /dev/null @@ -1 +0,0 @@ -SolendAction | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • SolendAction

Index

Constructors

Private constructor

  • new SolendAction(programId: PublicKey, connection: Connection, reserve: ReserveConfigType, lendingMarket: MarketConfigType, publicKey: PublicKey, obligationAddress: PublicKey, obligationAccountInfo: null | Obligation, userTokenAccountAddress: PublicKey, userCollateralAccountAddress: PublicKey, seed: string, symbol: string, positions: number, amount: string | BN, depositReserves: PublicKey[], borrowReserves: PublicKey[], hostAta?: PublicKey): SolendAction
  • Parameters

    • programId: PublicKey
    • connection: Connection
    • reserve: ReserveConfigType
    • lendingMarket: MarketConfigType
    • publicKey: PublicKey
    • obligationAddress: PublicKey
    • obligationAccountInfo: null | Obligation
    • userTokenAccountAddress: PublicKey
    • userCollateralAccountAddress: PublicKey
    • seed: string
    • symbol: string
    • positions: number
    • amount: string | BN
    • depositReserves: PublicKey[]
    • borrowReserves: PublicKey[]
    • Optional hostAta: PublicKey

    Returns SolendAction

Properties

amount

amount: BN

borrowReserves

borrowReserves: PublicKey[]

cleanupIxs

cleanupIxs: TransactionInstruction[]

connection

connection: Connection

depositReserves

depositReserves: PublicKey[]

Optional hostAta

hostAta?: PublicKey

lendingIxs

lendingIxs: TransactionInstruction[]

lendingMarket

lendingMarket: MarketConfigType

obligationAccountInfo

obligationAccountInfo: null | Obligation

obligationAddress

obligationAddress: PublicKey

Optional positions

positions?: number

postTxnIxs

postTxnIxs: TransactionInstruction[]

preTxnIxs

preTxnIxs: TransactionInstruction[]

programId

programId: PublicKey

publicKey

publicKey: PublicKey

reserve

seed

seed: string

setupIxs

setupIxs: TransactionInstruction[]

symbol

symbol: string

userCollateralAccountAddress

userCollateralAccountAddress: PublicKey

userTokenAccountAddress

userTokenAccountAddress: PublicKey

Methods

Private addAtaIxs

addBorrowIx

  • addBorrowIx(): void

addDepositIx

  • addDepositIx(): void

addDepositObligationCollateralIx

  • addDepositObligationCollateralIx(): void

addDepositReserveLiquidityIx

  • addDepositReserveLiquidityIx(): void

Private addObligationIxs

  • addObligationIxs(): Promise<void>

addRedeemReserveCollateralIx

  • addRedeemReserveCollateralIx(): void

Private addRefreshIxs

  • addRefreshIxs(): Promise<void>

addRepayIx

  • addRepayIx(): Promise<void>

addSupportIxs

addWithdrawIx

  • addWithdrawIx(): Promise<void>

getTransactions

  • getTransactions(): Promise<{ lendingTxn: null | Transaction; postLendingTxn: null | Transaction; preLendingTxn: null | Transaction }>
  • Returns Promise<{ lendingTxn: null | Transaction; postLendingTxn: null | Transaction; preLendingTxn: null | Transaction }>

Private sendSingleTransaction

  • sendSingleTransaction(txn: null | Transaction, sendTransaction: (txn: Transaction, connection: Connection) => Promise<string>): Promise<string>
  • Parameters

    • txn: null | Transaction
    • sendTransaction: (txn: Transaction, connection: Connection) => Promise<string>
        • (txn: Transaction, connection: Connection): Promise<string>
        • Parameters

          • txn: Transaction
          • connection: Connection

          Returns Promise<string>

    Returns Promise<string>

sendTransactions

  • sendTransactions(sendTransaction: (txn: Transaction, connection: Connection) => Promise<string>): Promise<string>
  • Parameters

    • sendTransaction: (txn: Transaction, connection: Connection) => Promise<string>
        • (txn: Transaction, connection: Connection): Promise<string>
        • Parameters

          • txn: Transaction
          • connection: Connection

          Returns Promise<string>

    Returns Promise<string>

Private updateWSOLAccount

  • updateWSOLAccount(action: ActionType): Promise<void>

Static buildBorrowTxns

  • buildBorrowTxns(connection: Connection, amount: string | BN, symbol: string, publicKey: PublicKey, environment?: "production" | "devnet", hostAta?: PublicKey, lendingMarketAddress?: PublicKey): Promise<SolendAction>
  • Parameters

    • connection: Connection
    • amount: string | BN
    • symbol: string
    • publicKey: PublicKey
    • environment: "production" | "devnet" = "production"
    • Optional hostAta: PublicKey
    • Optional lendingMarketAddress: PublicKey

    Returns Promise<SolendAction>

Static buildDepositObligationCollateralTxns

  • buildDepositObligationCollateralTxns(connection: Connection, amount: string | BN, symbol: string, publicKey: PublicKey, environment?: "production" | "devnet", lendingMarketAddress?: PublicKey): Promise<SolendAction>
  • Parameters

    • connection: Connection
    • amount: string | BN
    • symbol: string
    • publicKey: PublicKey
    • environment: "production" | "devnet" = "production"
    • Optional lendingMarketAddress: PublicKey

    Returns Promise<SolendAction>

Static buildDepositReserveLiquidityTxns

  • buildDepositReserveLiquidityTxns(connection: Connection, amount: string | BN, symbol: string, publicKey: PublicKey, environment?: "production" | "devnet", lendingMarketAddress?: PublicKey): Promise<SolendAction>
  • Parameters

    • connection: Connection
    • amount: string | BN
    • symbol: string
    • publicKey: PublicKey
    • environment: "production" | "devnet" = "production"
    • Optional lendingMarketAddress: PublicKey

    Returns Promise<SolendAction>

Static buildDepositTxns

  • buildDepositTxns(connection: Connection, amount: string | BN, symbol: string, publicKey: PublicKey, environment?: "production" | "devnet", lendingMarketAddress?: PublicKey): Promise<SolendAction>
  • Parameters

    • connection: Connection
    • amount: string | BN
    • symbol: string
    • publicKey: PublicKey
    • environment: "production" | "devnet" = "production"
    • Optional lendingMarketAddress: PublicKey

    Returns Promise<SolendAction>

Static buildRedeemReserveCollateralTxns

  • buildRedeemReserveCollateralTxns(connection: Connection, amount: string | BN, symbol: string, publicKey: PublicKey, environment?: "production" | "devnet", lendingMarketAddress?: PublicKey): Promise<SolendAction>
  • Parameters

    • connection: Connection
    • amount: string | BN
    • symbol: string
    • publicKey: PublicKey
    • environment: "production" | "devnet" = "production"
    • Optional lendingMarketAddress: PublicKey

    Returns Promise<SolendAction>

Static buildRepayTxns

  • buildRepayTxns(connection: Connection, amount: string | BN, symbol: string, publicKey: PublicKey, environment?: "production" | "devnet", lendingMarketAddress?: PublicKey): Promise<SolendAction>
  • Parameters

    • connection: Connection
    • amount: string | BN
    • symbol: string
    • publicKey: PublicKey
    • environment: "production" | "devnet" = "production"
    • Optional lendingMarketAddress: PublicKey

    Returns Promise<SolendAction>

Static buildWithdrawTxns

  • buildWithdrawTxns(connection: Connection, amount: string | BN, symbol: string, publicKey: PublicKey, environment?: "production" | "devnet", lendingMarketAddress?: PublicKey): Promise<SolendAction>
  • Parameters

    • connection: Connection
    • amount: string | BN
    • symbol: string
    • publicKey: PublicKey
    • environment: "production" | "devnet" = "production"
    • Optional lendingMarketAddress: PublicKey

    Returns Promise<SolendAction>

Static initialize

  • initialize(action: ActionType, amount: string | BN, symbol: string, publicKey: PublicKey, connection: Connection, environment?: "production" | "devnet", lendingMarketAddress?: PublicKey, hostAta?: PublicKey): Promise<SolendAction>
  • Parameters

    • action: ActionType
    • amount: string | BN
    • symbol: string
    • publicKey: PublicKey
    • connection: Connection
    • environment: "production" | "devnet" = "production"
    • Optional lendingMarketAddress: PublicKey
    • Optional hostAta: PublicKey

    Returns Promise<SolendAction>

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/classes/SolendClaim.html b/solend-sdk/docs/classes/SolendClaim.html deleted file mode 100644 index 377b7f0c..00000000 --- a/solend-sdk/docs/classes/SolendClaim.html +++ /dev/null @@ -1 +0,0 @@ -SolendClaim | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • SolendClaim

Index

Constructors

constructor

Properties

metadata

provider

provider: AnchorProvider

Methods

claim

  • claim(): Promise<string>

getClaimIxs

  • getClaimIxs(): Promise<TransactionInstruction[][]>

getExerciseIxs

  • getExerciseIxs(amount: number): Promise<any[][]>

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/classes/SolendMarket.html b/solend-sdk/docs/classes/SolendMarket.html deleted file mode 100644 index 5622d70f..00000000 --- a/solend-sdk/docs/classes/SolendMarket.html +++ /dev/null @@ -1 +0,0 @@ -SolendMarket | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • SolendMarket

Index

Constructors

Private constructor

Properties

config

Private connection

connection: Connection

programId

programId: PublicKey

reserves

reserves: SolendReserve[]

rewardsData

rewardsData: null | RewardsDataType

Methods

fetchObligationByWallet

Private getLatestRewardRate

  • getLatestRewardRate(rewardRates: { beginningSlot: number; name?: string; rewardRate: string }[], slot: number): { beginningSlot: number; name?: string; rewardRate: string }
  • Parameters

    • rewardRates: { beginningSlot: number; name?: string; rewardRate: string }[]
    • slot: number

    Returns { beginningSlot: number; name?: string; rewardRate: string }

    • beginningSlot: number
    • Optional name?: string
    • rewardRate: string

loadAll

  • loadAll(): Promise<void>

Private loadExternalRewardData

  • loadExternalRewardData(): Promise<({ lastSlot: number; rewardRates: { beginningSlot: number; name?: string; rewardRate: string }[]; rewardsPerShare: string; totalBalance: string } & { reserveID: string; rewardMint: string; rewardSymbol: string; side: "borrow" | "supply" })[]>
  • Returns Promise<({ lastSlot: number; rewardRates: { beginningSlot: number; name?: string; rewardRate: string }[]; rewardsPerShare: string; totalBalance: string } & { reserveID: string; rewardMint: string; rewardSymbol: string; side: "borrow" | "supply" })[]>

Private loadPriceData

  • loadPriceData(symbols: string[]): Promise<{}>

loadReserves

  • loadReserves(): Promise<void>

loadRewards

  • loadRewards(): Promise<void>

refreshAll

  • refreshAll(): Promise<void>

Static initialize

  • initialize(connection: Connection, environment?: "production" | "devnet" | "beta", marketAddress?: string): Promise<SolendMarket>
  • Parameters

    • connection: Connection
    • environment: "production" | "devnet" | "beta" = "production"
    • Optional marketAddress: string

    Returns Promise<SolendMarket>

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/classes/SolendObligation.html b/solend-sdk/docs/classes/SolendObligation.html deleted file mode 100644 index dceb52bb..00000000 --- a/solend-sdk/docs/classes/SolendObligation.html +++ /dev/null @@ -1 +0,0 @@ -SolendObligation | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • SolendObligation

Index

Constructors

constructor

Properties

borrows

borrows: Position[]

deposits

deposits: Position[]

obligationAddress

obligationAddress: PublicKey

obligationStats

obligationStats: ObligationStats

walletAddress

walletAddress: PublicKey

Methods

Private calculatePositions

  • calculatePositions(obligation: Obligation, reserves: SolendReserve[]): { borrows: { amount: BN; mintAddress: string }[]; deposits: { amount: BN; mintAddress: string }[]; stats: { borrowLimit: number; borrowUtilization: number; liquidationThreshold: number; netAccountValue: number; positions: number; userTotalBorrow: number; userTotalDeposit: number } }
  • Parameters

    Returns { borrows: { amount: BN; mintAddress: string }[]; deposits: { amount: BN; mintAddress: string }[]; stats: { borrowLimit: number; borrowUtilization: number; liquidationThreshold: number; netAccountValue: number; positions: number; userTotalBorrow: number; userTotalDeposit: number } }

    • borrows: { amount: BN; mintAddress: string }[]
    • deposits: { amount: BN; mintAddress: string }[]
    • stats: { borrowLimit: number; borrowUtilization: number; liquidationThreshold: number; netAccountValue: number; positions: number; userTotalBorrow: number; userTotalDeposit: number }
      • borrowLimit: number
      • borrowUtilization: number
      • liquidationThreshold: number
      • netAccountValue: number
      • positions: number
      • userTotalBorrow: number
      • userTotalDeposit: number

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/classes/SolendReserve.html b/solend-sdk/docs/classes/SolendReserve.html deleted file mode 100644 index ecac6a87..00000000 --- a/solend-sdk/docs/classes/SolendReserve.html +++ /dev/null @@ -1 +0,0 @@ -SolendReserve | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • SolendReserve

Index

Constructors

constructor

Properties

Private buffer

buffer: null | AccountInfo<Buffer>

config

Private connection

connection: Connection

Private rewardsData

rewardsData: null | RewardsDataType

stats

stats: null | ReserveDataType

Methods

Private calculateBorrowAPR

  • calculateBorrowAPR(reserve: Reserve): number

Private calculateBorrowAPY

  • calculateBorrowAPY(reserve: Reserve): number

calculateRewardAPY

  • calculateRewardAPY(rewardRate: string, poolSize: string, rewardPrice: number, tokenPrice: number, decimals: number): BigNumber
  • Parameters

    • rewardRate: string
    • poolSize: string
    • rewardPrice: number
    • tokenPrice: number
    • decimals: number

    Returns BigNumber

Private calculateSupplyAPR

  • calculateSupplyAPR(reserve: Reserve): number

Private calculateSupplyAPY

  • calculateSupplyAPY(reserve: Reserve): number

Private calculateUtilizationRatio

  • calculateUtilizationRatio(reserve: Reserve): number

Private formatReserveData

load

setBuffer

  • setBuffer(buffer: null | AccountInfo<Buffer>): void

totalBorrowAPY

  • totalBorrowAPY(): { interestAPY: number; rewards: { apy: number; price: number; rewardMint: undefined | string; rewardSymbol: string }[]; totalAPY: number }
  • Returns { interestAPY: number; rewards: { apy: number; price: number; rewardMint: undefined | string; rewardSymbol: string }[]; totalAPY: number }

    • interestAPY: number
    • rewards: { apy: number; price: number; rewardMint: undefined | string; rewardSymbol: string }[]
    • totalAPY: number

totalSupplyAPY

  • totalSupplyAPY(): { interestAPY: number; rewards: { apy: number; price: number; rewardMint: undefined | string; rewardSymbol: string }[]; totalAPY: number }
  • Returns { interestAPY: number; rewards: { apy: number; price: number; rewardMint: undefined | string; rewardSymbol: string }[]; totalAPY: number }

    • interestAPY: number
    • rewards: { apy: number; price: number; rewardMint: undefined | string; rewardSymbol: string }[]
    • totalAPY: number

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/classes/SolendWallet.html b/solend-sdk/docs/classes/SolendWallet.html deleted file mode 100644 index c09eba2b..00000000 --- a/solend-sdk/docs/classes/SolendWallet.html +++ /dev/null @@ -1 +0,0 @@ -SolendWallet | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • SolendWallet

Index

Constructors

Private constructor

  • new SolendWallet(wallet: Wallet, connection: Connection, environment: string): SolendWallet

Properties

config

config: null | ConfigType

programId

programId: PublicKey

provider

provider: AnchorProvider

rewards

rewards: {}

Type declaration

Methods

getClaimAllIxs

  • getClaimAllIxs(): Promise<TransactionInstruction[][]>

loadRewards

  • loadRewards(): Promise<void>

Static initialize

  • initialize(wallet: Wallet, connection: Connection, environment?: "production" | "devnet"): Promise<SolendWallet>

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/index.html b/solend-sdk/docs/index.html deleted file mode 100644 index 4c7a52ec..00000000 --- a/solend-sdk/docs/index.html +++ /dev/null @@ -1,66 +0,0 @@ -@solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

@solendprotocol/solend-sdk

Note: The Solend TS is in early stages of release and is subject to changes and improvements. To report any bugs or feature requests, the #dev-support channel in the Solend Discord is the fastest way to get a response.

- - -

Installation

-
-
yarn add @solendprotocol/solend-sdk
-
- - -

Solend Typescript SDK

-
-

This is the Solend Typescript to interact with http://solend.fi.

-

For the full set of developer tools, check out the brand new

-

-Screen Shot 2022-01-09 at 5 54 30 PM

-

Latest API documentation

- - -

Basic usage

-
- - -

Reading data

-
-
// There are three levels of data you can request (and cache) about the lending market.
// 1. Initalize market with parameters and metadata
const market = await SolendMarket.initialize(
connection,
"production", // optional environment argument
new PublicKey("7RCz8wb6WXxUhAigok9ttgrVgDFFFbibcirECzWSBauM") // optional market address (TURBO SOL). Defaults to 'Main' market
);
console.log(market.reserves.map((reserve) => reserve.config.loanToValueRatio));

// 2. Read on-chain accounts for reserve data and cache
await market.loadReserves();

const usdcReserve = market.reserves.find((res) => res.config.symbol === "USDC");
console.log(usdcReserve.stats.totalDepositsWads.toString());

// Read Solend liquidity mining stats
await market.loadRewards();
console.log(reserve.stats.totalSupplyAPY().rewards); // {apy: 0.07, rewardMint: "SLND...

// Refresh all cached data
market.refreshAll();

const obligation = market.fetchObligationByWallet("[WALLET_ID]");
console.log(obligation.stats.borrowLimit); -
- - -

Perform lending action

-
-
// Create one or more (may contain setup accuont creation txns) to perform a Solend action.
const solendAction = await SolendAction.buildDepositTxns(
connection,
amountBase,
symbol,
publicKey,
"production",
new PublicKey("7RCz8wb6WXxUhAigok9ttgrVgDFFFbibcirECzWSBauM") // optional market address (TURBO SOL). Defaults to 'Main' market
);

await solendAction.sendTransactions(sendTransaction); // sendTransaction from wallet adapter or custom -
- - -

Manage user rewards

-
-
const { wallet } = useWallet();
// const wallet = anchor.Wallet.local();

const solendWallet = await SolendWallet.initialize(wallet, connection);

// Claim rewards
const mndeRewards = solendWallet.rewards["MNDEFzGvMt87ueuHvVU9VcTqsAP5b3fTGPsHuuPA5ey"];
console.log(
"Claimable rewards:",
mndeRewards.claimableAmount / 10 ** mndeRewards.decimals
);

const sig1 = await mndeRewards.rewardClaims
.find((claim) => !claim.metadata.claimedAt)
?.claim();

// Exercise options (after claiming)
const slndOptionClaim = solendWallet.rewards["SLND_OPTION"].rewardClaims.find(
(claim) => claim.metadata.optionMarket.userBalance
);

const sig2 = await slndOptionClaim.exercise(
slndOptionClaim.optionMarket.userBalance
);

const [setupIxs, claimIxs] = await solendWallet.getClaimIxs();
// Claim all claimable rewards -
- - -

Upcoming

-
-
    -
  • Better support for obligation based actions (Fully repay borrow, max borrow up to borrow limit, etc.)
  • -
  • React hook API
  • -
- - -

FAQ

-
- - -

Interest rates do not match what's show on solend.fi

-
-

The Solend SDK pulls certain price data from cached sources from our backend api that's different from solend.fi's sources. Divergences should be very small and these price sources will soon be consolidated.

- - -

Multiple transactions being created for a lending action

-
-

Due to transaction size limits of Solana, a user with a high amount of positions might need their lending action to be broken into multiple transactions. Usually this involves creating or closing associated token accounts for up to 3 transactions.

- - -

Values are weird on devnet

-
-

Partner rewards and liquidity mining are not present on devnet.

-

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/LastUpdate.html b/solend-sdk/docs/interfaces/LastUpdate.html deleted file mode 100644 index 1c1db38b..00000000 --- a/solend-sdk/docs/interfaces/LastUpdate.html +++ /dev/null @@ -1 +0,0 @@ -LastUpdate | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • LastUpdate

Index

Properties

Properties

slot

slot: BN

stale

stale: boolean

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/LendingMarket.html b/solend-sdk/docs/interfaces/LendingMarket.html deleted file mode 100644 index 93cdff59..00000000 --- a/solend-sdk/docs/interfaces/LendingMarket.html +++ /dev/null @@ -1 +0,0 @@ -LendingMarket | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • LendingMarket

Index

Properties

isInitialized

isInitialized: boolean

quoteTokenMint

quoteTokenMint: PublicKey

tokenProgramId

tokenProgramId: PublicKey

version

version: number

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/Obligation.html b/solend-sdk/docs/interfaces/Obligation.html deleted file mode 100644 index cadc012f..00000000 --- a/solend-sdk/docs/interfaces/Obligation.html +++ /dev/null @@ -1 +0,0 @@ -Obligation | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • Obligation

Index

Properties

allowedBorrowValue

allowedBorrowValue: BN

borrowedValue

borrowedValue: BN

borrows

depositedValue

depositedValue: BN

deposits

lastUpdate

lastUpdate: LastUpdate

lendingMarket

lendingMarket: PublicKey

owner

owner: PublicKey

unhealthyBorrowValue

unhealthyBorrowValue: BN

version

version: number

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/ObligationCollateral.html b/solend-sdk/docs/interfaces/ObligationCollateral.html deleted file mode 100644 index 3d8e772b..00000000 --- a/solend-sdk/docs/interfaces/ObligationCollateral.html +++ /dev/null @@ -1 +0,0 @@ -ObligationCollateral | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • ObligationCollateral

Index

Properties

depositReserve

depositReserve: PublicKey

depositedAmount

depositedAmount: BN

marketValue

marketValue: BN

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/ObligationLiquidity.html b/solend-sdk/docs/interfaces/ObligationLiquidity.html deleted file mode 100644 index 8ef9c682..00000000 --- a/solend-sdk/docs/interfaces/ObligationLiquidity.html +++ /dev/null @@ -1 +0,0 @@ -ObligationLiquidity | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • ObligationLiquidity

Index

Properties

borrowReserve

borrowReserve: PublicKey

borrowedAmountWads

borrowedAmountWads: BN

cumulativeBorrowRateWads

cumulativeBorrowRateWads: BN

marketValue

marketValue: BN

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/ProtoObligation.html b/solend-sdk/docs/interfaces/ProtoObligation.html deleted file mode 100644 index 547ff7a1..00000000 --- a/solend-sdk/docs/interfaces/ProtoObligation.html +++ /dev/null @@ -1 +0,0 @@ -ProtoObligation | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • ProtoObligation

Index

Properties

allowedBorrowValue

allowedBorrowValue: BN

borrowedValue

borrowedValue: BN

borrowsLen

borrowsLen: number

dataFlat

dataFlat: Buffer

depositedValue

depositedValue: BN

depositsLen

depositsLen: number

lastUpdate

lastUpdate: LastUpdate

lendingMarket

lendingMarket: PublicKey

owner

owner: PublicKey

unhealthyBorrowValue

unhealthyBorrowValue: BN

version

version: number

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/Reserve.html b/solend-sdk/docs/interfaces/Reserve.html deleted file mode 100644 index 0cdc3fc5..00000000 --- a/solend-sdk/docs/interfaces/Reserve.html +++ /dev/null @@ -1 +0,0 @@ -Reserve | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • Reserve

Index

Properties

collateral

collateral: ReserveCollateral

config

lastUpdate

lastUpdate: LastUpdate

lendingMarket

lendingMarket: PublicKey

liquidity

liquidity: ReserveLiquidity

version

version: number

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/ReserveCollateral.html b/solend-sdk/docs/interfaces/ReserveCollateral.html deleted file mode 100644 index bed54450..00000000 --- a/solend-sdk/docs/interfaces/ReserveCollateral.html +++ /dev/null @@ -1 +0,0 @@ -ReserveCollateral | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • ReserveCollateral

Index

Properties

mintPubkey

mintPubkey: PublicKey

mintTotalSupply

mintTotalSupply: BN

supplyPubkey

supplyPubkey: PublicKey

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/ReserveConfig.html b/solend-sdk/docs/interfaces/ReserveConfig.html deleted file mode 100644 index 3ef7e536..00000000 --- a/solend-sdk/docs/interfaces/ReserveConfig.html +++ /dev/null @@ -1 +0,0 @@ -ReserveConfig | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • ReserveConfig

Index

Properties

borrowLimit

borrowLimit: BN

depositLimit

depositLimit: BN

Optional feeReceiver

feeReceiver?: PublicKey

fees

fees: { borrowFeeWad: BN; flashLoanFeeWad: BN; hostFeePercentage: number }

Type declaration

  • borrowFeeWad: BN
  • flashLoanFeeWad: BN
  • hostFeePercentage: number

liquidationBonus

liquidationBonus: number

liquidationThreshold

liquidationThreshold: number

loanToValueRatio

loanToValueRatio: number

maxBorrowRate

maxBorrowRate: number

minBorrowRate

minBorrowRate: number

optimalBorrowRate

optimalBorrowRate: number

optimalUtilizationRate

optimalUtilizationRate: number

protocolLiquidationFee

protocolLiquidationFee: number

protocolTakeRate

protocolTakeRate: number

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/interfaces/ReserveLiquidity.html b/solend-sdk/docs/interfaces/ReserveLiquidity.html deleted file mode 100644 index 290e6b2e..00000000 --- a/solend-sdk/docs/interfaces/ReserveLiquidity.html +++ /dev/null @@ -1 +0,0 @@ -ReserveLiquidity | @solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • ReserveLiquidity

Index

Properties

availableAmount

availableAmount: BN

borrowedAmountWads

borrowedAmountWads: BN

cumulativeBorrowRateWads

cumulativeBorrowRateWads: BN

marketPrice

marketPrice: BN

mintDecimals

mintDecimals: number

mintPubkey

mintPubkey: PublicKey

oracleOption

oracleOption: number

pythOraclePubkey

pythOraclePubkey: PublicKey

supplyPubkey

supplyPubkey: PublicKey

switchboardOraclePubkey

switchboardOraclePubkey: PublicKey

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/docs/modules.html b/solend-sdk/docs/modules.html deleted file mode 100644 index b8700c89..00000000 --- a/solend-sdk/docs/modules.html +++ /dev/null @@ -1,18 +0,0 @@ -@solendprotocol/solend-sdk
Options
All
  • Public
  • Public/Protected
  • All
Menu

@solendprotocol/solend-sdk

Index

Type aliases

ActionType

ActionType: "deposit" | "borrow" | "withdraw" | "repay" | "mint" | "redeem" | "depositCollateral"

ClaimType

ClaimType: { distributorPublicKey: string; incentivizer: string; index: number; lotNumber: number; name: string; obligationID: string; optionMarketKey: string; proof: string[]; quantity: string; root: string }

Type declaration

  • distributorPublicKey: string
  • incentivizer: string
  • index: number
  • lotNumber: number
  • name: string
  • obligationID: string
  • optionMarketKey: string
  • proof: string[]
  • quantity: string
  • root: string

ConfigType

ConfigType: MarketConfigType[]

EnrichedClaimType

EnrichedClaimType: { claimId: PublicKey; claimStatusBump: number; claimable: boolean; claimedAt: number | null; distributor: { bump: number; mint: PublicKey }; distributorATAPublicKey: PublicKey; mintAddress: string; optionMarket: (OptionMarketWithKey & { userBalance: number }) | null; quantity: string } & ClaimType

ExternalRewardStatType

ExternalRewardStatType: RewardStatType & { reserveID: string; rewardMint: string; rewardSymbol: string; side: "supply" | "borrow" }

MarketConfigType

MarketConfigType: { address: string; authorityAddress: string; creator: string; description: string; hidden: boolean; isPrimary: boolean; name: string; reserves: ReserveConfigType[] }

Type declaration

  • address: string
  • authorityAddress: string
  • creator: string
  • description: string
  • hidden: boolean
  • isPrimary: boolean
  • name: string
  • reserves: ReserveConfigType[]

ObligationStats

ObligationStats: { borrowLimit: number; borrowUtilization: number; liquidationThreshold: number; netAccountValue: number; positions: number; userTotalBorrow: number; userTotalDeposit: number }

Type declaration

  • borrowLimit: number
  • borrowUtilization: number
  • liquidationThreshold: number
  • netAccountValue: number
  • positions: number
  • userTotalBorrow: number
  • userTotalDeposit: number

Position

Position: { amount: BN; mintAddress: string }

Type declaration

  • amount: BN
  • mintAddress: string

ReserveConfigType

ReserveConfigType: { address: string; collateralMintAddress: string; collateralSupplyAddress: string; liquidityAddress: string; liquidityFeeReceiverAddress: string; liquidityToken: { coingeckoID: string; decimals: number; logo: string; mint: string; name: string; symbol: string; volume24h: number }; pythOracle: string; switchboardOracle: string; userBorrowCap: number; userSupplyCap: number }

Type declaration

  • address: string
  • collateralMintAddress: string
  • collateralSupplyAddress: string
  • liquidityAddress: string
  • liquidityFeeReceiverAddress: string
  • liquidityToken: { coingeckoID: string; decimals: number; logo: string; mint: string; name: string; symbol: string; volume24h: number }
    • coingeckoID: string
    • decimals: number
    • logo: string
    • mint: string
    • name: string
    • symbol: string
    • volume24h: number
  • pythOracle: string
  • switchboardOracle: string
  • userBorrowCap: number
  • userSupplyCap: number

ReserveDataType

ReserveDataType: { assetPriceUSD: number; borrowFeePercentage: number; borrowInterestAPY: number; cTokenExchangeRate: number; cumulativeBorrowRateWads: BN; decimals: number; depositLimit: BN; hostFeePercentage: number; liquidationBonus: number; liquidationThreshold: number; loanToValueRatio: number; maxBorrowRate: number; minBorrowRate: number; mintAddress: string; name: string; optimalBorrowRate: number; optimalUtilizationRate: number; protocolTakeRate: number; reserveBorrowLimit: BN; supplyInterestAPY: number; symbol: string; totalBorrowsWads: BN; totalDepositsWads: BN; totalLiquidityWads: BN; userDepositLimit?: number }

Type declaration

  • assetPriceUSD: number
  • borrowFeePercentage: number
  • borrowInterestAPY: number
  • cTokenExchangeRate: number
  • cumulativeBorrowRateWads: BN
  • decimals: number
  • depositLimit: BN
  • hostFeePercentage: number
  • liquidationBonus: number
  • liquidationThreshold: number
  • loanToValueRatio: number
  • maxBorrowRate: number
  • minBorrowRate: number
  • mintAddress: string
  • name: string
  • optimalBorrowRate: number
  • optimalUtilizationRate: number
  • protocolTakeRate: number
  • reserveBorrowLimit: BN
  • supplyInterestAPY: number
  • symbol: string
  • totalBorrowsWads: BN
  • totalDepositsWads: BN
  • totalLiquidityWads: BN
  • Optional userDepositLimit?: number

RewardInfoType

RewardInfoType: { price: number; rewardMint?: string; rewardRate: string; rewardSymbol: string }

Type declaration

  • price: number
  • Optional rewardMint?: string
  • rewardRate: string
  • rewardSymbol: string

RewardResponseType

RewardResponseType: { borrow: RewardStatType; supply: RewardStatType }

Type declaration

RewardStatType

RewardStatType: { lastSlot: number; rewardRates: { beginningSlot: number; name?: string; rewardRate: string }[]; rewardsPerShare: string; totalBalance: string } | null

RewardsDataType

RewardsDataType: {}

Type declaration

SolendReward

SolendReward: { claimableAmount: number; claimedAmount: number; lifetimeAmount: number; rewardClaims: SolendClaim[]; symbol: string }

Type declaration

  • claimableAmount: number
  • claimedAmount: number
  • lifetimeAmount: number
  • rewardClaims: SolendClaim[]
  • symbol: string

Variables

LENDING_MARKET_SIZE

LENDING_MARKET_SIZE: any = LendingMarketLayout.span

LastUpdateLayout

LastUpdateLayout: typeof BufferLayout.Structure = ...

LendingMarketLayout

LendingMarketLayout: typeof BufferLayout.Structure = ...

OBLIGATION_SIZE

OBLIGATION_SIZE: any = ObligationLayout.span

ObligationCollateralLayout

ObligationCollateralLayout: typeof BufferLayout.Structure = ...

ObligationLayout

ObligationLayout: typeof BufferLayout.Structure = ...

ObligationLiquidityLayout

ObligationLiquidityLayout: typeof BufferLayout.Structure = ...

POSITION_LIMIT

POSITION_LIMIT: 6 = 6

RESERVE_SIZE

RESERVE_SIZE: any = ReserveLayout.span

ReserveConfigLayout

ReserveConfigLayout: any = ...

ReserveLayout

ReserveLayout: typeof BufferLayout.Structure = ...

SLOTS_PER_YEAR

SLOTS_PER_YEAR: 63072000 = 63072000

SOLEND_BETA_PROGRAM_ID

SOLEND_BETA_PROGRAM_ID: PublicKey = ...

SOLEND_DEVNET_PROGRAM_ID

SOLEND_DEVNET_PROGRAM_ID: PublicKey = ...

SOLEND_PRODUCTION_PROGRAM_ID

SOLEND_PRODUCTION_PROGRAM_ID: PublicKey = ...

U64_MAX

U64_MAX: "18446744073709551615" = "18446744073709551615"

WAD

WAD: string = ...

WANG

WANG: string = ...

Functions

Const borrowObligationLiquidityInstruction

  • borrowObligationLiquidityInstruction(liquidityAmount: number | BN, sourceLiquidity: PublicKey, destinationLiquidity: PublicKey, borrowReserve: PublicKey, borrowReserveLiquidityFeeReceiver: PublicKey, obligation: PublicKey, lendingMarket: PublicKey, lendingMarketAuthority: PublicKey, obligationOwner: PublicKey, solendProgramAddress: PublicKey, hostFeeReceiver?: PublicKey): TransactionInstruction
  • Parameters

    • liquidityAmount: number | BN
    • sourceLiquidity: PublicKey
    • destinationLiquidity: PublicKey
    • borrowReserve: PublicKey
    • borrowReserveLiquidityFeeReceiver: PublicKey
    • obligation: PublicKey
    • lendingMarket: PublicKey
    • lendingMarketAuthority: PublicKey
    • obligationOwner: PublicKey
    • solendProgramAddress: PublicKey
    • Optional hostFeeReceiver: PublicKey

    Returns TransactionInstruction

Const depositObligationCollateralInstruction

  • depositObligationCollateralInstruction(collateralAmount: number | BN, sourceCollateral: PublicKey, destinationCollateral: PublicKey, depositReserve: PublicKey, obligation: PublicKey, lendingMarket: PublicKey, obligationOwner: PublicKey, transferAuthority: PublicKey, solendProgramAddress: PublicKey): TransactionInstruction
  • Parameters

    • collateralAmount: number | BN
    • sourceCollateral: PublicKey
    • destinationCollateral: PublicKey
    • depositReserve: PublicKey
    • obligation: PublicKey
    • lendingMarket: PublicKey
    • obligationOwner: PublicKey
    • transferAuthority: PublicKey
    • solendProgramAddress: PublicKey

    Returns TransactionInstruction

Const depositReserveLiquidityAndObligationCollateralInstruction

  • depositReserveLiquidityAndObligationCollateralInstruction(liquidityAmount: number | BN, sourceLiquidity: PublicKey, sourceCollateral: PublicKey, reserve: PublicKey, reserveLiquiditySupply: PublicKey, reserveCollateralMint: PublicKey, lendingMarket: PublicKey, lendingMarketAuthority: PublicKey, destinationCollateral: PublicKey, obligation: PublicKey, obligationOwner: PublicKey, pythOracle: PublicKey, switchboardFeedAddress: PublicKey, transferAuthority: PublicKey, solendProgramAddress: PublicKey): TransactionInstruction
  • Parameters

    • liquidityAmount: number | BN
    • sourceLiquidity: PublicKey
    • sourceCollateral: PublicKey
    • reserve: PublicKey
    • reserveLiquiditySupply: PublicKey
    • reserveCollateralMint: PublicKey
    • lendingMarket: PublicKey
    • lendingMarketAuthority: PublicKey
    • destinationCollateral: PublicKey
    • obligation: PublicKey
    • obligationOwner: PublicKey
    • pythOracle: PublicKey
    • switchboardFeedAddress: PublicKey
    • transferAuthority: PublicKey
    • solendProgramAddress: PublicKey

    Returns TransactionInstruction

Const depositReserveLiquidityInstruction

  • depositReserveLiquidityInstruction(liquidityAmount: number | BN, sourceLiquidity: PublicKey, destinationCollateral: PublicKey, reserve: PublicKey, reserveLiquiditySupply: PublicKey, reserveCollateralMint: PublicKey, lendingMarket: PublicKey, lendingMarketAuthority: PublicKey, transferAuthority: PublicKey, solendProgramAddress: PublicKey): TransactionInstruction
  • Parameters

    • liquidityAmount: number | BN
    • sourceLiquidity: PublicKey
    • destinationCollateral: PublicKey
    • reserve: PublicKey
    • reserveLiquiditySupply: PublicKey
    • reserveCollateralMint: PublicKey
    • lendingMarket: PublicKey
    • lendingMarketAuthority: PublicKey
    • transferAuthority: PublicKey
    • solendProgramAddress: PublicKey

    Returns TransactionInstruction

Const flashBorrowReserveLiquidityInstruction

  • flashBorrowReserveLiquidityInstruction(liquidityAmount: number | BN, sourceLiquidity: PublicKey, destinationLiquidity: PublicKey, reserve: PublicKey, lendingMarket: PublicKey, lendingProgramId: PublicKey): TransactionInstruction
  • Parameters

    • liquidityAmount: number | BN
    • sourceLiquidity: PublicKey
    • destinationLiquidity: PublicKey
    • reserve: PublicKey
    • lendingMarket: PublicKey
    • lendingProgramId: PublicKey

    Returns TransactionInstruction

Const flashRepayReserveLiquidityInstruction

  • flashRepayReserveLiquidityInstruction(liquidityAmount: number | BN, borrowInstructionIndex: number, sourceLiquidity: PublicKey, destinationLiquidity: PublicKey, reserveLiquidityFeeReceiver: PublicKey, hostFeeReceiver: PublicKey, reserve: PublicKey, lendingMarket: PublicKey, userTransferAuthority: PublicKey, lendingProgramId: PublicKey): TransactionInstruction
  • Parameters

    • liquidityAmount: number | BN
    • borrowInstructionIndex: number
    • sourceLiquidity: PublicKey
    • destinationLiquidity: PublicKey
    • reserveLiquidityFeeReceiver: PublicKey
    • hostFeeReceiver: PublicKey
    • reserve: PublicKey
    • lendingMarket: PublicKey
    • userTransferAuthority: PublicKey
    • lendingProgramId: PublicKey

    Returns TransactionInstruction

getProgramId

  • getProgramId(environment: string): PublicKey

Const initLendingMarketInstruction

  • initLendingMarketInstruction(owner: PublicKey, quoteCurrency: Buffer, lendingMarket: PublicKey, lendingProgramId: PublicKey, oracleProgramId: PublicKey, switchboardProgramId: PublicKey): TransactionInstruction
  • Parameters

    • owner: PublicKey
    • quoteCurrency: Buffer
    • lendingMarket: PublicKey
    • lendingProgramId: PublicKey
    • oracleProgramId: PublicKey
    • switchboardProgramId: PublicKey

    Returns TransactionInstruction

Const initObligationInstruction

  • initObligationInstruction(obligation: PublicKey, lendingMarket: PublicKey, obligationOwner: PublicKey, solendProgramAddress: PublicKey): TransactionInstruction
  • Parameters

    • obligation: PublicKey
    • lendingMarket: PublicKey
    • obligationOwner: PublicKey
    • solendProgramAddress: PublicKey

    Returns TransactionInstruction

Const initReserveInstruction

  • initReserveInstruction(liquidityAmount: number | BN, config: ReserveConfig, sourceLiquidity: PublicKey, destinationCollateral: PublicKey, reserve: PublicKey, liquidityMint: PublicKey, liquiditySupply: PublicKey, liquidityFeeReceiver: PublicKey, collateralMint: PublicKey, collateralSupply: PublicKey, pythProduct: PublicKey, pythPrice: PublicKey, switchboardFeed: PublicKey, lendingMarket: PublicKey, lendingMarketAuthority: PublicKey, lendingMarketOwner: PublicKey, transferAuthority: PublicKey, lendingProgramId: PublicKey): TransactionInstruction
  • Parameters

    • liquidityAmount: number | BN
    • config: ReserveConfig
    • sourceLiquidity: PublicKey
    • destinationCollateral: PublicKey
    • reserve: PublicKey
    • liquidityMint: PublicKey
    • liquiditySupply: PublicKey
    • liquidityFeeReceiver: PublicKey
    • collateralMint: PublicKey
    • collateralSupply: PublicKey
    • pythProduct: PublicKey
    • pythPrice: PublicKey
    • switchboardFeed: PublicKey
    • lendingMarket: PublicKey
    • lendingMarketAuthority: PublicKey
    • lendingMarketOwner: PublicKey
    • transferAuthority: PublicKey
    • lendingProgramId: PublicKey

    Returns TransactionInstruction

Const isLendingMarket

  • isLendingMarket(info: AccountInfo<Buffer>): boolean

Const isObligation

  • isObligation(info: AccountInfo<Buffer>): boolean

Const isReserve

  • isReserve(info: AccountInfo<Buffer>): boolean

obligationToString

  • obligationToString(obligation: Obligation): string

Const parseLendingMarket

  • parseLendingMarket(pubkey: PublicKey, info: AccountInfo<Buffer>): { account: { data: Buffer; executable: boolean; lamports: number; owner: PublicKey; rentEpoch?: number }; info: LendingMarket; pubkey: PublicKey }
  • Parameters

    • pubkey: PublicKey
    • info: AccountInfo<Buffer>

    Returns { account: { data: Buffer; executable: boolean; lamports: number; owner: PublicKey; rentEpoch?: number }; info: LendingMarket; pubkey: PublicKey }

    • account: { data: Buffer; executable: boolean; lamports: number; owner: PublicKey; rentEpoch?: number }
      • data: Buffer
        -

        Optional data assigned to the account

        -
      • executable: boolean
        -

        true if this account's data contains a loaded program

        -
      • lamports: number
        -

        Number of lamports assigned to the account

        -
      • owner: PublicKey
        -

        Identifier of the program that owns the account

        -
      • Optional rentEpoch?: number
        -

        Optional rent epoch infor for account

        -
    • info: LendingMarket
    • pubkey: PublicKey

Const parseObligation

  • parseObligation(pubkey: PublicKey, info: AccountInfo<Buffer>): null | { account: { data: Buffer; executable: boolean; lamports: number; owner: PublicKey; rentEpoch?: number }; info: Obligation; pubkey: PublicKey }
  • Parameters

    • pubkey: PublicKey
    • info: AccountInfo<Buffer>

    Returns null | { account: { data: Buffer; executable: boolean; lamports: number; owner: PublicKey; rentEpoch?: number }; info: Obligation; pubkey: PublicKey }

Const parseReserve

  • parseReserve(pubkey: PublicKey, info: AccountInfo<Buffer>): null | { account: { data: Buffer; executable: boolean; lamports: number; owner: PublicKey; rentEpoch?: number }; info: Reserve; pubkey: PublicKey }
  • Parameters

    • pubkey: PublicKey
    • info: AccountInfo<Buffer>

    Returns null | { account: { data: Buffer; executable: boolean; lamports: number; owner: PublicKey; rentEpoch?: number }; info: Reserve; pubkey: PublicKey }

Const redeemReserveCollateralInstruction

  • redeemReserveCollateralInstruction(collateralAmount: number | BN, sourceCollateral: PublicKey, destinationLiquidity: PublicKey, reserve: PublicKey, reserveCollateralMint: PublicKey, reserveLiquiditySupply: PublicKey, lendingMarket: PublicKey, lendingMarketAuthority: PublicKey, transferAuthority: PublicKey, solendProgramAddress: PublicKey): TransactionInstruction
  • Parameters

    • collateralAmount: number | BN
    • sourceCollateral: PublicKey
    • destinationLiquidity: PublicKey
    • reserve: PublicKey
    • reserveCollateralMint: PublicKey
    • reserveLiquiditySupply: PublicKey
    • lendingMarket: PublicKey
    • lendingMarketAuthority: PublicKey
    • transferAuthority: PublicKey
    • solendProgramAddress: PublicKey

    Returns TransactionInstruction

Const refreshObligationInstruction

  • refreshObligationInstruction(obligation: PublicKey, depositReserves: PublicKey[], borrowReserves: PublicKey[], solendProgramAddress: PublicKey): TransactionInstruction

Const refreshReserveInstruction

  • refreshReserveInstruction(reserve: PublicKey, solendProgramAddress: PublicKey, oracle?: PublicKey, switchboardFeedAddress?: PublicKey): TransactionInstruction
  • Parameters

    • reserve: PublicKey
    • solendProgramAddress: PublicKey
    • Optional oracle: PublicKey
    • Optional switchboardFeedAddress: PublicKey

    Returns TransactionInstruction

Const repayObligationLiquidityInstruction

  • repayObligationLiquidityInstruction(liquidityAmount: number | BN, sourceLiquidity: PublicKey, destinationLiquidity: PublicKey, repayReserve: PublicKey, obligation: PublicKey, lendingMarket: PublicKey, transferAuthority: PublicKey, solendProgramAddress: PublicKey): TransactionInstruction
  • Parameters

    • liquidityAmount: number | BN
    • sourceLiquidity: PublicKey
    • destinationLiquidity: PublicKey
    • repayReserve: PublicKey
    • obligation: PublicKey
    • lendingMarket: PublicKey
    • transferAuthority: PublicKey
    • solendProgramAddress: PublicKey

    Returns TransactionInstruction

reserveToString

  • reserveToString(reserve: Reserve): string

syncNative

  • syncNative(account: PublicKey, programId?: PublicKey): TransactionInstruction
  • -

    Construct a SyncNative instruction

    -

    Parameters

    • account: PublicKey
      -

      Native account to sync lamports from

      -
    • programId: PublicKey = TOKEN_PROGRAM_ID
      -

      SPL Token program account

      -

    Returns TransactionInstruction

    Instruction to add to a transaction

    -

Const updateReserveConfig

  • updateReserveConfig(reserve: PublicKey, lendingMarket: PublicKey, lendingMarketAuthority: PublicKey, lendingMarketOwner: PublicKey, pythProduct: PublicKey, pythPrice: PublicKey, switchboardOracle: PublicKey, reserveConfig: ReserveConfig, solendProgramAddress: PublicKey): TransactionInstruction
  • Parameters

    • reserve: PublicKey
    • lendingMarket: PublicKey
    • lendingMarketAuthority: PublicKey
    • lendingMarketOwner: PublicKey
    • pythProduct: PublicKey
    • pythPrice: PublicKey
    • switchboardOracle: PublicKey
    • reserveConfig: ReserveConfig
    • solendProgramAddress: PublicKey

    Returns TransactionInstruction

Const withdrawObligationCollateralAndRedeemReserveLiquidity

  • withdrawObligationCollateralAndRedeemReserveLiquidity(collateralAmount: number | BN, sourceCollateral: PublicKey, destinationCollateral: PublicKey, withdrawReserve: PublicKey, obligation: PublicKey, lendingMarket: PublicKey, lendingMarketAuthority: PublicKey, destinationLiquidity: PublicKey, reserveCollateralMint: PublicKey, reserveLiquiditySupply: PublicKey, obligationOwner: PublicKey, transferAuthority: PublicKey, solendProgramAddress: PublicKey): TransactionInstruction
  • Parameters

    • collateralAmount: number | BN
    • sourceCollateral: PublicKey
    • destinationCollateral: PublicKey
    • withdrawReserve: PublicKey
    • obligation: PublicKey
    • lendingMarket: PublicKey
    • lendingMarketAuthority: PublicKey
    • destinationLiquidity: PublicKey
    • reserveCollateralMint: PublicKey
    • reserveLiquiditySupply: PublicKey
    • obligationOwner: PublicKey
    • transferAuthority: PublicKey
    • solendProgramAddress: PublicKey

    Returns TransactionInstruction

Const withdrawObligationCollateralInstruction

  • withdrawObligationCollateralInstruction(collateralAmount: number | BN, sourceCollateral: PublicKey, destinationCollateral: PublicKey, withdrawReserve: PublicKey, obligation: PublicKey, lendingMarket: PublicKey, lendingMarketAuthority: PublicKey, obligationOwner: PublicKey, solendProgramAddress: PublicKey): TransactionInstruction
  • Parameters

    • collateralAmount: number | BN
    • sourceCollateral: PublicKey
    • destinationCollateral: PublicKey
    • withdrawReserve: PublicKey
    • obligation: PublicKey
    • lendingMarket: PublicKey
    • lendingMarketAuthority: PublicKey
    • obligationOwner: PublicKey
    • solendProgramAddress: PublicKey

    Returns TransactionInstruction

Legend

  • Constructor
  • Property
  • Method
  • Private property
  • Private method
  • Property
  • Static method

Settings

Theme

Generated using TypeDoc

\ No newline at end of file diff --git a/solend-sdk/package.json b/solend-sdk/package.json index 75842807..6db96b64 100644 --- a/solend-sdk/package.json +++ b/solend-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solendprotocol/solend-sdk", - "version": "0.8.8", + "version": "1.0.0", "private": true, "main": "src/index.ts", "module": "src/index.ts", @@ -10,44 +10,32 @@ ], "license": "MIT", "scripts": { - "docs": "typedoc", "prepublish": "yarn build", "build": "rm -rf dist/; tsc", - "test": "yarn jest", "watch": "tsc --watch", - "coverage": "jest --coverage", "lint": "prettier --write .; prettier --check .;eslint .", "release": "yarn build; ts-node ./prepublish.ts; yarn --cwd ./dist publish" }, "dependencies": { - "@marinade.finance/marinade-ts-sdk": "^3.1.1", - "@mithraic-labs/psy-american": "^0.2.1", "@project-serum/anchor": "^0.24.2", "@pythnetwork/client": "^2.5.1", "@solana/buffer-layout": "^4.0.0", "@solana/spl-token": "^0.3.6", "@solana/web3.js": "^1.78.7", - "@solflare-wallet/utl-sdk": "^1.4.0", "@switchboard-xyz/sbv2-lite": "^0.2.4", - "@types/bn.js": "^5.1.1", "axios": "^0.24.0", "bignumber.js": "^9.0.2", "bn.js": "^5.2.0", "buffer": "^6.0.3", "buffer-layout": "^1.2.0", "fzstd": "^0.1.0", - "hot-shots": "^9.3.0", "isomorphic-fetch": "^3.0.0", "jsbi": "^4.3.0", "typedoc-plugin-cname": "^1.0.1" }, "devDependencies": { - "@jup-ag/core": "^2.0.0-beta.3", - "@orca-so/sdk": "^1.2.25", - "@types/bs58": "^4.0.1", + "@types/bn.js": "^5.1.1", "@types/jest": "^29.2.3", - "@types/node": "^20.8.6", - "@types/node-fetch": "^2.6.2", "@typescript-eslint/eslint-plugin": "^6.7.4", "@typescript-eslint/parser": "^6.7.4", "eslint": "^8.50.0", @@ -56,12 +44,9 @@ "eslint-config-prettier": "^8.3.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-react": "^7.27.1", - "jest": "^29.3.1", - "jest-fetch-mock": "^3.0.3", "prettier": "^2.5.1", "ts-jest": "^28.0.7", "ts-node": "^10.9.1", - "typedoc": "^0.22.10", "typescript": "^4.5.2" } } diff --git a/solend-sdk/src/classes/action.ts b/solend-sdk/src/classes/action.ts deleted file mode 100644 index c845e2fc..00000000 --- a/solend-sdk/src/classes/action.ts +++ /dev/null @@ -1,912 +0,0 @@ -import { - Connection, - PublicKey, - SystemProgram, - Transaction, - TransactionInstruction, - TransactionSignature, -} from "@solana/web3.js"; -import { - NATIVE_MINT, - getAssociatedTokenAddress, - createAssociatedTokenAccountInstruction, - getMinimumBalanceForRentExemptAccount, - createCloseAccountInstruction, -} from "@solana/spl-token"; -import BN from "bn.js"; -import BigNumber from "bignumber.js"; -import axios from "axios"; -import { - Obligation, - OBLIGATION_SIZE, - parseObligation, -} from "../state/obligation"; -import { - depositReserveLiquidityAndObligationCollateralInstruction, - depositReserveLiquidityInstruction, - redeemReserveCollateralInstruction, - repayObligationLiquidityInstruction, - withdrawObligationCollateralAndRedeemReserveLiquidity, - refreshReserveInstruction, - initObligationInstruction, - borrowObligationLiquidityInstruction, - refreshObligationInstruction, - syncNative, - depositObligationCollateralInstruction, -} from "../instructions"; -import { U64_MAX, WAD, getProgramId } from "./constants"; -import { parseReserve } from "../state/reserve"; -import { ReserveConfigType, MarketConfigType, ConfigType } from "./shared"; -import { POSITION_LIMIT } from "../core/constants"; -import { ActionType } from "../core"; - -const API_ENDPOINT = "https://api.solend.fi"; - -const SOL_PADDING_FOR_INTEREST = "1000000"; - -function getTokenInfo(symbol: string, solendInfo: MarketConfigType) { - const tokenInfo = solendInfo.reserves.find( - (reserve) => reserve.liquidityToken.symbol === symbol - ); - if (!tokenInfo) { - throw new Error(`Could not find ${symbol} in ASSETS`); - } - return tokenInfo; -} - -export class SolendAction { - programId: PublicKey; - - connection: Connection; - - reserve: ReserveConfigType; - - lendingMarket: MarketConfigType; - - publicKey: PublicKey; - - obligationAddress: PublicKey; - - obligationAccountInfo: Obligation | null; - - userTokenAccountAddress: PublicKey; - - userCollateralAccountAddress: PublicKey; - - seed: string; - - symbol: string; - - positions?: number; - - amount: BN; - - hostAta?: PublicKey; - - setupIxs: Array; - - lendingIxs: Array; - - cleanupIxs: Array; - - preTxnIxs: Array; - - postTxnIxs: Array; - - depositReserves: Array; - - borrowReserves: Array; - - private constructor( - programId: PublicKey, - connection: Connection, - reserve: ReserveConfigType, - lendingMarket: MarketConfigType, - publicKey: PublicKey, - obligationAddress: PublicKey, - obligationAccountInfo: Obligation | null, - userTokenAccountAddress: PublicKey, - userCollateralAccountAddress: PublicKey, - seed: string, - symbol: string, - positions: number, - amount: string | BN, - depositReserves: Array, - borrowReserves: Array, - hostAta?: PublicKey - ) { - this.programId = programId; - this.connection = connection; - this.publicKey = publicKey; - this.amount = new BN(amount); - this.symbol = symbol; - this.positions = positions; - this.hostAta = hostAta; - this.obligationAccountInfo = obligationAccountInfo; - this.lendingMarket = lendingMarket; - this.seed = seed; - this.reserve = reserve; - this.obligationAddress = obligationAddress; - this.userTokenAccountAddress = userTokenAccountAddress; - this.userCollateralAccountAddress = userCollateralAccountAddress; - this.setupIxs = []; - this.lendingIxs = []; - this.cleanupIxs = []; - this.preTxnIxs = []; - this.postTxnIxs = []; - this.depositReserves = depositReserves; - this.borrowReserves = borrowReserves; - } - - static async initialize( - action: ActionType, - amount: string | BN, - symbol: string, - publicKey: PublicKey, - connection: Connection, - environment: "production" | "devnet" = "production", - lendingMarketAddress?: PublicKey, - hostAta?: PublicKey - ) { - const solendInfo = (await ( - await axios.get( - `${API_ENDPOINT}/v1/markets/configs?scope=all&deployment=${environment}` - ) - ).data) as ConfigType; - - let lendingMarket: MarketConfigType | undefined; - if (lendingMarketAddress) { - lendingMarket = solendInfo.find( - (market) => market.address == lendingMarketAddress.toBase58() - ); - if (!lendingMarket) { - throw `market address not found: ${lendingMarketAddress}`; - } - } else { - lendingMarket = - solendInfo.find((market) => market.isPrimary) ?? solendInfo[0]; - } - - const seed = lendingMarket.address.slice(0, 32); - - const programId = getProgramId(environment); - - const obligationAddress = await PublicKey.createWithSeed( - publicKey, - seed, - programId - ); - - const reserve = lendingMarket.reserves.find( - (res) => res.liquidityToken.symbol === symbol - ); - if (!reserve) { - throw new Error(`Could not find asset ${symbol} in reserves`); - } - - const obligationAccountInfo = await connection.getAccountInfo( - obligationAddress - ); - - let obligationDetails = null; - const depositReserves: Array = []; - const borrowReserves: Array = []; - - if (obligationAccountInfo) { - obligationDetails = parseObligation( - PublicKey.default, - obligationAccountInfo - )!.info; - - obligationDetails.deposits.forEach((deposit) => { - depositReserves.push(deposit.depositReserve); - }); - - obligationDetails.borrows.forEach((borrow) => { - borrowReserves.push(borrow.borrowReserve); - }); - } - - // Union of addresses - const distinctReserveCount = - [ - ...Array.from( - new Set([ - ...borrowReserves.map((e) => e.toBase58()), - ...(action === "borrow" ? [reserve.address] : []), - ]) - ), - ].length + - [ - ...Array.from( - new Set([ - ...depositReserves.map((e) => e.toBase58()), - ...(action === "deposit" ? [reserve.address] : []), - ]) - ), - ].length; - - if (distinctReserveCount > POSITION_LIMIT) { - throw Error( - `Obligation already has max number of positions: ${POSITION_LIMIT}` - ); - } - - const tokenInfo = getTokenInfo(symbol, lendingMarket); - const userTokenAccountAddress = await getAssociatedTokenAddress( - new PublicKey(tokenInfo.liquidityToken.mint), - publicKey, - true - ); - const userCollateralAccountAddress = await getAssociatedTokenAddress( - new PublicKey(reserve.collateralMintAddress), - publicKey, - true - ); - - return new SolendAction( - programId, - connection, - reserve, - lendingMarket, - publicKey, - obligationAddress, - obligationDetails, - userTokenAccountAddress, - userCollateralAccountAddress, - seed, - symbol, - distinctReserveCount, - amount, - depositReserves, - borrowReserves, - hostAta - ); - } - - static async buildDepositTxns( - connection: Connection, - amount: string | BN, - symbol: string, - publicKey: PublicKey, - environment: "production" | "devnet" = "production", - lendingMarketAddress?: PublicKey - ) { - const axn = await SolendAction.initialize( - "deposit", - amount, - symbol, - publicKey, - connection, - environment, - lendingMarketAddress - ); - - await axn.addSupportIxs("deposit"); - await axn.addDepositIx(); - - return axn; - } - - static async buildBorrowTxns( - connection: Connection, - amount: string | BN, - symbol: string, - publicKey: PublicKey, - environment: "production" | "devnet" = "production", - hostAta?: PublicKey, - lendingMarketAddress?: PublicKey - ) { - const axn = await SolendAction.initialize( - "borrow", - amount, - symbol, - publicKey, - connection, - environment, - lendingMarketAddress, - hostAta - ); - - await axn.addSupportIxs("borrow"); - await axn.addBorrowIx(); - - return axn; - } - static async buildDepositReserveLiquidityTxns( - connection: Connection, - amount: string | BN, - symbol: string, - publicKey: PublicKey, - environment: "production" | "devnet" = "production", - lendingMarketAddress?: PublicKey - ) { - const axn = await SolendAction.initialize( - "mint", - amount, - symbol, - publicKey, - connection, - environment, - lendingMarketAddress - ); - await axn.addSupportIxs("mint"); - await axn.addDepositReserveLiquidityIx(); - return axn; - } - - static async buildRedeemReserveCollateralTxns( - connection: Connection, - amount: string | BN, - symbol: string, - publicKey: PublicKey, - environment: "production" | "devnet" = "production", - lendingMarketAddress?: PublicKey - ) { - const axn = await SolendAction.initialize( - "redeem", - amount, - symbol, - publicKey, - connection, - environment, - lendingMarketAddress - ); - await axn.addSupportIxs("redeem"); - await axn.addRedeemReserveCollateralIx(); - return axn; - } - - static async buildDepositObligationCollateralTxns( - connection: Connection, - amount: string | BN, - symbol: string, - publicKey: PublicKey, - environment: "production" | "devnet" = "production", - lendingMarketAddress?: PublicKey - ) { - const axn = await SolendAction.initialize( - "depositCollateral", - amount, - symbol, - publicKey, - connection, - environment, - lendingMarketAddress - ); - await axn.addSupportIxs("depositCollateral"); - await axn.addDepositObligationCollateralIx(); - return axn; - } - - static async buildWithdrawTxns( - connection: Connection, - amount: string | BN, - symbol: string, - publicKey: PublicKey, - environment: "production" | "devnet" = "production", - lendingMarketAddress?: PublicKey - ) { - const axn = await SolendAction.initialize( - "withdraw", - amount, - symbol, - publicKey, - connection, - environment, - lendingMarketAddress - ); - - await axn.addSupportIxs("withdraw"); - await axn.addWithdrawIx(); - - return axn; - } - - static async buildRepayTxns( - connection: Connection, - amount: string | BN, - symbol: string, - publicKey: PublicKey, - environment: "production" | "devnet" = "production", - lendingMarketAddress?: PublicKey - ) { - const axn = await SolendAction.initialize( - "repay", - amount, - symbol, - publicKey, - connection, - environment, - lendingMarketAddress - ); - - await axn.addSupportIxs("repay"); - await axn.addRepayIx(); - - return axn; - } - - async getTransactions() { - const txns: { - preLendingTxn: Transaction | null; - lendingTxn: Transaction | null; - postLendingTxn: Transaction | null; - } = { - preLendingTxn: null, - lendingTxn: null, - postLendingTxn: null, - }; - - if (this.preTxnIxs.length) { - txns.preLendingTxn = new Transaction({ - feePayer: this.publicKey, - recentBlockhash: (await this.connection.getRecentBlockhash()).blockhash, - }).add(...this.preTxnIxs); - } - - txns.lendingTxn = new Transaction({ - feePayer: this.publicKey, - recentBlockhash: (await this.connection.getRecentBlockhash()).blockhash, - }).add(...this.setupIxs, ...this.lendingIxs, ...this.cleanupIxs); - - if (this.postTxnIxs.length) { - txns.postLendingTxn = new Transaction({ - feePayer: this.publicKey, - recentBlockhash: (await this.connection.getRecentBlockhash()).blockhash, - }).add(...this.postTxnIxs); - } - - return txns; - } - - async sendTransactions( - sendTransaction: ( - txn: Transaction, - connection: Connection - ) => Promise, - preCallback?: () => void, - lendingCallback?: () => void, - postCallback?: () => void - ) { - const txns = await this.getTransactions(); - - await this.sendSingleTransaction( - txns.preLendingTxn, - sendTransaction, - preCallback - ); - - const signature = await this.sendSingleTransaction( - txns.lendingTxn, - sendTransaction, - lendingCallback - ); - - await this.sendSingleTransaction( - txns.postLendingTxn, - sendTransaction, - postCallback - ); - - return signature; - } - - private async sendSingleTransaction( - txn: Transaction | null, - sendTransaction: ( - txn: Transaction, - connection: Connection - ) => Promise, - callback?: () => void - ) { - if (!txn) return ""; - - const signature = await sendTransaction(txn, this.connection); - if (callback) { - callback(); - } - await this.connection.confirmTransaction(signature); - - return signature; - } - - addDepositIx() { - this.lendingIxs.push( - depositReserveLiquidityAndObligationCollateralInstruction( - this.amount, - this.userTokenAccountAddress, - this.userCollateralAccountAddress, - new PublicKey(this.reserve.address), - new PublicKey(this.reserve.liquidityAddress), - new PublicKey(this.reserve.collateralMintAddress), - new PublicKey(this.lendingMarket.address), - new PublicKey(this.lendingMarket.authorityAddress), - new PublicKey(this.reserve.collateralSupplyAddress), // destinationCollateral - this.obligationAddress, // obligation - this.publicKey, // obligationOwner - new PublicKey(this.reserve.pythOracle), - new PublicKey(this.reserve.switchboardOracle), - this.publicKey, // transferAuthority - this.programId - ) - ); - } - - addDepositReserveLiquidityIx() { - this.lendingIxs.push( - depositReserveLiquidityInstruction( - this.amount, - this.userTokenAccountAddress, - this.userCollateralAccountAddress, - new PublicKey(this.reserve.address), - new PublicKey(this.reserve.liquidityAddress), - new PublicKey(this.reserve.collateralMintAddress), - new PublicKey(this.lendingMarket.address), - new PublicKey(this.lendingMarket.authorityAddress), - this.publicKey, // transferAuthority - this.programId - ) - ); - } - - addRedeemReserveCollateralIx() { - this.lendingIxs.push( - redeemReserveCollateralInstruction( - this.amount, - this.userCollateralAccountAddress, - this.userTokenAccountAddress, - new PublicKey(this.reserve.address), - new PublicKey(this.reserve.collateralMintAddress), - new PublicKey(this.reserve.liquidityAddress), - new PublicKey(this.lendingMarket.address), // lendingMarket - new PublicKey(this.lendingMarket.authorityAddress), // lendingMarketAuthority - this.publicKey, // transferAuthority - this.programId - ) - ); - } - - addDepositObligationCollateralIx() { - this.lendingIxs.push( - depositObligationCollateralInstruction( - this.amount, - this.userCollateralAccountAddress, - new PublicKey(this.reserve.collateralSupplyAddress), - new PublicKey(this.reserve.address), - this.obligationAddress, // obligation - new PublicKey(this.lendingMarket.address), - this.publicKey, // obligationOwner - this.publicKey, // transferAuthority - this.programId - ) - ); - } - - addBorrowIx() { - this.lendingIxs.push( - borrowObligationLiquidityInstruction( - this.amount, - new PublicKey(this.reserve.liquidityAddress), - this.userTokenAccountAddress, - new PublicKey(this.reserve.address), - new PublicKey(this.reserve.liquidityFeeReceiverAddress), - this.obligationAddress, - new PublicKey(this.lendingMarket.address), // lendingMarket - new PublicKey(this.lendingMarket.authorityAddress), // lendingMarketAuthority - this.publicKey, - this.programId, - this.hostAta - ) - ); - } - - async addWithdrawIx() { - const buffer = await this.connection.getAccountInfo( - new PublicKey(this.reserve.address), - "processed" - ); - - if (!buffer) { - throw Error( - `Unable to fetch reserve data for ${this.reserve.liquidityToken.name}` - ); - } - - const parsedData = parseReserve( - new PublicKey(this.reserve.address), - buffer - )?.info; - - if (!parsedData) { - throw Error( - `Unable to parse data of reserve ${this.reserve.liquidityToken.name}` - ); - } - - const totalBorrowsWads = parsedData.liquidity.borrowedAmountWads; - const totalLiquidityWads = parsedData.liquidity.availableAmount.mul( - new BN(WAD) - ); - const totalDepositsWads = totalBorrowsWads.add(totalLiquidityWads); - const cTokenExchangeRate = new BigNumber(totalDepositsWads.toString()) - .div(parsedData.collateral.mintTotalSupply.toString()) - .div(WAD); - - this.lendingIxs.push( - withdrawObligationCollateralAndRedeemReserveLiquidity( - this.amount.eq(new BN(U64_MAX)) - ? this.amount - : new BN( - new BigNumber(this.amount.toString()) - .dividedBy(cTokenExchangeRate) - .integerValue(BigNumber.ROUND_FLOOR) - .toString() - ), - new PublicKey(this.reserve.collateralSupplyAddress), - this.userCollateralAccountAddress, - new PublicKey(this.reserve.address), - this.obligationAddress, - new PublicKey(this.lendingMarket.address), - new PublicKey(this.lendingMarket.authorityAddress), - this.userTokenAccountAddress, // destinationLiquidity - new PublicKey(this.reserve.collateralMintAddress), - new PublicKey(this.reserve.liquidityAddress), - this.publicKey, // obligationOwner - this.publicKey, // transferAuthority - this.programId - ) - ); - } - - async addRepayIx() { - this.lendingIxs.push( - repayObligationLiquidityInstruction( - this.amount, - this.userTokenAccountAddress, - new PublicKey(this.reserve.liquidityAddress), - new PublicKey(this.reserve.address), - this.obligationAddress, - new PublicKey(this.lendingMarket.address), - this.publicKey, - this.programId - ) - ); - } - - async addSupportIxs(action: ActionType) { - if (["withdraw", "borrow"].includes(action)) { - await this.addRefreshIxs(); - } - if (!["mint", "redeem"].includes(action)) { - await this.addObligationIxs(); - } - await this.addAtaIxs(action); - } - - private async addRefreshIxs() { - // Union of addresses - const allReserveAddresses = [ - ...Array.from([ - ...this.depositReserves.map((e) => e.toBase58()), - ...this.borrowReserves.map((e) => e.toBase58()), - this.reserve.address, - ]), - ]; - - allReserveAddresses.forEach((reserveAddress) => { - const reserveInfo = this.lendingMarket.reserves.find( - (reserve) => reserve.address === reserveAddress - ); - if (!reserveInfo) { - throw new Error(`Could not find asset ${reserveAddress} in reserves`); - } - - const refreshReserveIx = refreshReserveInstruction( - new PublicKey(reserveAddress), - this.programId, - new PublicKey(reserveInfo.pythOracle), - new PublicKey(reserveInfo.switchboardOracle) - ); - this.setupIxs.push(refreshReserveIx); - }); - - const refreshObligationIx = refreshObligationInstruction( - this.obligationAddress, - this.depositReserves, - this.borrowReserves, - this.programId - ); - this.setupIxs.push(refreshObligationIx); - } - - private async addObligationIxs() { - if (!this.obligationAccountInfo) { - const obligationAccountInfoRentExempt = - await this.connection.getMinimumBalanceForRentExemption( - OBLIGATION_SIZE - ); - - this.setupIxs.push( - SystemProgram.createAccountWithSeed({ - fromPubkey: this.publicKey, - newAccountPubkey: this.obligationAddress, - basePubkey: this.publicKey, - seed: this.seed, - lamports: obligationAccountInfoRentExempt, - space: OBLIGATION_SIZE, - programId: this.programId, - }) - ); - const initObligationIx = initObligationInstruction( - this.obligationAddress, - new PublicKey(this.lendingMarket.address), - this.publicKey, - this.programId - ); - this.setupIxs.push(initObligationIx); - } - } - - private async addAtaIxs(action: ActionType) { - if (this.symbol === "SOL") { - await this.updateWSOLAccount(action); - } - - if ( - (action === "withdraw" || action === "borrow" || action === "redeem") && - this.symbol !== "SOL" - ) { - const userTokenAccountInfo = await this.connection.getAccountInfo( - this.userTokenAccountAddress - ); - if (!userTokenAccountInfo) { - const createUserTokenAccountIx = - createAssociatedTokenAccountInstruction( - this.publicKey, - this.userTokenAccountAddress, - this.publicKey, - new PublicKey(this.reserve.liquidityToken.mint) - ); - - if (this.positions === POSITION_LIMIT && this.hostAta) { - this.preTxnIxs.push(createUserTokenAccountIx); - } else { - this.setupIxs.push(createUserTokenAccountIx); - } - } - } - - if (action === "withdraw" || action === "mint" || action === "deposit") { - const userCollateralAccountInfo = await this.connection.getAccountInfo( - this.userCollateralAccountAddress - ); - - if (!userCollateralAccountInfo) { - const createUserCollateralAccountIx = - createAssociatedTokenAccountInstruction( - this.publicKey, - this.userCollateralAccountAddress, - this.publicKey, - new PublicKey(this.reserve.collateralMintAddress) - ); - - if (this.positions === POSITION_LIMIT && this.symbol === "SOL") { - this.preTxnIxs.push(createUserCollateralAccountIx); - } else { - this.setupIxs.push(createUserCollateralAccountIx); - } - } - } - } - - private async updateWSOLAccount(action: ActionType) { - const preIxs: Array = []; - const postIxs: Array = []; - - let safeRepay = new BN(this.amount); - - if ( - this.obligationAccountInfo && - action === "repay" && - this.amount.eq(new BN(U64_MAX)) - ) { - const buffer = await this.connection.getAccountInfo( - new PublicKey(this.reserve.address), - "processed" - ); - - if (!buffer) { - throw Error( - `Unable to fetch reserve data for ${this.reserve.liquidityToken.name}` - ); - } - - const parsedData = parseReserve( - new PublicKey(this.reserve.address), - buffer - )?.info; - - if (!parsedData) { - throw Error( - `Unable to parse data of reserve ${this.reserve.liquidityToken.name}` - ); - } - - const borrow = this.obligationAccountInfo.borrows.find( - (borrow) => borrow.borrowReserve.toBase58() === this.reserve.address - ); - - if (!borrow) { - throw Error( - `Unable to find obligation borrow to repay for ${this.obligationAccountInfo.owner.toBase58()}` - ); - } - - safeRepay = new BN( - Math.floor( - new BigNumber(borrow.borrowedAmountWads.toString()) - .multipliedBy( - parsedData.liquidity.cumulativeBorrowRateWads.toString() - ) - .dividedBy(borrow.cumulativeBorrowRateWads.toString()) - .dividedBy(WAD) - .plus(SOL_PADDING_FOR_INTEREST) - .toNumber() - ).toString() - ); - } - - const userWSOLAccountInfo = await this.connection.getAccountInfo( - this.userTokenAccountAddress - ); - - const rentExempt = await getMinimumBalanceForRentExemptAccount( - this.connection - ); - - const sendAction = - action === "deposit" || action === "repay" || action === "mint"; - const transferLamportsIx = SystemProgram.transfer({ - fromPubkey: this.publicKey, - toPubkey: this.userTokenAccountAddress, - lamports: - (userWSOLAccountInfo ? 0 : rentExempt) + - (sendAction ? parseInt(safeRepay.toString(), 10) : 0), - }); - preIxs.push(transferLamportsIx); - - const closeWSOLAccountIx = createCloseAccountInstruction( - this.userTokenAccountAddress, - this.publicKey, - this.publicKey, - [] - ); - - if (userWSOLAccountInfo) { - const syncIx = syncNative(this.userTokenAccountAddress); - if (sendAction) { - preIxs.push(syncIx); - } else { - postIxs.push(closeWSOLAccountIx); - } - } else { - const createUserWSOLAccountIx = createAssociatedTokenAccountInstruction( - this.publicKey, - this.userTokenAccountAddress, - this.publicKey, - NATIVE_MINT - ); - preIxs.push(createUserWSOLAccountIx); - postIxs.push(closeWSOLAccountIx); - } - - if (this.positions && this.positions >= POSITION_LIMIT) { - this.preTxnIxs.push(...preIxs); - this.postTxnIxs.push(...postIxs); - } else { - this.setupIxs.push(...preIxs); - this.cleanupIxs.push(...postIxs); - } - } -} diff --git a/solend-sdk/src/classes/claim.ts b/solend-sdk/src/classes/claim.ts deleted file mode 100644 index 9ab58aa2..00000000 --- a/solend-sdk/src/classes/claim.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { - getAssociatedTokenAddress, - createAssociatedTokenAccountInstruction, - TOKEN_PROGRAM_ID, -} from "@solana/spl-token"; -import { PublicKey, SystemProgram, Transaction } from "@solana/web3.js"; -import { PsyAmericanIdl, getOptionByKey } from "@mithraic-labs/psy-american"; -import * as anchor from "@project-serum/anchor"; -import { EnrichedClaimType } from "./wallet"; -import { - MERKLE_PROGRAM_ID, - MerkleDistributorJSON, -} from "../utils/merkle_distributor"; - -const toBytes32Array = (b: Buffer): number[] => { - const buf = Buffer.alloc(32); - b.copy(buf, 32 - b.length); - - return Array.from(buf); -}; - -export class SolendClaim { - metadata: EnrichedClaimType; - provider: anchor.AnchorProvider; - - constructor(metadata: EnrichedClaimType, provider: anchor.AnchorProvider) { - this.metadata = metadata; - this.provider = provider; - } - - async getExerciseIxs(amount: number) { - if (!this.metadata.optionMarketKey) { - throw Error( - "This reward is not an option and does not need to be exercised" - ); - } - const psyOptionsProgram = new anchor.Program( - PsyAmericanIdl, - new PublicKey("R2y9ip6mxmWUj4pt54jP2hz2dgvMozy9VTSwMWE7evs"), - this.provider - ) as any; - - // Mint a bunch of contracts to the minter - const optionMarket = await getOptionByKey( - psyOptionsProgram, - new PublicKey(this.metadata.optionMarketKey) - ); - - if (!optionMarket) { - throw new Error("Option market with that key is not found."); - } - const setupIxs = []; - const exerciseIxs = []; - - const claimantTokenAccountAddress = await getAssociatedTokenAddress( - optionMarket.underlyingAssetMint, - this.provider.wallet.publicKey, - true - ); - - const claimantTokenAccountInfo = - await this.provider.connection.getAccountInfo( - claimantTokenAccountAddress - ); - - if (!claimantTokenAccountInfo) { - const createUserTokenAccountIx = createAssociatedTokenAccountInstruction( - this.provider.wallet.publicKey, - claimantTokenAccountAddress, - this.provider.wallet.publicKey, - optionMarket.underlyingAssetMint - ); - setupIxs.push(createUserTokenAccountIx); - } - - const exerciserOptionTokenSrc = await getAssociatedTokenAddress( - optionMarket.optionMint, - this.provider.wallet.publicKey - ); - const underlyingAssetDest = await getAssociatedTokenAddress( - optionMarket.underlyingAssetMint, - this.provider.wallet.publicKey - ); - const quoteAssetSrc = await getAssociatedTokenAddress( - optionMarket.quoteAssetMint, - this.provider.wallet.publicKey - ); - - if (!optionMarket) { - throw new Error("Option market with that key is not found."); - } - - const exerciseOptionIx = psyOptionsProgram.instruction.exerciseOptionV2( - new anchor.BN(amount), - { - accounts: { - userAuthority: this.provider.wallet.publicKey, - optionAuthority: this.provider.wallet.publicKey, - optionMarket: optionMarket.key, - optionMint: optionMarket.optionMint, - exerciserOptionTokenSrc, - underlyingAssetPool: optionMarket.underlyingAssetPool, - underlyingAssetDest, - quoteAssetPool: optionMarket.quoteAssetPool, - quoteAssetSrc, - tokenProgram: TOKEN_PROGRAM_ID, - }, - } - ); - - exerciseIxs.push(exerciseOptionIx); - - return [setupIxs, exerciseIxs]; - } - - async getClaimIxs() { - if (!this.metadata.claimable || this.metadata.claimedAt) { - return [[], []]; - } - const anchorProgram = new anchor.Program( - MerkleDistributorJSON, - new PublicKey(MERKLE_PROGRAM_ID), - this.provider - ); - const setupIxs = []; - const claimIxs = []; - - const claimantTokenAccountAddress = await getAssociatedTokenAddress( - this.metadata.distributor.mint, - this.provider.wallet.publicKey, - true - ); - - const claimantTokenAccountInfo = - await this.provider.connection.getAccountInfo( - claimantTokenAccountAddress - ); - - if (!claimantTokenAccountInfo) { - const createUserTokenAccountIx = createAssociatedTokenAccountInstruction( - this.provider.wallet.publicKey, - this.metadata.distributor.mint, - this.provider.wallet.publicKey, - claimantTokenAccountAddress - ); - setupIxs.push(createUserTokenAccountIx); - } - - const claimIx = anchorProgram.instruction.claim( - this.metadata.claimStatusBump, - new anchor.BN(this.metadata.index), - new anchor.BN(this.metadata.quantity), - this.metadata.proof.map((p) => toBytes32Array(Buffer.from(p, "hex"))), - { - accounts: { - distributor: this.metadata.distributorPublicKey, - claimStatus: this.metadata.claimId, - from: this.metadata.distributorATAPublicKey, - to: claimantTokenAccountAddress, - claimant: this.provider.wallet.publicKey, - payer: this.provider.wallet.publicKey, - systemProgram: SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, - }, - } - ); - - claimIxs.push(claimIx); - - return [setupIxs, claimIxs]; - } - - async claim() { - const [setupIxs, claimIxs] = await this.getClaimIxs(); - return await this.provider.sendAndConfirm( - new Transaction().add(...setupIxs, ...claimIxs) - ); - } -} diff --git a/solend-sdk/src/classes/constants.ts b/solend-sdk/src/classes/constants.ts deleted file mode 100644 index 11a6671f..00000000 --- a/solend-sdk/src/classes/constants.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { PublicKey } from "@solana/web3.js"; - -export const WAD = "1".concat(Array(18 + 1).join("0")); -export const WANG = "1".concat(Array(36 + 1).join("0")); -export const U64_MAX = "18446744073709551615"; - -export const SOLEND_PRODUCTION_PROGRAM_ID = new PublicKey( - "So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo" -); -export const SOLEND_DEVNET_PROGRAM_ID = new PublicKey( - "ALend7Ketfx5bxh6ghsCDXAoDrhvEmsXT3cynB6aPLgx" -); -export const SOLEND_BETA_PROGRAM_ID = new PublicKey( - "BLendhFh4HGnycEDDFhbeFEUYLP4fXB5tTHMoTX8Dch5" -); - -export function getProgramId(environment?: string) { - switch (environment) { - case "mainnet-beta": - case "production": - return SOLEND_PRODUCTION_PROGRAM_ID; - break; - case "devnet": - return SOLEND_DEVNET_PROGRAM_ID; - break; - case "beta": - return SOLEND_BETA_PROGRAM_ID; - break; - } - - throw Error(`Unsupported environment: ${environment}`); -} diff --git a/solend-sdk/src/classes/index.ts b/solend-sdk/src/classes/index.ts deleted file mode 100644 index 42daac07..00000000 --- a/solend-sdk/src/classes/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -export * from "./action"; -export * from "./market"; -export * from "./wallet"; -export * from "./claim"; -export * from "./reserve"; -export * from "./obligation"; -export * from "./shared"; -export * from "./constants"; diff --git a/solend-sdk/src/classes/market.ts b/solend-sdk/src/classes/market.ts deleted file mode 100644 index 7076f83d..00000000 --- a/solend-sdk/src/classes/market.ts +++ /dev/null @@ -1,269 +0,0 @@ -import { Connection, PublicKey } from "@solana/web3.js"; -import { SolendObligation } from "./obligation"; -import { SolendReserve } from "./reserve"; -import axios from "axios"; -import { getProgramId } from "./constants"; -import { - RewardsDataType, - ExternalRewardStatType, - MarketConfigType, -} from "./shared"; -import { parseObligation } from "../state"; - -type Config = Array; - -const API_ENDPOINT = "https://api.solend.fi"; - -export class SolendMarket { - private connection: Connection; - - reserves: Array; - - rewardsData: RewardsDataType | null; - - config: MarketConfigType; - - programId: PublicKey; - - private constructor( - connection: Connection, - config: MarketConfigType, - reserves: Array, - programId: PublicKey - ) { - this.connection = connection; - this.reserves = reserves; - this.rewardsData = null; - this.config = config; - this.programId = programId; - } - - static async initialize( - connection: Connection, - environment: "production" | "devnet" | "beta" = "production", - marketAddress?: string - ) { - const config = (await ( - await axios.get( - `${API_ENDPOINT}/v1/markets/configs?scope=all&deployment=${environment}` - ) - ).data) as Config; - - let marketConfig; - if (marketAddress) { - marketConfig = - config.find((market) => market.address == marketAddress) ?? null; - if (!marketConfig) { - throw `market address not found: ${marketAddress}`; - } - } else { - marketConfig = config.find((market) => market.isPrimary) ?? config[0]; - } - - const reserves = marketConfig.reserves.map( - (res) => new SolendReserve(res, connection) - ); - - return new SolendMarket( - connection, - marketConfig, - reserves, - getProgramId(environment) - ); - } - - async fetchObligationByWallet(publicKey: PublicKey) { - const { config, reserves } = this; - if (!config) { - throw Error("Market must be initialized to call initialize."); - } - const obligationAddress = await PublicKey.createWithSeed( - publicKey, - config.address.slice(0, 32), - this.programId - ); - - const rawObligationData = await this.connection.getAccountInfo( - obligationAddress - ); - - if (!rawObligationData) { - return null; - } - - const parsedObligation = parseObligation( - PublicKey.default, - rawObligationData! - ); - - if (!parsedObligation) { - throw Error("Could not parse obligation."); - } - - if (!reserves.every((reserve) => reserve.stats)) { - await this.loadReserves(); - } - - const obligationInfo = parsedObligation.info; - - return new SolendObligation( - publicKey, - obligationAddress, - obligationInfo, - reserves - ); - } - - async loadAll() { - const promises = [this.loadReserves(), this.loadRewards()]; - - await Promise.all(promises); - } - - private async loadExternalRewardData() { - const data = ( - await axios.get( - `${API_ENDPOINT}/liquidity-mining/external-reward-stats-v2?flat=true` - ) - ).data as Promise>; - - return data; - } - - private async loadPriceData(symbols: Array) { - const data = (await ( - await axios.get(`${API_ENDPOINT}/v1/prices/?symbols=${symbols.join(",")}`) - ).data) as { - results: Array<{ - identifier: string; - price: string; - source: string; - }>; - }; - - return data.results.reduce( - (acc, price) => ({ - ...acc, - [price.identifier]: Number(price.price), - }), - {} as { [key: string]: number } - ); - } - - private getLatestRewardRate( - rewardRates: Array<{ - beginningSlot: number; - rewardRate: string; - name?: string; - }>, - slot: number - ) { - return rewardRates - .filter((rr) => slot >= rr.beginningSlot) - .reduce((v1, v2) => (v1.beginningSlot > v2.beginningSlot ? v1 : v2), { - beginningSlot: 0, - rewardRate: "0", - }); - } - - async loadRewards() { - if (!this.config) { - throw Error("Market must be initialized to call loadRewards."); - } - - const promises = [ - this.loadExternalRewardData(), - this.connection.getSlot("finalized"), - ] as const; - - const [externalRewards, currentSlot] = await Promise.all(promises); - - const querySymbols = [ - ...Array.from( - new Set(externalRewards.map((reward) => reward.rewardSymbol)) - ), - ]; - - const priceData = await this.loadPriceData(querySymbols.concat("SLND")); - - this.rewardsData = this.reserves.reduce((acc, reserve) => { - const supply = [ - ...externalRewards - .filter( - (externalReward) => - externalReward.reserveID === reserve.config.address && - externalReward.side === "supply" - ) - .map((externalReward) => ({ - rewardRate: this.getLatestRewardRate( - externalReward.rewardRates, - currentSlot - ).rewardRate, - rewardMint: externalReward.rewardMint, - rewardSymbol: externalReward.rewardSymbol, - price: priceData[externalReward.rewardSymbol], - })), - ].filter(Boolean); - - const borrow = [ - ...externalRewards - .filter( - (externalReward) => - externalReward.reserveID === reserve.config.address && - externalReward.side === "borrow" - ) - .map((externalReward) => ({ - rewardRate: this.getLatestRewardRate( - externalReward.rewardRates, - currentSlot - ).rewardRate, - rewardMint: externalReward.rewardMint, - rewardSymbol: externalReward.rewardSymbol, - price: priceData[externalReward.rewardSymbol], - })), - ].filter(Boolean); - - return { - ...acc, - [reserve.config.liquidityToken.mint]: { - supply, - borrow, - }, - }; - }, {}); - - const refreshReserves = this.reserves.map((reserve) => { - return reserve.load(this.rewardsData ?? undefined); - }); - - await Promise.all(refreshReserves); - } - - async loadReserves() { - const addresses = this.reserves.map( - (reserve) => new PublicKey(reserve.config.address) - ); - const reserveAccounts = await this.connection.getMultipleAccountsInfo( - addresses, - "processed" - ); - - const loadReserves = this.reserves.map((reserve, index) => { - reserve.setBuffer(reserveAccounts[index]); - return reserve.load(); - }); - - await Promise.all(loadReserves); - } - - async refreshAll() { - const promises = [ - this.reserves.every((reserve) => reserve.stats) - ? this.loadReserves() - : null, - this.rewardsData ? this.loadRewards() : null, - ].filter((x) => x); - - await Promise.all(promises); - } -} diff --git a/solend-sdk/src/classes/obligation.ts b/solend-sdk/src/classes/obligation.ts deleted file mode 100644 index c721bb2e..00000000 --- a/solend-sdk/src/classes/obligation.ts +++ /dev/null @@ -1,144 +0,0 @@ -/* eslint-disable max-classes-per-file */ -import { PublicKey } from "@solana/web3.js"; -import BigNumber from "bignumber.js"; -import { SolendReserve } from "./reserve"; -import { Obligation } from "../state/obligation"; -import BN from "bn.js"; -import { WAD } from "./constants"; - -export type Position = { - mintAddress: string; - amount: BN; -}; - -export type ObligationStats = { - liquidationThreshold: number; - userTotalDeposit: number; - userTotalBorrow: number; - borrowLimit: number; - borrowUtilization: number; - netAccountValue: number; - positions: number; -}; - -export class SolendObligation { - walletAddress: PublicKey; - - obligationAddress: PublicKey; - - deposits: Array; - - borrows: Array; - - obligationStats: ObligationStats; - - constructor( - walletAddress: PublicKey, - obligationAddress: PublicKey, - obligation: Obligation, - reserves: Array - ) { - this.walletAddress = walletAddress; - this.obligationAddress = obligationAddress; - - const positionDetails = this.calculatePositions(obligation, reserves); - - this.deposits = positionDetails.deposits; - this.borrows = positionDetails.borrows; - this.obligationStats = positionDetails.stats; - } - - private calculatePositions( - obligation: Obligation, - reserves: Array - ) { - let userTotalDeposit = new BigNumber(0); - let borrowLimit = new BigNumber(0); - let liquidationThreshold = new BigNumber(0); - let positions = 0; - - const deposits = obligation.deposits.map((deposit) => { - const reserve = reserves.find( - (reserve) => - reserve.config.address === deposit.depositReserve.toBase58() - ); - const loanToValue = reserve!.stats!.loanToValueRatio; - const liqThreshold = reserve!.stats!.liquidationThreshold; - - const supplyAmount = new BN( - Math.floor( - new BigNumber(deposit.depositedAmount.toString()) - .multipliedBy(reserve!.stats!.cTokenExchangeRate) - .toNumber() - ) - ); - const supplyAmountUSD = new BigNumber(supplyAmount.toString()) - .multipliedBy(reserve!.stats!.assetPriceUSD) - .dividedBy("1".concat(Array(reserve!.stats!.decimals + 1).join("0"))); - - userTotalDeposit = userTotalDeposit.plus(supplyAmountUSD); - - borrowLimit = borrowLimit.plus(supplyAmountUSD.multipliedBy(loanToValue)); - - liquidationThreshold = liquidationThreshold.plus( - supplyAmountUSD.multipliedBy(liqThreshold) - ); - - if (!supplyAmount.eq(new BN("0"))) { - positions += 1; - } - - return { - mintAddress: reserve!.config.liquidityToken.mint, - amount: supplyAmount, - }; - }); - - let userTotalBorrow = new BigNumber(0); - - const borrows = obligation.borrows.map((borrow) => { - const reserve = reserves.find( - (reserve) => reserve.config.address === borrow.borrowReserve.toBase58() - ); - - const borrowAmount = new BN( - Math.floor( - new BigNumber(borrow.borrowedAmountWads.toString()) - .multipliedBy(reserve!.stats!.cumulativeBorrowRateWads.toString()) - .dividedBy(borrow.cumulativeBorrowRateWads.toString()) - .dividedBy(WAD) - .toNumber() - ).toString() - ); - - const borrowAmountUSD = new BigNumber(borrowAmount.toString()) - .multipliedBy(reserve!.stats!.assetPriceUSD) - .dividedBy("1".concat(Array(reserve!.stats!.decimals + 1).join("0"))); - - if (!borrowAmount.eq(new BN("0"))) { - positions += 1; - } - - userTotalBorrow = userTotalBorrow.plus(borrowAmountUSD); - - return { - mintAddress: reserve!.config.liquidityToken.mint, - amount: borrowAmount, - }; - }); - - return { - deposits, - borrows, - stats: { - liquidationThreshold: liquidationThreshold.toNumber(), - userTotalDeposit: userTotalDeposit.toNumber(), - userTotalBorrow: userTotalBorrow.toNumber(), - borrowLimit: borrowLimit.toNumber(), - borrowUtilization: userTotalBorrow.dividedBy(borrowLimit).toNumber(), - netAccountValue: userTotalDeposit.minus(userTotalBorrow).toNumber(), - positions, - }, - }; - } -} diff --git a/solend-sdk/src/classes/utils.ts b/solend-sdk/src/classes/utils.ts deleted file mode 100644 index 76afe264..00000000 --- a/solend-sdk/src/classes/utils.ts +++ /dev/null @@ -1,100 +0,0 @@ -import BigNumber from "bignumber.js"; - -const SLOT_RATE = 2; -const DAILY_SLOTS = 24 * 60 * 60 * SLOT_RATE; -const ANNUAL_SLOTS = 365 * DAILY_SLOTS * SLOT_RATE; - -type ObligationFarmScoreType = { - obligationId: string; - balance: string; - debt: string; - score: string; - lastSlot: number; - tokenMint: string; - side: "supply" | "borrow"; -}; - -type RewardRate = { - beginningSlot: number; - rewardRate: string; - name?: string; -}; - -function getLatestRewardRate( - rewardRates: Array<{ - beginningSlot: number; - rewardRate: string; - name?: string; - }>, - slot: number -) { - return rewardRates - .filter((rr) => slot >= rr.beginningSlot) - .reduce((v1, v2) => (v1.beginningSlot > v2.beginningSlot ? v1 : v2), { - beginningSlot: 0, - rewardRate: "0", - }); -} - -export const calculateNewScore = ( - rewardStat: { - lastSlot: number; - rewardRates: Array; - rewardsPerShare: string; - totalBalance: string; - }, - pool: ObligationFarmScoreType, - rewardRate: string, - endSlot: number, - startSlot: number -) => { - const { balance, debt, score } = pool; - const { rewardsPerShare, totalBalance } = rewardStat; - - const oldDebt = new BigNumber(debt); - const oldScore = new BigNumber(score); - const oldRewardsPerShare = new BigNumber(rewardsPerShare); - const oldBalance = new BigNumber(balance); - const totalBalanceVal = new BigNumber(totalBalance); - - const newRewardsPerShare = !totalBalanceVal.isZero() - ? oldRewardsPerShare.plus( - new BigNumber(endSlot) - .minus(new BigNumber(startSlot.toString())) - .times(new BigNumber(rewardRate)) - .div(totalBalanceVal) - .div(new BigNumber(ANNUAL_SLOTS)) - ) - : new BigNumber(0); - - return oldScore.plus(newRewardsPerShare.times(oldBalance).minus(oldDebt)); -}; - -export const estimateCurrentScore = ( - rewardStat: { - lastSlot: number; - rewardRates: Array; - rewardsPerShare: string; - totalBalance: string; - }, - rewardScore: ObligationFarmScoreType, - mostRecentSlot: number, - mostRecentSlotTime: number -) => { - const { lastSlot, rewardRates } = rewardStat; - - const estimatedCurrentSlot = - mostRecentSlot + SLOT_RATE * (Date.now() / 1000 - mostRecentSlotTime); - - const { rewardRate } = getLatestRewardRate(rewardRates, estimatedCurrentSlot); - - const currentScore = calculateNewScore( - rewardStat, - rewardScore, - rewardRate, - estimatedCurrentSlot, - lastSlot - ); - - return currentScore; -}; diff --git a/solend-sdk/src/classes/wallet.ts b/solend-sdk/src/classes/wallet.ts deleted file mode 100644 index 2096c8f1..00000000 --- a/solend-sdk/src/classes/wallet.ts +++ /dev/null @@ -1,380 +0,0 @@ -import { Connection, PublicKey } from "@solana/web3.js"; -import axios from "axios"; -import { SolendClaim } from "./claim"; -import * as anchor from "@project-serum/anchor"; -import { - getAssociatedTokenAddress, - TOKEN_PROGRAM_ID, - ASSOCIATED_TOKEN_PROGRAM_ID, - unpackAccount, -} from "@solana/spl-token"; -import { - PsyAmericanIdl, - getOptionByKey, - OptionMarketWithKey, -} from "@mithraic-labs/psy-american"; -import { - MERKLE_PROGRAM_ID, - MerkleDistributorJSON, -} from "../utils/merkle_distributor"; -import { ExternalRewardStatType, ConfigType } from "./shared"; -import { estimateCurrentScore } from "./utils"; -import { getProgramId } from "./constants"; - -const API_ENDPOINT = "https://api.solend.fi"; - -export type ClaimType = { - obligationID: string; - lotNumber: number; - index: number; - quantity: string; - root: string; - proof: Array; - distributorPublicKey: string; - name: string; - incentivizer: string; - optionMarketKey: string; -}; - -export type EnrichedClaimType = { - claimable: boolean; - claimedAt: number | null; - mintAddress: string; - quantity: string; - distributor: { - mint: PublicKey; - bump: number; - }; - distributorATAPublicKey: PublicKey; - claimId: PublicKey; - claimStatusBump: number; - optionMarket: - | (OptionMarketWithKey & { - userBalance: number; - }) - | null; -} & ClaimType; - -type RewardScoreType = { - obligationId: string; - balance: string; - debt: string; - score: string; - lastSlot: number; - tokenMint: string; - side: "supply" | "borrow"; -}; - -type ExternalRewardScoreType = RewardScoreType & { - reserveID: string; - rewardMint: string; - rewardSymbol: string; -}; - -export type SolendReward = { - lifetimeAmount: number; - symbol: string; - claimedAmount: number; - claimableAmount: number; - rewardClaims: Array; -}; - -export class SolendWallet { - config: ConfigType | null; - - rewards: { [key: string]: SolendReward }; - - provider: anchor.AnchorProvider; - - programId: PublicKey; - - private constructor( - wallet: anchor.Wallet, - connection: Connection, - environment: string - ) { - this.config = null; - this.rewards = {}; - this.provider = new anchor.AnchorProvider(connection, wallet, {}); - this.programId = getProgramId(environment); - } - - static async initialize( - wallet: anchor.Wallet, - connection: Connection, - environment: "production" | "devnet" = "production" - ) { - const loadedWallet = new SolendWallet(wallet, connection, environment); - const config = (await ( - await axios.get( - `${API_ENDPOINT}/v1/markets/configs?scope=all&deployment=${environment}` - ) - ).data) as ConfigType; - loadedWallet.config = config; - - await loadedWallet.loadRewards(); - - return loadedWallet; - } - - async loadRewards() { - if (!this.config) { - throw Error("Wallet must be initialized to call loadRewards."); - } - const anchorProgram = new anchor.Program( - MerkleDistributorJSON, - new PublicKey(MERKLE_PROGRAM_ID), - this.provider - ); - - const psyOptionsProgram = new anchor.Program( - PsyAmericanIdl, - new PublicKey("R2y9ip6mxmWUj4pt54jP2hz2dgvMozy9VTSwMWE7evs"), - this.provider - ) as any; - - const externalStatResponse = ( - await axios.get( - `${API_ENDPOINT}/liquidity-mining/external-reward-stats-v2?flat=true` - ) - ).data as Promise>; - - const externalScoreResponse = ( - await axios.get( - `${API_ENDPOINT}/liquidity-mining/external-reward-score-v2?wallet=${this.provider.wallet.publicKey.toBase58()}` - ) - ).data as Promise>; - - const primaryMarketSeed = this.config - .find((market) => market.isPrimary)! - .address.slice(0, 32); - - const obligationAddress = await PublicKey.createWithSeed( - this.provider.wallet.publicKey, - primaryMarketSeed, - new PublicKey(this.programId) - ); - - const claimResponse = ( - await axios.get( - `${API_ENDPOINT}/liquidity-mining/reward-proofs?obligation=${obligationAddress}` - ) - ).data as Promise>; - - const [externalStatData, externalScoreData, claimData] = await Promise.all([ - externalStatResponse, - externalScoreResponse, - claimResponse, - ]); - - const optionMarkets = await Promise.all( - claimData.map((d) => - d.optionMarketKey - ? getOptionByKey(psyOptionsProgram, new PublicKey(d.optionMarketKey)) - : Promise.resolve(null) - ) - ); - - const optionAtas = await Promise.all( - optionMarkets.map((om) => - om - ? getAssociatedTokenAddress( - new PublicKey(om.optionMint), - this.provider.wallet.publicKey, - true - ) - : Promise.resolve( - new PublicKey("nu11111111111111111111111111111111111111111") - ) - ) - ); - - const optionBalances = - await this.provider.connection.getMultipleAccountsInfo(optionAtas); - - const parsedOptionBalances = optionBalances.map((om, index) => - om ? unpackAccount(optionAtas[index], om) : null - ); - - const merkleDistributors = - (await anchorProgram.account.merkleDistributor.fetchMultiple( - claimData.map((d) => d.distributorPublicKey) - )) as Array; - - const claimAndBumps = await Promise.all( - claimData.map(async (d) => { - const claimAndBump = await PublicKey.findProgramAddress( - [ - anchor.utils.bytes.utf8.encode("ClaimStatus"), - new anchor.BN(d.index).toArrayLike(Buffer, "le", 8), - new PublicKey(d.distributorPublicKey).toBytes(), - ], - new PublicKey(MERKLE_PROGRAM_ID) - ); - - return claimAndBump; - }) - ); - - const claimStatuses = - (await anchorProgram.account.claimStatus.fetchMultiple( - claimAndBumps.map((candb) => candb[0]) - )) as Array; - - const fullData = await Promise.all( - claimData.map(async (d, index) => { - const [distributorATAPublicKey, _bump] = - await PublicKey.findProgramAddress( - [ - new PublicKey(d.distributorPublicKey).toBuffer(), - TOKEN_PROGRAM_ID.toBuffer(), - merkleDistributors[index].mint.toBuffer(), - ], - ASSOCIATED_TOKEN_PROGRAM_ID - ); - - const claimable = - ( - await this.provider.connection.getTokenAccountBalance( - distributorATAPublicKey - ) - ).value.amount !== "0"; - - const om = optionMarkets[index]; - - return { - ...d, - optionMarket: om - ? { - ...om, - userBalance: Number(parsedOptionBalances[index]?.amount ?? 0), - expired: - om.expirationUnixTimestamp.toNumber() <= - Math.floor(new Date().getTime()) / 1000, - } - : null, - claimable, - claimedAt: claimStatuses[index]?.claimedAt, - mintAddress: merkleDistributors[index].mint, - distributor: merkleDistributors[index], - distributorATAPublicKey, - claimId: claimAndBumps[index][0], - claimStatusBump: claimAndBumps[index][1], - }; - }) - ); - - const mostRecentSlot = await this.provider.connection.getSlot("finalized"); - const mostRecentSlotTime = (await this.provider.connection.getBlockTime( - mostRecentSlot - )) as number; - - const rewards = fullData.reduce((acc, currentValue) => { - if (!acc[currentValue.distributor.mint]) { - acc[currentValue.distributor.mint] = []; - } - acc[currentValue.distributor.mint].push(currentValue); - return acc; - }, {} as { [mint: string]: Array }); - - const externalEarningsData = externalScoreData.reduce( - (acc, rewardScore) => { - const rewardStat = externalStatData.find( - (reward) => - reward.reserveID === rewardScore.reserveID && - reward.side === rewardScore.side - ); - const currentScore = rewardStat - ? estimateCurrentScore( - rewardStat, - rewardScore, - mostRecentSlot, - mostRecentSlotTime - ).toNumber() - : 0; - - return { - ...acc, - [rewardScore.rewardMint]: { - symbol: rewardScore.rewardSymbol, - lifetimeAmount: - (acc[rewardScore.rewardMint]?.lifetimeAmount ?? 0) + - Number(currentScore), - }, - }; - }, - {} as { - [key: string]: { - symbol: string; - lifetimeAmount: number; - }; - } - ); - - const rewardsData = { - ...externalEarningsData, - }; - - const rewardMetadata = ( - await ( - await axios.get( - `${API_ENDPOINT}/tokens/?symbols=${Object.values(rewardsData) - .map((rew) => rew.symbol) - .join(",")}` - ) - ).data - ).results as Array<{ - coingeckoID: string; - decimals: number; - logo: string; - mint: string; - name: string; - symbol: string; - }>; - - this.rewards = Object.fromEntries( - Object.entries(rewardsData).map(([rewardMint, earning]) => { - const rewardData = rewards[rewardMint]; - const rewardClaims = fullData - .filter((lot) => lot.mintAddress.toBase58() === rewardMint) - .map((reward) => new SolendClaim(reward, this.provider)); - const metadata = rewardMetadata.find( - (rew) => rew?.symbol === earning.symbol - ); - - return [ - rewardMint, - { - ...earning, - ...metadata, - lifetimeAmount: - earning.lifetimeAmount / 10 ** (36 - (metadata?.decimals ?? 0)), - claimedAmount: - rewardData - ?.filter((reward) => reward.claimedAt) - .reduce((acc, reward) => acc + Number(reward.quantity), 0) ?? 0, - claimableAmount: - rewardData - ?.filter((reward) => !reward.claimedAt && reward.claimable) - .reduce((acc, reward) => acc + Number(reward.quantity), 0) ?? 0, - rewardClaims: rewardClaims, - }, - ]; - }) - ); - } - - async getClaimAllIxs() { - const allSetupIxs = []; - const allClaimIxs = []; - for (const claim of Object.values(this.rewards).flatMap( - (reward) => reward.rewardClaims - )) { - const [setupIxs, claimIxs] = await claim.getClaimIxs(); - allSetupIxs.push(...setupIxs); - allClaimIxs.push(...claimIxs); - } - - return [allSetupIxs, allClaimIxs]; - } -} diff --git a/solend-sdk/src/core/action/action.ts b/solend-sdk/src/core/actions.ts similarity index 97% rename from solend-sdk/src/core/action/action.ts rename to solend-sdk/src/core/actions.ts index d98a0f19..c8b7841b 100644 --- a/solend-sdk/src/core/action/action.ts +++ b/solend-sdk/src/core/actions.ts @@ -19,8 +19,8 @@ import { Obligation, OBLIGATION_SIZE, parseObligation, -} from "../../state/obligation"; -import { parseReserve } from "../../state/reserve"; +} from "../state/obligation"; +import { parseReserve } from "../state/reserve"; import { depositReserveLiquidityAndObligationCollateralInstruction, depositReserveLiquidityInstruction, @@ -35,10 +35,10 @@ import { depositObligationCollateralInstruction, withdrawObligationCollateralInstruction, forgiveDebtInstruction, -} from "../../instructions"; -import { POSITION_LIMIT } from "../constants"; -import { EnvironmentType, PoolType, ReserveType } from "../types"; -import { getProgramId, U64_MAX, WAD } from "../../classes"; +} from "../instructions"; +import { POSITION_LIMIT } from "./constants"; +import { EnvironmentType, PoolType, ReserveType } from "./types"; +import { getProgramId, U64_MAX, WAD } from "./constants"; const SOL_PADDING_FOR_INTEREST = "1000000"; @@ -142,9 +142,10 @@ export class SolendActionCore { connection: Connection, environment: EnvironmentType = "production", customObligationAddress?: PublicKey, - hostAta?: PublicKey + hostAta?: PublicKey, + customObligationSeed?: string ) { - const seed = pool.address.slice(0, 32); + const seed = customObligationSeed ?? pool.address.slice(0, 32); const programId = getProgramId(environment); const obligationAddress = @@ -261,7 +262,9 @@ export class SolendActionCore { connection: Connection, amount: string, publicKey: PublicKey, - environment: EnvironmentType = "production" + environment: EnvironmentType = "production", + obligationAddress?: PublicKey, + obligationSeed?: string ) { const axn = await SolendActionCore.initialize( pool, @@ -270,7 +273,10 @@ export class SolendActionCore { new BN(amount), publicKey, connection, - environment + environment, + obligationAddress, + undefined, + obligationSeed ); await axn.addSupportIxs("deposit"); diff --git a/solend-sdk/src/core/constants.ts b/solend-sdk/src/core/constants.ts index 220797c8..b31b5dd3 100644 --- a/solend-sdk/src/core/constants.ts +++ b/solend-sdk/src/core/constants.ts @@ -1,3 +1,7 @@ +import { Cluster, PublicKey } from "@solana/web3.js"; +import BigNumber from "bignumber.js"; +import { ObligationType } from "./types"; +export const WAD = "1".concat(Array(18 + 1).join("0")); export const POSITION_LIMIT = 6; export const SOL_PADDING_FOR_INTEREST = "1000000"; export const SLOTS_PER_YEAR = 63072000; @@ -7,3 +11,60 @@ export const SOLEND_ADDRESSES = [ "81KTtWjRndxGQbJHGJq6EaJWL8JfXbyywVvZReVPQd1X", "GDmSxpPzLkfxxr6dHLNRnCoYVGzvgc41tozkrr4pHTjB", ]; +export const U64_MAX = "18446744073709551615"; +export const NULL_ORACLE = new PublicKey( + "nu11111111111111111111111111111111111111111" +); +export const SOLEND_PRODUCTION_PROGRAM_ID = new PublicKey( + "So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo" +); +export const SOLEND_DEVNET_PROGRAM_ID = new PublicKey( + "ALend7Ketfx5bxh6ghsCDXAoDrhvEmsXT3cynB6aPLgx" +); +export const SOLEND_BETA_PROGRAM_ID = new PublicKey( + "BLendhFh4HGnycEDDFhbeFEUYLP4fXB5tTHMoTX8Dch5" +); + +export function getProgramId(environment?: Cluster | "beta" | "production") { + switch (environment) { + case "mainnet-beta": + case "production": + return SOLEND_PRODUCTION_PROGRAM_ID; + break; + case "devnet": + return SOLEND_DEVNET_PROGRAM_ID; + break; + case "beta": + return SOLEND_BETA_PROGRAM_ID; + break; + } + + throw Error(`Unsupported environment: ${environment}`); +} + +export const BigZero = new BigNumber(0); + +export const EmptyObligation: ObligationType = { + address: "empty", + positions: 0, + deposits: [], + borrows: [], + poolAddress: "", + totalSupplyValue: BigZero, + totalBorrowValue: BigZero, + borrowLimit: BigZero, + liquidationThreshold: BigZero, + netAccountValue: BigZero, + liquidationThresholdFactor: BigZero, + borrowLimitFactor: BigZero, + borrowUtilization: BigZero, + weightedConservativeBorrowUtilization: BigZero, + weightedBorrowUtilization: BigZero, + isBorrowLimitReached: false, + borrowOverSupply: BigZero, + weightedTotalBorrowValue: BigZero, + minPriceUserTotalSupply: BigZero, + minPriceBorrowLimit: BigZero, + maxPriceUserTotalWeightedBorrow: BigZero, + netApy: BigZero, +}; diff --git a/solend-sdk/src/core/index.ts b/solend-sdk/src/core/index.ts index b4bf4349..2fe48100 100644 --- a/solend-sdk/src/core/index.ts +++ b/solend-sdk/src/core/index.ts @@ -1,4 +1,5 @@ export * from "./constants"; export * from "./utils"; export * from "./types"; -export * from "./action/action"; +export * from "./margin"; +export * from "./actions"; \ No newline at end of file diff --git a/solend-sdk/src/core/margin.ts b/solend-sdk/src/core/margin.ts new file mode 100644 index 00000000..75e0d63b --- /dev/null +++ b/solend-sdk/src/core/margin.ts @@ -0,0 +1,869 @@ +import { + AddressLookupTableAccount, + Connection, + PublicKey, + SystemProgram, + TransactionInstruction, + TransactionMessage, + VersionedTransaction, +} from "@solana/web3.js"; +import { + createAssociatedTokenAccountInstruction, + getAssociatedTokenAddress, + getAssociatedTokenAddressSync, +} from "@solana/spl-token"; +import { findProgramAddressSync } from "@project-serum/anchor/dist/cjs/utils/pubkey"; +import { ObligationType, PoolType, ReserveType } from "."; +import { + NULL_ORACLE, + SOLEND_PRODUCTION_PROGRAM_ID, + U64_MAX, +} from "./constants"; +import { + borrowObligationLiquidityInstruction, + depositReserveLiquidityAndObligationCollateralInstruction, + flashBorrowReserveLiquidityInstruction, + flashRepayReserveLiquidityInstruction, + initObligationInstruction, + refreshObligationInstruction, + refreshReserveInstruction, + repayObligationLiquidityInstruction, + withdrawObligationCollateralAndRedeemReserveLiquidity, +} from "../instructions"; +import BigNumber from "bignumber.js"; +import BN from "bn.js"; +import JSBI from "jsbi"; +import { SolendActionCore } from "./actions"; + +function dustAmountThreshold(decimals: number) { + const dustDecimal = new BigNumber(decimals / 2).integerValue( + BigNumber.ROUND_FLOOR + ); + return new BigNumber(1).multipliedBy(new BigNumber(10).pow(dustDecimal)); +} + +export class Margin { + connection: Connection; + + obligation?: ObligationType; + + owner: PublicKey; + + obligationAddress: PublicKey; + + longReserve: ReserveType; + + shortReserve: ReserveType; + + pool: PoolType; + + collateralReserve?: ReserveType; + + longReserveLiquidityAta: PublicKey; + + longReserveCollateralAta: PublicKey; + + shortReserveLiquidityAta: PublicKey; + + shortReserveCollateralAta: PublicKey; + + obligationSeed: string; + + lendingMarketAuthority: PublicKey; + + depositKeys: Array; + + borrowKeys: Array; + + constructor( + connection: Connection, + owner: PublicKey, + longReserve: ReserveType, + shortReserve: ReserveType, + pool: PoolType, + obligationAddress: PublicKey, + obligationSeed: string, + obligation?: ObligationType, + collateralReserve?: ReserveType + ) { + this.connection = connection; + this.obligation = obligation; + this.owner = owner; + this.longReserve = longReserve; + this.shortReserve = shortReserve; + this.obligationAddress = obligationAddress; + this.obligationSeed = obligationSeed; + this.pool = pool; + this.collateralReserve = collateralReserve; + + this.longReserveLiquidityAta = getAssociatedTokenAddressSync( + new PublicKey(this.longReserve.mintAddress), + this.owner + ); + this.longReserveCollateralAta = getAssociatedTokenAddressSync( + new PublicKey(this.longReserve.cTokenMint), + this.owner + ); + + this.shortReserveLiquidityAta = getAssociatedTokenAddressSync( + new PublicKey(this.shortReserve.mintAddress), + this.owner + ); + this.shortReserveCollateralAta = getAssociatedTokenAddressSync( + new PublicKey(this.shortReserve.cTokenMint), + this.owner + ); + + const [lendingMarketAuthority, _] = findProgramAddressSync( + [new PublicKey(this.pool.address).toBytes()], + SOLEND_PRODUCTION_PROGRAM_ID + ); + + this.lendingMarketAuthority = lendingMarketAuthority; + + this.depositKeys = + this.obligation && this.obligation.deposits.length > 0 + ? this.obligation.deposits.map((ol) => new PublicKey(ol.reserveAddress)) + : []; + this.borrowKeys = + this.obligation && this.obligation.borrows.length > 0 + ? this.obligation.borrows.map((ol) => new PublicKey(ol.reserveAddress)) + : []; + } + + calculateMaxUserBorrowPower = () => { + console.log( + "minPriceBorrowLimit", + this.obligation?.minPriceBorrowLimit.toString() + ); + console.log(this.obligation); + let curShortSupplyAmount = + this.obligation?.deposits.find( + (d) => d.reserveAddress === this.shortReserve.address + )?.amount ?? new BigNumber(0); + console.log( + "short supply", + curShortSupplyAmount.toString(), + this.shortReserve.address + ); + let curShortBorrowAmount = + this.obligation?.borrows.find( + (d) => d.reserveAddress === this.shortReserve.address + )?.amount ?? new BigNumber(0); + let curLongSupplyAmount = + this.obligation?.deposits.find( + (d) => d.reserveAddress === this.longReserve.address + )?.amount ?? new BigNumber(0); + let curLongBorrowAmount = + this.obligation?.borrows.find( + (d) => d.reserveAddress === this.longReserve.address + )?.amount ?? new BigNumber(0); + // handle the case where short token has non-zero ltv / infitie borrow weight e.g mSOL/stSOL + if ( + this.shortReserve.addedBorrowWeightBPS.toString() === U64_MAX || + new BigNumber(this.shortReserve.totalBorrow).isGreaterThanOrEqualTo( + new BigNumber(this.shortReserve.reserveBorrowCap) + ) + ) { + // convert to base and round up to match calculation logic in margin.tsx + const flashLoanFeeBase = curShortSupplyAmount + .multipliedBy(new BigNumber(this.shortReserve.flashLoanFee)) + .multipliedBy(new BigNumber(10 ** this.shortReserve.decimals)) + .integerValue(BigNumber.ROUND_CEIL); + const flashLoanFee = new BigNumber( + flashLoanFeeBase + .dividedBy(new BigNumber(10 ** this.shortReserve.decimals)) + .toString() + ); + const maxPossibleSwap = curShortSupplyAmount.minus(flashLoanFee); + + return maxPossibleSwap.toNumber(); + } + + const shortTokenPrice = this.shortReserve.price; + const longTokenPrice = this.longReserve.price; + + const shortTokenBorrowWeight = new BigNumber( + this.shortReserve.addedBorrowWeightBPS.toString() + ) + .plus(new BigNumber(10000)) + .dividedBy(new BigNumber(10000)); + const longTokenBorrowWeight = new BigNumber( + this.longReserve.addedBorrowWeightBPS.toString() + ) + .plus(new BigNumber(10000)) + .dividedBy(new BigNumber(10000)); + let totalShortSwapable = new BigNumber(0); + let curMinPriceBorrowLimit = + this.obligation?.minPriceBorrowLimit ?? BigNumber(0); + let curMaxPriceUserTotalWeightedBorrow = + this.obligation?.maxPriceUserTotalWeightedBorrow ?? BigNumber(0); + + for (let i = 0; i < 20; i += 1) { + if ( + curMaxPriceUserTotalWeightedBorrow.isGreaterThanOrEqualTo( + curMinPriceBorrowLimit + ) + ) { + break; + } + let swapable = new BigNumber(0); + const marginAvailible = curMinPriceBorrowLimit.minus( + curMaxPriceUserTotalWeightedBorrow + ); + if (curShortSupplyAmount > new BigNumber(0)) { + // case you still have longs of your short token to sell + if (this.shortReserve.loanToValueRatio.toString() === "0") { + swapable = curShortSupplyAmount; + } else { + swapable = BigNumber.min( + marginAvailible + .dividedBy(shortTokenPrice) + .dividedBy(new BigNumber(this.shortReserve.loanToValueRatio)), + curShortSupplyAmount + ); + } + + curShortSupplyAmount = curShortSupplyAmount.minus(swapable); + curMinPriceBorrowLimit = curMinPriceBorrowLimit.minus( + swapable + .times(shortTokenPrice) + .times(new BigNumber(this.shortReserve.loanToValueRatio)) + ); + } else { + // you are already short your short token + swapable = marginAvailible + .dividedBy(shortTokenBorrowWeight) + .dividedBy(shortTokenPrice); + curShortBorrowAmount = curShortBorrowAmount.plus(swapable); + + curMaxPriceUserTotalWeightedBorrow = + curMaxPriceUserTotalWeightedBorrow.plus( + swapable.times(shortTokenPrice).times(shortTokenBorrowWeight) + ); + } + + totalShortSwapable = totalShortSwapable.plus(swapable); + const longRecievedInSwap = swapable + .times(shortTokenPrice) + .dividedBy(longTokenPrice); + + if (curLongBorrowAmount > longRecievedInSwap) { + curLongBorrowAmount = curLongBorrowAmount.minus(longRecievedInSwap); + curMaxPriceUserTotalWeightedBorrow = + curMaxPriceUserTotalWeightedBorrow.minus( + longRecievedInSwap + .times(longTokenPrice) + .times(longTokenBorrowWeight) + ); + } else { + curLongSupplyAmount = curLongSupplyAmount + .plus(longRecievedInSwap) + .minus(curLongBorrowAmount); + curMaxPriceUserTotalWeightedBorrow = + curMaxPriceUserTotalWeightedBorrow.minus( + curLongBorrowAmount + .times(longTokenPrice) + .times(longTokenBorrowWeight) + ); + curMinPriceBorrowLimit = curMinPriceBorrowLimit.plus( + longRecievedInSwap + .minus(curLongBorrowAmount) + .times(longTokenPrice) + .times(new BigNumber(this.longReserve.loanToValueRatio)) + ); + curLongBorrowAmount = new BigNumber(0); + } + } + + return totalShortSwapable.times(new BigNumber(".975")).toNumber(); + }; + + setupTx = async (depositCollateralConfig?: { + collateralReserve: ReserveType; + amount: string; + }) => { + const ixs: TransactionInstruction[] = []; + // If we are depositing, the deposit instruction will handle creating the obligation + if ( + (!this.obligation || this.obligation.address === "empty") && + !depositCollateralConfig + ) { + ixs.push( + SystemProgram.createAccountWithSeed({ + fromPubkey: this.owner, + newAccountPubkey: this.obligationAddress, + basePubkey: this.owner, + seed: this.obligationSeed, + lamports: await this.connection.getMinimumBalanceForRentExemption( + 1300 + ), + space: 1300, + programId: SOLEND_PRODUCTION_PROGRAM_ID, + }) + ); + ixs.push( + initObligationInstruction( + this.obligationAddress, + new PublicKey(this.pool.address), + this.owner, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + } + + await Promise.all( + [ + new PublicKey(this.longReserve.mintAddress), + new PublicKey(this.shortReserve.mintAddress), + new PublicKey(this.longReserve.cTokenMint), + new PublicKey(this.shortReserve.cTokenMint), + ].map(async (mint) => { + const tokenAccount = await getAssociatedTokenAddress( + mint, + this.owner, + true + ); + + if (!(await this.connection.getAccountInfo(tokenAccount))) { + ixs.push( + createAssociatedTokenAccountInstruction( + this.owner, + tokenAccount, + this.owner, + mint + ) + ); + } + }) + ); + + if (depositCollateralConfig) { + const solendAction = await SolendActionCore.buildDepositTxns( + this.pool, + depositCollateralConfig.collateralReserve, + this.connection, + depositCollateralConfig.amount, + this.owner, + "production", + this.obligationAddress, + this.obligationSeed + ); + const { preLendingTxn, lendingTxn } = + await solendAction.getTransactions(); + ixs.push( + ...(preLendingTxn?.instructions ?? []), + ...(lendingTxn?.instructions ?? []) + ); + + // add newly deposited long reserve from step 4 if not already in deposits + if ( + !this.depositKeys.find( + (k) => + k.toString() === depositCollateralConfig.collateralReserve.address + ) + ) { + this.depositKeys.push( + new PublicKey(depositCollateralConfig.collateralReserve.address) + ); + } + } + + const blockhash = await this.connection + .getLatestBlockhash() + .then((res) => res.blockhash); + + const messageV0 = new TransactionMessage({ + payerKey: this.owner, + recentBlockhash: blockhash, + instructions: ixs, + }).compileToV0Message(); + + const tx = new VersionedTransaction(messageV0); + + return { + tx, + obligationAddress: this.obligationAddress, + }; + }; + + getSolendAccountCount = () => { + const depositKeys = + this.obligation && this.obligation.deposits.length > 0 + ? this.obligation.deposits.map((ol) => new PublicKey(ol.reserveAddress)) + : []; + const borrowKeys = + this.obligation && this.obligation.borrows.length > 0 + ? this.obligation.borrows.map((ol) => new PublicKey(ol.reserveAddress)) + : []; + + const ixs: TransactionInstruction[] = []; + + ixs.push( + flashBorrowReserveLiquidityInstruction( + 0, + new PublicKey(this.shortReserve.liquidityAddress), + new PublicKey(this.shortReserveLiquidityAta), + new PublicKey(this.shortReserve.address), + new PublicKey(this.pool.address), + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + ixs.push( + repayObligationLiquidityInstruction( + 0, + new PublicKey(this.longReserveLiquidityAta), + new PublicKey(this.longReserve.liquidityAddress), + new PublicKey(this.longReserve.address), + new PublicKey(this.obligationAddress), + new PublicKey(this.pool.address), + this.owner, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + // add newly deposited long reserve from step 4 if not already in deposits + if (!depositKeys.find((k) => k.toString() === this.longReserve.address)) { + depositKeys.push(new PublicKey(this.longReserve.address)); + } + + ixs.push( + depositReserveLiquidityAndObligationCollateralInstruction( + 0, + new PublicKey(this.longReserveLiquidityAta), + new PublicKey(this.longReserveCollateralAta), + new PublicKey(this.longReserve.address), + new PublicKey(this.longReserve.liquidityAddress), + new PublicKey(this.longReserve.cTokenMint), + new PublicKey(this.pool.address), + this.lendingMarketAuthority, + new PublicKey(this.longReserve.cTokenLiquidityAddress), + this.obligationAddress, + this.owner, + new PublicKey(this.longReserve.pythOracle), + new PublicKey(this.longReserve.switchboardOracle), + this.owner, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + // 5) withdraw prev available short token to repay flash loan + depositKeys.concat(borrowKeys).forEach((k) => { + const reserve = this.pool.reserves.find( + (r) => r.address === k.toString() + ); + + if (!reserve) { + throw new Error(`Failed to find reserve for address: ${k.toString()}`); + } + + ixs.push( + refreshReserveInstruction( + new PublicKey(reserve.address), + SOLEND_PRODUCTION_PROGRAM_ID, + new PublicKey(reserve.pythOracle), + new PublicKey(reserve.switchboardOracle) + ) + ); + }); + + ixs.push( + refreshObligationInstruction( + this.obligationAddress, + depositKeys, + borrowKeys, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + ixs.push( + withdrawObligationCollateralAndRedeemReserveLiquidity( + 0, + new PublicKey(this.shortReserve.cTokenLiquidityAddress), + new PublicKey(this.shortReserveCollateralAta), + new PublicKey(this.shortReserve.address), + new PublicKey(this.obligationAddress), + new PublicKey(this.pool.address), + this.lendingMarketAuthority, + new PublicKey(this.shortReserveLiquidityAta), + new PublicKey(this.shortReserve.cTokenMint), + new PublicKey(this.shortReserve.liquidityAddress), + new PublicKey(this.owner), + new PublicKey(this.owner), + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + // 6) borrow short token amount to repay flash loan if necessary + const allKeys = depositKeys.concat(borrowKeys); + + // add new borrow key if user wasn't already borrowing from this reserve + if ( + !borrowKeys.find( + (b) => b.toString() === this.shortReserve.address.toString() + ) + ) { + allKeys.push(new PublicKey(this.shortReserve.address)); + } + + allKeys.forEach((k) => { + const reserve = this.pool.reserves.find( + (r) => r.address === k.toString() + ); + + if (!reserve) { + throw new Error(`Failed to find reserve for address: ${k.toString()}`); + } + + ixs.push( + refreshReserveInstruction( + new PublicKey(reserve.address), + SOLEND_PRODUCTION_PROGRAM_ID, + new PublicKey(reserve.pythOracle), + new PublicKey(reserve.switchboardOracle) + ) + ); + }); + + ixs.push( + refreshObligationInstruction( + new PublicKey(this.obligationAddress), + depositKeys, + borrowKeys, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + ixs.push( + borrowObligationLiquidityInstruction( + 0, + new PublicKey(this.shortReserve.liquidityAddress), + new PublicKey(this.shortReserveLiquidityAta), + new PublicKey(this.shortReserve.address), + new PublicKey(this.shortReserve.feeReceiverAddress) ?? NULL_ORACLE, + new PublicKey(this.obligationAddress), + new PublicKey(this.pool.address), + this.lendingMarketAuthority, + this.owner, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + // 7) repay flash loan + ixs.push( + flashRepayReserveLiquidityInstruction( + 0, + 0, + new PublicKey(this.shortReserveLiquidityAta), + new PublicKey(this.shortReserve.liquidityAddress), + new PublicKey(this.shortReserve.feeReceiverAddress) ?? NULL_ORACLE, + new PublicKey(this.shortReserve.feeReceiverAddress) ?? NULL_ORACLE, + new PublicKey(this.shortReserve.address), + new PublicKey(this.pool.address), + this.owner, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + const txn = new TransactionMessage({ + payerKey: this.owner, + recentBlockhash: "", + instructions: ixs, + }).compileToLegacyMessage(); + + return txn.accountKeys.length; + }; + + leverTx = async ( + swapBaseAmount: BN, + route: { + outAmount: JSBI; + slippageBps: number; + }, + swapInstructions: Array, + lookupTableAccounts: AddressLookupTableAccount[] + ) => { + const swapBaseBigNumber = new BigNumber(swapBaseAmount.toString()); + const fee = swapBaseBigNumber + .multipliedBy(new BigNumber(this.shortReserve.flashLoanFee).toString()) + .integerValue(BigNumber.ROUND_CEIL); + + let finalAddressLookupTableAccounts: AddressLookupTableAccount[] = []; + + // High level: + // 1) flash borrow short token + // 2) swap short -> long + // 3) repay prev long borrows if any + // 4) deposit remaining long after repay + // 5) withdraw prev short if any + // 6) borrow remaining short needed to repay flash loan + // 7) repay flash borrow + const ixs: TransactionInstruction[] = []; + + ixs.push( + flashBorrowReserveLiquidityInstruction( + swapBaseAmount, + new PublicKey(this.shortReserve.liquidityAddress), + new PublicKey(this.shortReserveLiquidityAta), + new PublicKey(this.shortReserve.address), + new PublicKey(this.pool.address), + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + swapInstructions.forEach((ix) => ixs.push(ix)); + finalAddressLookupTableAccounts = [...lookupTableAccounts]; + + const longBalancePostSlippage = new BigNumber(route.outAmount.toString()) + .multipliedBy(1 - route.slippageBps / 10000) + .integerValue(BigNumber.ROUND_FLOOR); + + // 3) repay any prev long borrows + const prevLongBorrowAmount = + this.obligation?.borrows + ?.find((b) => b.reserveAddress === this.longReserve.address) + ?.amount?.shiftedBy(this.longReserve.decimals) + .toString() ?? "0"; + const maxLongRepayAmount = BigNumber.min( + prevLongBorrowAmount, + longBalancePostSlippage + ); + const longBalancePostRepay = + longBalancePostSlippage.minus(maxLongRepayAmount); + if (!maxLongRepayAmount.isZero()) { + // non-zero deposit amount post repay means we need to max repay + let repayAmount; + if (longBalancePostRepay.isZero()) { + repayAmount = new BN(maxLongRepayAmount.toString()); + } else { + repayAmount = new BN(U64_MAX); + this.borrowKeys = this.borrowKeys.filter( + (k) => k.toString() !== this.longReserve.address + ); + } + + ixs.push( + repayObligationLiquidityInstruction( + repayAmount, + new PublicKey(this.longReserveLiquidityAta), + new PublicKey(this.longReserve.liquidityAddress), + new PublicKey(this.longReserve.address), + new PublicKey(this.obligationAddress), + new PublicKey(this.pool.address), + this.owner, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + } + + // 4) deposit remaining long balance + if (!longBalancePostRepay.isZero()) { + // add newly deposited long reserve from step 4 if not already in deposits + if ( + !this.depositKeys.find((k) => k.toString() === this.longReserve.address) + ) { + this.depositKeys.push(new PublicKey(this.longReserve.address)); + } + + ixs.push( + depositReserveLiquidityAndObligationCollateralInstruction( + new BN(longBalancePostRepay.toString()), + new PublicKey(this.longReserveLiquidityAta), + new PublicKey(this.longReserveCollateralAta), + new PublicKey(this.longReserve.address), + new PublicKey(this.longReserve.liquidityAddress), + new PublicKey(this.longReserve.cTokenMint), + new PublicKey(this.pool.address), + this.lendingMarketAuthority, + new PublicKey(this.longReserve.cTokenLiquidityAddress), + new PublicKey(this.obligationAddress), + this.owner, + new PublicKey(this.longReserve.pythOracle), + new PublicKey(this.longReserve.switchboardOracle), + this.owner, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + } + + // 5) withdraw prev available short token to repay flash loan + const flashLoanAmountWithFee = swapBaseBigNumber.plus(fee); + const prevShortSupplyAmount = + this.obligation?.deposits + ?.find((b) => b.reserveAddress === this.shortReserve.address) + ?.amount?.shiftedBy(this.shortReserve.decimals) ?? new BigNumber("0"); + const shortWithdrawAmount = BigNumber.min( + flashLoanAmountWithFee, + prevShortSupplyAmount + ); + const shortBorrowAmountPostWithdrawal = + flashLoanAmountWithFee.minus(shortWithdrawAmount); + + if (!shortWithdrawAmount.isZero()) { + this.depositKeys.concat(this.borrowKeys).forEach((k) => { + const reserve = this.pool.reserves.find( + (r) => r.address === k.toString() + ); + + if (!reserve) { + throw new Error( + `Failed to find reserve for address: ${k.toString()}` + ); + } + + ixs.push( + refreshReserveInstruction( + new PublicKey(reserve.address), + SOLEND_PRODUCTION_PROGRAM_ID, + new PublicKey(reserve.pythOracle), + new PublicKey(reserve.switchboardOracle) + ) + ); + }); + + ixs.push( + refreshObligationInstruction( + new PublicKey(this.obligationAddress), + this.depositKeys, + this.borrowKeys, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + const shortSupplyAmountPostWithdrawal = + prevShortSupplyAmount.minus(shortWithdrawAmount); + const shortTokenDustThreshold = dustAmountThreshold( + this.shortReserve.decimals + ); + const hasSignificantShortSupplyAmountPostWithdrawal = + shortSupplyAmountPostWithdrawal.isGreaterThan(shortTokenDustThreshold); + + // Zero borrow amount post withdrawal means we have sufficient deposit to repay the flash loan. + // If post withdrawal amount is insignificant, we can just withdraw everything. + let withdrawCtokens; + if ( + shortBorrowAmountPostWithdrawal.isZero() && + hasSignificantShortSupplyAmountPostWithdrawal + ) { + withdrawCtokens = new BN( + shortWithdrawAmount + .dividedBy(new BigNumber(this.shortReserve.cTokenExchangeRate)) + .integerValue(BigNumber.ROUND_FLOOR) + .toString() + ); + } else { + withdrawCtokens = new BN(U64_MAX); + this.depositKeys = this.depositKeys.filter( + (k) => k.toString() !== this.shortReserve.address + ); + } + + ixs.push( + withdrawObligationCollateralAndRedeemReserveLiquidity( + withdrawCtokens, + new PublicKey(this.shortReserve.cTokenLiquidityAddress), + new PublicKey(this.shortReserveCollateralAta), + new PublicKey(this.shortReserve.address), + new PublicKey(this.obligationAddress), + new PublicKey(this.pool.address), + this.lendingMarketAuthority, + new PublicKey(this.shortReserveLiquidityAta), + new PublicKey(this.shortReserve.cTokenMint), + new PublicKey(this.shortReserve.liquidityAddress), + new PublicKey(this.owner), + new PublicKey(this.owner), + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + } + console.log( + "borrow short token amount needed after withdrawwal: ", + shortBorrowAmountPostWithdrawal.toString() + ); + // 6) borrow short token amount to repay flash loan if necessary + if (!shortBorrowAmountPostWithdrawal.isZero()) { + const allKeys = this.depositKeys.concat(this.borrowKeys); + + // add new borrow key if user wasn't already borrowing from this reserve + if ( + !this.borrowKeys.find( + (b) => b.toString() === this.shortReserve.address.toString() + ) + ) { + allKeys.push(new PublicKey(this.shortReserve.address)); + } + + allKeys.forEach((k) => { + const reserve = this.pool.reserves.find( + (r) => r.address === k.toString() + ); + + if (!reserve) { + throw new Error( + `Failed to find reserve for address: ${k.toString()}` + ); + } + + ixs.push( + refreshReserveInstruction( + new PublicKey(reserve.address), + SOLEND_PRODUCTION_PROGRAM_ID, + new PublicKey(reserve.pythOracle), + new PublicKey(reserve.switchboardOracle) + ) + ); + }); + + ixs.push( + refreshObligationInstruction( + new PublicKey(this.obligationAddress), + this.depositKeys, + this.borrowKeys, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + ixs.push( + borrowObligationLiquidityInstruction( + new BN(shortBorrowAmountPostWithdrawal.toString()), + new PublicKey(this.shortReserve.liquidityAddress), + new PublicKey(this.shortReserveLiquidityAta), + new PublicKey(this.shortReserve.address), + new PublicKey(this.shortReserve.feeReceiverAddress) ?? NULL_ORACLE, + new PublicKey(this.obligationAddress), + new PublicKey(this.pool.address), + this.lendingMarketAuthority, + this.owner, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + } + + // 7) repay flash loan + ixs.push( + flashRepayReserveLiquidityInstruction( + new BN(swapBaseAmount), + 0, + new PublicKey(this.shortReserveLiquidityAta), + new PublicKey(this.shortReserve.liquidityAddress), + new PublicKey(this.shortReserve.feeReceiverAddress) ?? NULL_ORACLE, + new PublicKey(this.shortReserve.feeReceiverAddress) ?? NULL_ORACLE, + new PublicKey(this.shortReserve.address), + new PublicKey(this.pool.address), + this.owner, + SOLEND_PRODUCTION_PROGRAM_ID + ) + ); + + const blockhash = await this.connection + .getLatestBlockhash() + .then((res) => res.blockhash); + + const messageV0 = new TransactionMessage({ + payerKey: this.owner, + recentBlockhash: blockhash, + instructions: ixs, + }).compileToV0Message(finalAddressLookupTableAccounts); + + return new VersionedTransaction(messageV0); + }; +} diff --git a/solend-sdk/src/core/types.ts b/solend-sdk/src/core/types.ts index 34100e66..60828636 100644 --- a/solend-sdk/src/core/types.ts +++ b/solend-sdk/src/core/types.ts @@ -1,6 +1,7 @@ import { Cluster } from "@solana/web3.js"; import BigNumber from "bignumber.js"; import { formatReserve } from "./utils/pools"; +import { formatObligation } from "./utils"; export type PoolMetadataCoreType = { name: string | null; @@ -33,6 +34,8 @@ export type PoolType = { reserves: Array; }; +export type ObligationType = Awaited>; + export type ReserveType = Omit< Awaited>, "symbol" diff --git a/solend-sdk/src/core/utils/config.ts b/solend-sdk/src/core/utils/config.ts index 32463709..a549d923 100644 --- a/solend-sdk/src/core/utils/config.ts +++ b/solend-sdk/src/core/utils/config.ts @@ -1,12 +1,8 @@ import { Connection, PublicKey } from "@solana/web3.js"; -import { - EnvironmentType, - getProgramId, - LENDING_MARKET_SIZE, -} from "@solendprotocol/solend-sdk"; -import { SOLEND_ADDRESSES } from "../constants"; +import { LENDING_MARKET_SIZE } from "../../state"; +import { SOLEND_ADDRESSES, getProgramId } from "../constants"; +import { EnvironmentType, PoolMetadataCoreType } from "../types"; import { titleCase } from "./utils"; -import { PoolMetadataCoreType } from "@solendprotocol/solend-sdk"; export async function fetchPoolMetadata( connection: Connection, diff --git a/solend-sdk/src/core/utils/index.ts b/solend-sdk/src/core/utils/index.ts index cc2eece9..576642e7 100644 --- a/solend-sdk/src/core/utils/index.ts +++ b/solend-sdk/src/core/utils/index.ts @@ -1,7 +1,6 @@ export * from "./config"; -export * from "./metadata"; export * from "./utils"; export * from "./pools"; export * from "./obligations"; -export * from "./wallet"; export * from "./rates"; +export * from "./prices"; diff --git a/solend-sdk/src/core/utils/metadata.ts b/solend-sdk/src/core/utils/metadata.ts deleted file mode 100644 index b5e8eb71..00000000 --- a/solend-sdk/src/core/utils/metadata.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Client, Token } from "@solflare-wallet/utl-sdk"; -import { Connection, PublicKey } from "@solana/web3.js"; - -export const fetchTokensInfo = async ( - mints: string[], - connection: Connection, - debug?: boolean -) => { - if (debug) console.log("getTokensInfo"); - - const defaultConfig = new Client(); - const utl = new Client({ - ...defaultConfig.config, - connection, - }); - - const tokens: Token[] = await utl.fetchMints( - mints.map((mint) => new PublicKey(mint)) - ); - - return Object.fromEntries( - tokens - .map((token) => - token - ? [ - token.address, - { - symbol: token.symbol, - logoUri: token.logoURI, - decimals: token.decimals ?? 0, - }, - ] - : [] - ) - .filter((x) => x.length) - ); -}; diff --git a/solend-sdk/src/core/utils/obligations.ts b/solend-sdk/src/core/utils/obligations.ts index 33baff38..5902737a 100644 --- a/solend-sdk/src/core/utils/obligations.ts +++ b/solend-sdk/src/core/utils/obligations.ts @@ -1,91 +1,95 @@ import { Connection, PublicKey } from "@solana/web3.js"; import BigNumber from "bignumber.js"; -import { Obligation, parseObligation } from "../../state"; -import { PoolType } from "../types"; +import { Obligation, OBLIGATION_SIZE, parseObligation } from "../../state"; +import { ReserveType } from "../types"; +import { sha256 as sha256$1 } from "js-sha256"; import { getBatchMultipleAccountsInfo } from "./utils"; -import { U64_MAX } from "../../classes/constants"; +import { U64_MAX } from "../constants"; + +export type FormattedObligation = ReturnType; export function formatObligation( obligation: { pubkey: PublicKey; info: Obligation }, - pool: PoolType + pool: { reserves: Array } ) { const poolAddress = obligation.info.lendingMarket.toBase58(); let minPriceUserTotalSupply = new BigNumber(0); let minPriceBorrowLimit = new BigNumber(0); let maxPriceUserTotalWeightedBorrow = new BigNumber(0); - const deposits = obligation.info.deposits - .filter((d) => d.depositedAmount.toString() !== "0") - .map((d) => { - const reserveAddress = d.depositReserve.toBase58(); - const reserve = pool.reserves.find((r) => r.address === reserveAddress); + const deposits = obligation.info.deposits.map((d) => { + const reserveAddress = d.depositReserve.toBase58(); + const reserve = pool.reserves.find((r) => r.address === reserveAddress); - if (!reserve) - throw Error("Deposit in obligation does not exist in the pool"); + if (!reserve) + throw Error("Deposit in obligation does not exist in the pool"); - const amount = new BigNumber(d.depositedAmount.toString()) - .shiftedBy(-reserve.decimals) - .times(reserve.cTokenExchangeRate); - const amountUsd = amount.times(reserve.price); + const amount = new BigNumber(d.depositedAmount.toString()) + .shiftedBy(-reserve.decimals) + .times(reserve.cTokenExchangeRate); + const amountUsd = amount.times(reserve.price); - minPriceUserTotalSupply = minPriceUserTotalSupply.plus( - amount.times(reserve.minPrice) - ); + minPriceUserTotalSupply = minPriceUserTotalSupply.plus( + amount.times(reserve.minPrice) + ); - minPriceBorrowLimit = minPriceBorrowLimit.plus( - amount.times(reserve.minPrice).times(reserve.loanToValueRatio) - ); + minPriceBorrowLimit = minPriceBorrowLimit.plus( + amount.times(reserve.minPrice).times(reserve.loanToValueRatio) + ); - return { - liquidationThreshold: reserve.liquidationThreshold, - loanToValueRatio: reserve.loanToValueRatio, - symbol: reserve.symbol, - price: reserve.price, - reserveAddress, - amount, - amountUsd, - }; - }); - - const borrows = obligation.info.borrows - .filter((b) => b.borrowedAmountWads.toString() !== "0") - .map((b) => { - const reserveAddress = b.borrowReserve.toBase58(); - const reserve = pool.reserves.find((r) => r.address === reserveAddress); - if (!reserve) - throw Error("Borrow in obligation does not exist in the pool"); - - const amount = new BigNumber(b.borrowedAmountWads.toString()) - .shiftedBy(-18 - reserve.decimals) - .times(reserve.cumulativeBorrowRate) - .dividedBy( - new BigNumber(b.cumulativeBorrowRateWads.toString()).shiftedBy(-18) - ); - const amountUsd = amount.times(reserve.price); - - const maxPrice = reserve.emaPrice - ? BigNumber.max(reserve.emaPrice, reserve.price) - : reserve.price; - - maxPriceUserTotalWeightedBorrow = maxPriceUserTotalWeightedBorrow.plus( - amount - .times(maxPrice) - .times(reserve.borrowWeight ? reserve.borrowWeight : U64_MAX) + return { + liquidationThreshold: reserve.liquidationThreshold, + loanToValueRatio: reserve.loanToValueRatio, + symbol: reserve.symbol, + price: reserve.price, + mintAddress: reserve.mintAddress, + reserveAddress, + amount, + amountUsd, + annualInterest: amountUsd.multipliedBy(reserve.supplyInterest), + }; + }); + + const borrows = obligation.info.borrows.map((b) => { + const reserveAddress = b.borrowReserve.toBase58(); + const reserve = pool.reserves.find((r) => r.address === reserveAddress); + if (!reserve) + throw Error("Borrow in obligation does not exist in the pool"); + + const amount = new BigNumber(b.borrowedAmountWads.toString()) + .shiftedBy(-18 - reserve.decimals) + .times(reserve.cumulativeBorrowRate) + .dividedBy( + new BigNumber(b.cumulativeBorrowRateWads.toString()).shiftedBy(-18) ); + const amountUsd = amount.times(reserve.price); + + const maxPrice = reserve.emaPrice + ? BigNumber.max(reserve.emaPrice, reserve.price) + : reserve.price; - return { - liquidationThreshold: reserve.liquidationThreshold, - loanToValueRatio: reserve.loanToValueRatio, - symbol: reserve.symbol, - price: reserve.price, - reserveAddress, - amount, - amountUsd, - weightedAmountUsd: new BigNumber(reserve.borrowWeight).multipliedBy( - amountUsd - ), - }; - }); + maxPriceUserTotalWeightedBorrow = maxPriceUserTotalWeightedBorrow.plus( + amount + .times(maxPrice) + .times(reserve.borrowWeight ? reserve.borrowWeight : U64_MAX) + ); + + return { + liquidationThreshold: reserve.liquidationThreshold, + loanToValueRatio: reserve.loanToValueRatio, + symbol: reserve.symbol, + price: reserve.price, + reserveAddress, + mintAddress: reserve.mintAddress, + borrowWeight: reserve.borrowWeight, + amount, + amountUsd, + weightedAmountUsd: new BigNumber(reserve.borrowWeight).multipliedBy( + amountUsd + ), + annualInterest: amountUsd.multipliedBy(reserve.borrowInterest), + }; + }); const totalSupplyValue = deposits.reduce( (acc, d) => acc.plus(d.amountUsd), @@ -137,6 +141,17 @@ export function formatObligation( ? new BigNumber(0) : maxPriceUserTotalWeightedBorrow.dividedBy(minPriceBorrowLimit); + const annualSupplyInterest = deposits.reduce( + (acc, d) => d.annualInterest.plus(acc), + new BigNumber(0) + ); + const annualBorrowInterest = borrows.reduce( + (acc, b) => b.annualInterest.plus(acc), + new BigNumber(0) + ); + const netApy = annualSupplyInterest + .minus(annualBorrowInterest) + .div(netAccountValue.toString()); return { address: obligation.pubkey.toBase58(), positions, @@ -159,6 +174,7 @@ export function formatObligation( minPriceUserTotalSupply, minPriceBorrowLimit, maxPriceUserTotalWeightedBorrow, + netApy, }; } @@ -211,3 +227,91 @@ export async function fetchObligationsByAddress( return parsedObligations; } + +export async function fetchObligationsByWallet( + publicKey: PublicKey, + connection: Connection, + programId: string, + debug?: boolean +) { + if (debug) console.log("fetchObligationsByWallet"); + + const filters = [ + { dataSize: OBLIGATION_SIZE }, + { memcmp: { offset: 42, bytes: publicKey.toBase58() } }, + ]; + + const rawObligations = await connection.getProgramAccounts( + new PublicKey(programId), + { + commitment: connection.commitment, + filters, + encoding: "base64", + } + ); + + const parsedObligations = rawObligations + .map((obligation, index) => + obligation ? parseObligation(obligation.pubkey, obligation.account) : null + ) + .filter(Boolean) as Array<{ info: Obligation; pubkey: PublicKey }>; + + return parsedObligations; +} + +export async function fetchObligationsOfPoolByWallet( + publicKey: PublicKey, + poolAddress: PublicKey, + programId: PublicKey, + connection: Connection, + debug?: boolean +) { + if (debug) console.log("fetchObligationsByWallet"); + + const filters = [ + { dataSize: OBLIGATION_SIZE }, + { memcmp: { offset: 42, bytes: publicKey.toBase58() } }, + { memcmp: { offset: 10, bytes: poolAddress.toBase58() } }, + ]; + + const rawObligations = await connection.getProgramAccounts(programId, { + commitment: connection.commitment, + filters, + encoding: "base64", + }); + + const parsedObligations = rawObligations + .map((obligation) => + obligation ? parseObligation(obligation.pubkey, obligation.account) : null + ) + .filter(Boolean) as Array<{ info: Obligation; pubkey: PublicKey }>; + + return parsedObligations; +} + +function createWithSeedSync( + fromPublicKey: PublicKey, + seed: string, + programId: PublicKey +) { + const buffer = Buffer.concat([ + fromPublicKey.toBuffer(), + Buffer.from(seed), + programId.toBuffer(), + ]); + const hash = sha256$1.digest(buffer); + return new PublicKey(Buffer.from(hash)); +} + +export function getNthObligationSeed(lendingMarket: PublicKey, n: number) { + return lendingMarket.toBase58().slice(0, 24) + `0000000${n}m`.slice(-7); +} + +export function getObligationAddressWithSeed( + publicKey: PublicKey, + seed: string, + programId: PublicKey +) { + // + <7 chars: 0000001 - 9999999> + return createWithSeedSync(publicKey, seed, programId); +} diff --git a/solend-sdk/src/core/utils/pools.ts b/solend-sdk/src/core/utils/pools.ts index 2aacdcc1..604990c1 100644 --- a/solend-sdk/src/core/utils/pools.ts +++ b/solend-sdk/src/core/utils/pools.ts @@ -170,18 +170,20 @@ export function formatReserve( export const getReservesOfPool = async ( lendingMarketPubkey: PublicKey, connection: Connection, - switchboardProgram: SwitchboardProgram, programId: string, currentSlot: number, + switchboardProgram?: SwitchboardProgram, debug?: boolean ) => { if (debug) console.log("getReservesOfPool"); + let sb = + switchboardProgram ?? (await SwitchboardProgram.loadMainnet(connection)); + const filters = [ { dataSize: 619 }, { memcmp: { offset: 10, bytes: lendingMarketPubkey.toBase58() } }, ]; - const rawReserves = await connection.getProgramAccounts( new PublicKey(programId), { @@ -197,12 +199,7 @@ export const getReservesOfPool = async ( ) .filter(Boolean) as Array<{ info: Reserve; pubkey: PublicKey }>; - const prices = await fetchPrices( - parsedReserves, - connection, - switchboardProgram, - debug - ); + const prices = await fetchPrices(parsedReserves, connection, sb, debug); return parsedReserves.map((r) => formatReserve(r, prices[r.pubkey.toBase58()], currentSlot) @@ -246,3 +243,21 @@ export const getReservesFromChain = async ( formatReserve(r, prices[r.pubkey.toBase58()], currentSlot) ); }; + +export async function fetchPoolByAddress( + poolAddress: string, + connection: Connection, + debug?: boolean +) { + if (debug) console.log("fetchPoolByAddress"); + + const accountInfo = await connection.getAccountInfo( + new PublicKey(poolAddress) + ); + + if (!accountInfo) { + return null; + } + + return parseReserve(new PublicKey(poolAddress), accountInfo); +} diff --git a/solend-sdk/src/core/utils/prices.ts b/solend-sdk/src/core/utils/prices.ts index a94c9397..6181b4d8 100644 --- a/solend-sdk/src/core/utils/prices.ts +++ b/solend-sdk/src/core/utils/prices.ts @@ -1,7 +1,7 @@ import { Connection, PublicKey } from "@solana/web3.js"; import { parsePriceData } from "@pythnetwork/client"; import SwitchboardProgram from "@switchboard-xyz/sbv2-lite"; -import { Reserve } from "@solendprotocol/solend-sdk/src/state"; +import { Reserve } from "../../state"; import { getBatchMultipleAccountsInfo } from "./utils"; const SBV2_MAINNET = "SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"; diff --git a/solend-sdk/src/core/utils/wallet.ts b/solend-sdk/src/core/utils/wallet.ts deleted file mode 100644 index 1df7e024..00000000 --- a/solend-sdk/src/core/utils/wallet.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { - getAssociatedTokenAddress, - NATIVE_MINT, - unpackAccount, -} from "@solana/spl-token"; -import { Connection, LAMPORTS_PER_SOL, PublicKey } from "@solana/web3.js"; -import BigNumber from "bignumber.js"; -import { TokenMetadata, WalletType } from "../types"; -import { getBatchMultipleAccountsInfo } from "./utils"; - -export function formatWalletAssets( - rawWalletData: Awaited>, - metadata: TokenMetadata -) { - const { userAssociatedTokenAccounts, wSolAddress, nativeSolBalance } = - rawWalletData; - const assets = userAssociatedTokenAccounts - .map((parsedAccount) => { - if (!parsedAccount) return null; - const mintAddress = parsedAccount.mint.toBase58(); - const tokenMetadata = metadata[mintAddress]; - const decimals = tokenMetadata?.decimals ?? 0; - - return { - decimals, - symbol: - tokenMetadata?.symbol === "SOL" ? "wSOL" : tokenMetadata?.symbol, - address: parsedAccount.address.toBase58(), - amount: new BigNumber(parsedAccount.amount.toString()).shiftedBy( - -decimals - ), - mintAddress: tokenMetadata?.symbol === "SOL" ? "wSOL" : mintAddress, - }; - }) - .filter(Boolean) as WalletType; - - return assets.concat([ - { - decimals: Math.log10(LAMPORTS_PER_SOL), - symbol: "SOL", - address: wSolAddress, - amount: nativeSolBalance, - mintAddress: NATIVE_MINT.toBase58(), - }, - ]); -} - -export async function fetchWalletAssets( - uniqueAssets: Array, - publicKey: string, - connection: Connection, - debug?: boolean -) { - if (debug) console.log("fetchWalletAssets", uniqueAssets.length); - const userTokenAssociatedAddresses = await Promise.all( - uniqueAssets.map(async (asset) => { - const userTokenAccount = await getAssociatedTokenAddress( - new PublicKey(asset), - new PublicKey(publicKey), - true - ); - return userTokenAccount; - }) - ); - - const userAssociatedTokenAccounts = await getBatchMultipleAccountsInfo( - userTokenAssociatedAddresses, - connection - ); - - const nativeSolBalance = await connection.getBalance( - new PublicKey(publicKey) - ); - - const wSolAddress = ( - await getAssociatedTokenAddress(NATIVE_MINT, new PublicKey(publicKey), true) - ).toBase58(); - - return { - userAssociatedTokenAccounts: userAssociatedTokenAccounts.map( - (account, index) => - account - ? unpackAccount(userTokenAssociatedAddresses[index], account) - : null - ), - nativeSolBalance: new BigNumber(nativeSolBalance).dividedBy( - LAMPORTS_PER_SOL - ), - wSolAddress, - }; -} diff --git a/solend-sdk/src/experimental/break_flash_loans.ts b/solend-sdk/src/experimental/break_flash_loans.ts deleted file mode 100644 index 328eb3bd..00000000 --- a/solend-sdk/src/experimental/break_flash_loans.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* eslint-disable no-unused-vars */ -import { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js"; -import { - SOLEND_BETA_PROGRAM_ID, - SolendMarket, - flashBorrowReserveLiquidityInstruction, - flashRepayReserveLiquidityInstruction, -} from "../../dist"; -import { getAssociatedTokenAddress } from "@solana/spl-token"; - -const SOLANA_RPC_ENDPOINT = "https://api.devnet.solana.com"; - -const connection = new Connection(SOLANA_RPC_ENDPOINT); - -const WALLET_PRIVATE_KEY: number[] = JSON.parse( - process.env.WALLET_PRIVATE_KEY || "[]" -); -export const USER_KEYPAIR = Keypair.fromSecretKey( - Uint8Array.from(WALLET_PRIVATE_KEY) -); - -const getATA = async (mintAddress: PublicKey, owner: PublicKey) => { - return getAssociatedTokenAddress(mintAddress, owner); -}; - -const main = async () => { - const payer = USER_KEYPAIR; - - const lendingMarketKey = new PublicKey( - "HB1cecsgnFPBfKxEDfarVtKXEARWuViJKCqztWiFB3Uk" - ); - - // main pool - const market = await SolendMarket.initialize( - connection, - "beta", - lendingMarketKey.toString() - ); - - const solReserve = market.reserves.find( - (res) => res.config.liquidityToken.symbol == "SOL" - ); - const msolReserve = market.reserves.find( - (res) => res.config.liquidityToken.symbol == "mSOL" - ); - - if (!solReserve || !msolReserve) { - console.log("Can't find both reserves."); - return; - } - console.log(solReserve!.config.address); - - // turbo sol pool - const marketTurbo = await SolendMarket.initialize( - connection, - "beta", - "Az4MpWtMcpENQZwbEbTnrgyd2qk3wsMwQXimadUiHSQp" - ); - const solReserveTurbo = - marketTurbo.reserves.find( - (res) => res.config.liquidityToken.symbol == "SOL" - ) ?? null; - - if (!solReserveTurbo) { - console.log("Can't find turbo sol reserve"); - return; - } - - const solATA = await getATA( - new PublicKey(solReserve.config.liquidityToken.mint), - payer.publicKey - ); - - console.log(solReserveTurbo.config.liquidityAddress); - - const tx = new Transaction(); - - tx.add( - flashBorrowReserveLiquidityInstruction( - // liquidity amount - 1e9, - - // source liquidity - new PublicKey(solReserve.config.liquidityAddress), - - // destination liquidity - solATA, - - // reserve address - new PublicKey(solReserve.config.address), - - // lending market address - new PublicKey(market.config.address), - - // program id - SOLEND_BETA_PROGRAM_ID - ), - flashRepayReserveLiquidityInstruction( - // liquidity amount - 1e9, - - // index of flash borrow instruction - 0, - - // source liquidity - solATA, - - // destination liquidity - new PublicKey(solReserve.config.liquidityAddress), - - // fee receiver - new PublicKey(solReserve.config.liquidityFeeReceiverAddress), - - // host fees - solATA, - - // reserve address - new PublicKey(solReserve.config.address), - - // lending market address - new PublicKey(market.config!.address), - - // user transfer authority - payer.publicKey, - - // program id - SOLEND_BETA_PROGRAM_ID - ) - ); - - const sig = await connection.sendTransaction(tx, [payer]); - console.log(`https://solscan.io/tx/${sig}`); - - await connection.confirmTransaction(sig); -}; - -main(); diff --git a/solend-sdk/src/hooks/margin.tsx b/solend-sdk/src/hooks/margin.tsx new file mode 100644 index 00000000..9b1a3573 --- /dev/null +++ b/solend-sdk/src/hooks/margin.tsx @@ -0,0 +1,35 @@ +import React, { useEffect, useState } from "react"; +import { Connection } from "@solana/web3.js"; +import { ReserveType, fetchPoolByAddress, formatReserve } from "../core"; +import { fetchPrices } from "../core/utils/prices"; +import SwitchboardProgram from "@switchboard-xyz/sbv2-lite"; + +export function useReserve( + connection: Connection, + reserveAddress: string | null +) { + const [reserve, setReserve] = useState(); + + async function loadReserve() { + if (!reserveAddress) { + setReserve(null); + } else { + const [parsedReserve, switchboardProgram] = await Promise.all([ + fetchPoolByAddress(reserveAddress, connection), + SwitchboardProgram.loadMainnet(connection), + ]); + if (parsedReserve) { + const [prices, currentSlot] = await Promise.all([ + fetchPrices([parsedReserve], connection, switchboardProgram), + connection.getSlot(), + ]); + setReserve(formatReserve(parsedReserve, prices[0], currentSlot)); + } + } + } + useEffect(() => { + loadReserve(); + }, [reserveAddress]); + + return reserve; +} diff --git a/solend-sdk/src/hooks/obligation.tsx b/solend-sdk/src/hooks/obligation.tsx new file mode 100644 index 00000000..1e57e6e6 --- /dev/null +++ b/solend-sdk/src/hooks/obligation.tsx @@ -0,0 +1,29 @@ +import React, { useEffect, useState } from "react"; +import { Connection } from "@solana/web3.js"; +import { ReserveType, fetchObligationByAddress } from "../core"; +import { RawObligationType } from "../state"; + +export function useObligation( + connection: Connection, + reserve: ReserveType | null, + obligationAddress: string | null +) { + const [obligation, setObligation] = useState(); + + async function loadObligation() { + if (!obligationAddress || !reserve) { + setObligation(null); + } else { + const res = await fetchObligationByAddress(obligationAddress, connection); + if (res) { + setObligation(res); + } + } + } + + useEffect(() => { + loadObligation(); + }, [obligationAddress]); + + return obligation; +} diff --git a/solend-sdk/src/hooks/reserve.tsx b/solend-sdk/src/hooks/reserve.tsx new file mode 100644 index 00000000..9b1a3573 --- /dev/null +++ b/solend-sdk/src/hooks/reserve.tsx @@ -0,0 +1,35 @@ +import React, { useEffect, useState } from "react"; +import { Connection } from "@solana/web3.js"; +import { ReserveType, fetchPoolByAddress, formatReserve } from "../core"; +import { fetchPrices } from "../core/utils/prices"; +import SwitchboardProgram from "@switchboard-xyz/sbv2-lite"; + +export function useReserve( + connection: Connection, + reserveAddress: string | null +) { + const [reserve, setReserve] = useState(); + + async function loadReserve() { + if (!reserveAddress) { + setReserve(null); + } else { + const [parsedReserve, switchboardProgram] = await Promise.all([ + fetchPoolByAddress(reserveAddress, connection), + SwitchboardProgram.loadMainnet(connection), + ]); + if (parsedReserve) { + const [prices, currentSlot] = await Promise.all([ + fetchPrices([parsedReserve], connection, switchboardProgram), + connection.getSlot(), + ]); + setReserve(formatReserve(parsedReserve, prices[0], currentSlot)); + } + } + } + useEffect(() => { + loadReserve(); + }, [reserveAddress]); + + return reserve; +} diff --git a/solend-sdk/src/instructions/borrowObligationLiquidity.ts b/solend-sdk/src/instructions/borrowObligationLiquidity.ts index f29655d9..8b02e711 100644 --- a/solend-sdk/src/instructions/borrowObligationLiquidity.ts +++ b/solend-sdk/src/instructions/borrowObligationLiquidity.ts @@ -1,7 +1,7 @@ import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/depositObligationCollateral.ts b/solend-sdk/src/instructions/depositObligationCollateral.ts index 4e5c45e8..abdf065c 100644 --- a/solend-sdk/src/instructions/depositObligationCollateral.ts +++ b/solend-sdk/src/instructions/depositObligationCollateral.ts @@ -1,7 +1,7 @@ import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/depositReserveLiquidity.ts b/solend-sdk/src/instructions/depositReserveLiquidity.ts index b04bb992..be7c0c19 100644 --- a/solend-sdk/src/instructions/depositReserveLiquidity.ts +++ b/solend-sdk/src/instructions/depositReserveLiquidity.ts @@ -1,7 +1,7 @@ import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/depositReserveLiquidityAndObligationCollateral.ts b/solend-sdk/src/instructions/depositReserveLiquidityAndObligationCollateral.ts index 0546a57e..233990e5 100644 --- a/solend-sdk/src/instructions/depositReserveLiquidityAndObligationCollateral.ts +++ b/solend-sdk/src/instructions/depositReserveLiquidityAndObligationCollateral.ts @@ -1,7 +1,7 @@ import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/flashBorrowReserveLiquidity.ts b/solend-sdk/src/instructions/flashBorrowReserveLiquidity.ts index ad611513..bcb2f3d2 100644 --- a/solend-sdk/src/instructions/flashBorrowReserveLiquidity.ts +++ b/solend-sdk/src/instructions/flashBorrowReserveLiquidity.ts @@ -6,7 +6,7 @@ import { } from "@solana/web3.js"; import { findProgramAddressSync } from "@project-serum/anchor/dist/cjs/utils/pubkey"; import BN from "bn.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/flashRepayReserveLiquidity.ts b/solend-sdk/src/instructions/flashRepayReserveLiquidity.ts index b4ffb638..2669566a 100644 --- a/solend-sdk/src/instructions/flashRepayReserveLiquidity.ts +++ b/solend-sdk/src/instructions/flashRepayReserveLiquidity.ts @@ -5,7 +5,7 @@ import { TransactionInstruction, } from "@solana/web3.js"; import BN from "bn.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/forgiveDebt.ts b/solend-sdk/src/instructions/forgiveDebt.ts index d365c1c6..868771a3 100644 --- a/solend-sdk/src/instructions/forgiveDebt.ts +++ b/solend-sdk/src/instructions/forgiveDebt.ts @@ -1,6 +1,6 @@ import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import * as BufferLayout from "buffer-layout"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; import BN from "bn.js"; diff --git a/solend-sdk/src/instructions/index.ts b/solend-sdk/src/instructions/index.ts index a61dfe88..82a0dd00 100644 --- a/solend-sdk/src/instructions/index.ts +++ b/solend-sdk/src/instructions/index.ts @@ -6,8 +6,10 @@ export * from "./redeemReserveCollateral"; export * from "./refreshObligation"; export * from "./refreshReserve"; export * from "./repayObligationLiquidity"; +export * from "./repayMaxObligationLiquidity"; export * from "./withdrawObligationCollateral"; export * from "./depositReserveLiquidityAndObligationCollateral"; +export * from "./depositMaxReserveLiquidityAndObligationCollateral"; export * from "./withdrawObligationCollateralAndRedeemReserveLiquidity"; export * from "./syncNative"; export * from "./initLendingMarket"; diff --git a/solend-sdk/src/instructions/initLendingMarket.ts b/solend-sdk/src/instructions/initLendingMarket.ts index f243537b..d01c87dc 100644 --- a/solend-sdk/src/instructions/initLendingMarket.ts +++ b/solend-sdk/src/instructions/initLendingMarket.ts @@ -4,7 +4,7 @@ import { SYSVAR_RENT_PUBKEY, TransactionInstruction, } from "@solana/web3.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/initReserve.ts b/solend-sdk/src/instructions/initReserve.ts index 950a3fbc..93365b81 100644 --- a/solend-sdk/src/instructions/initReserve.ts +++ b/solend-sdk/src/instructions/initReserve.ts @@ -5,7 +5,7 @@ import { TransactionInstruction, } from "@solana/web3.js"; import BN from "bn.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { ReserveConfig } from "../state"; import { LendingInstruction } from "./instruction"; diff --git a/solend-sdk/src/instructions/redeemReserveCollateral.ts b/solend-sdk/src/instructions/redeemReserveCollateral.ts index e913b906..45b6bbe2 100644 --- a/solend-sdk/src/instructions/redeemReserveCollateral.ts +++ b/solend-sdk/src/instructions/redeemReserveCollateral.ts @@ -1,7 +1,7 @@ import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/repayObligationLiquidity.ts b/solend-sdk/src/instructions/repayObligationLiquidity.ts index 4ed5b26e..20920693 100644 --- a/solend-sdk/src/instructions/repayObligationLiquidity.ts +++ b/solend-sdk/src/instructions/repayObligationLiquidity.ts @@ -1,7 +1,7 @@ import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/setLendingMarketOwnerAndConfig.ts b/solend-sdk/src/instructions/setLendingMarketOwnerAndConfig.ts index 39969fa8..2fe16602 100644 --- a/solend-sdk/src/instructions/setLendingMarketOwnerAndConfig.ts +++ b/solend-sdk/src/instructions/setLendingMarketOwnerAndConfig.ts @@ -1,7 +1,7 @@ import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import * as BufferLayout from "buffer-layout"; import { RateLimiterConfig } from "../state/rateLimiter"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; /// Sets the new owner of a lending market. diff --git a/solend-sdk/src/instructions/updateReserveConfig.ts b/solend-sdk/src/instructions/updateReserveConfig.ts index 1daf0daa..c1b21295 100644 --- a/solend-sdk/src/instructions/updateReserveConfig.ts +++ b/solend-sdk/src/instructions/updateReserveConfig.ts @@ -1,7 +1,7 @@ import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import { RateLimiterConfig } from "../state/rateLimiter"; import { ReserveConfig } from "../state/reserve"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/withdrawObligationCollateral.ts b/solend-sdk/src/instructions/withdrawObligationCollateral.ts index a9517b92..95d6e6d7 100644 --- a/solend-sdk/src/instructions/withdrawObligationCollateral.ts +++ b/solend-sdk/src/instructions/withdrawObligationCollateral.ts @@ -1,7 +1,7 @@ import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/instructions/withdrawObligationCollateralAndRedeemReserveLiquidity.ts b/solend-sdk/src/instructions/withdrawObligationCollateralAndRedeemReserveLiquidity.ts index 1858bec5..6f46c66d 100644 --- a/solend-sdk/src/instructions/withdrawObligationCollateralAndRedeemReserveLiquidity.ts +++ b/solend-sdk/src/instructions/withdrawObligationCollateralAndRedeemReserveLiquidity.ts @@ -1,7 +1,7 @@ import { TOKEN_PROGRAM_ID } from "@solana/spl-token"; import { PublicKey, TransactionInstruction } from "@solana/web3.js"; import BN from "bn.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LendingInstruction } from "./instruction"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/utils/layout.ts b/solend-sdk/src/layout.ts similarity index 100% rename from solend-sdk/src/utils/layout.ts rename to solend-sdk/src/layout.ts diff --git a/solend-sdk/src/lib.ts b/solend-sdk/src/lib.ts index 2d850e4a..110032b7 100644 --- a/solend-sdk/src/lib.ts +++ b/solend-sdk/src/lib.ts @@ -1,3 +1,2 @@ export * from "./instructions"; export * from "./state"; -export * from "./classes"; diff --git a/solend-sdk/src/state/lastUpdate.ts b/solend-sdk/src/state/lastUpdate.ts index eb843d05..ffb97a90 100644 --- a/solend-sdk/src/state/lastUpdate.ts +++ b/solend-sdk/src/state/lastUpdate.ts @@ -1,5 +1,5 @@ import BN from "bn.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/state/lendingMarket.ts b/solend-sdk/src/state/lendingMarket.ts index 75ee0350..8fe4f0ce 100644 --- a/solend-sdk/src/state/lendingMarket.ts +++ b/solend-sdk/src/state/lendingMarket.ts @@ -1,6 +1,6 @@ import { AccountInfo, PublicKey } from "@solana/web3.js"; import * as fzstd from "fzstd"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { RateLimiter, RateLimiterLayout } from "./rateLimiter"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/state/obligation.ts b/solend-sdk/src/state/obligation.ts index 78f5d5e2..56ffd530 100644 --- a/solend-sdk/src/state/obligation.ts +++ b/solend-sdk/src/state/obligation.ts @@ -1,7 +1,7 @@ import { AccountInfo, PublicKey } from "@solana/web3.js"; import BN from "bn.js"; import * as fzstd from "fzstd"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LastUpdate, LastUpdateLayout } from "./lastUpdate"; const BufferLayout = require("buffer-layout"); @@ -24,6 +24,7 @@ export interface Obligation { borrowingIsolatedAsset: boolean; } +export type RawObligationType = ReturnType; // BN defines toJSON property, which messes up serialization // @ts-ignore BN.prototype.toJSON = undefined; diff --git a/solend-sdk/src/state/rateLimiter.ts b/solend-sdk/src/state/rateLimiter.ts index bc34a28c..ed9d1098 100644 --- a/solend-sdk/src/state/rateLimiter.ts +++ b/solend-sdk/src/state/rateLimiter.ts @@ -1,5 +1,5 @@ import BigNumber from "bignumber.js"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import BN from "bn.js"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/state/reserve.ts b/solend-sdk/src/state/reserve.ts index f85dfbc9..13befda7 100644 --- a/solend-sdk/src/state/reserve.ts +++ b/solend-sdk/src/state/reserve.ts @@ -4,7 +4,7 @@ import BN from "bn.js"; import { Buffer } from "buffer"; import * as fzstd from "fzstd"; import { RateLimiterLayout, RateLimiter } from "./rateLimiter"; -import * as Layout from "../utils/layout"; +import * as Layout from "../layout"; import { LastUpdate, LastUpdateLayout } from "./lastUpdate"; const BufferLayout = require("buffer-layout"); diff --git a/solend-sdk/src/utils/merkle_distributor.ts b/solend-sdk/src/utils/merkle_distributor.ts deleted file mode 100644 index 737e6dc4..00000000 --- a/solend-sdk/src/utils/merkle_distributor.ts +++ /dev/null @@ -1,492 +0,0 @@ -export const MERKLE_PROGRAM_ID = "mrksLcZ6rMs9xkmJgw6oKiR3GECw44Gb5NeDqu64kiw"; - -export type MerkleDistributorIDL = { - version: "0.0.0"; - name: "merkle_distributor"; - instructions: [ - { - name: "newDistributor"; - accounts: [ - { - name: "base"; - isMut: false; - isSigner: true; - }, - { - name: "distributor"; - isMut: true; - isSigner: false; - }, - { - name: "mint"; - isMut: false; - isSigner: false; - }, - { - name: "payer"; - isMut: false; - isSigner: true; - }, - { - name: "systemProgram"; - isMut: false; - isSigner: false; - } - ]; - args: [ - { - name: "bump"; - type: "u8"; - }, - { - name: "root"; - type: { - array: ["u8", 32]; - }; - }, - { - name: "maxTotalClaim"; - type: "u64"; - }, - { - name: "maxNumNodes"; - type: "u64"; - } - ]; - }, - { - name: "claim"; - accounts: [ - { - name: "distributor"; - isMut: true; - isSigner: false; - }, - { - name: "claimStatus"; - isMut: true; - isSigner: false; - }, - { - name: "from"; - isMut: true; - isSigner: false; - }, - { - name: "to"; - isMut: true; - isSigner: false; - }, - { - name: "claimant"; - isMut: false; - isSigner: true; - }, - { - name: "payer"; - isMut: false; - isSigner: true; - }, - { - name: "systemProgram"; - isMut: false; - isSigner: false; - }, - { - name: "tokenProgram"; - isMut: false; - isSigner: false; - } - ]; - args: [ - { - name: "bump"; - type: "u8"; - }, - { - name: "index"; - type: "u64"; - }, - { - name: "amount"; - type: "u64"; - }, - { - name: "proof"; - type: { - vec: { - array: ["u8", 32]; - }; - }; - } - ]; - } - ]; - accounts: [ - { - name: "merkleDistributor" | "MerkleDistributor"; - type: { - kind: "struct"; - fields: [ - { - name: "base"; - type: "publicKey"; - }, - { - name: "bump"; - type: "u8"; - }, - { - name: "root"; - type: { - array: ["u8", 32]; - }; - }, - { - name: "mint"; - type: "publicKey"; - }, - { - name: "maxTotalClaim"; - type: "u64"; - }, - { - name: "maxNumNodes"; - type: "u64"; - }, - { - name: "totalAmountClaimed"; - type: "u64"; - }, - { - name: "numNodesClaimed"; - type: "u64"; - } - ]; - }; - }, - { - name: "claimStatus" | "ClaimStatus"; - type: { - kind: "struct"; - fields: [ - { - name: "isClaimed"; - type: "bool"; - }, - { - name: "claimant"; - type: "publicKey"; - }, - { - name: "claimedAt"; - type: "i64"; - }, - { - name: "amount"; - type: "u64"; - } - ]; - }; - } - ]; - events: [ - { - name: "ClaimedEvent"; - fields: [ - { - name: "index"; - type: "u64"; - index: false; - }, - { - name: "claimant"; - type: "publicKey"; - index: false; - }, - { - name: "amount"; - type: "u64"; - index: false; - } - ]; - } - ]; - errors: [ - { - code: 300; - name: "InvalidProof"; - msg: "Invalid Merkle proof."; - }, - { - code: 301; - name: "DropAlreadyClaimed"; - msg: "Drop already claimed."; - }, - { - code: 302; - name: "ExceededMaxClaim"; - msg: "Exceeded maximum claim amount."; - }, - { - code: 303; - name: "ExceededMaxNumNodes"; - msg: "Exceeded maximum number of claimed nodes."; - }, - { - code: 304; - name: "Unauthorized"; - msg: "Account is not authorized to execute this instruction"; - }, - { - code: 305; - name: "OwnerMismatch"; - msg: "Token account owner did not match intended owner"; - } - ]; -}; -export const MerkleDistributorJSON: MerkleDistributorIDL = { - version: "0.0.0", - name: "merkle_distributor", - instructions: [ - { - name: "newDistributor", - accounts: [ - { - name: "base", - isMut: false, - isSigner: true, - }, - { - name: "distributor", - isMut: true, - isSigner: false, - }, - { - name: "mint", - isMut: false, - isSigner: false, - }, - { - name: "payer", - isMut: false, - isSigner: true, - }, - { - name: "systemProgram", - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: "bump", - type: "u8", - }, - { - name: "root", - type: { - array: ["u8", 32], - }, - }, - { - name: "maxTotalClaim", - type: "u64", - }, - { - name: "maxNumNodes", - type: "u64", - }, - ], - }, - { - name: "claim", - accounts: [ - { - name: "distributor", - isMut: true, - isSigner: false, - }, - { - name: "claimStatus", - isMut: true, - isSigner: false, - }, - { - name: "from", - isMut: true, - isSigner: false, - }, - { - name: "to", - isMut: true, - isSigner: false, - }, - { - name: "claimant", - isMut: false, - isSigner: true, - }, - { - name: "payer", - isMut: false, - isSigner: true, - }, - { - name: "systemProgram", - isMut: false, - isSigner: false, - }, - { - name: "tokenProgram", - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: "bump", - type: "u8", - }, - { - name: "index", - type: "u64", - }, - { - name: "amount", - type: "u64", - }, - { - name: "proof", - type: { - vec: { - array: ["u8", 32], - }, - }, - }, - ], - }, - ], - accounts: [ - { - name: "MerkleDistributor", - type: { - kind: "struct", - fields: [ - { - name: "base", - type: "publicKey", - }, - { - name: "bump", - type: "u8", - }, - { - name: "root", - type: { - array: ["u8", 32], - }, - }, - { - name: "mint", - type: "publicKey", - }, - { - name: "maxTotalClaim", - type: "u64", - }, - { - name: "maxNumNodes", - type: "u64", - }, - { - name: "totalAmountClaimed", - type: "u64", - }, - { - name: "numNodesClaimed", - type: "u64", - }, - ], - }, - }, - { - name: "ClaimStatus", - type: { - kind: "struct", - fields: [ - { - name: "isClaimed", - type: "bool", - }, - { - name: "claimant", - type: "publicKey", - }, - { - name: "claimedAt", - type: "i64", - }, - { - name: "amount", - type: "u64", - }, - ], - }, - }, - ], - events: [ - { - name: "ClaimedEvent", - fields: [ - { - name: "index", - type: "u64", - index: false, - }, - { - name: "claimant", - type: "publicKey", - index: false, - }, - { - name: "amount", - type: "u64", - index: false, - }, - ], - }, - ], - errors: [ - { - code: 300, - name: "InvalidProof", - msg: "Invalid Merkle proof.", - }, - { - code: 301, - name: "DropAlreadyClaimed", - msg: "Drop already claimed.", - }, - { - code: 302, - name: "ExceededMaxClaim", - msg: "Exceeded maximum claim amount.", - }, - { - code: 303, - name: "ExceededMaxNumNodes", - msg: "Exceeded maximum number of claimed nodes.", - }, - { - code: 304, - name: "Unauthorized", - msg: "Account is not authorized to execute this instruction", - }, - { - code: 305, - name: "OwnerMismatch", - msg: "Token account owner did not match intended owner", - }, - ], -}; diff --git a/solend-sdk/src/utils/rpc/cached.ts b/solend-sdk/src/utils/rpc/cached.ts deleted file mode 100644 index 98436b8e..00000000 --- a/solend-sdk/src/utils/rpc/cached.ts +++ /dev/null @@ -1,303 +0,0 @@ -import { - AccountInfo, - AddressLookupTableAccount, - Blockhash, - BlockhashWithExpiryBlockHeight, - BlockheightBasedTransactionConfirmationStrategy, - Commitment, - ConfirmedSignatureInfo, - ConfirmedSignaturesForAddress2Options, - FeeCalculator, - Finality, - GetAccountInfoConfig, - GetLatestBlockhashConfig, - GetMultipleAccountsConfig, - GetProgramAccountsConfig, - GetProgramAccountsResponse, - GetSlotConfig, - GetTransactionConfig, - GetVersionedTransactionConfig, - PublicKey, - RpcResponseAndContext, - SendOptions, - SignatureResult, - SimulatedTransactionResponse, - SimulateTransactionConfig, - TokenAmount, - TransactionResponse, - TransactionSignature, - VersionedTransaction, - VersionedTransactionResponse, -} from "@solana/web3.js"; -import { SolendRPCConnection } from "./interface"; - -export interface RPCCacheInterface { - get(key: string): Promise; - set(key: string, value: any): Promise; -} - -type CachedObject = { - timestamp: number; - value: any; -}; - -export class InMemoryCache implements RPCCacheInterface { - expireMS: number; - maxCacheSize: number | null; - data: { [key: string]: CachedObject | null }; - - constructor(expireMS: number, maxCacheSize: number | null = null) { - this.expireMS = expireMS; - this.maxCacheSize = maxCacheSize; - this.data = {}; - } - - async get(key: string) { - const cachedObject = this.data[key]; - if (cachedObject === undefined || cachedObject === null) { - return null; - } - const msElapsed = Date.now() - cachedObject.timestamp; - if (msElapsed > this.expireMS) { - this.data[key] = null; - return null; - } - return cachedObject.value; - } - - async set(key: string, valuePromise: Promise) { - const value = await valuePromise; - this.data[key] = { - timestamp: Date.now(), - value: value, - }; - // We don't want to let the cache get infinitely big - // so we just discard the oldest item - if ( - this.maxCacheSize !== null && - Object.keys(this.data).length === this.maxCacheSize - ) { - delete this.data[Object.keys(this.data)[0]]; - } - return value; - } -} - -// Wraps a cache around a connection. You can define a custom cache by -// implementing the RPCCache interface -export class CachedConnection implements SolendRPCConnection { - connection: SolendRPCConnection; - cache: RPCCacheInterface; - public rpcEndpoint: string; - - constructor(connection: SolendRPCConnection, cache: RPCCacheInterface) { - this.connection = connection; - this.rpcEndpoint = this.connection.rpcEndpoint; - this.cache = cache; - } - - async getAccountInfo( - publicKey: PublicKey, - commitmentOrConfig?: Commitment | GetAccountInfoConfig - ): Promise | null> { - const key = `getAccountInfo_${publicKey.toBase58()}_${commitmentOrConfig}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getAccountInfo(publicKey, commitmentOrConfig) - )) - ); - } - - async getConfirmedSignaturesForAddress2( - address: PublicKey, - options?: ConfirmedSignaturesForAddress2Options, - commitment?: Finality - ): Promise> { - const key = `getConfirmedSignaturesForAddress2_${address.toBase58()}_${JSON.stringify( - options - )}_${commitment}}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getConfirmedSignaturesForAddress2( - address, - options, - commitment - ) - )) - ); - } - - async getLatestBlockhash( - commitmentOrConfig?: Commitment | GetLatestBlockhashConfig - ): Promise { - const key = `getLatestBlockhash_${commitmentOrConfig}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getLatestBlockhash(commitmentOrConfig) - )) - ); - } - - async getMultipleAccountsInfo( - publicKeys: PublicKey[], - commitmentOrConfig?: Commitment | GetMultipleAccountsConfig - ): Promise<(AccountInfo | null)[]> { - const key = `getMultipleAccountsInfo_${publicKeys - .map((pk) => pk.toBase58) - .join("_")}_${JSON.stringify(commitmentOrConfig)}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getMultipleAccountsInfo(publicKeys, commitmentOrConfig) - )) - ); - } - - async getProgramAccounts( - programId: PublicKey, - configOrCommitment?: GetProgramAccountsConfig | Commitment - ): Promise> { - const key = `getProgramAccounts_${programId.toBase58()}_${JSON.stringify( - configOrCommitment - )}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getProgramAccounts(programId, configOrCommitment) - )) - ); - } - - async getRecentBlockhash(commitment?: Commitment): Promise<{ - blockhash: Blockhash; - feeCalculator: FeeCalculator; - }> { - const key = `getRecentBlockhash_${commitment}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getRecentBlockhash(commitment) - )) - ); - } - - async getSlot( - commitmentOrConfig?: Commitment | GetSlotConfig - ): Promise { - const key = `getSlot_${commitmentOrConfig}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set(key, this.connection.getSlot(commitmentOrConfig))) - ); - } - - async getTokenAccountBalance( - tokenAddress: PublicKey, - commitment?: Commitment - ): Promise> { - const key = `getTokenAccountBalance_${tokenAddress.toBase58()}_${commitment}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getTokenAccountBalance(tokenAddress, commitment) - )) - ); - } - - async getTokenSupply( - tokenMintAddress: PublicKey, - commitment?: Commitment - ): Promise> { - const key = `getTokenSupply_${tokenMintAddress.toBase58()}_${commitment}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getTokenSupply(tokenMintAddress, commitment) - )) - ); - } - - async getTransaction( - signature: string, - rawConfig?: GetTransactionConfig - ): Promise; - - async getTransaction( - signature: string, - rawConfig: GetVersionedTransactionConfig - ): Promise { - const key = `getTransaction_${signature}_${JSON.stringify(rawConfig)}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getTransaction(signature, rawConfig) - )) - ); - } - - // This does not make sense to cache, so we don't - async sendTransaction( - transaction: VersionedTransaction, - options?: SendOptions - ): Promise { - return await this.connection.sendTransaction(transaction, options); - } - - async simulateTransaction( - transaction: VersionedTransaction, - config?: SimulateTransactionConfig - ): Promise> { - const key = `simulateTransaction_${JSON.stringify( - transaction - )}_${JSON.stringify(config)}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.simulateTransaction(transaction, config) - )) - ); - } - - async getAddressLookupTable( - accountKey: PublicKey, - config?: GetAccountInfoConfig - ): Promise> { - const key = `getAddressLookupTable_${accountKey.toBase58()}_${JSON.stringify( - config - )}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.getAddressLookupTable(accountKey, config) - )) - ); - } - - async confirmTransaction( - strategy: BlockheightBasedTransactionConfirmationStrategy, - commitment?: Commitment - ): Promise> { - const key = `confirmTransaction_${JSON.stringify(strategy)}_${commitment}`; - return ( - (await this.cache.get(key)) || - (await this.cache.set( - key, - this.connection.confirmTransaction(strategy, commitment) - )) - ); - } -} diff --git a/solend-sdk/src/utils/rpc/index.ts b/solend-sdk/src/utils/rpc/index.ts deleted file mode 100644 index 1cc52c7b..00000000 --- a/solend-sdk/src/utils/rpc/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./instrumented"; -export * from "./interface"; -export * from "./multi"; -export * from "./retry"; -export * from "./cached"; diff --git a/solend-sdk/src/utils/rpc/instrumented.ts b/solend-sdk/src/utils/rpc/instrumented.ts deleted file mode 100644 index 912746f8..00000000 --- a/solend-sdk/src/utils/rpc/instrumented.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { - AccountInfo, - AddressLookupTableAccount, - Blockhash, - BlockhashWithExpiryBlockHeight, - BlockheightBasedTransactionConfirmationStrategy, - Commitment, - ConfirmedSignatureInfo, - ConfirmedSignaturesForAddress2Options, - FeeCalculator, - Finality, - GetAccountInfoConfig, - GetLatestBlockhashConfig, - GetMultipleAccountsConfig, - GetProgramAccountsConfig, - GetProgramAccountsResponse, - GetSlotConfig, - GetTransactionConfig, - GetVersionedTransactionConfig, - PublicKey, - RpcResponseAndContext, - SendOptions, - SignatureResult, - SimulatedTransactionResponse, - SimulateTransactionConfig, - TokenAmount, - TransactionResponse, - TransactionSignature, - VersionedTransaction, - VersionedTransactionResponse, -} from "@solana/web3.js"; -import { StatsD } from "hot-shots"; -import { SolendRPCConnection } from "./interface"; - -// Adds statsd metrics to RPC calls -export class InstrumentedConnection implements SolendRPCConnection { - connection: SolendRPCConnection; - statsd: StatsD; - prefix: string; - public rpcEndpoint: string; - - constructor( - connection: SolendRPCConnection, - statsd: StatsD, - prefix: string = "" - ) { - this.connection = connection; - this.statsd = statsd; - this.prefix = prefix; - this.rpcEndpoint = this.connection.rpcEndpoint; - } - - getAccountInfo( - publicKey: PublicKey, - commitmentOrConfig?: Commitment | GetAccountInfoConfig - ): Promise | null> { - return this.withStats( - this.connection.getAccountInfo(publicKey, commitmentOrConfig), - "getAccountInfo" - ); - } - - getConfirmedSignaturesForAddress2( - address: PublicKey, - options?: ConfirmedSignaturesForAddress2Options, - commitment?: Finality - ): Promise> { - return this.withStats( - this.connection.getConfirmedSignaturesForAddress2( - address, - options, - commitment - ), - "getConfirmedSignaturesForAddress2" - ); - } - - getLatestBlockhash( - commitmentOrConfig?: Commitment | GetLatestBlockhashConfig - ): Promise { - return this.withStats( - this.connection.getLatestBlockhash(commitmentOrConfig), - "getLatestBlockhash" - ); - } - - getMultipleAccountsInfo( - publicKeys: PublicKey[], - commitmentOrConfig?: Commitment | GetMultipleAccountsConfig - ): Promise<(AccountInfo | null)[]> { - return this.withStats( - this.connection.getMultipleAccountsInfo(publicKeys, commitmentOrConfig), - "getMultipleAccountsInfo" - ); - } - - getProgramAccounts( - programId: PublicKey, - configOrCommitment?: GetProgramAccountsConfig | Commitment - ): Promise> { - return this.withStats( - this.connection.getProgramAccounts(programId, configOrCommitment), - "getProgramAccounts" - ); - } - - getRecentBlockhash(commitment?: Commitment): Promise<{ - blockhash: Blockhash; - feeCalculator: FeeCalculator; - }> { - return this.withStats( - this.connection.getRecentBlockhash(commitment), - "getRecentBlockhash" - ); - } - - getSlot(commitmentOrConfig?: Commitment | GetSlotConfig): Promise { - return this.withStats( - this.connection.getSlot(commitmentOrConfig), - "getSlot" - ); - } - - getTokenAccountBalance( - tokenAddress: PublicKey, - commitment?: Commitment - ): Promise> { - return this.withStats( - this.connection.getTokenAccountBalance(tokenAddress, commitment), - "getTokenAccountBalance" - ); - } - - getTokenSupply( - tokenMintAddress: PublicKey, - commitment?: Commitment - ): Promise> { - return this.withStats( - this.connection.getTokenSupply(tokenMintAddress, commitment), - "getTokenSupply" - ); - } - - getTransaction( - signature: string, - rawConfig?: GetTransactionConfig - ): Promise; - - getTransaction( - signature: string, - rawConfig: GetVersionedTransactionConfig - ): Promise { - return this.withStats( - this.connection.getTransaction(signature, rawConfig), - "getTransaction" - ); - } - - sendTransaction( - transaction: VersionedTransaction, - options?: SendOptions - ): Promise { - return this.withStats( - this.connection.sendTransaction(transaction, options), - "sendTransaction" - ); - } - - simulateTransaction( - transaction: VersionedTransaction, - config?: SimulateTransactionConfig - ): Promise> { - return this.withStats( - this.connection.simulateTransaction(transaction, config), - "simulateTransaction" - ); - } - - getAddressLookupTable( - accountKey: PublicKey, - config?: GetAccountInfoConfig - ): Promise> { - return this.withStats( - this.connection.getAddressLookupTable(accountKey, config), - "getAddressLookupTable" - ); - } - - async confirmTransaction( - strategy: BlockheightBasedTransactionConfirmationStrategy, - commitment?: Commitment - ): Promise> { - return this.withStats( - this.connection.confirmTransaction(strategy, commitment), - "confirmTransaction" - ); - } - - async withStats(fn: Promise, fnName: string) { - const tags = [`rpc:${this.prefix}`, `function:${fnName}`]; - this.statsd.increment("rpc_method_call", tags); - const start = Date.now(); - let result; - try { - result = await fn; - } catch (e: any) { - this.statsd.increment("rpc_method_error", tags); - throw e; - } - const duration = Date.now() - start; - this.statsd.gauge("rpc_method_duration", duration, tags); - return result; - } -} diff --git a/solend-sdk/src/utils/rpc/interface.ts b/solend-sdk/src/utils/rpc/interface.ts deleted file mode 100644 index 75da66ac..00000000 --- a/solend-sdk/src/utils/rpc/interface.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { - AccountInfo, - AddressLookupTableAccount, - Blockhash, - BlockhashWithExpiryBlockHeight, - BlockheightBasedTransactionConfirmationStrategy, - Commitment, - ConfirmedSignatureInfo, - ConfirmedSignaturesForAddress2Options, - FeeCalculator, - Finality, - GetAccountInfoConfig, - GetLatestBlockhashConfig, - GetMultipleAccountsConfig, - GetProgramAccountsConfig, - GetProgramAccountsResponse, - GetSlotConfig, - GetTransactionConfig, - GetVersionedTransactionConfig, - PublicKey, - RpcResponseAndContext, - SendOptions, - SignatureResult, - SimulatedTransactionResponse, - SimulateTransactionConfig, - TokenAmount, - TransactionResponse, - TransactionSignature, - VersionedTransaction, - VersionedTransactionResponse, -} from "@solana/web3.js"; - -// Connection and and all *Connection classes should implement -// SolendRPCConnection -export interface SolendRPCConnection { - rpcEndpoint: string; - - getAccountInfo( - publicKey: PublicKey, - commitmentOrConfig?: Commitment | GetAccountInfoConfig - ): Promise | null>; - getConfirmedSignaturesForAddress2( - address: PublicKey, - options?: ConfirmedSignaturesForAddress2Options, - commitment?: Finality - ): Promise>; - getLatestBlockhash( - commitmentOrConfig?: Commitment | GetLatestBlockhashConfig - ): Promise; - getMultipleAccountsInfo( - publicKeys: PublicKey[], - commitmentOrConfig?: Commitment | GetMultipleAccountsConfig - ): Promise<(AccountInfo | null)[]>; - getProgramAccounts( - programId: PublicKey, - configOrCommitment?: GetProgramAccountsConfig | Commitment - ): Promise>; - getRecentBlockhash(commitment?: Commitment): Promise<{ - blockhash: Blockhash; - feeCalculator: FeeCalculator; - }>; - getSlot(commitmentOrConfig?: Commitment | GetSlotConfig): Promise; - getTokenAccountBalance( - tokenAddress: PublicKey, - commitment?: Commitment - ): Promise>; - getTokenSupply( - tokenMintAddress: PublicKey, - commitment?: Commitment - ): Promise>; - getTransaction( - signature: string, - rawConfig?: GetTransactionConfig - ): Promise; - getTransaction( - signature: string, - rawConfig: GetVersionedTransactionConfig - ): Promise; - sendTransaction( - transaction: VersionedTransaction, - options?: SendOptions - ): Promise; - simulateTransaction( - transaction: VersionedTransaction, - config?: SimulateTransactionConfig - ): Promise>; - getAddressLookupTable( - accountKey: PublicKey, - config?: GetAccountInfoConfig - ): Promise>; - confirmTransaction( - strategy: BlockheightBasedTransactionConfirmationStrategy, - commitment?: Commitment - ): Promise>; -} diff --git a/solend-sdk/src/utils/rpc/multi.ts b/solend-sdk/src/utils/rpc/multi.ts deleted file mode 100644 index 5accd3cf..00000000 --- a/solend-sdk/src/utils/rpc/multi.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { - AccountInfo, - AddressLookupTableAccount, - Blockhash, - BlockhashWithExpiryBlockHeight, - BlockheightBasedTransactionConfirmationStrategy, - Commitment, - ConfirmedSignatureInfo, - ConfirmedSignaturesForAddress2Options, - FeeCalculator, - Finality, - GetAccountInfoConfig, - GetLatestBlockhashConfig, - GetMultipleAccountsConfig, - GetProgramAccountsConfig, - GetProgramAccountsResponse, - GetSlotConfig, - GetTransactionConfig, - GetVersionedTransactionConfig, - PublicKey, - RpcResponseAndContext, - SendOptions, - SignatureResult, - SimulatedTransactionResponse, - SimulateTransactionConfig, - TokenAmount, - TransactionResponse, - TransactionSignature, - VersionedTransaction, - VersionedTransactionResponse, -} from "@solana/web3.js"; -import { SolendRPCConnection } from "./interface"; - -// MultiConnection implements SolendRPCConnection -// The default connection is index 0, the rest are backups. -// The default connection's result gets returned as soon as possible -// If the default connection takes longer than backupDelay ms to return, -// the first backup connection to return gets returned. -export class MultiConnection implements SolendRPCConnection { - public rpcEndpoint: string; - delay: number; - connections: SolendRPCConnection[]; - - constructor(connections: SolendRPCConnection[], backupDelay: number = 500) { - this.connections = connections; - this.rpcEndpoint = this.connections[0].rpcEndpoint; - this.delay = backupDelay; - } - - getAccountInfo( - publicKey: PublicKey, - commitmentOrConfig?: Commitment | GetAccountInfoConfig - ): Promise | null> { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.getAccountInfo(publicKey, commitmentOrConfig) - ) - ) - ); - } - - getConfirmedSignaturesForAddress2( - address: PublicKey, - options?: ConfirmedSignaturesForAddress2Options, - commitment?: Finality - ): Promise> { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.getConfirmedSignaturesForAddress2(address, options, commitment) - ) - ) - ); - } - - getLatestBlockhash( - commitmentOrConfig?: Commitment | GetLatestBlockhashConfig - ): Promise { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.getLatestBlockhash(commitmentOrConfig) - ) - ) - ); - } - - getMultipleAccountsInfo( - publicKeys: PublicKey[], - commitmentOrConfig?: Commitment | GetMultipleAccountsConfig - ): Promise<(AccountInfo | null)[]> { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.getMultipleAccountsInfo(publicKeys, commitmentOrConfig) - ) - ) - ); - } - - getProgramAccounts( - programId: PublicKey, - configOrCommitment?: GetProgramAccountsConfig | Commitment - ): Promise> { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.getProgramAccounts(programId, configOrCommitment) - ) - ) - ); - } - - getRecentBlockhash(commitment?: Commitment): Promise<{ - blockhash: Blockhash; - feeCalculator: FeeCalculator; - }> { - return Promise.race( - this.connections.map((c, index) => - delayed(index === 0 ? 0 : this.delay, c.getRecentBlockhash(commitment)) - ) - ); - } - - getSlot(commitmentOrConfig?: Commitment | GetSlotConfig): Promise { - return Promise.race( - this.connections.map((c, index) => - delayed(index === 0 ? 0 : this.delay, c.getSlot(commitmentOrConfig)) - ) - ); - } - - getTokenAccountBalance( - tokenAddress: PublicKey, - commitment?: Commitment - ): Promise> { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.getTokenAccountBalance(tokenAddress, commitment) - ) - ) - ); - } - - getTokenSupply( - tokenMintAddress: PublicKey, - commitment?: Commitment - ): Promise> { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.getTokenSupply(tokenMintAddress, commitment) - ) - ) - ); - } - - getTransaction( - signature: string, - rawConfig?: GetTransactionConfig - ): Promise; - getTransaction( - signature: string, - rawConfig: GetVersionedTransactionConfig - ): Promise { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.getTransaction(signature, rawConfig) - ) - ) - ); - } - - // Does it make sense to do multiple instances of this? - sendTransaction( - transaction: VersionedTransaction, - options?: SendOptions - ): Promise { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.sendTransaction(transaction, options) - ) - ) - ); - } - - simulateTransaction( - transaction: VersionedTransaction, - config?: SimulateTransactionConfig - ): Promise> { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.simulateTransaction(transaction, config) - ) - ) - ); - } - - getAddressLookupTable( - accountKey: PublicKey, - config?: GetAccountInfoConfig - ): Promise> { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.getAddressLookupTable(accountKey, config) - ) - ) - ); - } - - confirmTransaction( - strategy: BlockheightBasedTransactionConfirmationStrategy, - commitment?: Commitment - ): Promise> { - return Promise.race( - this.connections.map((c, index) => - delayed( - index === 0 ? 0 : this.delay, - c.confirmTransaction(strategy, commitment) - ) - ) - ); - } -} - -const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); - -async function delayed(ms: number, promise: any) { - const promises = [promise, sleep(ms)]; - return (await Promise.all(promises))[0]; -} diff --git a/solend-sdk/src/utils/rpc/retry.ts b/solend-sdk/src/utils/rpc/retry.ts deleted file mode 100644 index 15f064f4..00000000 --- a/solend-sdk/src/utils/rpc/retry.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { - AccountInfo, - AddressLookupTableAccount, - Blockhash, - BlockhashWithExpiryBlockHeight, - BlockheightBasedTransactionConfirmationStrategy, - Commitment, - ConfirmedSignatureInfo, - ConfirmedSignaturesForAddress2Options, - FeeCalculator, - Finality, - GetAccountInfoConfig, - GetLatestBlockhashConfig, - GetMultipleAccountsConfig, - GetProgramAccountsConfig, - GetProgramAccountsResponse, - GetSlotConfig, - GetTransactionConfig, - GetVersionedTransactionConfig, - PublicKey, - RpcResponseAndContext, - SendOptions, - SignatureResult, - SimulatedTransactionResponse, - SimulateTransactionConfig, - TokenAmount, - TransactionResponse, - TransactionSignature, - VersionedTransaction, - VersionedTransactionResponse, -} from "@solana/web3.js"; -import { SolendRPCConnection } from "./interface"; - -// Adds retries to RPC Calls -export class RetryConnection implements SolendRPCConnection { - connection: SolendRPCConnection; - maxRetries: number; - public rpcEndpoint: string; - constructor(connection: SolendRPCConnection, maxRetries: number = 3) { - this.connection = connection; - this.maxRetries = maxRetries; - this.rpcEndpoint = this.connection.rpcEndpoint; - } - - getAccountInfo( - publicKey: PublicKey, - commitmentOrConfig?: Commitment | GetAccountInfoConfig - ): Promise | null> { - return this.withRetries( - this.connection.getAccountInfo(publicKey, commitmentOrConfig) - ); - } - - getConfirmedSignaturesForAddress2( - address: PublicKey, - options?: ConfirmedSignaturesForAddress2Options, - commitment?: Finality - ): Promise> { - return this.withRetries( - this.connection.getConfirmedSignaturesForAddress2( - address, - options, - commitment - ) - ); - } - - getLatestBlockhash( - commitmentOrConfig?: Commitment | GetLatestBlockhashConfig - ): Promise { - return this.withRetries( - this.connection.getLatestBlockhash(commitmentOrConfig) - ); - } - - getMultipleAccountsInfo( - publicKeys: PublicKey[], - commitmentOrConfig?: Commitment | GetMultipleAccountsConfig - ): Promise<(AccountInfo | null)[]> { - return this.withRetries( - this.connection.getMultipleAccountsInfo(publicKeys, commitmentOrConfig) - ); - } - - getProgramAccounts( - programId: PublicKey, - configOrCommitment?: GetProgramAccountsConfig | Commitment - ): Promise> { - return this.withRetries( - this.connection.getProgramAccounts(programId, configOrCommitment) - ); - } - - getRecentBlockhash(commitment?: Commitment): Promise<{ - blockhash: Blockhash; - feeCalculator: FeeCalculator; - }> { - return this.withRetries(this.connection.getRecentBlockhash(commitment)); - } - - getSlot(commitmentOrConfig?: Commitment | GetSlotConfig): Promise { - return this.withRetries(this.connection.getSlot(commitmentOrConfig)); - } - - getTokenAccountBalance( - tokenAddress: PublicKey, - commitment?: Commitment - ): Promise> { - return this.withRetries( - this.connection.getTokenAccountBalance(tokenAddress, commitment) - ); - } - - getTokenSupply( - tokenMintAddress: PublicKey, - commitment?: Commitment - ): Promise> { - return this.withRetries( - this.connection.getTokenSupply(tokenMintAddress, commitment) - ); - } - - getTransaction( - signature: string, - rawConfig?: GetTransactionConfig - ): Promise; - getTransaction( - signature: string, - rawConfig: GetVersionedTransactionConfig - ): Promise { - return this.withRetries( - this.connection.getTransaction(signature, rawConfig) - ); - } - - sendTransaction( - transaction: VersionedTransaction, - options?: SendOptions - ): Promise { - return this.withRetries( - this.connection.sendTransaction(transaction, options) - ); - } - - simulateTransaction( - transaction: VersionedTransaction, - config?: SimulateTransactionConfig - ): Promise> { - return this.withRetries( - this.connection.simulateTransaction(transaction, config) - ); - } - - getAddressLookupTable( - accountKey: PublicKey, - config?: GetAccountInfoConfig - ): Promise> { - return this.withRetries( - this.connection.getAddressLookupTable(accountKey, config) - ); - } - - confirmTransaction( - strategy: BlockheightBasedTransactionConfirmationStrategy, - commitment?: Commitment - ): Promise> { - return this.withRetries( - this.connection.confirmTransaction(strategy, commitment) - ); - } - - async withRetries(fn: Promise) { - let numTries = 0; - let lastException; - while (numTries <= this.maxRetries) { - try { - return await fn; - } catch (e: any) { - lastException = e; - numTries += 1; - } - } - throw lastException; - } -}