feat(console-lite): add trade balance component and hook (#516)
* feat(console-lite): add trade balance component and hook * feat(console-lite): review fixes Co-authored-by: Dexter <dexter.edwards93@gmail.com>
This commit is contained in:
parent
d0452aeb81
commit
fde5149912
59
apps/simple-trading-app/src/app/components/deal-ticket/__generated__/PartyBalanceQuery.ts
generated
Normal file
59
apps/simple-trading-app/src/app/components/deal-ticket/__generated__/PartyBalanceQuery.ts
generated
Normal file
@ -0,0 +1,59 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: PartyBalanceQuery
|
||||
// ====================================================
|
||||
|
||||
export interface PartyBalanceQuery_party_accounts_asset {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The id of the asset
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The symbol of the asset (e.g: GBP)
|
||||
*/
|
||||
symbol: string;
|
||||
/**
|
||||
* The full name of the asset (e.g: Great British Pound)
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The precision of the asset
|
||||
*/
|
||||
decimals: number;
|
||||
}
|
||||
|
||||
export interface PartyBalanceQuery_party_accounts {
|
||||
__typename: "Account";
|
||||
/**
|
||||
* Balance as string - current account balance (approx. as balances can be updated several times per second)
|
||||
*/
|
||||
balance: string;
|
||||
/**
|
||||
* Asset, the 'currency'
|
||||
*/
|
||||
asset: PartyBalanceQuery_party_accounts_asset;
|
||||
}
|
||||
|
||||
export interface PartyBalanceQuery_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Collateral accounts relating to a party
|
||||
*/
|
||||
accounts: PartyBalanceQuery_party_accounts[] | null;
|
||||
}
|
||||
|
||||
export interface PartyBalanceQuery {
|
||||
/**
|
||||
* An entity that is trading on the VEGA network
|
||||
*/
|
||||
party: PartyBalanceQuery_party | null;
|
||||
}
|
||||
|
||||
export interface PartyBalanceQueryVariables {
|
||||
partyId: string;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
import * as React from 'react';
|
||||
import type { DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartyBalanceQuery_party_accounts } from './__generated__/PartyBalanceQuery';
|
||||
import { useSettlementAccount } from '../../hooks/use-settlement-account';
|
||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||
|
||||
interface DealTicketBalanceProps {
|
||||
settlementAsset: DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset;
|
||||
accounts: PartyBalanceQuery_party_accounts[];
|
||||
isWalletConnected: boolean;
|
||||
}
|
||||
|
||||
export const DealTicketBalance = ({
|
||||
settlementAsset,
|
||||
accounts,
|
||||
isWalletConnected,
|
||||
}: DealTicketBalanceProps) => {
|
||||
const settlementAssetId = settlementAsset?.id;
|
||||
const settlementAssetSymbol = settlementAsset?.symbol;
|
||||
const settlementAccount = useSettlementAccount(settlementAssetId, accounts);
|
||||
const formatedNumber =
|
||||
settlementAccount?.balance &&
|
||||
settlementAccount.asset.decimals &&
|
||||
addDecimalsFormatNumber(
|
||||
settlementAccount.balance,
|
||||
settlementAccount.asset.decimals
|
||||
);
|
||||
|
||||
const balance = settlementAccount ? (
|
||||
<p>
|
||||
{t(
|
||||
`${formatedNumber} ${settlementAccount.asset.symbol} available to trade`
|
||||
)}
|
||||
</p>
|
||||
) : (
|
||||
<p>{t(`You have no ${settlementAssetSymbol} available to trade`)}</p>
|
||||
);
|
||||
|
||||
const connectWallet = (
|
||||
<p>
|
||||
{t(
|
||||
"Please connect your Vega wallet to see your balance for this market's settlement asset"
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="text-right">
|
||||
<div className="border border-current p-16 inline-block">
|
||||
<small className="text-text">{t('Balance')}</small>
|
||||
{isWalletConnected ? balance : connectWallet}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -4,15 +4,58 @@ import {
|
||||
DealTicketContainer as Container,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import { DealTicketSteps } from './deal-ticket-steps';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { DealTicketBalance } from './deal-ticket-balance';
|
||||
import * as React from 'react';
|
||||
import type { PartyBalanceQuery } from './__generated__/PartyBalanceQuery';
|
||||
|
||||
const tempEmptyText = <p>Please select a market from the markets page</p>;
|
||||
|
||||
const PARTY_BALANCE_QUERY = gql`
|
||||
query PartyBalanceQuery($partyId: ID!) {
|
||||
party(id: $partyId) {
|
||||
accounts {
|
||||
balance
|
||||
asset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
decimals
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const DealTicketContainer = () => {
|
||||
const { marketId } = useParams<{ marketId: string }>();
|
||||
const { keypair } = useVegaWallet();
|
||||
|
||||
const { data: partyData, loading } = useQuery<PartyBalanceQuery>(
|
||||
PARTY_BALANCE_QUERY,
|
||||
{
|
||||
variables: { partyId: keypair?.pub },
|
||||
skip: !keypair?.pub,
|
||||
}
|
||||
);
|
||||
|
||||
return marketId ? (
|
||||
<Container marketId={marketId}>
|
||||
{(data) => (
|
||||
<DealTicketManager market={data.market}>
|
||||
{loading ? (
|
||||
'Loading...'
|
||||
) : (
|
||||
<DealTicketBalance
|
||||
settlementAsset={
|
||||
data.market.tradableInstrument.instrument.product
|
||||
?.settlementAsset
|
||||
}
|
||||
accounts={partyData?.party?.accounts || []}
|
||||
isWalletConnected={!!keypair?.pub}
|
||||
/>
|
||||
)}
|
||||
<DealTicketSteps market={data.market} />
|
||||
</DealTicketManager>
|
||||
)}
|
||||
|
@ -0,0 +1,61 @@
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { useSettlementAccount } from './use-settlement-account';
|
||||
import type { PartyBalanceQuery_party_accounts } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
|
||||
describe('useSettlementAccount Hook', () => {
|
||||
it('should filter accounts by settlementAssetId', () => {
|
||||
const accounts: PartyBalanceQuery_party_accounts[] = [
|
||||
{
|
||||
__typename: 'Account',
|
||||
balance: '2000000000000000000000',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
name: 'tBTC TEST',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'Account',
|
||||
balance: '1000000000',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: '6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61',
|
||||
symbol: 'tDAI',
|
||||
name: 'tDAI TEST',
|
||||
decimals: 5,
|
||||
},
|
||||
},
|
||||
{
|
||||
__typename: 'Account',
|
||||
balance: '5000000000000000000',
|
||||
asset: {
|
||||
__typename: 'Asset',
|
||||
id: 'fc7fd956078fb1fc9db5c19b88f0874c4299b2a7639ad05a47a28c0aef291b55',
|
||||
symbol: 'VEGA',
|
||||
name: 'Vega (testnet)',
|
||||
decimals: 18,
|
||||
},
|
||||
},
|
||||
];
|
||||
const settlementAssetId =
|
||||
'6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61';
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useSettlementAccount(settlementAssetId, accounts)
|
||||
);
|
||||
expect(result.current?.balance).toBe(accounts[1].balance);
|
||||
expect(result.current?.asset).toEqual(accounts[1].asset);
|
||||
});
|
||||
|
||||
it('should return null if no accounts', () => {
|
||||
const accounts: PartyBalanceQuery_party_accounts[] = [];
|
||||
const settlementAssetId =
|
||||
'6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61';
|
||||
const { result } = renderHook(() =>
|
||||
useSettlementAccount(settlementAssetId, accounts)
|
||||
);
|
||||
expect(result.current).toBe(undefined);
|
||||
});
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
import type { PartyBalanceQuery_party_accounts } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const useSettlementAccount = (
|
||||
settlementAssetId: string,
|
||||
accounts: PartyBalanceQuery_party_accounts[]
|
||||
): PartyBalanceQuery_party_accounts | null => {
|
||||
const callback = () =>
|
||||
accounts.find((account) => account.asset.id === settlementAssetId);
|
||||
const account = useMemo(callback, [accounts, settlementAssetId]);
|
||||
return account as PartyBalanceQuery_party_accounts;
|
||||
};
|
@ -18,6 +18,12 @@ export const generateDealTicketQuery = (
|
||||
instrument: {
|
||||
product: {
|
||||
quoteName: 'BTC',
|
||||
settlementAsset: {
|
||||
__typename: 'Asset',
|
||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
||||
symbol: 'tBTC',
|
||||
name: 'tBTC TEST',
|
||||
},
|
||||
__typename: 'Future',
|
||||
},
|
||||
__typename: 'Instrument',
|
||||
|
@ -9,12 +9,32 @@ import { MarketState, MarketTradingMode } from "@vegaprotocol/types";
|
||||
// GraphQL query operation: DealTicketQuery
|
||||
// ====================================================
|
||||
|
||||
export interface DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The id of the asset
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The symbol of the asset (e.g: GBP)
|
||||
*/
|
||||
symbol: string;
|
||||
/**
|
||||
* The full name of the asset (e.g: Great British Pound)
|
||||
*/
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface DealTicketQuery_market_tradableInstrument_instrument_product {
|
||||
__typename: "Future";
|
||||
/**
|
||||
* String representing the quote (e.g. BTCUSD -> USD is quote)
|
||||
*/
|
||||
quoteName: string;
|
||||
/**
|
||||
* The name of the asset (string)
|
||||
*/
|
||||
settlementAsset: DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset;
|
||||
}
|
||||
|
||||
export interface DealTicketQuery_market_tradableInstrument_instrument {
|
||||
|
@ -21,6 +21,11 @@ const DEAL_TICKET_QUERY = gql`
|
||||
product {
|
||||
... on Future {
|
||||
quoteName
|
||||
settlementAsset {
|
||||
id
|
||||
symbol
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user