Skip to content

Commit

Permalink
fix: balance format precision with tooltips (#1571)
Browse files Browse the repository at this point in the history
- Closes #1564
- Closes #1575

---

I've also removed the `balances` from our browser storage. Let's keep it
fetching directly from the node.

| 📷  Tiny | Regular | Huge |
| --- | --- | --- |
| <img width="380" alt="small amounts"
src="https://github.com/user-attachments/assets/0994b6c5-20f7-468f-be39-6d741b960f11">
| <img width="386" alt="not so small"
src="https://github.com/user-attachments/assets/9384c85a-f73f-4cde-a549-e8888e9cdfdc">
|<img width="374" alt="huge amount"
src="https://github.com/user-attachments/assets/383f0bec-c8df-44c1-b608-e3f484541c61">
|
  • Loading branch information
helciofranco authored Oct 11, 2024
1 parent 9718513 commit 112e002
Show file tree
Hide file tree
Showing 16 changed files with 230 additions and 102 deletions.
6 changes: 6 additions & 0 deletions .changeset/violet-candles-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fuel-wallet/types": minor
"fuels-wallet": minor
---

Format tiny, large, and regular amounts, applying 6 decimal places of precision.
6 changes: 3 additions & 3 deletions packages/app/playwright/e2e/HomeWallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ test.describe('HomeWallet', () => {

test('should not show user balance when user sets it to hidden', async () => {
await visit(page, '/wallet');
await hasText(page, /ETH.+0\.0/i);
await hasText(page, /ETH.+0/i);
await getByAriaLabel(page, 'Hide balance').click(); // click on the hide balance
await hasText(page, /ETH.+/i); // should hide balance
await reload(page); // reload the page
await hasText(page, /ETH.+/i); // should not show balance
await getByAriaLabel(page, 'Show balance').click();
await hasText(page, /ETH.+0\.0/i);
await hasText(page, /ETH.+0/i);
await reload(page); // reload the page
await hasText(page, /ETH.+0\.0/i);
await hasText(page, /ETH.+0/i);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export const BalanceAssets = ({
amount={balance.amount}
onRemove={onRemove}
onEdit={onEdit}
showActions
/>
))}
{!!(!isLoading && unknownLength) && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { bn } from 'fuels';

import { MOCK_ACCOUNTS } from '../../__mocks__';

import type { AccountWithBalance } from '@fuel-wallet/types';
import type { BalanceWidgetProps } from './BalanceWidget';
import { BalanceWidget } from './BalanceWidget';

Expand All @@ -11,10 +12,11 @@ export default {
title: 'Account/Components/BalanceWidget',
};

const ACCOUNT = {
const ACCOUNT: AccountWithBalance = {
...MOCK_ACCOUNTS[0],
balance: bn(12008943834),
balanceSymbol: '$',
balances: [],
};

export const Usage = (args: BalanceWidgetProps) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import { renderWithProvider } from '~/systems/Core/__tests__/utils';

import { MOCK_ACCOUNTS } from '../../__mocks__';

import { Address } from 'fuels';
import type { AccountWithBalance } from '@fuel-wallet/types';
import { Address, bn } from 'fuels';
import { act } from 'react';
import { BalanceWidget } from './BalanceWidget';

const ACCOUNT = {
const ACCOUNT: AccountWithBalance = {
...MOCK_ACCOUNTS[0],
balance: '4999989994',
balance: bn(4999989994),
balanceSymbol: 'ETH',
balances: [],
};

describe('BalanceWidget', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { cssObj } from '@fuel-ui/css';
import { Avatar, Box, Button, Heading, Icon, Text } from '@fuel-ui/react';
import type { Account } from '@fuel-wallet/types';
import {
Avatar,
Box,
Button,
Heading,
Icon,
Text,
Tooltip,
} from '@fuel-ui/react';
import type { AccountWithBalance } from '@fuel-wallet/types';
import { type ReactNode, useMemo } from 'react';
import { FuelAddress } from '~/systems/Account';
import type { Maybe } from '~/systems/Core';
import { AmountVisibility, VisibilityButton } from '~/systems/Core';
import {
AmountVisibility,
VisibilityButton,
formatBalance,
} from '~/systems/Core';

import { useAccounts } from '../../hooks';

Expand All @@ -29,20 +40,26 @@ export function BalanceWidgetWrapper({
}

export type BalanceWidgetProps = {
account?: Maybe<Account>;
account?: AccountWithBalance;
isLoading?: boolean;
visibility?: boolean;
onPressAccounts?: () => void;
onChangeVisibility?: (visibility: boolean) => void;
};

const decimals = DECIMAL_FUEL;
export function BalanceWidget({
account,
isLoading,
visibility = true,
onChangeVisibility,
}: BalanceWidgetProps) {
const { handlers } = useAccounts();

const { original, tooltip } = useMemo(() => {
return formatBalance(account?.balance, decimals);
}, [account]);

if (isLoading || !account) return <BalanceWidget.Loader />;

return (
Expand Down Expand Up @@ -84,14 +101,20 @@ export function BalanceWidget({
<>
<Text className="label">Balance</Text>
<Box.Flex>
<Text aria-hidden={visibility} data-account-name={account.name}>
{account.balanceSymbol || '$'}&nbsp;
<AmountVisibility
value={account.balance}
visibility={visibility}
units={DECIMAL_FUEL}
/>
</Text>
<Tooltip
content={original.display}
delayDuration={0}
open={visibility && tooltip ? undefined : false}
>
<Text aria-hidden={visibility} data-account-name={account.name}>
{account.balanceSymbol || '$'}&nbsp;
<AmountVisibility
value={account.balance}
visibility={visibility}
units={decimals}
/>
</Text>
</Tooltip>
<VisibilityButton
aria-label={visibility ? 'Hide balance' : 'Show balance'}
visibility={visibility}
Expand All @@ -111,7 +134,6 @@ const styles = {
display: 'flex',
flexDirection: 'column',
borderRadius: '$default',
pb: '$3',
}),
balanceAddress: cssObj({
color: '$intentsBase11',
Expand All @@ -131,6 +153,10 @@ const styles = {
color: '$textInverse',
fontSize: '$3xl',
fontFamily: '$mono',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
overflow: 'hidden',
lineHeight: 'normal',
},
'.label': {
lineHeight: '$tight',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@ import { BalanceWidgetWrapper } from './BalanceWidget';
export const BalanceWidgetLoader = (props: ContentLoaderProps) => (
<BalanceWidgetWrapper
top={
<>
<ContentLoader width={320} height={42} viewBox="0 0 320 42" {...props}>
<circle cx="16" cy="22" r="16" />
<rect x="44" y="3" width="67" height="13" rx="4" />
<rect x="44" y="25" width="90" height="13" rx="4" />
<rect x="224" y="6" width="94" height="28" rx="4" />
</ContentLoader>
</>
<ContentLoader width={320} height={42} viewBox="0 0 320 42" {...props}>
<circle cx="16" cy="22" r="16" />
<rect x="44" y="3" width="67" height="13" rx="4" />
<rect x="44" y="25" width="90" height="13" rx="4" />
<rect x="224" y="6" width="94" height="28" rx="4" />
</ContentLoader>
}
bottom={
<>
<ContentLoader width={320} height={52} viewBox="0 0 320 52" {...props}>
<rect y="4" width="67" height="13" rx="4" />
<rect y="27" width="181" height="24" rx="4" />
</ContentLoader>
</>
<ContentLoader width={320} height={67} viewBox="0 0 320 52" {...props}>
<rect y="4" width="67" height="9" rx="4" />
<rect y="27" width="181" height="19" rx="4" />
</ContentLoader>
}
/>
);
2 changes: 0 additions & 2 deletions packages/app/src/systems/Account/hooks/useAccounts.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import type { AssetData } from '@fuel-wallet/types';
import { bn } from 'fuels';
import { useEffect, useRef } from 'react';
import { Services, store } from '~/store';
import { useAssets } from '~/systems/Asset';
import { useOverlay } from '~/systems/Overlay';

import type { AccountsMachineState } from '../machines';
Expand Down
10 changes: 5 additions & 5 deletions packages/app/src/systems/Account/machines/accountsMachine.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { Account } from '@fuel-wallet/types';
import type { Account, AccountWithBalance } from '@fuel-wallet/types';
import type { InterpreterFrom, StateFrom } from 'xstate';
import { assign, createMachine } from 'xstate';
import { IS_LOGGED_KEY } from '~/config';
import { store } from '~/store';
import type { Maybe } from '~/systems/Core';
import { CoreService, FetchMachine, Storage } from '~/systems/Core';
import { NetworkService } from '~/systems/Network';

Expand All @@ -12,7 +11,7 @@ import type { AccountInputs } from '../services/account';

type MachineContext = {
accounts?: Account[];
account?: Maybe<Account>;
account?: AccountWithBalance;
error?: unknown;
};

Expand All @@ -21,7 +20,7 @@ type MachineServices = {
data: Account[];
};
fetchAccount: {
data: Account;
data: AccountWithBalance;
};
setCurrentAccount: {
data: Account;
Expand Down Expand Up @@ -229,7 +228,7 @@ export const accountsMachine = createMachine(
return AccountService.getAccounts();
},
}),
fetchAccount: FetchMachine.create<never, Account | undefined>({
fetchAccount: FetchMachine.create<never, AccountWithBalance | undefined>({
showError: true,
maxAttempts: 1,
async fetch() {
Expand All @@ -245,6 +244,7 @@ export const accountsMachine = createMachine(
account: accountToFetch,
providerUrl,
});

return accountWithBalance;
},
}),
Expand Down
59 changes: 28 additions & 31 deletions packages/app/src/systems/Account/services/account.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { createProvider } from '@fuel-wallet/connections';
import type { Account, CoinAsset } from '@fuel-wallet/types';
import type {
Account,
AccountBalance,
AccountWithBalance,
CoinAsset,
} from '@fuel-wallet/types';
import { Address, type Provider, bn } from 'fuels';
import { AssetService } from '~/systems/Asset/services';
import { getFuelAssetByAssetId } from '~/systems/Asset/utils';
Expand All @@ -24,9 +29,6 @@ export type AccountInputs = {
fetchAccount: {
address: string;
};
setBalance: {
data: Pick<Account, 'address' | 'balance' | 'balanceSymbol' | 'balances'>;
};
setCurrentAccount: {
address: string;
};
Expand Down Expand Up @@ -85,7 +87,9 @@ export class AccountService {
return account;
}

static async fetchBalance(input: AccountInputs['fetchBalance']) {
static async fetchBalance(
input: AccountInputs['fetchBalance']
): Promise<AccountWithBalance> {
if (!input.account) {
throw new Error('Account not defined');
}
Expand All @@ -111,7 +115,7 @@ export class AccountService {
...prev,
{
...balance,
amount: balance.amount.toString(),
amount: balance.amount,
asset,
},
];
Expand All @@ -137,38 +141,31 @@ export class AccountService {
(balance) => balance.assetId === baseAssetId.toString()
);
const ethBalance = ethAsset?.amount;
const nextAccountWithAssets = {
address: account.address || '',
balance: bn(ethBalance || 0).toString(),
const accountAssets: AccountBalance = {
balance: ethBalance ?? bn(0),
balanceSymbol: 'ETH',
balances: nextBalancesWithAssets,
};

const nextAccount = await AccountService.setBalance({
data: nextAccountWithAssets,
});
const result: AccountWithBalance = {
...account,
...accountAssets,
};

return nextAccount ?? account;
return result;
} catch (_error) {
const nextAccount = await AccountService.setBalance({
data: {
address: account.address || '',
balance: bn(0).toString(),
balanceSymbol: 'ETH',
balances: [],
},
});
return nextAccount ?? account;
}
}
const accountAssets: AccountBalance = {
balance: bn(0),
balanceSymbol: 'ETH',
balances: [],
};
const result: AccountWithBalance = {
...account,
...accountAssets,
};

static async setBalance(input: AccountInputs['setBalance']) {
if (!db.isOpen()) return;
return db.transaction('rw!', db.accounts, async () => {
const { address, ...updateData } = input.data;
await db.accounts.update(address, updateData);
return db.accounts.get({ address: input.data.address });
});
return result;
}
}

static toMap(accounts: Account[]) {
Expand Down
Loading

0 comments on commit 112e002

Please sign in to comment.