mirror of https://github.com/certusone/oyster.git
refactoring
This commit is contained in:
parent
97bc5f76e3
commit
cee89c00d3
|
@ -34,7 +34,7 @@ export const borrowObligationLiquidity = async (
|
|||
obligation: ParsedAccount<Obligation>,
|
||||
) => {
|
||||
notify({
|
||||
message: 'Borrowing funds...',
|
||||
message: 'Borrowing liquidity...',
|
||||
description: 'Please review transactions to approve.',
|
||||
type: 'warn',
|
||||
});
|
||||
|
@ -146,7 +146,7 @@ export const borrowObligationLiquidity = async (
|
|||
);
|
||||
|
||||
notify({
|
||||
message: 'Funds borrowed.',
|
||||
message: 'Liquidity borrowed.',
|
||||
type: 'success',
|
||||
description: `Transaction - ${txid}`,
|
||||
});
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
import {
|
||||
contexts,
|
||||
LENDING_PROGRAM_ID,
|
||||
models,
|
||||
notify,
|
||||
TokenAccount,
|
||||
} from '@oyster/common';
|
||||
import {
|
||||
Account,
|
||||
Connection,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import {
|
||||
depositObligationCollateralInstruction,
|
||||
refreshReserveInstruction,
|
||||
Reserve,
|
||||
} from '../models';
|
||||
|
||||
const { approve } = models;
|
||||
const { sendTransaction } = contexts.Connection;
|
||||
|
||||
// @FIXME
|
||||
export const depositObligationCollateral = async (
|
||||
connection: Connection,
|
||||
wallet: any,
|
||||
collateralAmount: number,
|
||||
source: TokenAccount,
|
||||
reserve: Reserve,
|
||||
reserveAddress: PublicKey,
|
||||
obligationAddress: PublicKey
|
||||
) => {
|
||||
notify({
|
||||
message: 'Depositing collateral...',
|
||||
description: 'Please review transactions to approve.',
|
||||
type: 'warn',
|
||||
});
|
||||
|
||||
// user from account
|
||||
const signers: Account[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const cleanupInstructions: TransactionInstruction[] = [];
|
||||
|
||||
const [lendingMarketAuthority] = await PublicKey.findProgramAddress(
|
||||
[reserve.lendingMarket.toBuffer()],
|
||||
LENDING_PROGRAM_ID,
|
||||
);
|
||||
|
||||
const sourceCollateral = source.pubkey;
|
||||
|
||||
// create approval for transfer transactions
|
||||
const transferAuthority = approve(
|
||||
instructions,
|
||||
cleanupInstructions,
|
||||
sourceCollateral,
|
||||
wallet.publicKey,
|
||||
collateralAmount,
|
||||
);
|
||||
|
||||
signers.push(transferAuthority);
|
||||
|
||||
instructions.push(
|
||||
refreshReserveInstruction(
|
||||
reserveAddress,
|
||||
reserve.liquidity.oracleOption
|
||||
? reserve.liquidity.oraclePubkey
|
||||
: undefined,
|
||||
),
|
||||
depositObligationCollateralInstruction(
|
||||
collateralAmount,
|
||||
sourceCollateral,
|
||||
reserve.collateral.mintPubkey,
|
||||
reserveAddress,
|
||||
obligationAddress,
|
||||
reserve.lendingMarket,
|
||||
lendingMarketAuthority,
|
||||
// @FIXME: wallet must sign
|
||||
wallet.publicKey,
|
||||
transferAuthority.publicKey,
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
let { txid } = await sendTransaction(
|
||||
connection,
|
||||
wallet,
|
||||
instructions.concat(cleanupInstructions),
|
||||
signers,
|
||||
true,
|
||||
);
|
||||
|
||||
notify({
|
||||
message: 'Collateral deposited.',
|
||||
type: 'success',
|
||||
description: `Transaction - ${txid}`,
|
||||
});
|
||||
} catch {
|
||||
// TODO:
|
||||
}
|
||||
};
|
|
@ -15,20 +15,14 @@ import {
|
|||
} from '@solana/web3.js';
|
||||
import {
|
||||
depositReserveLiquidityInstruction,
|
||||
initReserveInstruction,
|
||||
refreshReserveInstruction,
|
||||
Reserve,
|
||||
} from '../models';
|
||||
|
||||
const { sendTransaction } = contexts.Connection;
|
||||
const {
|
||||
createUninitializedAccount,
|
||||
ensureSplAccount,
|
||||
findOrCreateAccountByMint,
|
||||
} = actions;
|
||||
const { ensureSplAccount, findOrCreateAccountByMint } = actions;
|
||||
const { approve } = models;
|
||||
|
||||
// @FIXME: split up into deposit, and init which requires lending market owner
|
||||
export const depositReserveLiquidity = async (
|
||||
connection: Connection,
|
||||
wallet: any,
|
||||
|
@ -38,13 +32,11 @@ export const depositReserveLiquidity = async (
|
|||
reserveAddress: PublicKey,
|
||||
) => {
|
||||
notify({
|
||||
message: 'Depositing funds...',
|
||||
message: 'Depositing liquidity...',
|
||||
description: 'Please review transactions to approve.',
|
||||
type: 'warn',
|
||||
});
|
||||
|
||||
const isInitalized = true; // TODO: finish reserve init
|
||||
|
||||
// user from account
|
||||
const signers: Account[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
|
@ -79,8 +71,7 @@ export const depositReserveLiquidity = async (
|
|||
|
||||
signers.push(transferAuthority);
|
||||
|
||||
let destinationCollateralAccount: PublicKey = isInitalized
|
||||
? await findOrCreateAccountByMint(
|
||||
let destinationCollateralAccount: PublicKey = await findOrCreateAccountByMint(
|
||||
wallet.publicKey,
|
||||
wallet.publicKey,
|
||||
instructions,
|
||||
|
@ -88,15 +79,8 @@ export const depositReserveLiquidity = async (
|
|||
accountRentExempt,
|
||||
reserve.collateral.mintPubkey,
|
||||
signers,
|
||||
)
|
||||
: createUninitializedAccount(
|
||||
instructions,
|
||||
wallet.publicKey,
|
||||
accountRentExempt,
|
||||
signers,
|
||||
);
|
||||
|
||||
if (isInitalized) {
|
||||
instructions.push(
|
||||
refreshReserveInstruction(
|
||||
reserveAddress,
|
||||
|
@ -116,33 +100,6 @@ export const depositReserveLiquidity = async (
|
|||
transferAuthority.publicKey,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// TODO: finish reserve init
|
||||
// @FIXME: reserve config
|
||||
const MAX_UTILIZATION_RATE = 80;
|
||||
instructions.push(
|
||||
initReserveInstruction(
|
||||
liquidityAmount,
|
||||
MAX_UTILIZATION_RATE,
|
||||
sourceLiquidityAccount,
|
||||
destinationCollateralAccount,
|
||||
reserveAddress,
|
||||
reserve.liquidity.mintPubkey,
|
||||
reserve.liquidity.supplyPubkey,
|
||||
reserve.liquidity.feeReceiver,
|
||||
reserve.collateral.mintPubkey,
|
||||
reserve.collateral.supplyPubkey,
|
||||
reserve.lendingMarket,
|
||||
lendingMarketAuthority,
|
||||
// @FIXME: lending market owner
|
||||
lendingMarketOwner,
|
||||
transferAuthority.publicKey,
|
||||
reserve.liquidity.oracleOption
|
||||
? reserve.liquidity.oraclePubkey
|
||||
: undefined,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
let { txid } = await sendTransaction(
|
||||
|
@ -154,7 +111,7 @@ export const depositReserveLiquidity = async (
|
|||
);
|
||||
|
||||
notify({
|
||||
message: 'Funds deposited.',
|
||||
message: 'Liquidity deposited.',
|
||||
type: 'success',
|
||||
description: `Transaction - ${txid}`,
|
||||
});
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import { contexts, notify } from '@oyster/common';
|
||||
import {
|
||||
Account,
|
||||
Connection,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { initObligationInstruction, Obligation } from '../models';
|
||||
|
||||
const { sendTransaction } = contexts.Connection;
|
||||
|
||||
export const initObligation = async (
|
||||
connection: Connection,
|
||||
wallet: any,
|
||||
obligation: Obligation,
|
||||
obligationAddress: PublicKey
|
||||
) => {
|
||||
notify({
|
||||
message: 'Initializing obligation...',
|
||||
description: 'Please review transactions to approve.',
|
||||
type: 'warn',
|
||||
});
|
||||
|
||||
// user from account
|
||||
const signers: Account[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const cleanupInstructions: TransactionInstruction[] = [];
|
||||
|
||||
// @FIXME: obligation owner must sign
|
||||
signers.push(wallet.info.account);
|
||||
|
||||
instructions.push(
|
||||
initObligationInstruction(
|
||||
obligationAddress,
|
||||
obligation.lendingMarket,
|
||||
// @FIXME: need to sign with wallet
|
||||
wallet.publicKey
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
let { txid } = await sendTransaction(
|
||||
connection,
|
||||
wallet,
|
||||
instructions.concat(cleanupInstructions),
|
||||
signers,
|
||||
true,
|
||||
);
|
||||
|
||||
notify({
|
||||
message: 'Obligation initialized.',
|
||||
type: 'success',
|
||||
description: `Transaction - ${txid}`,
|
||||
});
|
||||
} catch {
|
||||
// TODO:
|
||||
throw new Error();
|
||||
}
|
||||
};
|
|
@ -0,0 +1,122 @@
|
|||
import {
|
||||
actions,
|
||||
contexts,
|
||||
LENDING_PROGRAM_ID,
|
||||
models,
|
||||
notify,
|
||||
TokenAccount,
|
||||
} from '@oyster/common';
|
||||
import { AccountLayout } from '@solana/spl-token';
|
||||
import {
|
||||
Account,
|
||||
Connection,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import { initReserveInstruction, Reserve } from '../models';
|
||||
|
||||
const { sendTransaction } = contexts.Connection;
|
||||
const {
|
||||
createUninitializedAccount,
|
||||
ensureSplAccount,
|
||||
} = actions;
|
||||
const { approve } = models;
|
||||
|
||||
export const initReserve = async (
|
||||
connection: Connection,
|
||||
// @FIXME: wallet must be lending market owner
|
||||
wallet: any,
|
||||
liquidityAmount: number,
|
||||
source: TokenAccount,
|
||||
reserve: Reserve,
|
||||
reserveAddress: PublicKey,
|
||||
) => {
|
||||
notify({
|
||||
message: 'Initializing reserve...',
|
||||
description: 'Please review transactions to approve.',
|
||||
type: 'warn',
|
||||
});
|
||||
|
||||
// user from account
|
||||
const signers: Account[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const cleanupInstructions: TransactionInstruction[] = [];
|
||||
|
||||
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
|
||||
AccountLayout.span,
|
||||
);
|
||||
|
||||
const [lendingMarketAuthority] = await PublicKey.findProgramAddress(
|
||||
[reserve.lendingMarket.toBuffer()], // which account should be authority
|
||||
LENDING_PROGRAM_ID,
|
||||
);
|
||||
|
||||
const sourceLiquidityAccount = ensureSplAccount(
|
||||
instructions,
|
||||
cleanupInstructions,
|
||||
source,
|
||||
wallet.publicKey,
|
||||
liquidityAmount + accountRentExempt,
|
||||
signers,
|
||||
);
|
||||
|
||||
// create approval for transfer transactions
|
||||
const transferAuthority = approve(
|
||||
instructions,
|
||||
cleanupInstructions,
|
||||
sourceLiquidityAccount,
|
||||
wallet.publicKey,
|
||||
liquidityAmount,
|
||||
);
|
||||
|
||||
signers.push(transferAuthority);
|
||||
|
||||
let destinationCollateralAccount: PublicKey = createUninitializedAccount(
|
||||
instructions,
|
||||
wallet.publicKey,
|
||||
accountRentExempt,
|
||||
signers,
|
||||
);
|
||||
|
||||
instructions.push(
|
||||
initReserveInstruction(
|
||||
liquidityAmount,
|
||||
reserve.config,
|
||||
sourceLiquidityAccount,
|
||||
destinationCollateralAccount,
|
||||
reserveAddress,
|
||||
reserve.liquidity.mintPubkey,
|
||||
reserve.liquidity.supplyPubkey,
|
||||
reserve.liquidity.feeReceiver,
|
||||
reserve.collateral.mintPubkey,
|
||||
reserve.collateral.supplyPubkey,
|
||||
reserve.lendingMarket,
|
||||
lendingMarketAuthority,
|
||||
// @FIXME: need to sign with wallet as lending market owner
|
||||
wallet.publicKey,
|
||||
transferAuthority.publicKey,
|
||||
reserve.liquidity.oracleOption
|
||||
? reserve.liquidity.oraclePubkey
|
||||
: undefined,
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
let { txid } = await sendTransaction(
|
||||
connection,
|
||||
wallet,
|
||||
instructions.concat(cleanupInstructions),
|
||||
signers,
|
||||
true,
|
||||
);
|
||||
|
||||
notify({
|
||||
message: 'Reserve initialized.',
|
||||
type: 'success',
|
||||
description: `Transaction - ${txid}`,
|
||||
});
|
||||
} catch {
|
||||
// TODO:
|
||||
throw new Error();
|
||||
}
|
||||
};
|
|
@ -39,7 +39,7 @@ export const liquidateObligation = async (
|
|||
obligation: ParsedAccount<Obligation>,
|
||||
) => {
|
||||
notify({
|
||||
message: 'Repaying funds...',
|
||||
message: 'Liquidating obligation...',
|
||||
description: 'Please review transactions to approve.',
|
||||
type: 'warn',
|
||||
});
|
||||
|
@ -146,7 +146,7 @@ export const liquidateObligation = async (
|
|||
);
|
||||
|
||||
notify({
|
||||
message: 'Funds liquidated.',
|
||||
message: 'Obligation liquidated.',
|
||||
type: 'success',
|
||||
description: `Transaction - ${txid}`,
|
||||
});
|
||||
|
|
|
@ -32,7 +32,7 @@ export const redeemReserveCollateral = async (
|
|||
reserveAddress: PublicKey,
|
||||
) => {
|
||||
notify({
|
||||
message: 'Withdrawing funds...',
|
||||
message: 'Redeeming collateral...',
|
||||
description: 'Please review transactions to approve.',
|
||||
type: 'warn',
|
||||
});
|
||||
|
@ -105,7 +105,7 @@ export const redeemReserveCollateral = async (
|
|||
);
|
||||
|
||||
notify({
|
||||
message: 'Funds deposited.',
|
||||
message: 'Collateral redeemed.',
|
||||
type: 'success',
|
||||
description: `Transaction - ${txid}`,
|
||||
});
|
||||
|
|
|
@ -35,7 +35,7 @@ export const repayObligationLiquidity = async (
|
|||
obligation: ParsedAccount<Obligation>,
|
||||
) => {
|
||||
notify({
|
||||
message: 'Repaying funds...',
|
||||
message: 'Repaying liquidity...',
|
||||
description: 'Please review transactions to approve.',
|
||||
type: 'warn',
|
||||
});
|
||||
|
@ -117,7 +117,7 @@ export const repayObligationLiquidity = async (
|
|||
);
|
||||
|
||||
notify({
|
||||
message: 'Funds repaid.',
|
||||
message: 'Liquidity repaid.',
|
||||
type: 'success',
|
||||
description: `Transaction - ${txid}`,
|
||||
});
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
import {
|
||||
contexts,
|
||||
findOrCreateAccountByMint,
|
||||
LENDING_PROGRAM_ID,
|
||||
models,
|
||||
notify,
|
||||
TokenAccount,
|
||||
} from '@oyster/common';
|
||||
import { AccountLayout } from '@solana/spl-token';
|
||||
import {
|
||||
Account,
|
||||
Connection,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import {
|
||||
withdrawObligationCollateralInstruction,
|
||||
refreshReserveInstruction,
|
||||
Reserve,
|
||||
} from '../models';
|
||||
|
||||
const { approve } = models;
|
||||
const { sendTransaction } = contexts.Connection;
|
||||
|
||||
// @FIXME
|
||||
export const withdrawObligationCollateral = async (
|
||||
connection: Connection,
|
||||
wallet: any,
|
||||
collateralAmount: number,
|
||||
source: TokenAccount,
|
||||
reserve: Reserve,
|
||||
reserveAddress: PublicKey,
|
||||
obligationAddress: PublicKey,
|
||||
) => {
|
||||
notify({
|
||||
message: 'Withdrawing collateral...',
|
||||
description: 'Please review transactions to approve.',
|
||||
type: 'warn',
|
||||
});
|
||||
|
||||
// user from account
|
||||
const signers: Account[] = [];
|
||||
const instructions: TransactionInstruction[] = [];
|
||||
const cleanupInstructions: TransactionInstruction[] = [];
|
||||
|
||||
const accountRentExempt = await connection.getMinimumBalanceForRentExemption(
|
||||
AccountLayout.span,
|
||||
);
|
||||
|
||||
const [lendingMarketAuthority] = await PublicKey.findProgramAddress(
|
||||
[reserve.lendingMarket.toBuffer()],
|
||||
LENDING_PROGRAM_ID,
|
||||
);
|
||||
|
||||
// @FIXME: wallet must sign as obligation owner
|
||||
signers.push(wallet.info.account);
|
||||
|
||||
// get destination account
|
||||
const destinationCollateral = await findOrCreateAccountByMint(
|
||||
wallet.publicKey,
|
||||
wallet.publicKey,
|
||||
instructions,
|
||||
cleanupInstructions,
|
||||
accountRentExempt,
|
||||
reserve.collateral.mintPubkey,
|
||||
signers,
|
||||
);
|
||||
|
||||
instructions.push(
|
||||
refreshReserveInstruction(
|
||||
reserveAddress,
|
||||
reserve.liquidity.oracleOption
|
||||
? reserve.liquidity.oraclePubkey
|
||||
: undefined,
|
||||
),
|
||||
withdrawObligationCollateralInstruction(
|
||||
collateralAmount,
|
||||
reserve.collateral.supplyPubkey,
|
||||
destinationCollateral,
|
||||
reserveAddress,
|
||||
obligationAddress,
|
||||
reserve.lendingMarket,
|
||||
lendingMarketAuthority,
|
||||
// @FIXME: wallet must sign
|
||||
wallet.publicKey
|
||||
),
|
||||
);
|
||||
|
||||
try {
|
||||
let { txid } = await sendTransaction(
|
||||
connection,
|
||||
wallet,
|
||||
instructions.concat(cleanupInstructions),
|
||||
signers,
|
||||
true,
|
||||
);
|
||||
|
||||
notify({
|
||||
message: 'Collateral withdrawn.',
|
||||
type: 'success',
|
||||
description: `Transaction - ${txid}`,
|
||||
});
|
||||
} catch {
|
||||
// TODO:
|
||||
}
|
||||
};
|
|
@ -145,9 +145,7 @@ export const BorrowInput = (props: {
|
|||
parseFloat(value),
|
||||
borrowReserve,
|
||||
// TODO: select existing obligations by collateral reserve
|
||||
userObligationsByReserve.length > 0
|
||||
? userObligationsByReserve[0].obligation.account
|
||||
: undefined,
|
||||
userObligationsByReserve[0].obligation.account
|
||||
);
|
||||
|
||||
setValue('');
|
||||
|
|
|
@ -45,13 +45,11 @@ export const useLending = () => {
|
|||
const processAccount = useCallback(
|
||||
(item: { pubkey: PublicKey; account: AccountInfo<Buffer> }) => {
|
||||
if (isReserve(item.account)) {
|
||||
const reserve = cache.add(
|
||||
return cache.add(
|
||||
item.pubkey.toBase58(),
|
||||
item.account,
|
||||
ReserveParser,
|
||||
);
|
||||
|
||||
return reserve;
|
||||
} else if (isLendingMarket(item.account)) {
|
||||
return cache.add(
|
||||
item.pubkey.toBase58(),
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
import BN from 'bn.js';
|
||||
import * as BufferLayout from 'buffer-layout';
|
||||
import * as Layout from '../../utils/layout';
|
||||
import { ReserveConfig } from '../state';
|
||||
import { LendingInstruction } from './instruction';
|
||||
|
||||
/// Initializes a new lending market reserve.
|
||||
|
@ -42,8 +43,7 @@ import { LendingInstruction } from './instruction';
|
|||
// },
|
||||
export const initReserveInstruction = (
|
||||
liquidityAmount: number | BN,
|
||||
// @FIXME: reserve config
|
||||
maxUtilizationRate: number,
|
||||
config: ReserveConfig,
|
||||
sourceLiquidity: PublicKey,
|
||||
destinationCollateral: PublicKey,
|
||||
reserve: PublicKey,
|
||||
|
@ -61,8 +61,15 @@ export const initReserveInstruction = (
|
|||
const dataLayout = BufferLayout.struct([
|
||||
BufferLayout.u8('instruction'),
|
||||
Layout.uint64('liquidityAmount'),
|
||||
// @FIXME: reserve config
|
||||
BufferLayout.u8('maxUtilizationRate'),
|
||||
BufferLayout.u8('optimalUtilizationRate'),
|
||||
BufferLayout.u8('loanToValueRatio'),
|
||||
BufferLayout.u8('liquidationBonus'),
|
||||
BufferLayout.u8('liquidationThreshold'),
|
||||
BufferLayout.u8('minBorrowRate'),
|
||||
BufferLayout.u8('optimalBorrowRate'),
|
||||
BufferLayout.u8('maxBorrowRate'),
|
||||
Layout.uint64('borrowFeeWad'),
|
||||
BufferLayout.u8('hostFeePercentage'),
|
||||
]);
|
||||
|
||||
const data = Buffer.alloc(dataLayout.span);
|
||||
|
@ -70,7 +77,15 @@ export const initReserveInstruction = (
|
|||
{
|
||||
instruction: LendingInstruction.InitReserve,
|
||||
liquidityAmount: new BN(liquidityAmount),
|
||||
maxUtilizationRate,
|
||||
optimalUtilizationRate: config.optimalUtilizationRate,
|
||||
loanToValueRatio: config.loanToValueRatio,
|
||||
liquidationBonus: config.liquidationBonus,
|
||||
liquidationThreshold: config.liquidationThreshold,
|
||||
minBorrowRate: config.minBorrowRate,
|
||||
optimalBorrowRate: config.optimalBorrowRate,
|
||||
maxBorrowRate: config.maxBorrowRate,
|
||||
borrowFeeWad: config.fees.borrowFeeWad,
|
||||
hostFeePercentage: config.fees.hostFeePercentage,
|
||||
},
|
||||
data,
|
||||
);
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import BN from 'bn.js';
|
||||
import * as BufferLayout from 'buffer-layout';
|
||||
import * as Layout from '../../utils/layout';
|
||||
|
||||
export const LastUpdateLayout: typeof BufferLayout.Structure = BufferLayout.struct(
|
||||
[Layout.uint64('slot'), BufferLayout.u8('stale')],
|
||||
'lastUpdate'
|
||||
);
|
||||
|
||||
export interface LastUpdate {
|
||||
slot: BN;
|
||||
|
|
|
@ -2,6 +2,13 @@ import { AccountInfo, PublicKey } from '@solana/web3.js';
|
|||
import * as BufferLayout from 'buffer-layout';
|
||||
import * as Layout from '../../utils/layout';
|
||||
|
||||
export interface LendingMarket {
|
||||
version: number;
|
||||
isInitialized: boolean;
|
||||
quoteTokenMint: PublicKey;
|
||||
tokenProgramId: PublicKey;
|
||||
}
|
||||
|
||||
export const LendingMarketLayout: typeof BufferLayout.Structure = BufferLayout.struct(
|
||||
[
|
||||
BufferLayout.u8('version'),
|
||||
|
@ -14,13 +21,6 @@ export const LendingMarketLayout: typeof BufferLayout.Structure = BufferLayout.s
|
|||
],
|
||||
);
|
||||
|
||||
export interface LendingMarket {
|
||||
version: number;
|
||||
isInitialized: boolean;
|
||||
quoteTokenMint: PublicKey;
|
||||
tokenProgramId: PublicKey;
|
||||
}
|
||||
|
||||
export const isLendingMarket = (info: AccountInfo<Buffer>) => {
|
||||
return info.data.length === LendingMarketLayout.span;
|
||||
};
|
||||
|
|
|
@ -2,16 +2,41 @@ import { AccountInfo, PublicKey } from '@solana/web3.js';
|
|||
import BN from 'bn.js';
|
||||
import * as BufferLayout from 'buffer-layout';
|
||||
import * as Layout from '../../utils/layout';
|
||||
import { LastUpdate } from './lastUpdate';
|
||||
import { LastUpdate, LastUpdateLayout } from './lastUpdate';
|
||||
|
||||
export interface Obligation {
|
||||
version: number;
|
||||
lastUpdate: LastUpdate;
|
||||
lendingMarket: PublicKey;
|
||||
owner: PublicKey;
|
||||
// @FIXME: check usages
|
||||
deposits: ObligationCollateral[];
|
||||
// @FIXME: check usages
|
||||
borrows: ObligationLiquidity[];
|
||||
depositedValue: BN; // decimals
|
||||
borrowedValue: BN; // decimals
|
||||
allowedBorrowValue: BN; // decimals
|
||||
unhealthyBorrowValue: BN; // decimals
|
||||
}
|
||||
|
||||
export interface ObligationCollateral {
|
||||
depositReserve: PublicKey;
|
||||
depositedAmount: BN;
|
||||
marketValue: BN; // decimals
|
||||
}
|
||||
|
||||
export interface ObligationLiquidity {
|
||||
borrowReserve: PublicKey;
|
||||
cumulativeBorrowRateWads: BN; // decimals
|
||||
borrowedAmountWads: BN; // decimals
|
||||
marketValue: BN; // decimals
|
||||
}
|
||||
|
||||
export const ObligationLayout: typeof BufferLayout.Structure = BufferLayout.struct(
|
||||
[
|
||||
BufferLayout.u8('version'),
|
||||
|
||||
BufferLayout.struct(
|
||||
[Layout.uint64('slot'), BufferLayout.u8('stale')],
|
||||
'lastUpdate',
|
||||
),
|
||||
LastUpdateLayout,
|
||||
|
||||
Layout.publicKey('lendingMarket'),
|
||||
Layout.publicKey('owner'),
|
||||
|
@ -61,34 +86,6 @@ export interface ProtoObligation {
|
|||
dataFlat: Buffer;
|
||||
}
|
||||
|
||||
export interface Obligation {
|
||||
version: number;
|
||||
lastUpdate: LastUpdate;
|
||||
lendingMarket: PublicKey;
|
||||
owner: PublicKey;
|
||||
// @FIXME: check usages
|
||||
deposits: ObligationCollateral[];
|
||||
// @FIXME: check usages
|
||||
borrows: ObligationLiquidity[];
|
||||
depositedValue: BN; // decimals
|
||||
borrowedValue: BN; // decimals
|
||||
allowedBorrowValue: BN; // decimals
|
||||
unhealthyBorrowValue: BN; // decimals
|
||||
}
|
||||
|
||||
export interface ObligationCollateral {
|
||||
depositReserve: PublicKey;
|
||||
depositedAmount: BN;
|
||||
marketValue: BN; // decimals
|
||||
}
|
||||
|
||||
export interface ObligationLiquidity {
|
||||
borrowReserve: PublicKey;
|
||||
cumulativeBorrowRateWads: BN; // decimals
|
||||
borrowedAmountWads: BN; // decimals
|
||||
marketValue: BN; // decimals
|
||||
}
|
||||
|
||||
export const ObligationParser = (
|
||||
pubkey: PublicKey,
|
||||
info: AccountInfo<Buffer>,
|
||||
|
|
|
@ -3,70 +3,7 @@ import { AccountInfo, PublicKey } from '@solana/web3.js';
|
|||
import BN from 'bn.js';
|
||||
import * as BufferLayout from 'buffer-layout';
|
||||
import * as Layout from '../../utils/layout';
|
||||
import { LastUpdate } from './lastUpdate';
|
||||
|
||||
export const ReserveLayout: typeof BufferLayout.Structure = BufferLayout.struct(
|
||||
[
|
||||
BufferLayout.u8('version'),
|
||||
|
||||
BufferLayout.struct(
|
||||
[Layout.uint64('slot'), BufferLayout.u8('stale')],
|
||||
'lastUpdate',
|
||||
),
|
||||
|
||||
Layout.publicKey('lendingMarket'),
|
||||
|
||||
BufferLayout.struct(
|
||||
[
|
||||
Layout.publicKey('mintPubkey'),
|
||||
BufferLayout.u8('mintDecimals'),
|
||||
Layout.publicKey('supplyPubkey'),
|
||||
Layout.publicKey('feeReceiver'),
|
||||
// @FIXME: oracle option
|
||||
// TODO: replace u32 option with generic equivalent
|
||||
BufferLayout.u32('oracleOption'),
|
||||
Layout.publicKey('oracle'),
|
||||
Layout.uint64('availableAmount'),
|
||||
Layout.uint128('borrowedAmountWads'),
|
||||
Layout.uint128('cumulativeBorrowRateWads'),
|
||||
Layout.uint64('marketPrice'),
|
||||
],
|
||||
'liquidity',
|
||||
),
|
||||
|
||||
BufferLayout.struct(
|
||||
[
|
||||
Layout.publicKey('mintPubkey'),
|
||||
Layout.uint64('mintTotalSupply'),
|
||||
Layout.publicKey('supplyPubkey'),
|
||||
],
|
||||
'collateral',
|
||||
),
|
||||
|
||||
BufferLayout.struct(
|
||||
[
|
||||
BufferLayout.u8('optimalUtilizationRate'),
|
||||
BufferLayout.u8('loanToValueRatio'),
|
||||
BufferLayout.u8('liquidationBonus'),
|
||||
BufferLayout.u8('liquidationThreshold'),
|
||||
BufferLayout.u8('minBorrowRate'),
|
||||
BufferLayout.u8('optimalBorrowRate'),
|
||||
BufferLayout.u8('maxBorrowRate'),
|
||||
BufferLayout.struct(
|
||||
[Layout.uint64('borrowFeeWad'), BufferLayout.u8('hostFeePercentage')],
|
||||
'fees',
|
||||
),
|
||||
],
|
||||
'config',
|
||||
),
|
||||
|
||||
BufferLayout.blob(256, 'padding'),
|
||||
],
|
||||
);
|
||||
|
||||
export const isReserve = (info: AccountInfo<Buffer>) => {
|
||||
return info.data.length === ReserveLayout.span;
|
||||
};
|
||||
import { LastUpdate, LastUpdateLayout } from './lastUpdate';
|
||||
|
||||
export interface Reserve {
|
||||
version: number;
|
||||
|
@ -111,6 +48,66 @@ export interface ReserveConfig {
|
|||
};
|
||||
}
|
||||
|
||||
export const ReserveLayout: typeof BufferLayout.Structure = BufferLayout.struct(
|
||||
[
|
||||
BufferLayout.u8('version'),
|
||||
|
||||
LastUpdateLayout,
|
||||
|
||||
Layout.publicKey('lendingMarket'),
|
||||
|
||||
BufferLayout.struct(
|
||||
[
|
||||
Layout.publicKey('mintPubkey'),
|
||||
BufferLayout.u8('mintDecimals'),
|
||||
Layout.publicKey('supplyPubkey'),
|
||||
Layout.publicKey('feeReceiver'),
|
||||
// @FIXME: oracle option
|
||||
// TODO: replace u32 option with generic equivalent
|
||||
BufferLayout.u32('oracleOption'),
|
||||
Layout.publicKey('oracle'),
|
||||
Layout.uint64('availableAmount'),
|
||||
Layout.uint128('borrowedAmountWads'),
|
||||
Layout.uint128('cumulativeBorrowRateWads'),
|
||||
Layout.uint64('marketPrice'),
|
||||
],
|
||||
'liquidity',
|
||||
),
|
||||
|
||||
BufferLayout.struct(
|
||||
[
|
||||
Layout.publicKey('mintPubkey'),
|
||||
Layout.uint64('mintTotalSupply'),
|
||||
Layout.publicKey('supplyPubkey'),
|
||||
],
|
||||
'collateral'
|
||||
),
|
||||
|
||||
BufferLayout.struct(
|
||||
[
|
||||
BufferLayout.u8('optimalUtilizationRate'),
|
||||
BufferLayout.u8('loanToValueRatio'),
|
||||
BufferLayout.u8('liquidationBonus'),
|
||||
BufferLayout.u8('liquidationThreshold'),
|
||||
BufferLayout.u8('minBorrowRate'),
|
||||
BufferLayout.u8('optimalBorrowRate'),
|
||||
BufferLayout.u8('maxBorrowRate'),
|
||||
BufferLayout.struct(
|
||||
[Layout.uint64('borrowFeeWad'), BufferLayout.u8('hostFeePercentage')],
|
||||
'fees',
|
||||
),
|
||||
],
|
||||
'config'
|
||||
),
|
||||
|
||||
BufferLayout.blob(256, 'padding'),
|
||||
],
|
||||
);
|
||||
|
||||
export const isReserve = (info: AccountInfo<Buffer>) => {
|
||||
return info.data.length === ReserveLayout.span;
|
||||
};
|
||||
|
||||
export const ReserveParser = (pubkey: PublicKey, info: AccountInfo<Buffer>) => {
|
||||
const buffer = Buffer.from(info.data);
|
||||
const reserve = ReserveLayout.decode(buffer) as Reserve;
|
||||
|
|
Loading…
Reference in New Issue