Skip to content

Commit

Permalink
Add a new formatDenomWithBadge that returns a ReactNode
Browse files Browse the repository at this point in the history
This will add a badge if the denom is verified.

Fixes #250
  • Loading branch information
hansl committed Feb 7, 2025
1 parent 64be274 commit a5a6c19
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 19 deletions.
17 changes: 9 additions & 8 deletions components/bank/components/historyBox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { TransactionAmount, TxMessage } from '../types';
import { shiftDigits, formatLargeNumber, formatDenom } from '@/utils';
import { shiftDigits, formatLargeNumber, formatDenom, formatDenomWithBadge } from '@/utils';
import { getHandler } from '@/components/bank/handlers/handlerRegistry';
import { MetadataSDKType } from '@liftedinit/manifestjs/dist/codegen/cosmos/bank/v1beta1/bank';
import { useTokenFactoryDenomsMetadata } from '@/hooks';
Expand Down Expand Up @@ -159,13 +159,14 @@ export function HistoryBox({
tx.sender === address ? (
<div className="text-gray-500 text-xs mt-1">
Incl.:{' '}
{tx.fee &&
formatLargeNumber(
Number(shiftDigits(tx.fee.amount?.[0]?.amount, -6))
) +
' ' +
formatDenom(tx.fee.amount?.[0]?.denom)}{' '}
fee
{tx.fee && (
<>
{formatLargeNumber(
Number(shiftDigits(tx.fee.amount?.[0]?.amount, -6))
)}{' '}
{formatDenomWithBadge(tx.fee.amount?.[0]?.denom, true)} fee
</>
)}
</div>
) : null
) : (
Expand Down
11 changes: 8 additions & 3 deletions components/bank/handlers/createMessageUtils.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import React from 'react';
import { denomToAsset, formatAmount, formatDenom, formatLargeNumber } from '@/utils';
import {
denomToAsset,
formatAmount,
formatDenom,
formatDenomWithBadge,
formatLargeNumber,
} from '@/utils';
import { format } from 'react-string-format';
import { TruncatedAddressWithCopy } from '@/components/react/addressCopy';
import { MetadataSDKType } from '@liftedinit/manifestjs/dist/codegen/cosmos/bank/v1beta1/bank';
Expand All @@ -13,8 +19,7 @@ export const createTokenMessage = (
metadata?: MetadataSDKType[]
) => {
const formattedAmount = formatLargeNumber(formatAmount(amount, denom, metadata));

const formattedDenom = formatDenom(denom);
const formattedDenom = formatDenomWithBadge(denom);

// coloredAmount is {0}
const coloredAmount = (
Expand Down
15 changes: 13 additions & 2 deletions components/factory/components/DenomDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ import { DenomImage, VerifiedIcon } from '@/components';
import { formatTokenDisplay } from '@/utils';
import React from 'react';

export const DenomVerifiedBadge = ({
base,
...props
}: { base?: string } & { [i: string]: unknown }) => {
const verified = base === 'umfx';

return verified ? <VerifiedIcon {...props} /> : <></>;
};

export const DenomDisplay = ({
denom,
metadata,
Expand All @@ -15,7 +24,6 @@ export const DenomDisplay = ({
withBackground?: boolean;
}) => {
const name = formatTokenDisplay(denom ?? metadata?.display ?? '?').toUpperCase();
const verified = metadata?.base === 'umfx';

return (
<>
Expand All @@ -24,7 +32,10 @@ export const DenomDisplay = ({
</div>
<p className="align-middle font-semibold text-[#161616] dark:text-white">
{name}
{verified && <VerifiedIcon className="w-4 mx-1 inline relative bottom-1 text-primary" />}
<DenomVerifiedBadge
base={metadata?.base}
className="w-4 mx-1 inline relative bottom-1 text-primary"
/>
</p>
</>
);
Expand Down
28 changes: 22 additions & 6 deletions utils/format.ts → utils/format.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { MetadataSDKType } from '@liftedinit/manifestjs/dist/codegen/cosmos/bank/v1beta1/bank';
import { shiftDigits } from '@/utils/maths';
import { denomToAsset } from './ibc';
import { DenomDisplay, DenomVerifiedBadge } from '@/components/factory/components/DenomDisplay';
import env from '@/config/env';
import { ReactNode } from 'react';

export function formatLargeNumber(num: number): string {
if (!Number.isFinite(num)) return 'Invalid number';
Expand Down Expand Up @@ -31,19 +33,33 @@ export function formatLargeNumber(num: number): string {
return num.toFixed(6);
}

/**
* Format a denom to a display name react node with a verified badge.
* @param denom The denom to format.
* @param small Whether to use a smaller badge.
*/
export function formatDenomWithBadge(denom: string, small?: boolean): ReactNode {
const cleanDenom = formatDenom(denom);
const classes = `${small ? 'w-3' : 'w-5'} mx-1 inline relative bottom-1 text-primary`;

return (
<>
{cleanDenom} <DenomVerifiedBadge base={denom} className={classes} />
</>
);
}

export function formatDenom(denom: string): string {
const assetInfo = denomToAsset(env.chain, denom);

// Fallback to cleaning the denom if no assetInfo
const cleanDenom = denom?.replace(/^factory\/[^/]+\//, '');
let cleanDenom = denom.replace(/^factory\/[^/]+\//, '');

// Skip cleaning for IBC denoms as they should be resolved via assetInfo
if (cleanDenom.startsWith('ibc/')) {
return assetInfo?.display.toUpperCase() ?? '';
}

if (cleanDenom?.startsWith('u')) {
return cleanDenom.slice(1).toUpperCase();
cleanDenom = assetInfo?.display.toUpperCase() ?? '';

Check warning on line 60 in utils/format.tsx

View check run for this annotation

Codecov / codecov/patch

utils/format.tsx#L60

Added line #L60 was not covered by tests
} else if (cleanDenom.startsWith('u')) {
cleanDenom = cleanDenom.slice(1).toUpperCase();
}

return cleanDenom;
Expand Down

0 comments on commit a5a6c19

Please sign in to comment.