mirror of
https://github.com/apotdevin/thunderhub.git
synced 2024-11-20 02:08:59 +01:00
parent
603f5de7f1
commit
a9df78ac2d
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "thunderhub-client",
|
||||
"version": "0.1.15",
|
||||
"version": "0.1.16",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
@ -187,6 +187,10 @@ export const OverflowText = styled.div`
|
||||
word-wrap: break-word;
|
||||
-ms-word-break: break-all;
|
||||
word-break: break-all;
|
||||
|
||||
@media (${mediaWidths.mobile}) {
|
||||
margin-left: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const ResponsiveLine = styled(SingleLine)`
|
||||
|
@ -362,3 +362,17 @@ export const GET_PEERS = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const GET_UTXOS = gql`
|
||||
query GetUtxos($auth: authType!) {
|
||||
getUtxos(auth: $auth) {
|
||||
address
|
||||
address_format
|
||||
confirmation_count
|
||||
output_script
|
||||
tokens
|
||||
transaction_id
|
||||
transaction_vout
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
@ -9,7 +9,6 @@ import { ChannelView } from '../../views/channels/ChannelView';
|
||||
import { SettingsView } from '../../views/settings/Settings';
|
||||
import { TransactionList } from '../../views/transactions/TransactionList';
|
||||
import { FeesView } from '../../views/fees/Fees';
|
||||
import { ChainTransactions } from '../../views/chain/ChainTransactions';
|
||||
import { ForwardsList } from '../../views/forwards/ForwardList';
|
||||
import { TermsView } from '../../views/other/terms/TermsView';
|
||||
import { PrivacyView } from '../../views/other/privacy/PrivacyView';
|
||||
@ -23,6 +22,7 @@ import { LoadingView, ErrorView } from 'views/stateViews/StateCards';
|
||||
import { BalanceView } from 'views/balance/Balance';
|
||||
import { PeersList } from 'views/peers/PeersList';
|
||||
import { ToolsView } from 'views/tools';
|
||||
import { ChainView } from 'views/chain/ChainView';
|
||||
|
||||
const Container = styled.div`
|
||||
display: grid;
|
||||
@ -75,7 +75,7 @@ const Content = () => {
|
||||
<Route path="/forwards" render={() => getGrid(ForwardsList)} />
|
||||
<Route
|
||||
path="/chaintransactions"
|
||||
render={() => getGrid(ChainTransactions)}
|
||||
render={() => getGrid(ChainView)}
|
||||
/>
|
||||
<Route path="/settings" render={() => getGrid(SettingsView)} />
|
||||
<Route path="/fees" render={() => getGrid(FeesView)} />
|
||||
|
13
client/src/views/chain/ChainView.tsx
Normal file
13
client/src/views/chain/ChainView.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
|
||||
import { ChainTransactions } from './transactions/ChainTransactions';
|
||||
import { ChainUtxos } from './utxos/ChainUtxos';
|
||||
|
||||
export const ChainView = () => {
|
||||
return (
|
||||
<>
|
||||
<ChainUtxos />
|
||||
<ChainTransactions />
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,11 +1,15 @@
|
||||
import React, { useState } from 'react';
|
||||
import { SubTitle, Card, CardWithTitle } from '../../components/generic/Styled';
|
||||
import { useAccount } from '../../context/AccountContext';
|
||||
import { GET_CHAIN_TRANSACTIONS } from '../../graphql/query';
|
||||
import {
|
||||
SubTitle,
|
||||
Card,
|
||||
CardWithTitle,
|
||||
} from '../../../components/generic/Styled';
|
||||
import { useAccount } from '../../../context/AccountContext';
|
||||
import { GET_CHAIN_TRANSACTIONS } from '../../../graphql/query';
|
||||
import { useQuery } from '@apollo/react-hooks';
|
||||
import { toast } from 'react-toastify';
|
||||
import { getErrorContent } from '../../utils/error';
|
||||
import { LoadingCard } from '../../components/loading/LoadingCard';
|
||||
import { getErrorContent } from '../../../utils/error';
|
||||
import { LoadingCard } from '../../../components/loading/LoadingCard';
|
||||
import { TransactionsCard } from './TransactionsCard';
|
||||
|
||||
export const ChainTransactions = () => {
|
@ -5,19 +5,19 @@ import {
|
||||
SingleLine,
|
||||
DarkSubTitle,
|
||||
ResponsiveLine,
|
||||
} from '../../components/generic/Styled';
|
||||
import { MainInfo } from '../channels/Channels.style';
|
||||
} from '../../../components/generic/Styled';
|
||||
import { MainInfo } from '../../channels/Channels.style';
|
||||
import {
|
||||
getDateDif,
|
||||
getFormatDate,
|
||||
renderLine,
|
||||
} from '../../components/generic/Helpers';
|
||||
} from '../../../components/generic/Helpers';
|
||||
import styled from 'styled-components';
|
||||
import { getPrice } from 'components/price/Price';
|
||||
import { useSettings } from 'context/SettingsContext';
|
||||
import { usePriceState } from 'context/PriceContext';
|
||||
|
||||
export const AddMargin = styled.div`
|
||||
const AddMargin = styled.div`
|
||||
margin-right: 10px;
|
||||
`;
|
||||
|
49
client/src/views/chain/utxos/ChainUtxos.tsx
Normal file
49
client/src/views/chain/utxos/ChainUtxos.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
SubTitle,
|
||||
Card,
|
||||
CardWithTitle,
|
||||
} from '../../../components/generic/Styled';
|
||||
import { useAccount } from '../../../context/AccountContext';
|
||||
import { GET_UTXOS } from '../../../graphql/query';
|
||||
import { useQuery } from '@apollo/react-hooks';
|
||||
import { toast } from 'react-toastify';
|
||||
import { getErrorContent } from '../../../utils/error';
|
||||
import { LoadingCard } from '../../../components/loading/LoadingCard';
|
||||
import { UtxoCard } from './UtxoCard';
|
||||
|
||||
export const ChainUtxos = () => {
|
||||
const [indexOpen, setIndexOpen] = useState(0);
|
||||
const { host, viewOnly, cert, sessionAdmin } = useAccount();
|
||||
const auth = {
|
||||
host,
|
||||
macaroon: viewOnly !== '' ? viewOnly : sessionAdmin,
|
||||
cert,
|
||||
};
|
||||
|
||||
const { loading, data } = useQuery(GET_UTXOS, {
|
||||
variables: { auth },
|
||||
onError: (error) => toast.error(getErrorContent(error)),
|
||||
});
|
||||
|
||||
if (loading || !data || !data.getUtxos) {
|
||||
return <LoadingCard title={'Unspent Utxos'} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<CardWithTitle>
|
||||
<SubTitle>Unspent Utxos</SubTitle>
|
||||
<Card>
|
||||
{data.getUtxos.map((utxo: any, index: number) => (
|
||||
<UtxoCard
|
||||
utxo={utxo}
|
||||
key={index}
|
||||
index={index + 1}
|
||||
setIndexOpen={setIndexOpen}
|
||||
indexOpen={indexOpen}
|
||||
/>
|
||||
))}
|
||||
</Card>
|
||||
</CardWithTitle>
|
||||
);
|
||||
};
|
68
client/src/views/chain/utxos/UtxoCard.tsx
Normal file
68
client/src/views/chain/utxos/UtxoCard.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import { Separation, SubCard } from '../../../components/generic/Styled';
|
||||
import { MainInfo } from '../../channels/Channels.style';
|
||||
import { renderLine } from '../../../components/generic/Helpers';
|
||||
import { getPrice } from 'components/price/Price';
|
||||
import { useSettings } from 'context/SettingsContext';
|
||||
import { usePriceState } from 'context/PriceContext';
|
||||
|
||||
interface TransactionsCardProps {
|
||||
utxo: any;
|
||||
index: number;
|
||||
setIndexOpen: (index: number) => void;
|
||||
indexOpen: number;
|
||||
}
|
||||
|
||||
export const UtxoCard = ({
|
||||
utxo,
|
||||
index,
|
||||
setIndexOpen,
|
||||
indexOpen,
|
||||
}: TransactionsCardProps) => {
|
||||
const { currency } = useSettings();
|
||||
const priceContext = usePriceState();
|
||||
const format = getPrice(currency, priceContext);
|
||||
|
||||
const {
|
||||
address,
|
||||
address_format,
|
||||
confirmation_count,
|
||||
output_script,
|
||||
tokens,
|
||||
transaction_id,
|
||||
transaction_vout,
|
||||
} = utxo;
|
||||
|
||||
const formatAmount = format({ amount: tokens });
|
||||
|
||||
const handleClick = () => {
|
||||
if (indexOpen === index) {
|
||||
setIndexOpen(0);
|
||||
} else {
|
||||
setIndexOpen(index);
|
||||
}
|
||||
};
|
||||
|
||||
const renderDetails = () => {
|
||||
return (
|
||||
<>
|
||||
<Separation />
|
||||
{renderLine('Address Format:', address_format)}
|
||||
{renderLine('Confirmations: ', confirmation_count)}
|
||||
{renderLine('Output Script: ', output_script)}
|
||||
{renderLine('Transaction Id: ', transaction_id)}
|
||||
{renderLine('Transaction Vout: ', transaction_vout)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SubCard key={index}>
|
||||
<MainInfo onClick={() => handleClick()}>
|
||||
{renderLine('Address', address)}
|
||||
{renderLine('Amount', formatAmount)}
|
||||
</MainInfo>
|
||||
{index === indexOpen && renderDetails()}
|
||||
</SubCard>
|
||||
);
|
||||
};
|
@ -66,6 +66,10 @@ export const DetailLine = styled.div`
|
||||
word-wrap: break-word;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@media (${mediaWidths.mobile}) {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
`;
|
||||
|
||||
export const MainInfo = styled.div`
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "thunderhub-server",
|
||||
"version": "0.1.15",
|
||||
"version": "0.1.16",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
|
43
server/src/schemas/query/chain/getUtxos.ts
Normal file
43
server/src/schemas/query/chain/getUtxos.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { getUtxos as getLnUtxos } from 'ln-service';
|
||||
import { logger } from '../../../helpers/logger';
|
||||
import { requestLimiter } from '../../../helpers/rateLimiter';
|
||||
import {
|
||||
GraphQLInt,
|
||||
GraphQLObjectType,
|
||||
GraphQLString,
|
||||
GraphQLList,
|
||||
} from 'graphql';
|
||||
import { getAuthLnd, getErrorMsg } from '../../../helpers/helpers';
|
||||
import { defaultParams } from '../../../helpers/defaultProps';
|
||||
|
||||
const GetUtxosType = new GraphQLObjectType({
|
||||
name: 'getUtxosType',
|
||||
fields: () => ({
|
||||
address: { type: GraphQLString },
|
||||
address_format: { type: GraphQLString },
|
||||
confirmation_count: { type: GraphQLInt },
|
||||
output_script: { type: GraphQLString },
|
||||
tokens: { type: GraphQLInt },
|
||||
transaction_id: { type: GraphQLString },
|
||||
transaction_vout: { type: GraphQLInt },
|
||||
}),
|
||||
});
|
||||
|
||||
export const getUtxos = {
|
||||
type: new GraphQLList(GetUtxosType),
|
||||
args: defaultParams,
|
||||
resolve: async (root: any, params: any, context: any) => {
|
||||
await requestLimiter(context.ip, 'getUtxos');
|
||||
|
||||
const lnd = getAuthLnd(params.auth);
|
||||
|
||||
try {
|
||||
const { utxos } = await getLnUtxos({ lnd });
|
||||
|
||||
return utxos;
|
||||
} catch (error) {
|
||||
params.logger && logger.error('Error getting utxos: %o', error);
|
||||
throw new Error(getErrorMsg(error));
|
||||
}
|
||||
},
|
||||
};
|
10
server/src/schemas/query/chain/index.ts
Normal file
10
server/src/schemas/query/chain/index.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { getChainBalance, getPendingChainBalance } from './chainBalance';
|
||||
import { getChainTransactions } from './chainTransactions';
|
||||
import { getUtxos } from './getUtxos';
|
||||
|
||||
export const chainQueries = {
|
||||
getChainBalance,
|
||||
getPendingChainBalance,
|
||||
getChainTransactions,
|
||||
getUtxos,
|
||||
};
|
@ -1,11 +1,8 @@
|
||||
import { getChainBalance, getPendingChainBalance } from './chainBalance';
|
||||
import { getNetworkInfo } from './networkInfo';
|
||||
import { getNodeInfo } from './nodeInfo';
|
||||
import { adminCheck } from './adminCheck';
|
||||
|
||||
export const generalQueries = {
|
||||
getChainBalance,
|
||||
getPendingChainBalance,
|
||||
getNetworkInfo,
|
||||
getNodeInfo,
|
||||
adminCheck,
|
||||
|
@ -8,6 +8,7 @@ import { backupQueries } from './backup';
|
||||
import { routeQueries } from './route';
|
||||
import { peerQueries } from './peer';
|
||||
import { messageQueries } from './message';
|
||||
import { chainQueries } from './chain';
|
||||
|
||||
export const query = {
|
||||
...channelQueries,
|
||||
@ -20,4 +21,5 @@ export const query = {
|
||||
...routeQueries,
|
||||
...peerQueries,
|
||||
...messageQueries,
|
||||
...chainQueries,
|
||||
};
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { getForwards } from './forwards';
|
||||
import { getResume } from './resume';
|
||||
import { getChainTransactions } from './chainTransactions';
|
||||
|
||||
export const invoiceQueries = {
|
||||
getResume,
|
||||
getForwards,
|
||||
getChainTransactions,
|
||||
};
|
||||
|
@ -46,4 +46,5 @@ export const RateConfig: RateConfigProps = {
|
||||
removePeer: { max: 10, window: '1s' },
|
||||
signMessage: { max: 10, window: '1s' },
|
||||
verifyMessage: { max: 10, window: '1s' },
|
||||
getUtxos: { max: 10, window: '1s' },
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user