Skip to content

Mint Info

Let's now look at how we can display some basic info about the status of the mint and the user:

  • The price of the mint in PYUSD
  • The user's balance of PYUSD
  • The number of tokens minted so far

We'll create a new file, src/components/MintInfo.tsx that fetches all this.

Formatting PYUSD amounts

You may have noticed that we're dealing with bigint values for the PYUSD amounts. We'll need to format these nicely for display by consulting the token's decimals value (which is 6, but we'll look it up dynamically so that our solution is more general).

viem provides a formatUnits function that can help with this.

tsx
import { formatUnits } from "viem";
//...

const formattedMintPrice = mintPrice.isSuccess
  ? formatUnits(mintPrice.data, token.data.decimals)
  : mintPrice.isPending
  ? "Loading..."
  : mintPrice.status;

Here, our formattedMintPrice will be a string that represents the mint price in PYUSD. If mintPrice has loaded, we'll format it using formatUnits and the token's decimals. If it's still loading, we'll show "Loading...". If it's in any other state, we'll just show it directly.

MintInfo component

tsx
import { formatUnits } from "viem";
import { useAccount } from "wagmi";
import { useMintPrice, useTotalIssued } from "../hooks/helloPyusd";
import { useToken, useTokenBalance } from "../hooks/erc20";
import { usePaymentTokenAddress } from "../hooks/paymentToken";

export default function MintInfo() {
  const account = useAccount();
  const paymentToken = usePaymentTokenAddress();
  const token = useToken(paymentToken);
  const balance = useTokenBalance(paymentToken, account.address);
  const mintPrice = useMintPrice();
  const totalIssued = useTotalIssued();

  // If the token query has not loaded, display a loading message or error.
  if (!token.data) {
    return (
      <div className='text-sm opacity-50'>
        {token.error?.message || "Loading..."}
      </div>
    );
  }

  // We format the mint price and user balance using the token's decimals and Viem's formatUnits function.
  // If the mint price or user balance is still loading, we display a loading message.

  const formattedMintPrice = mintPrice.isSuccess
    ? formatUnits(mintPrice.data, token.data.decimals)
    : mintPrice.isPending
    ? "Loading..."
    : mintPrice.status;

  const formattedUserBalance = balance.isSuccess
    ? formatUnits(balance.data, token.data.decimals)
    : balance.isPending
    ? "Loading..."
    : mintPrice.status;

  // If the total issued query has loaded, we display the total minted tokens.

  const totalMinted = totalIssued.isSuccess
    ? totalIssued.data.toString()
    : totalIssued.isPending
    ? "Loading..."
    : mintPrice.status;

  return (
    <div className='grid grid-cols-2 gap-1 text-sm opacity-50'>
      <span>{token.data.symbol} Price</span>
      <span className='text-right'>{formattedMintPrice}</span>

      <span>Total Minted</span>
      <span className='text-right'>{totalMinted}</span>

      {account.isConnected && (
        <>
          <span>{token.data.symbol} Balance</span>
          <span className='text-right'>{formattedUserBalance}</span>
        </>
      )}
    </div>
  );
}

The key here is that we're using the hooks we created earlier to fetch the total issued amount, the mint price, and the user's balance. We then format them nicely and display them in the component.