feat: style deposits

This commit is contained in:
bartosz-lipinski 2020-11-19 12:51:57 -06:00
parent 56d9d9f673
commit 1c63b1bc39
13 changed files with 544 additions and 68 deletions

177
package-lock.json generated
View File

@ -1,5 +1,5 @@
{
"name": "token-swap-ui",
"name": "token-lending-ui",
"version": "0.1.0",
"lockfileVersion": 1,
"requires": true,
@ -1392,6 +1392,108 @@
"resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz",
"integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg=="
},
"@formatjs/ecma402-abstract": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.4.0.tgz",
"integrity": "sha512-Mv027hcLFjE45K8UJ8PjRpdDGfR0aManEFj1KzoN8zXNveHGEygpZGfFf/FTTMl+QEVSrPAUlyxaCApvmv47AQ==",
"requires": {
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/intl": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-1.4.6.tgz",
"integrity": "sha512-NpmOi3T0ADalssZK0JJkS8mfbaiCwbHdlzdsp33cDY6ZMLSkLASwMUirmmEV9Qdh1TEVOixz9bSdy03eo+k7XA==",
"requires": {
"@formatjs/ecma402-abstract": "1.4.0",
"@formatjs/intl-datetimeformat": "2.8.4",
"@formatjs/intl-displaynames": "3.4.6",
"@formatjs/intl-listformat": "4.3.6",
"@formatjs/intl-relativetimeformat": "7.3.6",
"fast-memoize": "^2.5.2",
"intl-messageformat": "9.3.18",
"intl-messageformat-parser": "6.0.16",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/intl-datetimeformat": {
"version": "2.8.4",
"resolved": "https://registry.npmjs.org/@formatjs/intl-datetimeformat/-/intl-datetimeformat-2.8.4.tgz",
"integrity": "sha512-aCD6VoUvdLiJrAfKfHojbzX/e5inqvO+N9rj9kdOzCMTEdDGJ+Jd9SmXPn2YKb1glp785mYxAPp5vxjgErjq/g==",
"requires": {
"@formatjs/ecma402-abstract": "1.4.0",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/intl-displaynames": {
"version": "3.4.6",
"resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-3.4.6.tgz",
"integrity": "sha512-XWVhTQjcyWweHm2Hi0n92hYILpktbnh8x5Sj5nSBIUNz4Os4uHDj2itJI3xCxl+aDNW8M7VRJ9m0OsnhI8qQrg==",
"requires": {
"@formatjs/ecma402-abstract": "1.4.0",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/intl-listformat": {
"version": "4.3.6",
"resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-4.3.6.tgz",
"integrity": "sha512-+ePU3/rmgUd8QHcf7EGJAIU12+Y6eMGaDhI3tPw3kKN/vByE9hJAyR8etXTk9fSIV6D7us2tEDM4h0wn8eenig==",
"requires": {
"@formatjs/ecma402-abstract": "1.4.0",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@formatjs/intl-relativetimeformat": {
"version": "7.3.6",
"resolved": "https://registry.npmjs.org/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-7.3.6.tgz",
"integrity": "sha512-RtmdGG6Lwf99xlGjFiIk6pYe9LQJpTYa7VofV322Q3gmb3tAU6Pgyn7LML4xbG7Pd1F7JBmnVNVwFyofUfyJQA==",
"requires": {
"@formatjs/ecma402-abstract": "1.4.0",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"@hapi/address": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
@ -2217,6 +2319,15 @@
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz",
"integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA=="
},
"@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/identicon.js": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@types/identicon.js/-/identicon.js-2.3.0.tgz",
@ -6674,6 +6785,11 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"fast-memoize": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
"integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw=="
},
"faye-websocket": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
@ -7924,6 +8040,39 @@
}
}
},
"intl-messageformat": {
"version": "9.3.18",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.3.18.tgz",
"integrity": "sha512-OKrLWppdxXtRdRCPjmRZ9Ru7UZkZJDlMl+1Vpb3sCLWK0mFpr129K+gIlIb5zrWoAH3NiYDzekBXPTRWCyHSIA==",
"requires": {
"fast-memoize": "^2.5.2",
"intl-messageformat-parser": "6.0.16",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"intl-messageformat-parser": {
"version": "6.0.16",
"resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-6.0.16.tgz",
"integrity": "sha512-Qy3Zz0vF4fhMVuW4BDqUr55LsOl9enM03wuwbP4Yg7v29rYNpf7Z76Whstu6uDLDJokrjbpgDvRcjSDTAhxKJw==",
"requires": {
"@formatjs/ecma402-abstract": "1.4.0",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@ -12619,6 +12768,32 @@
"github-buttons": "^2.8.0"
}
},
"react-intl": {
"version": "5.10.2",
"resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.10.2.tgz",
"integrity": "sha512-g5sxQXdmXSBo8tqi1I2PBpsAG40dgmHnVGoLdBJPwPNHvJbzc08J1r2IOKomPqHMDDjD47Q/Z1Ls87spw/ES5w==",
"requires": {
"@formatjs/ecma402-abstract": "1.4.0",
"@formatjs/intl": "1.4.6",
"@formatjs/intl-displaynames": "3.4.6",
"@formatjs/intl-listformat": "4.3.6",
"@formatjs/intl-relativetimeformat": "7.3.6",
"@types/hoist-non-react-statics": "^3.3.1",
"fast-memoize": "^2.5.2",
"hoist-non-react-statics": "^3.3.2",
"intl-messageformat": "9.3.18",
"intl-messageformat-parser": "6.0.16",
"shallow-equal": "^1.2.1",
"tslib": "^2.0.1"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",

View File

@ -27,6 +27,7 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-github-btn": "^1.2.0",
"react-intl": "^5.10.2",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.3",
"typescript": "^4.0.0"

View File

@ -202,6 +202,50 @@ body {
}
}
.card-row {
box-sizing: border-box;
margin: 5px 0px;
min-width: 0px;
width: 100%;
display: flex;
flex-direction: row;
padding: 0px;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: justify;
justify-content: space-between;
.card-cell {
display: flex;
flex-direction: column;
align-items: flex-end;
box-sizing: border-box;
text-align: left;
margin: 0px;
min-width: 0px;
font-size: 14px;
font-weight: 500;
}
.left {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.small {
font-size: 11px;
}
}
.token-input {
display: flex;
align-items: center;
border: 1px solid grey;
padding: 0px 10px;
margin: 5px 0px;
}
@media only screen and (max-width: 600px) {
.exchange-card {
width: 360px;

View File

@ -0,0 +1,92 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useLendingReserve, useTokenName, useUserAccounts, useUserBalance } from './../../hooks';
import { LendingReserve, LendingReserveParser } from "../../models/lending";
import { TokenIcon } from "../../components/TokenIcon";
import { formatNumber } from "../../utils/utils";
import { Button, Card } from "antd";
import { useParams } from "react-router-dom";
import { cache, useAccount } from "../../contexts/accounts";
import { NumericInput } from "../../components/Input/numeric";
import { useConnection } from "../../contexts/connection";
import { useWallet } from "../../contexts/wallet";
import { deposit } from './../../actions/deposit';
import { PublicKey } from "@solana/web3.js";
import './style.less';
export const DepositAdd = (props: { className?: string, reserve: LendingReserve, address: PublicKey }) => {
const connection = useConnection();
const { wallet } = useWallet();
const { id } = useParams<{ id: string }>();
const [value, setValue] = useState('');
const reserve = props.reserve;
const address = props.address;
const name = useTokenName(reserve?.liquidityMint);
const { balance: tokenBalance, accounts: fromAccounts } = useUserBalance(reserve?.liquidityMint);
// const collateralBalance = useUserBalance(reserve?.collateralMint);
useEffect(() => {
(async () => {
console.log(`utlization: ${reserve.maxUtilizationRate}`)
console.log(`cumulativeBorrowRate: ${reserve.cumulativeBorrowRate.toString()}`)
console.log(`cumulativeBorrowRate: ${reserve.cumulativeBorrowRate.toString()}`)
console.log(`totalBorrows: ${reserve.totalBorrows.toString()}`)
console.log(`totalLiquidity: ${reserve.totalLiquidity.toString()}`)
console.log(`lendingMarket: ${reserve.lendingMarket.toBase58()}`);
const lendingMarket = await cache.get(reserve.lendingMarket);
console.log(`lendingMarket quote: ${lendingMarket?.info.quoteMint.toBase58()}`);
console.log(`liquiditySupply: ${reserve.liquiditySupply.toBase58()}`);
console.log(`liquidityMint: ${reserve.liquidityMint.toBase58()}`);
console.log(`collateralSupply: ${reserve.collateralSupply.toBase58()}`);
console.log(`collateralMint: ${reserve.collateralMint.toBase58()}`);
})();
}, [reserve])
const onDeposit = useCallback(() => {
deposit(
fromAccounts[0],
parseFloat(value),
reserve,
address,
connection,
wallet);
}, [value, reserve, fromAccounts, address]);
const bodyStyle: React.CSSProperties = {
display: 'flex',
justifyContent: 'center',
width: '100%',
height: '100%',
alignItems: 'center'
};
return <Card className={props.className} bodyStyle={bodyStyle}>
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-around' }}>
<div className="deposit-add-title">
How much would you like to deposit?
</div>
<div className="token-input">
<TokenIcon mintAddress={reserve?.liquidityMint} />
<NumericInput value={value}
onChange={(val: any) => {
setValue(val);
}}
style={{
fontSize: 20,
boxShadow: "none",
borderColor: "transparent",
outline: "transpaernt",
}}
placeholder="0.00"
/>
<div>{name}</div>
</div>
<Button type="primary" onClick={onDeposit} disabled={fromAccounts.length === 0}>Deposit</Button>
</div>
</Card >;
}

View File

@ -0,0 +1,3 @@
.deposit-add-title {
font-size: 1.05rem;
}

View File

@ -0,0 +1,38 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useLendingReserve, useTokenName, useUserAccounts, useUserBalance } from './../../hooks';
import { LendingReserve, LendingReserveParser } from "../../models/lending";
import { TokenIcon } from "../../components/TokenIcon";
import { formatNumber } from "../../utils/utils";
import { Button, Card } from "antd";
import { useParams } from "react-router-dom";
import { cache, useAccount } from "../../contexts/accounts";
import { NumericInput } from "../../components/Input/numeric";
import { useConnection } from "../../contexts/connection";
import { useWallet } from "../../contexts/wallet";
import { deposit } from './../../actions/deposit';
import './style.less';
import { PublicKey } from "@solana/web3.js";
export const DepositInfoLine = (props: {
className?: string,
reserve: LendingReserve,
address: PublicKey }) => {
const name = useTokenName(props.reserve.liquidityMint);
const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint);
const { balance: collateralBalance } = useUserBalance(props.reserve.collateralMint);
return <Card className={props.className} bodyStyle={{ display: 'flex', justifyContent: 'space-around', }} >
<div className="deposit-info-line-item ">
<div>Your balance in Oyster</div>
<div>{formatNumber.format(collateralBalance)} {name}</div>
</div>
<div className="deposit-info-line-item ">
<div>Your wallet balance</div>
<div>{formatNumber.format(tokenBalance)} {name}</div>
</div>
<div className="deposit-info-line-item ">
<div>Health factor</div>
<div>--</div>
</div>
</Card>
}

View File

@ -0,0 +1,10 @@
.deposit-info-line {
display: flex;
flex-direction: row;
}
.deposit-info-line-item {
display: flex;
flex-direction: column;
justify-content: space-between;
}

View File

@ -0,0 +1,117 @@
import React, { useMemo } from "react";
import { useLendingReserve, useTokenName, useUserAccounts, useUserBalance } from './../../hooks';
import { LendingReserve, LendingReserveParser } from "../../models/lending";
import { TokenIcon } from "../../components/TokenIcon";
import { formatNumber, formatPct, fromLamports } from "../../utils/utils";
import { Button, Card, Typography } from "antd";
import { useParams } from "react-router-dom";
import { useAccount, useMint } from "../../contexts/accounts";
import { PublicKey } from "@solana/web3.js";
const { Text } = Typography;
export enum SideReserveOverviewMode {
Deposit = 'deposit',
Borrow = 'borrow'
}
export const SideReserveOverview = (props: {
className?: string;
reserve: LendingReserve,
address: PublicKey,
mode: SideReserveOverviewMode
}) => {
const reserve = props.reserve;
const mode = props.mode;
const name = useTokenName(reserve?.liquidityMint);
const liquidityMint = useMint(props.reserve.liquidityMint);
const totalLiquidity = fromLamports(props.reserve.totalLiquidity.toNumber(), liquidityMint);
// TODO: calculate
const utilizationRate = 0.5802;
const depositApy = 0.048;
const borrowApy = 0.048;
const maxLTV = 0.75;
const liquidiationThreshold = 0.8;
const liquidiationPenalty = 0.05;
let extraInfo: JSX.Element | null = null;
if (mode === SideReserveOverviewMode.Deposit) {
extraInfo = <>
<div className="card-row">
<Text type="secondary" className="card-cell ">
Deposit APY:
</Text>
<div className="card-cell ">
{formatPct.format(depositApy)}
</div>
</div>
<div className="card-row">
<Text type="secondary" className="card-cell ">
Maxiumum LTV:
</Text>
<div className="card-cell ">
{formatPct.format(maxLTV)}
</div>
</div>
<div className="card-row">
<Text type="secondary" className="card-cell ">
Liquidation threashold:
</Text>
<div className="card-cell ">
{formatPct.format(liquidiationThreshold)}
</div>
</div>
<div className="card-row">
<Text type="secondary" className="card-cell ">
Liquidation penalty:
</Text>
<div className="card-cell ">
{formatPct.format(liquidiationPenalty)}
</div>
</div>
</>;
} else if (mode === SideReserveOverviewMode.Borrow) {
extraInfo = <>
<div className="card-row">
<Text type="secondary" className="card-cell ">
Borrow APY:
</Text>
<div className="card-cell ">
{formatPct.format(borrowApy)}
</div>
</div>
</>;
}
return <Card className={props.className} title={
<div style={{ display: 'flex', alignItems: 'center', fontSize: '1.2rem', justifyContent: 'center' }}>
<TokenIcon mintAddress={reserve?.liquidityMint} style={{ width: 30, height: 30 }} /> {name} Reserve Overview
</div>
}>
<div className="card-row">
<Text type="secondary" className="card-cell ">
Utilization rate:
</Text>
<div className="card-cell ">
{formatPct.format(utilizationRate)}
</div>
</div>
<div className="card-row">
<Text type="secondary" className="card-cell ">
Available liquidity:
</Text>
<div className="card-cell ">
{formatNumber.format(totalLiquidity)} {name}
</div>
</div>
{extraInfo}
</Card>;
}

View File

@ -38,4 +38,4 @@ export const LendingMarketParser = (pubKey: PublicKey, info: AccountInfo<Buffer>
// TODO:
// create instructions for init, deposit and withdraw
// create instructions for init

View File

@ -0,0 +1 @@
export const x = 1;

View File

@ -24,8 +24,11 @@ export const LendingReserveLayout: typeof BufferLayout.Structure = BufferLayout.
// TODO: replace u32 option with generic quivalent
BufferLayout.u32('dexMarketOption'),
Layout.publicKey("dexMarket"),
BufferLayout.u8("maxUtilizationRate"),
BufferLayout.u8("collateralFactor"),
Layout.uint128("cumulativeBorrowRate"),
Layout.uint128("totalBorrows"),
@ -46,13 +49,13 @@ export interface LendingReserve {
liquidityMint: PublicKey;
collateralSupply: PublicKey;
collateralMint: PublicKey;
// TODO: replace u32 option with generic quivalent
dexMarketOption: number;
dexMarket: PublicKey;
dexMarketPrice: BN; // what is precision on the price?
maxUtilizationRate: number;
dexMarketPriceUpdatedSlot: BN;
// collateralFactor: number;
cumulativeBorrowRate: BN;
totalBorrows: BN;

View File

@ -10,78 +10,38 @@ import { NumericInput } from "../../../components/Input/numeric";
import { useConnection } from "../../../contexts/connection";
import { useWallet } from "../../../contexts/wallet";
import { deposit } from './../../../actions/deposit';
import './style.less';
import { DepositAdd } from './../../../components/DepositAdd';
import { DepositInfoLine } from './../../../components/DepositInfoLine';
import { SideReserveOverview, SideReserveOverviewMode } from './../../../components/SideReserveOverview';
export const DepositAddView = () => {
const connection = useConnection();
const { wallet } = useWallet();
const { id } = useParams<{ id: string }>();
const [value, setValue] = useState('');
const lendingReserve = useLendingReserve(id);
const reserve = lendingReserve?.info;
const name = useTokenName(reserve?.liquidityMint);
const { balance: tokenBalance, accounts: fromAccounts } = useUserBalance(reserve?.liquidityMint);
// const collateralBalance = useUserBalance(reserve?.collateralMint);
if (!reserve || !lendingReserve) {
return null;
}
useEffect(() => {
(async () => {
const reserve = lendingReserve?.info;
if (!reserve) {
return;
}
console.log(`utlization: ${reserve.maxUtilizationRate}`)
console.log(`cumulativeBorrowRate: ${reserve.cumulativeBorrowRate.toString()}`)
console.log(`cumulativeBorrowRate: ${reserve.cumulativeBorrowRate.toString()}`)
console.log(`totalBorrows: ${reserve.totalBorrows.toString()}`)
console.log(`totalLiquidity: ${reserve.totalLiquidity.toString()}`)
console.log(`lendingMarket: ${reserve.lendingMarket.toBase58()}`);
const lendingMarket = await cache.get(reserve.lendingMarket);
console.log(`lendingMarket quote: ${lendingMarket?.info.quoteMint.toBase58()}`);
console.log(`liquiditySupply: ${reserve.liquiditySupply.toBase58()}`);
console.log(`liquidityMint: ${reserve.liquidityMint.toBase58()}`);
console.log(`collateralSupply: ${reserve.collateralSupply.toBase58()}`);
console.log(`collateralMint: ${reserve.collateralMint.toBase58()}`);
})();
}, [lendingReserve])
const onDeposit = useCallback(() => {
if (!lendingReserve || !reserve) {
return;
}
deposit(
fromAccounts[0],
parseFloat(value),
reserve,
lendingReserve.pubkey,
connection,
wallet);
}, [value, reserve, fromAccounts, lendingReserve]);
return <Card title={(
<h2 style={{ display: 'flex', alignItems: 'center', width: 400 }}>
<TokenIcon mintAddress={reserve?.liquidityMint} style={{ width: 40, height: 40 }} /> Deposit {name}
</h2>
)}>
<div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-around' }}>
<NumericInput value={value}
onChange={(val: any) => {
setValue(val);
}}
style={{
fontSize: 20,
boxShadow: "none",
borderColor: "transparent",
outline: "transpaernt",
}}
placeholder="0.00"
/>
<Button type="primary" onClick={onDeposit} disabled={fromAccounts.length === 0}>Deposit</Button>
return <div className="deposit-add">
<DepositInfoLine
className="deposit-add-item"
reserve={reserve}
address={lendingReserve.pubkey} />
<div className="deposit-add-container">
<DepositAdd
className="deposit-add-item deposit-add-item-left"
reserve={reserve}
address={lendingReserve.pubkey} />
<SideReserveOverview
className="deposit-add-item deposit-add-item-right"
reserve={reserve}
address={lendingReserve.pubkey}
mode={SideReserveOverviewMode.Deposit} />
</div>
</Card >;
</div>;
}

View File

@ -0,0 +1,32 @@
.deposit-add {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
}
.deposit-add-item {
margin: 4px;
}
.deposit-add-container {
display: flex;
flex-wrap: wrap;
height: 100%;
width: 100%;
}
.deposit-add-item-left {
flex: 60%;
}
.deposit-add-item-right {
flex: 30%;
}
/* Responsive layout - makes a one column layout instead of a two-column layout */
@media (max-width: 600px) {
.deposit-add-item-right, .deposit-add-item-left {
flex: 100%;
}
}