Skip to content

Commit

Permalink
adds an <ObservedBalance/> component to show the "free" native toke…
Browse files Browse the repository at this point in the history
…ns of a contract
  • Loading branch information
peetzweg committed Nov 22, 2023
1 parent 6874b31 commit 59e834b
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 13 deletions.
41 changes: 41 additions & 0 deletions src/ui/components/common/ObservedBalance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2022 @paritytech/contracts-ui authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import { useEffect, useState } from 'react';
import { useApi } from '../../contexts';
import { Balance } from 'types';

const formatBalance = (balance: Balance, decimals = 12, unit?: string) => {
const balanceAsBigInt = balance.toBigInt();
const prefix = balanceAsBigInt / BigInt(10 ** decimals);
const suffix = balanceAsBigInt - prefix * BigInt(10 ** decimals);
const number = Number(`${prefix.toString()}.${suffix.toString().slice(0, 2)}`);

return (
Intl.NumberFormat('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(
number,
) + (unit ? ` ${unit}` : '')
);
};

export const ObservedBalance = ({ address }: { address: string }) => {
const { api, tokenDecimals, tokenSymbol } = useApi();

const [balance, setBalance] = useState<null | Balance>(null);
useEffect(() => {
const unsubscribePromise = api.query.system.account(address, result => {
setBalance(result.data.free);
});

return () => {
unsubscribePromise
.then(unsubscribe => {
unsubscribe();
})
.catch(console.error);
};
}, [address, api]);

if (!balance) return null;
return formatBalance(balance, tokenDecimals, tokenSymbol);
};
23 changes: 15 additions & 8 deletions src/ui/components/contract/ContractRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { Identicon } from '../account/Identicon';
import { ObservedBalance } from '../common/ObservedBalance';
import { ContractDocument } from 'types';
import { useApi } from 'ui/contexts';
import { displayDate } from 'lib/util';
import { displayDate, truncate } from 'lib/util';
import { getContractInfo } from 'services/chain';

interface Props {
Expand All @@ -27,20 +28,26 @@ export function ContractRow({ contract: { address, name, date } }: Props) {

return (
<Link
className={`inline-flex w-full cursor-pointer items-center border border-l-0 border-r-0 border-t-0 border-gray-200 p-3 text-sm last:border-b-0 hover:bg-gray-50 dark:border-gray-700 dark:text-white dark:hover:bg-elevation-1`}
className={`grid grid-cols-4 w-full cursor-pointer items-center border border-l-0 border-r-0 border-t-0 border-gray-200 p-3 text-sm last:border-b-0 hover:bg-gray-50 dark:border-gray-700 dark:text-white dark:hover:bg-elevation-1`}
to={`/contract/${address}`}
>
<Identicon className="pr-2" size={18} value={address} />
<div className="w-36">{name}</div>
<div className="gap-2 flex flex-row">
<Identicon size={18} value={address} />
<div>{name}</div>
</div>

{isOnChain ? (
<div className="flex-grow text-gray-500 dark:text-gray-400">
{address.slice(0, 4)}...{address.slice(-4)}
<div className="font-mono text-gray-500 dark:text-gray-400" title={address}>
{truncate(address, 4)}
</div>
) : (
<div className="mr-3 flex-grow text-xs text-gray-500 dark:text-gray-400">not on-chain</div>
<div className="text-gray-500 dark:text-gray-400">not on-chain</div>
)}
<div className="w-14 text-gray-500 dark:text-gray-400">{displayDate(date)}</div>
<div className="text-gray-500 dark:text-gray-400">{displayDate(date)}</div>

<div className="font-mono text-gray-500 dark:text-gray-400 justify-self-end">
<ObservedBalance address={address} />
</div>
</Link>
);
}
21 changes: 16 additions & 5 deletions src/ui/pages/ContractHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Link } from 'react-router-dom';
import { CopyButton } from '../components/common/CopyButton';
import { displayDate, truncate } from 'lib/util';
import { UIContract } from 'types';
import { ObservedBalance } from '../components/common/ObservedBalance';

interface Props {
document: UIContract;
Expand All @@ -16,33 +17,43 @@ export function ContractHeader({ document: { name, type, address, date, codeHash
return (
<div>
You added this contract from{' '}
<div className="inline-flex items-center">
<span className="relative inline-block rounded bg-blue-500 bg-opacity-20 px-1.5 py-1 font-mono text-xs text-blue-400">
<div className="inline-flex items-center" title={address}>
<span className="px-1.5 py-1 relative inline-block rounded bg-blue-500 bg-opacity-20 font-mono text-xs text-blue-400">
{truncate(address, 4)}
</span>
<CopyButton className="ml-1" id="header-address" value={address} />
</div>{' '}
on {displayDate(date)}
on {displayDate(date)} and holds a value of{' '}
<span className="relative inline-block rounded bg-blue-500 bg-opacity-20 px-1.5 py-1 font-mono text-xs text-blue-400">
<ObservedBalance address={address} />
</span>
</div>
);
case 'instantiated':
return (
<div>
You instantiated this contract{' '}
<div className="inline-flex items-center">
<span className="relative inline-block rounded bg-blue-500 bg-opacity-20 px-1.5 py-1 font-mono text-xs text-blue-400">
<span
className="relative inline-block rounded bg-blue-500 bg-opacity-20 px-1.5 py-1 font-mono text-xs text-blue-400"
title={address}
>
{truncate(address, 4)}
</span>
<CopyButton className="ml-1" id="header-address" value={address} />
</div>{' '}
from{' '}
<Link
className="relative inline-block rounded bg-blue-500 bg-opacity-20 px-1.5 py-1 font-mono text-xs text-blue-400"
title={codeHash}
to={`/instantiate/${codeHash}`}
>
{name}
</Link>{' '}
on {displayDate(date)}
on {displayDate(date)} and holds a value of{' '}
<span className="relative inline-block rounded bg-blue-500 bg-opacity-20 px-1.5 py-1 font-mono text-xs text-blue-400">
<ObservedBalance address={address} />
</span>
</div>
);
}
Expand Down

0 comments on commit 59e834b

Please sign in to comment.