Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hook up audit rpc to UI balance #170

Merged
merged 3 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions apps/guardian-ui/src/GuardianApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { JsonRpcError, JsonRpcWebsocket } from 'jsonrpc-client-websocket';
import { ConfigGenParams, ConsensusState, PeerHashMap } from './setup/types';
import {
AuditSummary,
ConfigResponse,
FederationStatus,
ServerStatus,
Expand Down Expand Up @@ -208,6 +209,7 @@ enum AdminRpc {
inviteCode = 'invite_code',
config = 'config',
module = 'module',
audit = 'audit',
}

export enum LightningModuleRpc {
Expand All @@ -221,6 +223,7 @@ export interface AdminApiInterface extends SharedApiInterface {
fetchEpochCount: () => Promise<number>;
inviteCode: () => Promise<string>;
config: (connection: string) => Promise<ConfigResponse>;
audit: () => Promise<AuditSummary>;
moduleApiCall: <T>(moduleId: number, rpc: ModuleRpc) => Promise<T>;
}

Expand Down Expand Up @@ -366,6 +369,10 @@ export class GuardianApi
return this.base.call<ConfigResponse>(AdminRpc.config, connection);
};

audit = (): Promise<AuditSummary> => {
return this.base.call<AuditSummary>(AdminRpc.audit);
};

moduleApiCall = <T>(moduleId: number, rpc: ModuleRpc): Promise<T> => {
const method = `${AdminRpc.module}_${moduleId}_${rpc}`;
return this.base.call_any_method<T>(method);
Expand Down
28 changes: 22 additions & 6 deletions apps/guardian-ui/src/components/BalanceCard.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
import { Card, CardBody, CardHeader, Text } from '@chakra-ui/react';
import { Card, CardBody, CardHeader, Skeleton, Text } from '@chakra-ui/react';
import { KeyValues } from '@fedimint/ui';
import { useTranslation } from '@fedimint/utils';
import React, { useMemo } from 'react';
import { MSats, formatMsatsToBtc, useTranslation } from '@fedimint/utils';
import React, { useEffect, useMemo, useState } from 'react';
import { AuditSummary } from '../types';
import { useAdminContext } from '../hooks';

export const BalanceCard: React.FC = () => {
const { t } = useTranslation();
const { api } = useAdminContext();
const [auditSummary, setAuditSummary] = useState<AuditSummary>();

const walletBalance = auditSummary
? auditSummary.module_summaries.wallet?.net_assets || (0 as MSats)
: undefined;

useEffect(() => {
api.audit().then(setAuditSummary).catch(console.error);
EthnTuttle marked this conversation as resolved.
Show resolved Hide resolved
}, [api]);

const keyValues = useMemo(
() => [
{
key: 'bitcoin',
label: t('common.bitcoin'),
// TODO: Use `audit` api to fill this in
value: '0.00000000',
value:
typeof walletBalance === 'number' ? (
formatMsatsToBtc(walletBalance)
) : (
<Skeleton height='20px' />
),
},
],
[t]
[walletBalance, t]
);

return (
Expand Down
11 changes: 11 additions & 0 deletions apps/guardian-ui/src/types.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { MSats } from '@fedimint/utils';

export enum ServerStatus {
AwaitingPassword = 'AwaitingPassword',
SharingConfigGenParams = 'SharingConfigGenParams',
Expand Down Expand Up @@ -153,3 +155,12 @@ export interface InitializationState {
needsAuth: boolean;
serverStatus: ServerStatus;
}

export interface ModuleSummary {
net_assets: MSats;
}

export interface AuditSummary {
net_assets: MSats;
module_summaries: Record<string, ModuleSummary | undefined>;
}
6 changes: 6 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ services:
- '18184:18184'
volumes:
- ./fm_2/data:/data
depends_on:
- bitcoind

# gatewayd_2:
# image: fedimint/gatewayd:master
Expand All @@ -92,6 +94,8 @@ services:
- '18185:18185'
volumes:
- ./fm_3/data:/data
depends_on:
- bitcoind

fedimintd_4:
image: fedimint/fedimintd:v0.1.0-rc3
Expand All @@ -107,6 +111,8 @@ services:
- '18186:18186'
volumes:
- ./fm_4/data:/data
depends_on:
- bitcoind

bitcoind:
image: btcpayserver/bitcoin:24.1
Expand Down
13 changes: 13 additions & 0 deletions packages/utils/src/format.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { MSats } from './types';

/**
* Given a string, turn it into an "ellipsis sandwich" with the start and
* end showing. If the text is shorter than it would be with an ellipsis,
Expand All @@ -9,3 +11,14 @@ export function formatEllipsized(text: string, size = 6) {
}
return `${text.substring(0, size)}...${text.substring(text.length - size)}`;
}

/**
* Given some number of msats, return a formatted string in the format of
* 0.0000000 or 1,234,5678.9000000
*/
export function formatMsatsToBtc(msats: MSats): string {
EthnTuttle marked this conversation as resolved.
Show resolved Hide resolved
return Intl.NumberFormat(undefined, {
style: 'decimal',
minimumFractionDigits: 8,
}).format(msats / 1_00_000_000_000);
}
1 change: 1 addition & 0 deletions packages/utils/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './i18n';
export * from './format';
export * from './types';
5 changes: 5 additions & 0 deletions packages/utils/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Opaque numeric types to avoid mixing different denominations of bitcoin
type BitcoinUnit<K, T> = K & { _: T };
export type Btc = BitcoinUnit<number, 'Btc'>;
export type Sats = BitcoinUnit<number, 'Sats'>;
export type MSats = BitcoinUnit<number, 'MSats'>;
EthnTuttle marked this conversation as resolved.
Show resolved Hide resolved