Skip to content

Commit

Permalink
Merge pull request #516 from Kodylow/new-gateway-typing
Browse files Browse the repository at this point in the history
  • Loading branch information
Kodylow authored Sep 9, 2024
2 parents bed8d93 + 8f25ad2 commit 1990658
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 99 deletions.
57 changes: 29 additions & 28 deletions apps/gateway-ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,7 @@ export type Unit = (typeof UNIT_OPTIONS)[number];
export const App = React.memo(function Admin(): JSX.Element {
const gateway = useRef(() => new GatewayApi());
const [balances, setBalances] = useState<GatewayBalances | null>(null);

const [gatewayInfo, setGatewayInfo] = useState<GatewayInfo>({
federations: [],
fees: {
base_msat: 0,
proportional_millionths: 0,
},
gateway_id: '',
gateway_state: '',
lightning_alias: '',
lightning_pub_key: '',
route_hints: [],
version_hash: '',
network: undefined,
});
const [gatewayInfo, setGatewayInfo] = useState<GatewayInfo | null>(null);

// Whether the user has successfully authenticated with the gateway.
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
Expand Down Expand Up @@ -71,17 +57,24 @@ export const App = React.memo(function Admin(): JSX.Element {

useEffect(() => {
if (isAuthenticated) {
const fetchInfo = () => {
gateway
.current()
.fetchInfo()
.then((gatewayInfo) => {
setGatewayInfo(gatewayInfo);
})
.catch(({ message, error }) => {
console.error(error);
setError(message);
});
const fetchInfoAndConfigs = async () => {
try {
const gatewayInfo = await gateway.current().fetchInfo();

const configs = await gateway.current().fetchConfigs();

const updatedFederations = gatewayInfo.federations.map(
(federation) => ({
...federation,
config: configs.federations[federation.federation_id],
})
);

setGatewayInfo({ ...gatewayInfo, federations: updatedFederations });
} catch (error: unknown) {
console.error(error);
setError((error as Error).message);
}
};

const fetchBalances = () => {
Expand All @@ -97,9 +90,10 @@ export const App = React.memo(function Admin(): JSX.Element {
});
};

fetchInfo();
fetchInfoAndConfigs();
fetchBalances();
const interval = setInterval(fetchInfo, 5000);

const interval = setInterval(fetchInfoAndConfigs, 5000);
return () => clearInterval(interval);
}
}, [isAuthenticated]);
Expand All @@ -117,6 +111,8 @@ export const App = React.memo(function Admin(): JSX.Element {
);
}

if (!gatewayInfo) return <Loading />;

return (
<Flex direction='column' gap={4}>
<HeaderWithUnitSelector setUnit={setUnit} />
Expand All @@ -131,6 +127,11 @@ export const App = React.memo(function Admin(): JSX.Element {
<LightningCard
nodeId={gatewayInfo.gateway_id}
network={gatewayInfo.network}
alias={gatewayInfo.lightning_alias}
mode={gatewayInfo.lightning_mode}
pubkey={gatewayInfo.lightning_pub_key}
blockHeight={gatewayInfo.block_height}
syncedToChain={gatewayInfo.synced_to_chain}
/>
<FederationsTable
unit={unit}
Expand Down
6 changes: 2 additions & 4 deletions apps/gateway-ui/src/GatewayApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,9 @@ export class GatewayApi {
}
};

fetchConfig = async (federationId: string): Promise<GatewayFedConfig> => {
fetchConfigs = async (): Promise<GatewayFedConfig> => {
try {
const res: Response = await this.post('config', {
federation_id: federationId,
});
const res: Response = await this.post('config', {});

if (res.ok) {
const config: GatewayFedConfig = await res.json();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const FederationsTable: React.FC<FederationsTableProps> = ({
const rows: TableRow<'name' | 'id' | 'balance' | 'actions'>[] =
federations.map((federation) => ({
key: federation.federation_id,
name: federation.config.meta.federation_name,
name: federation.config.global.meta.federation_name,
id: (
<Flex direction='column' alignItems='flex-start'>
<Text fontSize='sm' fontWeight='medium'>
Expand Down
4 changes: 2 additions & 2 deletions apps/gateway-ui/src/components/federations/ViewConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import { formatEllipsized, useTranslation } from '@fedimint/utils';
import CodeMirror from '@uiw/react-codemirror';
import { json } from '@codemirror/lang-json';
import { githubLight } from '@uiw/codemirror-theme-github';
import { GatewayClientConfig } from '@fedimint/types';
import { JsonClientConfig } from '@fedimint/types';

interface ViewConfigModalProps {
federationId: string;
config: GatewayClientConfig;
config: JsonClientConfig;
}

export const ViewConfigModal = forwardRef<
Expand Down
134 changes: 80 additions & 54 deletions apps/gateway-ui/src/components/lightning/LightningCard.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,109 @@
import React from 'react';
import {
Text,
useTheme,
Flex,
Link,
Box,
useClipboard,
SimpleGrid,
} from '@chakra-ui/react';
import { Network } from '@fedimint/types';
import { LightningMode, Network } from '@fedimint/types';
import { formatEllipsized, getNodeUrl, useTranslation } from '@fedimint/utils';
import { GatewayCard } from '..';
import { ReactComponent as CopyIcon } from '../../assets/svgs/copy.svg';
import { ReactComponent as LinkIcon } from '../../assets/svgs/linkIcon.svg';

interface LightningCardProps {
nodeId: string;
network?: Network;
network: Network;
alias: string;
mode: LightningMode;
pubkey: string;
blockHeight: number;
syncedToChain: boolean;
}

export const LightningCard = React.memo(function LightningCard({
nodeId,
network,
alias,
mode,
pubkey,
blockHeight,
syncedToChain,
}: LightningCardProps): JSX.Element {
const { t } = useTranslation();
const theme = useTheme();
const { onCopy, hasCopied } = useClipboard(nodeId);
const url = getNodeUrl(nodeId, network);

const InfoItem = ({
label,
value,
}: {
label: string;
value: React.ReactNode;
}) => (
<Flex>
<Text fontWeight='bold' mr={2}>
{label}:
</Text>
<Text>{value}</Text>
</Flex>
);

return (
<GatewayCard title={t('info-card.card_header')}>
<Flex alignItems='center'>
<Text
fontSize='md'
color={theme.colors.gray[900]}
fontFamily={theme.fonts.body}
mr='2'
>
{formatEllipsized(nodeId, 24)}
</Text>
<Box>
{hasCopied ? (
<Text
fontSize='xs'
fontWeight='semibold'
color={theme.colors.green[500]}
bgColor={theme.colors.green[50]}
p='1'
px='2'
borderRadius='full'
>
{t('common.copied')}
</Text>
) : (
<Box
as={CopyIcon}
color={theme.colors.gray[500]}
height='20px'
width='20px'
onClick={onCopy}
cursor='pointer'
_hover={{ color: theme.colors.gray[700] }}
/>
)}
</Box>
</Flex>
<Link
fontSize='sm'
color={theme.colors.blue[600]}
fontFamily={theme.fonts.body}
href={url.toString()}
target='_blank'
rel='noreferrer'
display='flex'
alignItems='center'
_hover={{ textDecoration: 'underline', color: theme.colors.blue[700] }}
>
{t('federation-card.view-link-on', { host: url.host })}
<Box as={LinkIcon} ml='1' boxSize='4' />
</Link>
<GatewayCard title={t('info-card.card-header')}>
<SimpleGrid columns={2} spacing={4}>
<InfoItem
label={t('info-card.node-id')}
value={
<Flex alignItems='center' gap={2}>
{formatEllipsized(nodeId, 8)}
<Box
ml={2}
as={CopyIcon}
color='gray.500'
height='20px'
width='20px'
onClick={onCopy}
cursor='pointer'
_hover={{ color: 'gray.700' }}
/>
{hasCopied && (
<Text fontSize='xs' color='green.500' ml={2}>
{t('common.copied')}
</Text>
)}
<Link
fontSize='sm'
color='blue.600'
href={url.toString()}
target='_blank'
rel='noreferrer'
display='flex'
alignItems='center'
_hover={{ textDecoration: 'underline', color: 'blue.700' }}
>
{t('federation-card.view-link-on', { host: url.host })}
<Box as={LinkIcon} ml={1} boxSize={4} />
</Link>
</Flex>
}
/>

<InfoItem label={t('info-card.alias')} value={alias} />
<InfoItem
label={t('info-card.pubkey')}
value={formatEllipsized(pubkey, 8)}
/>
<InfoItem label={t('info-card.network')} value={network} />
<InfoItem label={t('info-card.block-height')} value={blockHeight} />
<InfoItem
label={t('info-card.synced-to-chain')}
value={syncedToChain ? 'Yes' : 'No'}
/>
<InfoItem label={t('info-card.mode')} value={Object.keys(mode)[0]} />
</SimpleGrid>
</GatewayCard>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ const FederationSelector: React.FC<FederationSelectorProps> = ({
key={federation.federation_id}
value={federation.federation_id}
>
{federation.config.meta.federation_name || federation.federation_id}
{federation.config.global.meta.federation_name ||
federation.federation_id}
</option>
))}
</Select>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ const ReceiveOnchain: React.FC<ReceiveOnchainProps> = ({
<Text>
{t('wallet-modal.receive.peg-in-instructions', {
federationName:
walletModalState.selectedFederation?.config.meta.federation_name,
walletModalState.selectedFederation?.config.global.meta
.federation_name,
})}
</Text>
<QRCodeTabs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ const SendEcash: React.FC<SendEcashProps> = ({
{t('wallet-modal.send.ecash-created', {
amount,
federationName:
walletModalState.selectedFederation?.config.meta.federation_name,
walletModalState.selectedFederation?.config.global.meta
.federation_name,
})}
</Text>
<QRCodeTabs
Expand Down
9 changes: 8 additions & 1 deletion apps/gateway-ui/src/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,14 @@
"title": "Lightning Gateway Dashboard"
},
"info-card": {
"card_header": "Lightning Node ID"
"card-header": "Lightning Node Info",
"node-id": "Node ID",
"alias": "Alias",
"mode": "Mode",
"pubkey": "Pubkey",
"network": "Network",
"block-height": "Block Height",
"synced-to-chain": "Synced to Chain"
},
"withdraw-card": {
"address-label": "Your address:",
Expand Down
Loading

0 comments on commit 1990658

Please sign in to comment.