feat: add exchnage rate

This commit is contained in:
bartosz-lipinski 2020-12-14 13:33:13 -06:00
parent c753d150a1
commit 2b31d79654
12 changed files with 54 additions and 42 deletions

View File

@ -2,7 +2,7 @@ import React from "react";
import { import {
useTokenName, useTokenName,
useUserBalance, useUserBalance,
useCollateralBalance, useUserCollateralBalance,
} from "./../../hooks"; } from "./../../hooks";
import { LendingReserve } from "../../models/lending"; import { LendingReserve } from "../../models/lending";
import { formatNumber } from "../../utils/utils"; import { formatNumber } from "../../utils/utils";
@ -17,7 +17,7 @@ export const DepositInfoLine = (props: {
}) => { }) => {
const name = useTokenName(props.reserve.liquidityMint); const name = useTokenName(props.reserve.liquidityMint);
const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint); const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint);
const { balance: collateralBalance } = useCollateralBalance(props.reserve); const { balance: collateralBalance } = useUserCollateralBalance(props.reserve);
return ( return (
<Card <Card

View File

@ -46,7 +46,7 @@ export const DepositInput = (props: {
[balance] [balance]
); );
const { value, setValue, mark, setMark, type } = useSliderInput(convert); const { value, setValue, pct, setPct, type } = useSliderInput(convert);
const onDeposit = useCallback(() => { const onDeposit = useCallback(() => {
setPendingTx(true); setPendingTx(true);
@ -55,8 +55,8 @@ export const DepositInput = (props: {
try { try {
await deposit( await deposit(
fromAccounts[0], fromAccounts[0],
type === InputType.Slider type === InputType.Percent
? (mark * balanceLamports) / 100 ? (pct * balanceLamports) / 100
: Math.ceil(balanceLamports * (parseFloat(value) / balance)), : Math.ceil(balanceLamports * (parseFloat(value) / balance)),
reserve, reserve,
address, address,
@ -79,7 +79,7 @@ export const DepositInput = (props: {
balance, balance,
wallet, wallet,
value, value,
mark, pct,
type, type,
reserve, reserve,
fromAccounts, fromAccounts,
@ -126,7 +126,7 @@ export const DepositInput = (props: {
<div>{name}</div> <div>{name}</div>
</div> </div>
<Slider marks={marks} value={mark} onChange={setMark} /> <Slider marks={marks} value={pct} onChange={setPct} />
<Button <Button
type="primary" type="primary"

View File

@ -69,7 +69,7 @@ export const RepayInput = (props: {
[borrowAmount] [borrowAmount]
); );
const { value, setValue, mark, setMark, type } = useSliderInput(convert); const { value, setValue, pct, setPct, type } = useSliderInput(convert);
const onRepay = useCallback(() => { const onRepay = useCallback(() => {
if ( if (
@ -85,8 +85,8 @@ export const RepayInput = (props: {
(async () => { (async () => {
try { try {
const toRepayLamports = type === InputType.Slider const toRepayLamports = type === InputType.Percent
? (mark * borrowAmountLamports) / 100 ? (pct * borrowAmountLamports) / 100
: Math.ceil(borrowAmountLamports * (parseFloat(value) / borrowAmount)); : Math.ceil(borrowAmountLamports * (parseFloat(value) / borrowAmount));
await repay( await repay(
@ -114,7 +114,7 @@ export const RepayInput = (props: {
} }
})(); })();
}, [ }, [
mark, pct,
value, value,
borrowAmount, borrowAmount,
borrowAmountLamports, borrowAmountLamports,
@ -170,8 +170,8 @@ export const RepayInput = (props: {
</div> </div>
<Slider <Slider
marks={marks} marks={marks}
value={mark} value={pct}
onChange={setMark} onChange={setPct}
/> />
<div className="repay-input-title">{LABELS.SELECT_COLLATERAL}</div> <div className="repay-input-title">{LABELS.SELECT_COLLATERAL}</div>
<CollateralSelector <CollateralSelector

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import { import {
useCollateralBalance, useUserCollateralBalance,
useTokenName, useTokenName,
useUserBalance, useUserBalance,
useBorrowedAmount, useBorrowedAmount,
@ -24,7 +24,7 @@ export const UserLendingCard = (props: {
const name = useTokenName(reserve?.liquidityMint); const name = useTokenName(reserve?.liquidityMint);
const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint); const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint);
const { balance: collateralBalance } = useCollateralBalance(props.reserve); const { balance: collateralBalance } = useUserCollateralBalance(props.reserve);
const { borrowed: totalBorrowed } = useBorrowedAmount(address); const { borrowed: totalBorrowed } = useBorrowedAmount(address);

View File

@ -1,7 +1,7 @@
import React, { useCallback, useState } from "react"; import React, { useCallback, useState } from "react";
import { import {
InputType, InputType,
useCollateralBalance, useUserCollateralBalance,
useSliderInput, useSliderInput,
useTokenName, useTokenName,
useUserBalance, useUserBalance,
@ -36,7 +36,7 @@ export const WithdrawInput = (props: {
balanceLamports: collateralBalanceLamports, balanceLamports: collateralBalanceLamports,
accounts: fromAccounts, accounts: fromAccounts,
} = useUserBalance(reserve?.collateralMint); } = useUserBalance(reserve?.collateralMint);
const { balance: collateralBalanceInLiquidity } = useCollateralBalance( const { balance: collateralBalanceInLiquidity } = useUserCollateralBalance(
reserve reserve
); );
@ -51,7 +51,7 @@ export const WithdrawInput = (props: {
[collateralBalanceInLiquidity] [collateralBalanceInLiquidity]
); );
const { value, setValue, mark, setMark, type } = useSliderInput(convert); const { value, setValue, pct, setPct, type } = useSliderInput(convert);
const onWithdraw = useCallback(() => { const onWithdraw = useCallback(() => {
setPendingTx(true); setPendingTx(true);
@ -60,8 +60,8 @@ export const WithdrawInput = (props: {
try { try {
await withdraw( await withdraw(
fromAccounts[0], fromAccounts[0],
type === InputType.Slider type === InputType.Percent
? (mark * collateralBalanceLamports) / 100 ? (pct * collateralBalanceLamports) / 100
: Math.ceil( : Math.ceil(
collateralBalanceLamports * collateralBalanceLamports *
(parseFloat(value) / collateralBalanceInLiquidity) (parseFloat(value) / collateralBalanceInLiquidity)
@ -86,7 +86,7 @@ export const WithdrawInput = (props: {
collateralBalanceLamports, collateralBalanceLamports,
connection, connection,
fromAccounts, fromAccounts,
mark, pct,
reserve, reserve,
setValue, setValue,
type, type,
@ -132,7 +132,7 @@ export const WithdrawInput = (props: {
<div>{name}</div> <div>{name}</div>
</div> </div>
<Slider marks={marks} value={mark} onChange={setMark} /> <Slider marks={marks} value={pct} onChange={setPct} />
<Button <Button
type="primary" type="primary"

View File

@ -4,7 +4,7 @@ import { LendingReserve, reserveMarketCap } from "../models/lending";
import { fromLamports } from "../utils/utils"; import { fromLamports } from "../utils/utils";
import { useUserBalance } from "./useUserBalance"; import { useUserBalance } from "./useUserBalance";
export function useCollateralBalance( export function useUserCollateralBalance(
reserve?: LendingReserve, reserve?: LendingReserve,
account?: PublicKey account?: PublicKey
) { ) {

View File

@ -1,36 +1,36 @@
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
export enum InputType { export enum InputType {
Input = 0, AbsoluteValue = 0,
Slider = 1, Percent = 1,
} }
export const useSliderInput = ( export const useSliderInput = (
convert: (val: string | number) => string | number convert: (val: string | number) => string | number
) => { ) => {
const [value, setValue] = useState(""); const [value, setValue] = useState("");
const [mark, setMark] = useState(0); const [pct, setPct] = useState(0);
const [type, setType] = useState(InputType.Slider); const [type, setType] = useState(InputType.Percent);
return { return {
value, value,
setValue: useCallback( setValue: useCallback(
(val: string) => { (val: string) => {
console.log(val); console.log(val);
setType(InputType.Input); setType(InputType.AbsoluteValue);
setValue(val); setValue(val);
setMark(convert(val) as number); setPct(convert(val) as number);
}, },
[setType, setValue, setMark, convert] [setType, setValue, setPct, convert]
), ),
mark, pct,
setMark: useCallback( setPct: useCallback(
(val: number) => { (val: number) => {
setType(InputType.Input); setType(InputType.AbsoluteValue);
setMark(val); setPct(val);
setValue(convert(val) as string); setValue(convert(val) as string);
}, },
[setType, setValue, setMark, convert] [setType, setValue, setPct, convert]
), ),
type, type,
}; };

View File

@ -183,3 +183,7 @@ export const reserveMarketCap = (reserve?: LendingReserve) => {
return total; return total;
}; };
export const collateralExchangeRate = (reserve?: LendingReserve) => {
return (reserve?.collateralMintSupply.toNumber() || 1) / reserveMarketCap(reserve);
}

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { useCollateralBalance, useTokenName } from "../../hooks"; import { useUserCollateralBalance, useTokenName } from "../../hooks";
import { calculateBorrowAPY, LendingReserve } from "../../models/lending"; import { calculateBorrowAPY, LendingReserve } from "../../models/lending";
import { TokenIcon } from "../../components/TokenIcon"; import { TokenIcon } from "../../components/TokenIcon";
import { formatNumber, formatPct } from "../../utils/utils"; import { formatNumber, formatPct } from "../../utils/utils";
@ -17,7 +17,7 @@ export const BorrowItem = (props: {
const price = useMidPriceInUSD(props.reserve.liquidityMint.toBase58()).price; const price = useMidPriceInUSD(props.reserve.liquidityMint.toBase58()).price;
// TODO: calculate avilable amount... based on total owned collateral across all the reserves // TODO: calculate avilable amount... based on total owned collateral across all the reserves
const { balance: collateralBalance } = useCollateralBalance(props.reserve); const { balance: collateralBalance } = useUserCollateralBalance(props.reserve);
const apr = calculateBorrowAPY(props.reserve); const apr = calculateBorrowAPY(props.reserve);

View File

@ -1,5 +1,5 @@
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import { useCollateralBalance, useTokenName } from "../../hooks"; import { useUserCollateralBalance, useTokenName } from "../../hooks";
import { calculateDepositAPY, LendingReserve } from "../../models/lending"; import { calculateDepositAPY, LendingReserve } from "../../models/lending";
import { TokenIcon } from "../../components/TokenIcon"; import { TokenIcon } from "../../components/TokenIcon";
import { formatNumber, formatPct } from "../../utils/utils"; import { formatNumber, formatPct } from "../../utils/utils";
@ -15,7 +15,7 @@ export const DepositItem = (props: {
}) => { }) => {
const mintAddress = props.reserve.info.liquidityMint; const mintAddress = props.reserve.info.liquidityMint;
const name = useTokenName(mintAddress); const name = useTokenName(mintAddress);
const { balance: collateralBalance } = useCollateralBalance( const { balance: collateralBalance } = useUserCollateralBalance(
props.reserve.info, props.reserve.info,
props.account.pubkey props.account.pubkey
); );

View File

@ -1,9 +1,11 @@
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import { useTokenName } from "../../hooks"; import { useUserCollateralBalance, useTokenName } from "../../hooks";
import { import {
calculateBorrowAPY, calculateBorrowAPY,
collateralExchangeRate,
LendingObligation, LendingObligation,
LendingReserve, LendingReserve,
reserveMarketCap,
} from "../../models/lending"; } from "../../models/lending";
import { TokenIcon } from "../../components/TokenIcon"; import { TokenIcon } from "../../components/TokenIcon";
import { import {
@ -28,6 +30,7 @@ export const ObligationItem = (props: {
const name = useTokenName(borrowReserve?.info.liquidityMint); const name = useTokenName(borrowReserve?.info.liquidityMint);
const liquidityMint = useMint(borrowReserve.info.liquidityMint); const liquidityMint = useMint(borrowReserve.info.liquidityMint);
const collateralMint = useMint(borrowReserve.info.collateralMint);
const borrowAmount = fromLamports( const borrowAmount = fromLamports(
wadToLamports(obligation.info.borrowAmountWad), wadToLamports(obligation.info.borrowAmountWad),
@ -38,6 +41,11 @@ export const ObligationItem = (props: {
borrowReserve, borrowReserve,
]); ]);
const rate = collateralExchangeRate(borrowReserve.info) ;
console.log(`collateral ${fromLamports(obligation.info.collateralAmount.toNumber() / rate, collateralMint)}`);
return ( return (
<Card> <Card>
<div className="dashboard-item"> <div className="dashboard-item">

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import { import {
useCollateralBalance, useUserCollateralBalance,
useTokenName, useTokenName,
useUserBalance, useUserBalance,
} from "../../../hooks"; } from "../../../hooks";
@ -18,7 +18,7 @@ export const ReserveItem = (props: {
}) => { }) => {
const name = useTokenName(props.reserve.liquidityMint); const name = useTokenName(props.reserve.liquidityMint);
const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint); const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint);
const { balance: collateralBalance } = useCollateralBalance(props.reserve); const { balance: collateralBalance } = useUserCollateralBalance(props.reserve);
const apy = calculateDepositAPY(props.reserve); const apy = calculateDepositAPY(props.reserve);