chore: account balances changes (#344)

This commit is contained in:
Anthony Potdevin 2021-09-28 10:43:22 +02:00 committed by GitHub
parent 02e2a14d0c
commit b74ad8ab6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 259 additions and 203 deletions

View File

@ -5,6 +5,7 @@ import { NextPageContext } from 'next';
import { getProps } from 'src/utils/ssr';
import { MempoolReport } from 'src/views/home/reports/mempool';
import { LiquidityGraph } from 'src/views/home/reports/liquidReport/LiquidityGraph';
import { AccountButtons } from 'src/views/home/account/AccountButtons';
import { NetworkInfo } from '../src/views/home/networkInfo/NetworkInfo';
import { AccountInfo } from '../src/views/home/account/AccountInfo';
import { QuickActions } from '../src/views/home/quickActions/QuickActions';
@ -16,6 +17,7 @@ const HomeView = () => (
<>
<Version />
<AccountInfo />
<AccountButtons />
<ConnectCard />
<QuickActions />
<FlowBox />

View File

@ -128,6 +128,7 @@ export const channelTypes = gql`
is_active: Boolean!
is_closing: Boolean!
is_opening: Boolean!
is_timelocked: Boolean!
local_balance: Int!
local_reserve: Int!
partner_public_key: String!
@ -139,5 +140,7 @@ export const channelTypes = gql`
transaction_id: String!
transaction_vout: Int!
partner_node_info: Node!
timelock_blocks: Int
timelock_expiration: Int
}
`;

View File

@ -150,7 +150,7 @@ export const nodeResolvers = {
const closing =
pending_channels
.filter(p => p.is_closing)
.filter(p => p.is_timelocked)
.reduce((p, c) => p + c.local_balance, 0) || 0;
return closing || 0;

View File

@ -546,6 +546,7 @@ export const getPendingChannelsResponse = {
is_active: true,
is_closing: true,
is_opening: true,
is_timelocked: true,
is_partner_initiated: true,
local_balance: 1000,
local_reserve: 1000,
@ -576,6 +577,7 @@ export const getPendingChannelsResponse = {
is_active: true,
is_closing: true,
is_opening: true,
is_timelocked: true,
is_partner_initiated: true,
local_balance: 1000,
local_reserve: 1000,
@ -606,6 +608,7 @@ export const getPendingChannelsResponse = {
is_active: true,
is_closing: true,
is_opening: true,
is_timelocked: true,
is_partner_initiated: true,
local_balance: 1000,
local_reserve: 1000,

View File

@ -157,6 +157,7 @@ export type PendingChannelType = {
is_active: boolean;
is_closing: boolean;
is_opening: boolean;
is_timelocked: boolean;
local_balance: number;
local_reserve: number;
partner_public_key: string;
@ -167,6 +168,8 @@ export type PendingChannelType = {
transaction_fee: number;
transaction_id: string;
transaction_vout: number;
timelock_blocks?: number;
timelock_expiration?: number;
};
export type GetPendingChannelsType = { pending_channels: PendingChannelType[] };

View File

@ -2,6 +2,7 @@ import React from 'react';
import styled, { css } from 'styled-components';
import { ChevronRight } from 'react-feather';
import ScaleLoader from 'react-spinners/ScaleLoader';
import { ThemeSet } from 'styled-theming';
import {
textColor,
colorButtonBackground,
@ -72,11 +73,13 @@ interface BorderProps {
borderColor?: string;
selected?: boolean;
withBorder?: boolean;
backgroundColor?: string | ThemeSet;
}
const BorderButton = styled(GeneralButton)<BorderProps>`
${({ selected }) => selected && 'font-weight: 800'};
background-color: ${colorButtonBackground};
background-color: ${({ backgroundColor }) =>
backgroundColor || colorButtonBackground};
color: ${textColor};
border: 1px solid
${({ borderColor, selected, withBorder }) =>
@ -127,6 +130,7 @@ export interface ColorButtonProps {
fullWidth?: boolean;
mobileFullWidth?: boolean;
width?: string;
backgroundColor?: string | ThemeSet;
}
export const ColorButton: React.FC<ColorButtonProps> = ({
@ -143,6 +147,7 @@ export const ColorButton: React.FC<ColorButtonProps> = ({
mobileFullWidth,
width,
onClick,
backgroundColor,
}) => {
if (disabled && !loading) {
return (
@ -184,6 +189,7 @@ export const ColorButton: React.FC<ColorButtonProps> = ({
fullWidth={fullWidth}
mobileFullWidth={mobileFullWidth}
buttonWidth={width}
backgroundColor={backgroundColor}
>
{children}
{arrow && renderArrow()}

View File

@ -7,7 +7,7 @@ const defaultOptions = {}
export type GetPendingChannelsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type GetPendingChannelsQuery = { __typename?: 'Query', getPendingChannels?: Types.Maybe<Array<Types.Maybe<{ __typename?: 'pendingChannelType', close_transaction_id?: Types.Maybe<string>, is_active: boolean, is_closing: boolean, is_opening: boolean, local_balance: number, local_reserve: number, partner_public_key: string, received: number, remote_balance: number, remote_reserve: number, sent: number, transaction_fee?: Types.Maybe<number>, transaction_id: string, transaction_vout: number, partner_node_info: { __typename?: 'Node', node: { __typename?: 'nodeType', alias: string, capacity?: Types.Maybe<string>, channel_count?: Types.Maybe<number>, color?: Types.Maybe<string>, updated_at?: Types.Maybe<string> } } }>>> };
export type GetPendingChannelsQuery = { __typename?: 'Query', getPendingChannels?: Types.Maybe<Array<Types.Maybe<{ __typename?: 'pendingChannelType', close_transaction_id?: Types.Maybe<string>, is_active: boolean, is_closing: boolean, is_opening: boolean, is_timelocked: boolean, local_balance: number, local_reserve: number, timelock_blocks?: Types.Maybe<number>, timelock_expiration?: Types.Maybe<number>, partner_public_key: string, received: number, remote_balance: number, remote_reserve: number, sent: number, transaction_fee?: Types.Maybe<number>, transaction_id: string, transaction_vout: number, partner_node_info: { __typename?: 'Node', node: { __typename?: 'nodeType', alias: string, capacity?: Types.Maybe<string>, channel_count?: Types.Maybe<number>, color?: Types.Maybe<string>, updated_at?: Types.Maybe<string> } } }>>> };
export const GetPendingChannelsDocument = gql`
@ -17,8 +17,11 @@ export const GetPendingChannelsDocument = gql`
is_active
is_closing
is_opening
is_timelocked
local_balance
local_reserve
timelock_blocks
timelock_expiration
partner_public_key
received
remote_balance

View File

@ -778,6 +778,7 @@ Object {
"is_active": true,
"is_closing": true,
"is_opening": true,
"is_timelocked": true,
"local_balance": 1000,
"local_reserve": 1000,
"partner_node_info": Object {
@ -794,6 +795,8 @@ Object {
"remote_balance": 1000,
"remote_reserve": 1000,
"sent": 1000,
"timelock_blocks": null,
"timelock_expiration": 1000,
"transaction_fee": 1000,
"transaction_id": "string",
"transaction_vout": 1000,
@ -803,6 +806,7 @@ Object {
"is_active": true,
"is_closing": true,
"is_opening": true,
"is_timelocked": true,
"local_balance": 1000,
"local_reserve": 1000,
"partner_node_info": Object {
@ -819,6 +823,8 @@ Object {
"remote_balance": 1000,
"remote_reserve": 1000,
"sent": 1000,
"timelock_blocks": null,
"timelock_expiration": 1000,
"transaction_fee": 1000,
"transaction_id": "string",
"transaction_vout": 1000,
@ -828,6 +834,7 @@ Object {
"is_active": true,
"is_closing": true,
"is_opening": true,
"is_timelocked": true,
"local_balance": 1000,
"local_reserve": 1000,
"partner_node_info": Object {
@ -844,6 +851,8 @@ Object {
"remote_balance": 1000,
"remote_reserve": 1000,
"sent": 1000,
"timelock_blocks": null,
"timelock_expiration": 1000,
"transaction_fee": 1000,
"transaction_id": "string",
"transaction_vout": 1000,

View File

@ -7,8 +7,11 @@ export const GET_PENDING_CHANNELS = gql`
is_active
is_closing
is_opening
is_timelocked
local_balance
local_reserve
timelock_blocks
timelock_expiration
partner_public_key
received
remote_balance

View File

@ -1124,6 +1124,7 @@ export type PendingChannelType = {
is_active: Scalars['Boolean'];
is_closing: Scalars['Boolean'];
is_opening: Scalars['Boolean'];
is_timelocked: Scalars['Boolean'];
local_balance: Scalars['Int'];
local_reserve: Scalars['Int'];
partner_node_info: Node;
@ -1132,6 +1133,8 @@ export type PendingChannelType = {
remote_balance: Scalars['Int'];
remote_reserve: Scalars['Int'];
sent: Scalars['Int'];
timelock_blocks?: Maybe<Scalars['Int']>;
timelock_expiration?: Maybe<Scalars['Int']>;
transaction_fee?: Maybe<Scalars['Int']>;
transaction_id: Scalars['String'];
transaction_vout: Scalars['Int'];

View File

@ -6,6 +6,7 @@ import { getPrice, Price } from 'src/components/price/Price';
import { addEllipsis, renderLine } from 'src/components/generic/helpers';
import { useNodeInfo } from 'src/hooks/UseNodeInfo';
import { useNodeBalances } from 'src/hooks/UseNodeBalances';
import Big from 'big.js';
import { unSelectedNavButton } from '../../../styles/Themes';
import {
Separation,
@ -85,6 +86,14 @@ export const NodeInfo = ({ isOpen, isBurger }: NodeInfoProps) => {
const formatCCB = format({ amount: lightning.confirmed });
const formatPCB = format({ amount: lightning.pending });
const totalChain = new Big(onchain.confirmed).add(onchain.pending).toString();
const totalLightning = new Big(lightning.confirmed)
.add(lightning.pending)
.toString();
const chainPending = Number(onchain.pending) + Number(onchain.closing);
const channelPending = Number(lightning.pending);
if (!alias) return null;
if (isBurger) {
@ -105,33 +114,17 @@ export const NodeInfo = ({ isOpen, isBurger }: NodeInfoProps) => {
<SingleLine>
<Zap
size={18}
color={Number(lightning.pending) === 0 ? '#FFD300' : '#652EC7'}
fill={Number(lightning.pending) === 0 ? '#FFD300' : '#652EC7'}
color={channelPending === 0 ? '#FFD300' : '#652EC7'}
fill={channelPending === 0 ? '#FFD300' : '#652EC7'}
/>
{Number(lightning.pending) > 0 ? (
<>
{formatCCB}
{' / '}
{formatPCB}
</>
) : (
<Price amount={lightning.confirmed} />
)}
<Price amount={totalLightning} />
</SingleLine>
<SingleLine>
<Anchor
size={18}
color={Number(onchain.pending) === 0 ? '#FFD300' : '#652EC7'}
color={chainPending === 0 ? '#FFD300' : '#652EC7'}
/>
{Number(onchain.pending) > 0 ? (
<>
{formatCB}
{' / '}
{formatPB}
</>
) : (
<Price amount={onchain.confirmed} />
)}
<Price amount={totalChain} />
</SingleLine>
</>
);
@ -147,7 +140,7 @@ export const NodeInfo = ({ isOpen, isBurger }: NodeInfoProps) => {
strokeWidth={'0'}
fill={syncedToChain ? '#95de64' : '#ff7875'}
/>
{(Number(lightning.pending) > 0 || Number(onchain.pending) > 0) && (
{(channelPending > 0 || chainPending > 0) && (
<div>
<Circle size={18} fill={'#652EC7'} strokeWidth={'0'} />
</div>
@ -155,13 +148,13 @@ export const NodeInfo = ({ isOpen, isBurger }: NodeInfoProps) => {
<Margin>
<Zap
size={18}
fill={Number(lightning.pending) === 0 ? '#FFD300' : '#652EC7'}
color={Number(lightning.pending) === 0 ? '#FFD300' : '#652EC7'}
fill={channelPending === 0 ? '#FFD300' : '#652EC7'}
color={channelPending === 0 ? '#FFD300' : '#652EC7'}
/>
</Margin>
<Anchor
size={18}
color={Number(onchain.pending) === 0 ? '#FFD300' : '#652EC7'}
color={chainPending === 0 ? '#FFD300' : '#652EC7'}
/>
</div>
<div data-tip data-for="full_node_tip">
@ -197,20 +190,12 @@ export const NodeInfo = ({ isOpen, isBurger }: NodeInfoProps) => {
</Title>
<Separation lineColor={unSelectedNavButton} />
<Balance data-tip data-for="balance_tip">
<Zap
size={18}
color={Number(lightning.pending) === 0 ? '#FFD300' : '#652EC7'}
/>
<Price amount={lightning.confirmed} />
{/* <AnimatedNumber amount={channelBalance} /> */}
<Zap size={18} color={channelPending === 0 ? '#FFD300' : '#652EC7'} />
<Price amount={totalLightning} />
</Balance>
<Balance data-tip data-for="chain_balance_tip">
<Anchor
size={18}
color={Number(onchain.pending) === 0 ? '#FFD300' : '#652EC7'}
/>
<Price amount={onchain.confirmed} />
{/* <AnimatedNumber amount={chainBalance} /> */}
<Anchor size={18} color={chainPending === 0 ? '#FFD300' : '#652EC7'} />
<Price amount={totalChain} />
</Balance>
<Balance
data-tip

View File

@ -1,12 +1,5 @@
import React from 'react';
import {
Sun,
Moon,
ChevronLeft,
ChevronRight,
Icon,
Star,
} from 'react-feather';
import React, { FC, SVGAttributes } from 'react';
import { Sun, Moon, ChevronLeft, ChevronRight, Star } from 'react-feather';
import styled from 'styled-components';
import { SatoshiSymbol } from 'src/components/satoshi/Satoshi';
import { Separation, SingleLine } from '../../../components/generic/Styled';
@ -22,6 +15,14 @@ import {
} from '../../../styles/Themes';
import { usePriceState } from '../../../context/PriceContext';
// Icon import from react-feather is not working
// TODO: recheck if the type is available
type IconProps = SVGAttributes<SVGElement> & {
color?: string;
size?: string | number;
};
type Icon = FC<IconProps>;
const SelectedIcon = styled.div<{ selected: boolean }>`
display: flex;
justify-content: center;
@ -59,7 +60,7 @@ const BurgerPadding = styled(SingleLine)`
margin: 16px 0;
`;
const currencyArray = ['sat', 'btc', 'EUR', 'USD'];
const currencyArray = ['sat', 'btc', 'fiat'];
const currencyNoFiatArray = ['sat', 'btc'];
const themeArray = ['light', 'dark', 'night'];
@ -67,8 +68,7 @@ const themeArray = ['light', 'dark', 'night'];
const currencyMap: { [key: string]: string } = {
sat: 'S',
btc: '₿',
EUR: '€',
USD: '$',
fiat: 'F',
};
const currencyNoFiatMap: { [key: string]: string } = {
sat: 'S',

View File

@ -178,7 +178,7 @@ export const chatSentBubbleColor = theme('mode', {
// BUTTON COLORS
// ---------------------------------------
export const colorButtonBackground = theme('mode', {
light: themeColors.grey,
light: themeColors.grey2,
dark: themeColors.blue7,
night: '#0a0a0a',
});

View File

@ -1,7 +1,7 @@
import React from 'react';
import ReactTooltip from 'react-tooltip';
import { PendingChannelType } from 'src/graphql/types';
import { getPercent } from '../../../utils/helpers';
import { blockToTime, getPercent } from '../../../utils/helpers';
import {
Progress,
ProgressBar,
@ -63,6 +63,9 @@ export const PendingCard = ({
transaction_id,
transaction_vout,
partner_node_info,
is_timelocked,
timelock_blocks,
timelock_expiration,
} = channelInfo;
const {
@ -101,10 +104,31 @@ export const PendingCard = ({
<DarkSubTitle>Partner node not found</DarkSubTitle>
);
const renderTimelock = () => {
if (!is_timelocked) return null;
return (
<>
{renderLine(
'Total locked time',
`${blockToTime(
timelock_expiration || 0
)} (${timelock_expiration} blocks)`
)}
{renderLine(
'Pending locked time',
`${blockToTime(timelock_blocks || 0)} (${timelock_blocks} blocks)`
)}
<Separation />
</>
);
};
const renderDetails = () => {
return (
<>
<Separation />
{renderLine('Force Closed', is_timelocked ? 'Yes' : 'No')}
{renderTimelock()}
{renderLine('State:', is_active ? 'Active' : 'Inactive')}
{renderLine('Status:', is_opening ? 'Opening' : 'Closing')}
{renderLine('Local Balance:', local_balance)}

View File

@ -0,0 +1,102 @@
import { useState } from 'react';
import { Anchor, X, Zap } from 'react-feather';
import { ColorButton } from 'src/components/buttons/colorButton/ColorButton';
import { Card } from 'src/components/generic/Styled';
import { mediaWidths } from 'src/styles/Themes';
import styled from 'styled-components';
import { CreateInvoiceCard } from './createInvoice/CreateInvoice';
import { PayCard } from './pay/Payment';
import { ReceiveOnChainCard } from './receiveOnChain/ReceiveOnChain';
import { SendOnChainCard } from './sendOnChain/SendOnChain';
const SECTION_COLOR = '#FFD300';
const S = {
grid: styled.div`
display: grid;
grid-gap: 8px;
grid-template-columns: 1fr 1fr 1fr 1fr;
margin-bottom: 32px;
@media (${mediaWidths.mobile}) {
grid-template-columns: 1fr 1fr;
}
`,
};
export const AccountButtons = () => {
const [state, setState] = useState<string>('none');
const renderContent = () => {
switch (state) {
case 'send_ln':
return <PayCard setOpen={() => setState('none')} />;
case 'receive_ln':
return <CreateInvoiceCard color={SECTION_COLOR} />;
case 'send_chain':
return <SendOnChainCard setOpen={() => setState('none')} />;
case 'receive_chain':
return <ReceiveOnChainCard />;
default:
return null;
}
};
return (
<>
<S.grid>
<ColorButton
withBorder={state === 'send_ln'}
onClick={() => setState(state === 'send_ln' ? 'none' : 'send_ln')}
>
{state === 'send_ln' ? (
<X size={18} color={SECTION_COLOR} />
) : (
<Zap size={18} color={SECTION_COLOR} />
)}
Send
</ColorButton>
<ColorButton
withBorder={state === 'receive_ln'}
onClick={() =>
setState(state === 'receive_ln' ? 'none' : 'receive_ln')
}
>
{state === 'receive_ln' ? (
<X size={18} color={SECTION_COLOR} />
) : (
<Zap size={18} color={SECTION_COLOR} />
)}
Receive
</ColorButton>
<ColorButton
withBorder={state === 'send_chain'}
onClick={() =>
setState(state === 'send_chain' ? 'none' : 'send_chain')
}
>
{state === 'send_chain' ? (
<X size={18} color={SECTION_COLOR} />
) : (
<Anchor size={18} color={SECTION_COLOR} />
)}
Send
</ColorButton>
<ColorButton
withBorder={state === 'receive_chain'}
onClick={() =>
setState(state === 'receive_chain' ? 'none' : 'receive_chain')
}
>
{state === 'receive_chain' ? (
<X size={18} color={SECTION_COLOR} />
) : (
<Anchor size={18} color={SECTION_COLOR} />
)}
Receive
</ColorButton>
</S.grid>
{state !== 'none' && <Card>{renderContent()}</Card>}
</>
);
};

View File

@ -1,11 +1,9 @@
import React, { useState } from 'react';
import React from 'react';
import styled from 'styled-components';
import { Zap, Anchor, Pocket, HelpCircle, X } from 'react-feather';
import { ColorButton } from 'src/components/buttons/colorButton/ColorButton';
import ReactTooltip from 'react-tooltip';
import { renderLine } from 'src/components/generic/helpers';
import { Zap, Anchor, Pocket } from 'react-feather';
import { useNodeBalances } from 'src/hooks/UseNodeBalances';
import Big from 'big.js';
import { renderLine } from 'src/components/generic/helpers';
import {
Card,
CardWithTitle,
@ -13,13 +11,22 @@ import {
Separation,
DarkSubTitle,
ResponsiveLine,
SingleLine,
} from '../../../components/generic/Styled';
import { Price } from '../../../components/price/Price';
import { mediaWidths } from '../../../styles/Themes';
import { ReceiveOnChainCard } from './receiveOnChain/ReceiveOnChain';
import { SendOnChainCard } from './sendOnChain/SendOnChain';
import { PayCard } from './pay/Payment';
import { CreateInvoiceCard } from './createInvoice/CreateInvoice';
const S = {
grid: styled.div`
display: grid;
grid-gap: 16px;
grid-template-columns: 1fr 1fr;
@media (${mediaWidths.mobile}) {
display: block;
}
`,
};
const Tile = styled.div`
display: flex;
@ -36,25 +43,14 @@ const Tile = styled.div`
}
`;
const AccountButtonWrapper = styled.div`
display: flex;
flex-direction: column;
@media (${mediaWidths.mobile}) {
flex-direction: row;
width: 100%;
}
`;
const sectionColor = '#FFD300';
export const AccountInfo = () => {
const [state, setState] = useState<string>('none');
const { onchain, lightning } = useNodeBalances();
const totalAmount = new Big(onchain.confirmed)
.add(onchain.pending)
.add(onchain.closing)
.add(lightning.confirmed)
.add(lightning.pending)
.toString();
@ -64,126 +60,18 @@ export const AccountInfo = () => {
.add(lightning.pending)
.toString();
const chainBalance = Number(onchain.confirmed);
const chainPending = Number(onchain.pending);
const channelBalance = Number(lightning.confirmed);
const activeLightning = new Big(lightning.active)
.sub(lightning.commit)
.toString();
const inactiveLightning = new Big(lightning.confirmed)
.sub(lightning.active)
.add(lightning.commit)
.toString();
const chainPending = Number(onchain.pending) + Number(onchain.closing);
const channelPending = Number(lightning.pending);
const renderContent = () => {
switch (state) {
case 'send_ln':
return <PayCard setOpen={() => setState('none')} />;
case 'receive_ln':
return <CreateInvoiceCard color={sectionColor} />;
case 'send_chain':
return <SendOnChainCard setOpen={() => setState('none')} />;
case 'receive_chain':
return <ReceiveOnChainCard />;
default:
return null;
}
};
const getTitle = () => {
switch (state) {
case 'send_ln':
return 'Send Sats over Lightning';
case 'receive_ln':
return 'Receive Sats over Lightning';
case 'send_chain':
return 'Send To On Chain Address';
case 'receive_chain':
return 'Create Address to Receive';
default:
return 'Your Accounts';
}
};
const showLn =
state === 'send_ln' || state === 'receive_ln' || state === 'none';
const showChain =
state === 'send_chain' || state === 'receive_chain' || state === 'none';
const renderBalances = (current: number, pending: number, key: string) => (
<>
<Tile>
<DarkSubTitle>Pending Balance</DarkSubTitle>
<div>
<Price amount={pending} />
</div>
</Tile>
<Tile data-tip data-for={key}>
<DarkSubTitle>
Total Balance{pending > 0 && <HelpCircle size={12} />}
</DarkSubTitle>
<div>
<Price amount={current + pending} />
</div>
</Tile>
<ReactTooltip id={key} effect={'solid'} place={'bottom'}>
{renderLine('Total', <Price amount={current + pending} />)}
<Separation withMargin={'8px 0'} />
{renderLine('Current', <Price amount={current} />)}
{renderLine('Pending', <Price amount={pending} />)}
</ReactTooltip>
</>
);
const renderButtons = (send: string, receive: string) => (
<AccountButtonWrapper>
<ColorButton
fullWidth={true}
withMargin={'0 0 2px'}
mobileMargin={'8px 4px 0 0'}
onClick={() => setState(send)}
>
Send
</ColorButton>
<ColorButton
fullWidth={true}
withMargin={'2px 0 0'}
mobileMargin={'8px 0 0 4px'}
onClick={() => setState(receive)}
>
Receive
</ColorButton>
</AccountButtonWrapper>
);
const renderLnAccount = () => (
<ResponsiveLine>
<Zap size={18} color={channelPending === 0 ? sectionColor : '#652EC7'} />
<Tile startTile={true}>
<DarkSubTitle>Account</DarkSubTitle>
<div>Lightning</div>
</Tile>
{renderBalances(channelBalance, channelPending, 'lightning')}
{showLn && showChain && renderButtons('send_ln', 'receive_ln')}
{showLn && !showChain && (
<ColorButton onClick={() => setState('none')}>
<X size={18} />
</ColorButton>
)}
</ResponsiveLine>
);
const renderChainAccount = () => (
<ResponsiveLine>
<Anchor size={18} color={chainPending === 0 ? sectionColor : '#652EC7'} />
<Tile startTile={true}>
<DarkSubTitle>Account</DarkSubTitle>
<div>Bitcoin</div>
</Tile>
{renderBalances(chainBalance, chainPending, 'onchain')}
{showLn && showChain && renderButtons('send_chain', 'receive_chain')}
{!showLn && showChain && (
<ColorButton onClick={() => setState('none')}>
<X size={18} />
</ColorButton>
)}
</ResponsiveLine>
);
return (
<>
<CardWithTitle>
@ -219,16 +107,38 @@ export const AccountInfo = () => {
</ResponsiveLine>
</Card>
</CardWithTitle>
<CardWithTitle>
<SubTitle>{getTitle()}</SubTitle>
<Card>
{showLn && renderLnAccount()}
{showLn && <Separation />}
{showChain && renderChainAccount()}
{!showLn && showChain && <Separation />}
{renderContent()}
</Card>
</CardWithTitle>
<S.grid>
<CardWithTitle>
<Card>
<SingleLine>
<Zap
size={18}
color={channelPending === 0 ? sectionColor : '#652EC7'}
/>
<SubTitle>Lightning</SubTitle>
</SingleLine>
<Separation />
{renderLine('Available', <Price amount={activeLightning} />)}
{renderLine('Not Available', <Price amount={inactiveLightning} />)}
{renderLine('Pending', <Price amount={lightning.pending} />)}
</Card>
</CardWithTitle>
<CardWithTitle>
<Card>
<SingleLine>
<Anchor
size={18}
color={chainPending === 0 ? sectionColor : '#652EC7'}
/>
<SubTitle>Bitcoin</SubTitle>
</SingleLine>
<Separation />
{renderLine('Available', <Price amount={onchain.confirmed} />)}
{renderLine('Pending', <Price amount={onchain.pending} />)}
{renderLine('Force Closures', <Price amount={onchain.closing} />)}
</Card>
</CardWithTitle>
</S.grid>
</>
);
};