Split up balances page
This commit is contained in:
parent
286eeabf71
commit
787b5b1e05
|
@ -0,0 +1,73 @@
|
|||
import { Button } from 'antd';
|
||||
import React from 'react';
|
||||
import {
|
||||
useSelectedOpenOrdersAccount,
|
||||
useMarket,
|
||||
useSelectedBaseCurrencyAccount,
|
||||
useSelectedQuoteCurrencyAccount,
|
||||
} from '../../utils/markets';
|
||||
import DataTable from '../layout/DataTable';
|
||||
import { useConnection } from '../../utils/connection';
|
||||
import { useWallet } from '../../utils/wallet';
|
||||
import { settleFunds } from '../../utils/send';
|
||||
|
||||
export default function AccountsTable({ accountBalances }) {
|
||||
const baseCurrencyAccount = useSelectedBaseCurrencyAccount();
|
||||
const quoteCurrencyAccount = useSelectedQuoteCurrencyAccount();
|
||||
const connection = useConnection();
|
||||
const [, wallet] = useWallet();
|
||||
const openOrdersAccount = useSelectedOpenOrdersAccount(true);
|
||||
const { market } = useMarket();
|
||||
|
||||
async function onSettleFunds() {
|
||||
return await settleFunds({
|
||||
market,
|
||||
openOrders: openOrdersAccount,
|
||||
connection,
|
||||
wallet,
|
||||
baseCurrencyAccount,
|
||||
quoteCurrencyAccount,
|
||||
});
|
||||
}
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Key',
|
||||
dataIndex: 'key',
|
||||
key: 'key',
|
||||
},
|
||||
{
|
||||
title: 'Coin',
|
||||
dataIndex: 'coin',
|
||||
key: 'coin',
|
||||
},
|
||||
{
|
||||
title: 'Orders',
|
||||
dataIndex: 'orders',
|
||||
key: 'orders',
|
||||
},
|
||||
{
|
||||
title: 'Unsettled',
|
||||
dataIndex: 'unsettled',
|
||||
key: 'unsettled',
|
||||
},
|
||||
{
|
||||
key: 'action',
|
||||
render: () => (
|
||||
<div style={{ textAlign: 'right' }}>
|
||||
<Button ghost style={{ marginRight: 12 }} onClick={onSettleFunds}>
|
||||
Settle
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
return (
|
||||
<DataTable
|
||||
emptyLabel="No balances"
|
||||
dataSource={accountBalances}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import React from 'react';
|
||||
import DataTable from '../layout/DataTable';
|
||||
|
||||
export default function WalletBalancesTable({
|
||||
loaded = false,
|
||||
walletBalances,
|
||||
}) {
|
||||
const columns = [
|
||||
{
|
||||
title: 'Key',
|
||||
dataIndex: 'key',
|
||||
key: 'key',
|
||||
},
|
||||
{
|
||||
title: 'Coin',
|
||||
dataIndex: 'coin',
|
||||
key: 'coin',
|
||||
},
|
||||
{
|
||||
title: 'Wallet Balance',
|
||||
dataIndex: 'wallet',
|
||||
key: 'wallet',
|
||||
},
|
||||
];
|
||||
return (
|
||||
<DataTable
|
||||
emptyLabel="No balances"
|
||||
dataSource={walletBalances}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
loading={!loaded}
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -6,6 +6,7 @@ export default function DataTable({
|
|||
columns,
|
||||
emptyLabel = 'No data',
|
||||
pagination = false,
|
||||
loading = false,
|
||||
pageSize = 10,
|
||||
}) {
|
||||
const customizeRenderEmpty = () => (
|
||||
|
@ -27,6 +28,7 @@ export default function DataTable({
|
|||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
pagination={pagination ? { pagination: true, pageSize } : false}
|
||||
loading={loading}
|
||||
/>
|
||||
</ConfigProvider>
|
||||
);
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
import React from 'react';
|
||||
import { useBalancesForAllMarkets } from '../utils/markets';
|
||||
import { Tabs } from 'antd';
|
||||
import { useWalletBalancesForAllMarkets, useOpenOrderAccountBalancesForAllMarkets } from '../utils/markets';
|
||||
import FloatingElement from '../components/layout/FloatingElement';
|
||||
import BalancesTable from '../components/UserInfoTable/BalancesTable';
|
||||
import WalletBalancesTable from '../components/UserInfoTable/WalletBalancesTable';
|
||||
import AccountsTable from '../components/UserInfoTable/AccountsTable';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
export default function BalancesPage() {
|
||||
const [balances] = useBalancesForAllMarkets();
|
||||
console.log(JSON.stringify(balances));
|
||||
const [walletBalances, loadedWalletBalances] = useWalletBalancesForAllMarkets();
|
||||
const [accountBalances, accountBalancesLoaded] = useOpenOrderAccountBalancesForAllMarkets();
|
||||
|
||||
return (
|
||||
<FloatingElement style={{ flex: 1, paddingTop: 10 }}>
|
||||
<BalancesTable balances={balances} />
|
||||
<Tabs defaultActiveKey="accounts">
|
||||
<TabPane tab="Balances" key="balances">
|
||||
<WalletBalancesTable loaded={loadedWalletBalances} walletBalances={walletBalances} />
|
||||
</TabPane>
|
||||
<TabPane tab="Accounts" key="accounts">
|
||||
<AccountsTable loaded={accountBalancesLoaded} accountBalances={accountBalances} />
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
</FloatingElement>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -592,13 +592,13 @@ export function useBalances() {
|
|||
];
|
||||
}
|
||||
|
||||
export function useBalancesForAllMarkets() {
|
||||
export function useWalletBalancesForAllMarkets() {
|
||||
const [connected, wallet] = useWallet();
|
||||
|
||||
const connection = useConnection();
|
||||
const allMarkets = useAllMarkets();
|
||||
|
||||
async function getBalancesForAllMarkets() {
|
||||
async function getWalletBalancesForAllMarkets() {
|
||||
let balances = [];
|
||||
if (!connected) {
|
||||
return balances;
|
||||
|
@ -612,26 +612,32 @@ export function useBalancesForAllMarkets() {
|
|||
}
|
||||
const baseCurrency = marketName.includes('/') && marketName.split('/')[0];
|
||||
if (!balances.find((balance) => balance.coin === baseCurrency)) {
|
||||
const baseBalance = await getBalanceForMarket(
|
||||
const baseBalance = await getCurrencyBalance(
|
||||
market,
|
||||
connection,
|
||||
wallet,
|
||||
baseCurrency,
|
||||
true,
|
||||
);
|
||||
balances.push(baseBalance);
|
||||
balances.push({
|
||||
key: baseCurrency,
|
||||
coin: baseCurrency,
|
||||
wallet: baseBalance,
|
||||
});
|
||||
}
|
||||
const quoteCurrency =
|
||||
marketName.includes('/') && marketName.split('/')[1];
|
||||
if (!balances.find((balance) => balance.coin === quoteCurrency)) {
|
||||
const quoteBalance = await getBalanceForMarket(
|
||||
const quoteBalance = await getCurrencyBalance(
|
||||
market,
|
||||
connection,
|
||||
wallet,
|
||||
quoteCurrency,
|
||||
false,
|
||||
);
|
||||
balances.push(quoteBalance);
|
||||
balances.push({
|
||||
key: quoteCurrency,
|
||||
coin: quoteCurrency,
|
||||
wallet: quoteBalance,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -639,9 +645,9 @@ export function useBalancesForAllMarkets() {
|
|||
}
|
||||
|
||||
return useAsyncData(
|
||||
getBalancesForAllMarkets,
|
||||
getWalletBalancesForAllMarkets,
|
||||
tuple(
|
||||
'getBalancesForAllMarkets',
|
||||
'getWalletBalancesForAllMarkets',
|
||||
connected,
|
||||
connection,
|
||||
wallet,
|
||||
|
@ -651,16 +657,7 @@ export function useBalancesForAllMarkets() {
|
|||
);
|
||||
}
|
||||
|
||||
async function getBalanceForMarket(
|
||||
market,
|
||||
connection,
|
||||
wallet,
|
||||
currency,
|
||||
base = true,
|
||||
) {
|
||||
if (!market) {
|
||||
return;
|
||||
}
|
||||
async function getCurrencyBalance(market, connection, wallet, base = true) {
|
||||
const currencyAccounts = base
|
||||
? await market.findBaseTokenAccountsForOwner(connection, wallet.publicKey)
|
||||
: await market.findQuoteTokenAccountsForOwner(connection, wallet.publicKey);
|
||||
|
@ -668,33 +665,90 @@ async function getBalanceForMarket(
|
|||
const tokenAccountBalances = await connection.getTokenAccountBalance(
|
||||
currencyAccount.pubkey,
|
||||
);
|
||||
const currencyBalances = tokenAccountBalances?.value?.uiAmount;
|
||||
const openOrdersAccounts = await market.findOpenOrdersAccountsForOwner(
|
||||
return tokenAccountBalances?.value?.uiAmount;
|
||||
}
|
||||
|
||||
export function useOpenOrderAccountBalancesForAllMarkets() {
|
||||
const [connected, wallet] = useWallet();
|
||||
|
||||
const connection = useConnection();
|
||||
const allMarkets = useAllMarkets();
|
||||
|
||||
async function getOpenOrderAccountsForAllMarkets() {
|
||||
let accounts = [];
|
||||
if (!connected) {
|
||||
return accounts;
|
||||
}
|
||||
|
||||
let marketData;
|
||||
for (marketData of allMarkets) {
|
||||
const { market, marketName } = marketData;
|
||||
if (!market) {
|
||||
return accounts;
|
||||
}
|
||||
const openOrderAccounts = await market.findOpenOrdersAccountsForOwner(
|
||||
connection,
|
||||
wallet.publicKey,
|
||||
);
|
||||
const openOrdersAccount = openOrdersAccounts && openOrdersAccounts[0];
|
||||
const inOrders = base
|
||||
? openOrdersAccount?.baseTokenTotal &&
|
||||
if (!openOrderAccounts) {
|
||||
continue;
|
||||
}
|
||||
const baseCurrency = marketName.includes('/') && marketName.split('/')[0];
|
||||
const quoteCurrency =
|
||||
marketName.includes('/') && marketName.split('/')[1];
|
||||
|
||||
const openOrderAccountBalances = [];
|
||||
openOrderAccounts.forEach((openOrdersAccount) => {
|
||||
const inOrdersBase =
|
||||
openOrdersAccount?.baseTokenTotal &&
|
||||
openOrdersAccount?.baseTokenFree &&
|
||||
market.baseSplSizeToNumber(
|
||||
openOrdersAccount.baseTokenTotal.sub(openOrdersAccount.baseTokenFree),
|
||||
)
|
||||
: openOrdersAccount?.quoteTokenTotal &&
|
||||
openOrdersAccount?.quoteTokenFree &&
|
||||
market.quoteSplSizeToNumber(
|
||||
openOrdersAccount.quoteTokenTotal.sub(openOrdersAccount.quoteTokenFree),
|
||||
openOrdersAccount.baseTokenTotal.sub(
|
||||
openOrdersAccount.baseTokenFree,
|
||||
),
|
||||
);
|
||||
const unsettled = base
|
||||
? openOrdersAccount?.baseTokenFree &&
|
||||
market.baseSplSizeToNumber(openOrdersAccount.baseTokenFree)
|
||||
: openOrdersAccount?.quoteTokenFree &&
|
||||
const inOrdersQuote =
|
||||
openOrdersAccount?.quoteTokenTotal &&
|
||||
openOrdersAccount?.quoteTokenFree &&
|
||||
market.baseSplSizeToNumber(
|
||||
openOrdersAccount.quoteTokenTotal.sub(
|
||||
openOrdersAccount.quoteTokenFree,
|
||||
),
|
||||
);
|
||||
const unsettledBase =
|
||||
openOrdersAccount?.baseTokenFree &&
|
||||
market.baseSplSizeToNumber(openOrdersAccount.baseTokenFree);
|
||||
return {
|
||||
key: currency,
|
||||
coin: currency,
|
||||
wallet: currencyBalances,
|
||||
orders: inOrders,
|
||||
unsettled: unsettled,
|
||||
};
|
||||
const unsettledQuote =
|
||||
openOrdersAccount?.quoteTokenFree &&
|
||||
market.baseSplSizeToNumber(openOrdersAccount.quoteTokenFree);
|
||||
openOrderAccountBalances.push({
|
||||
key: baseCurrency,
|
||||
coin: baseCurrency,
|
||||
orders: inOrdersBase,
|
||||
unsettled: unsettledBase,
|
||||
});
|
||||
openOrderAccountBalances.push({
|
||||
key: quoteCurrency,
|
||||
coin: quoteCurrency,
|
||||
orders: inOrdersQuote,
|
||||
unsettled: unsettledQuote,
|
||||
});
|
||||
});
|
||||
accounts = accounts.concat(openOrderAccountBalances);
|
||||
}
|
||||
|
||||
return accounts;
|
||||
}
|
||||
|
||||
return useAsyncData(
|
||||
getOpenOrderAccountsForAllMarkets,
|
||||
tuple(
|
||||
'getOpenOrderAccountsForAllMarkets',
|
||||
connected,
|
||||
connection,
|
||||
wallet,
|
||||
allMarkets,
|
||||
),
|
||||
{ refreshInterval: _SLOW_REFRESH_INTERVAL },
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue