2021-11-01 21:30:26 -07:00
|
|
|
import {
|
|
|
|
Account,
|
|
|
|
NFTData,
|
|
|
|
TokenProgramData,
|
|
|
|
useFetchAccountInfo,
|
|
|
|
} from "providers/accounts";
|
2020-08-08 23:02:01 +08:00
|
|
|
import {
|
|
|
|
TokenAccount,
|
|
|
|
MintAccountInfo,
|
|
|
|
TokenAccountInfo,
|
|
|
|
MultisigAccountInfo,
|
|
|
|
} from "validators/accounts/token";
|
2021-03-13 13:31:52 +08:00
|
|
|
import { create } from "superstruct";
|
2020-08-08 23:02:01 +08:00
|
|
|
import { TableCardBody } from "components/common/TableCardBody";
|
|
|
|
import { Address } from "components/common/Address";
|
|
|
|
import { UnknownAccountCard } from "./UnknownAccountCard";
|
2021-04-16 10:09:05 -07:00
|
|
|
import { Cluster, useCluster } from "providers/cluster";
|
2021-07-20 09:43:17 -07:00
|
|
|
import { abbreviatedNumber, normalizeTokenAmount } from "utils";
|
2020-09-08 08:57:17 -07:00
|
|
|
import { addressLabel } from "utils/tx";
|
2020-09-18 10:47:58 +08:00
|
|
|
import { reportError } from "utils/sentry";
|
2021-02-24 12:30:55 -08:00
|
|
|
import { useTokenRegistry } from "providers/mints/token-registry";
|
2021-03-05 11:34:26 -08:00
|
|
|
import { BigNumber } from "bignumber.js";
|
2021-03-16 11:47:43 -07:00
|
|
|
import { Copyable } from "components/common/Copyable";
|
2021-05-17 12:43:18 -07:00
|
|
|
import { CoingeckoStatus, useCoinGecko } from "utils/coingecko";
|
|
|
|
import { displayTimestampWithoutDate } from "utils/date";
|
2021-07-20 09:43:17 -07:00
|
|
|
import { LoadingCard } from "components/common/LoadingCard";
|
2021-10-16 19:14:50 -07:00
|
|
|
import { PublicKey } from "@solana/web3.js";
|
2021-11-01 21:30:26 -07:00
|
|
|
import isMetaplexNFT from "providers/accounts/utils/isMetaplexNFT";
|
2020-08-08 23:02:01 +08:00
|
|
|
|
2021-03-17 10:53:50 -05:00
|
|
|
const getEthAddress = (link?: string) => {
|
|
|
|
let address = "";
|
|
|
|
if (link) {
|
|
|
|
const extractEth = link.match(/0x[a-fA-F0-9]{40,64}/);
|
|
|
|
|
|
|
|
if (extractEth) {
|
|
|
|
address = extractEth[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return address;
|
|
|
|
};
|
|
|
|
|
2020-08-08 23:02:01 +08:00
|
|
|
export function TokenAccountSection({
|
|
|
|
account,
|
|
|
|
tokenAccount,
|
|
|
|
}: {
|
|
|
|
account: Account;
|
|
|
|
tokenAccount: TokenAccount;
|
|
|
|
}) {
|
2021-04-16 10:09:05 -07:00
|
|
|
const { cluster } = useCluster();
|
|
|
|
|
2020-08-08 23:02:01 +08:00
|
|
|
try {
|
|
|
|
switch (tokenAccount.type) {
|
|
|
|
case "mint": {
|
2021-03-13 13:31:52 +08:00
|
|
|
const info = create(tokenAccount.info, MintAccountInfo);
|
2021-10-05 14:30:05 -04:00
|
|
|
|
2021-11-03 12:52:04 -07:00
|
|
|
if (isMetaplexNFT(account.details?.data, info)) {
|
2021-10-05 14:30:05 -04:00
|
|
|
return (
|
|
|
|
<NonFungibleTokenMintAccountCard
|
|
|
|
account={account}
|
2021-11-01 21:30:26 -07:00
|
|
|
nftData={(account.details!.data as TokenProgramData).nftData!}
|
2021-10-05 14:30:05 -04:00
|
|
|
mintInfo={info}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return <FungibleTokenMintAccountCard account={account} info={info} />;
|
2020-08-08 23:02:01 +08:00
|
|
|
}
|
|
|
|
case "account": {
|
2021-03-13 13:31:52 +08:00
|
|
|
const info = create(tokenAccount.info, TokenAccountInfo);
|
2020-08-08 23:02:01 +08:00
|
|
|
return <TokenAccountCard account={account} info={info} />;
|
|
|
|
}
|
|
|
|
case "multisig": {
|
2021-03-13 13:31:52 +08:00
|
|
|
const info = create(tokenAccount.info, MultisigAccountInfo);
|
2020-08-08 23:02:01 +08:00
|
|
|
return <MultisigAccountCard account={account} info={info} />;
|
|
|
|
}
|
|
|
|
}
|
2020-08-14 17:54:21 +08:00
|
|
|
} catch (err) {
|
2021-04-16 10:09:05 -07:00
|
|
|
if (cluster !== Cluster.Custom) {
|
|
|
|
reportError(err, {
|
|
|
|
address: account.pubkey.toBase58(),
|
|
|
|
});
|
|
|
|
}
|
2020-08-14 17:54:21 +08:00
|
|
|
}
|
2020-08-08 23:02:01 +08:00
|
|
|
return <UnknownAccountCard account={account} />;
|
|
|
|
}
|
|
|
|
|
2021-10-05 14:30:05 -04:00
|
|
|
function FungibleTokenMintAccountCard({
|
2020-08-08 23:02:01 +08:00
|
|
|
account,
|
|
|
|
info,
|
|
|
|
}: {
|
|
|
|
account: Account;
|
|
|
|
info: MintAccountInfo;
|
|
|
|
}) {
|
2021-02-24 12:30:55 -08:00
|
|
|
const { tokenRegistry } = useTokenRegistry();
|
2020-08-13 01:31:21 +08:00
|
|
|
const mintAddress = account.pubkey.toBase58();
|
|
|
|
const fetchInfo = useFetchAccountInfo();
|
2020-08-29 20:50:45 +08:00
|
|
|
const refresh = () => fetchInfo(account.pubkey);
|
2021-02-24 12:30:55 -08:00
|
|
|
const tokenInfo = tokenRegistry.get(mintAddress);
|
2021-03-16 11:47:43 -07:00
|
|
|
|
2021-03-17 10:53:50 -05:00
|
|
|
const bridgeContractAddress = getEthAddress(
|
|
|
|
tokenInfo?.extensions?.bridgeContract
|
|
|
|
);
|
|
|
|
const assetContractAddress = getEthAddress(
|
|
|
|
tokenInfo?.extensions?.assetContract
|
|
|
|
);
|
2021-03-16 11:47:43 -07:00
|
|
|
|
2021-05-17 12:43:18 -07:00
|
|
|
const coinInfo = useCoinGecko(tokenInfo?.extensions?.coingeckoId);
|
|
|
|
|
|
|
|
let tokenPriceInfo;
|
2021-11-15 13:45:49 +01:00
|
|
|
let tokenPriceDecimals = 2;
|
2021-05-17 12:43:18 -07:00
|
|
|
if (coinInfo?.status === CoingeckoStatus.Success) {
|
|
|
|
tokenPriceInfo = coinInfo.coinInfo;
|
2021-11-15 13:45:49 +01:00
|
|
|
if (tokenPriceInfo && tokenPriceInfo.price < 1) {
|
|
|
|
tokenPriceDecimals = 6;
|
|
|
|
}
|
2021-05-17 12:43:18 -07:00
|
|
|
}
|
|
|
|
|
2020-08-08 23:02:01 +08:00
|
|
|
return (
|
2021-07-20 09:43:17 -07:00
|
|
|
<>
|
|
|
|
{tokenInfo?.extensions?.coingeckoId &&
|
|
|
|
coinInfo?.status === CoingeckoStatus.Loading && (
|
|
|
|
<LoadingCard message="Loading token price data" />
|
2021-05-17 12:43:18 -07:00
|
|
|
)}
|
2021-08-12 11:12:07 -07:00
|
|
|
{tokenPriceInfo && tokenPriceInfo.price && (
|
2021-07-20 09:43:17 -07:00
|
|
|
<div className="row">
|
|
|
|
<div className="col-12 col-lg-4 col-xl">
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-body">
|
|
|
|
<h4>
|
|
|
|
Price{" "}
|
2021-11-15 14:17:57 +01:00
|
|
|
{tokenPriceInfo.market_cap_rank && (
|
2021-11-28 14:49:22 -06:00
|
|
|
<span className="ms-2 badge bg-primary rank">
|
2021-11-15 14:17:57 +01:00
|
|
|
Rank #{tokenPriceInfo.market_cap_rank}
|
|
|
|
</span>
|
|
|
|
)}
|
2021-07-20 09:43:17 -07:00
|
|
|
</h4>
|
|
|
|
<h1 className="mb-0">
|
2021-11-15 13:45:49 +01:00
|
|
|
${tokenPriceInfo.price.toFixed(tokenPriceDecimals)}{" "}
|
2021-07-20 09:43:17 -07:00
|
|
|
{tokenPriceInfo.price_change_percentage_24h > 0 && (
|
|
|
|
<small className="change-positive">
|
|
|
|
↑{" "}
|
|
|
|
{tokenPriceInfo.price_change_percentage_24h.toFixed(2)}%
|
|
|
|
</small>
|
|
|
|
)}
|
|
|
|
{tokenPriceInfo.price_change_percentage_24h < 0 && (
|
|
|
|
<small className="change-negative">
|
|
|
|
↓{" "}
|
|
|
|
{tokenPriceInfo.price_change_percentage_24h.toFixed(2)}%
|
|
|
|
</small>
|
|
|
|
)}
|
|
|
|
{tokenPriceInfo.price_change_percentage_24h === 0 && (
|
|
|
|
<small>0%</small>
|
|
|
|
)}
|
|
|
|
</h1>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="col-12 col-lg-4 col-xl">
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-body">
|
|
|
|
<h4>24 Hour Volume</h4>
|
|
|
|
<h1 className="mb-0">
|
|
|
|
${abbreviatedNumber(tokenPriceInfo.volume_24)}
|
|
|
|
</h1>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="col-12 col-lg-4 col-xl">
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-body">
|
|
|
|
<h4>Market Cap</h4>
|
|
|
|
<h1 className="mb-0">
|
|
|
|
${abbreviatedNumber(tokenPriceInfo.market_cap)}
|
|
|
|
</h1>
|
|
|
|
<p className="updated-time text-muted">
|
|
|
|
Updated at{" "}
|
|
|
|
{displayTimestampWithoutDate(
|
|
|
|
tokenPriceInfo.last_updated.getTime()
|
|
|
|
)}
|
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-header">
|
|
|
|
<h3 className="card-header-title mb-0 d-flex align-items-center">
|
|
|
|
{tokenInfo ? "Overview" : "Token Mint"}
|
|
|
|
</h3>
|
|
|
|
<button className="btn btn-white btn-sm" onClick={refresh}>
|
2021-11-28 14:49:22 -06:00
|
|
|
<span className="fe fe-refresh-cw me-2"></span>
|
2021-07-20 09:43:17 -07:00
|
|
|
Refresh
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<TableCardBody>
|
2020-08-13 22:57:53 +08:00
|
|
|
<tr>
|
2021-07-20 09:43:17 -07:00
|
|
|
<td>Address</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-07-20 09:43:17 -07:00
|
|
|
<Address pubkey={account.pubkey} alignRight raw />
|
2020-08-13 22:57:53 +08:00
|
|
|
</td>
|
|
|
|
</tr>
|
2020-08-29 20:50:45 +08:00
|
|
|
<tr>
|
2021-07-20 09:43:17 -07:00
|
|
|
<td>
|
|
|
|
{info.mintAuthority === null ? "Fixed Supply" : "Current Supply"}
|
2020-08-29 20:50:45 +08:00
|
|
|
</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-07-20 09:43:17 -07:00
|
|
|
{normalizeTokenAmount(info.supply, info.decimals).toLocaleString(
|
|
|
|
"en-US",
|
|
|
|
{
|
|
|
|
minimumFractionDigits: info.decimals,
|
|
|
|
}
|
|
|
|
)}
|
2020-08-29 20:50:45 +08:00
|
|
|
</td>
|
|
|
|
</tr>
|
2021-07-20 09:43:17 -07:00
|
|
|
{tokenInfo?.extensions?.website && (
|
|
|
|
<tr>
|
|
|
|
<td>Website</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-03-16 11:47:43 -07:00
|
|
|
<a
|
2021-07-20 09:43:17 -07:00
|
|
|
rel="noopener noreferrer"
|
2021-03-16 11:47:43 -07:00
|
|
|
target="_blank"
|
2021-07-20 09:43:17 -07:00
|
|
|
href={tokenInfo.extensions.website}
|
2021-03-16 11:47:43 -07:00
|
|
|
>
|
2021-07-20 09:43:17 -07:00
|
|
|
{tokenInfo.extensions.website}
|
2021-11-28 14:49:22 -06:00
|
|
|
<span className="fe fe-external-link ms-2"></span>
|
2021-03-16 11:47:43 -07:00
|
|
|
</a>
|
2021-07-20 09:43:17 -07:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
{info.mintAuthority && (
|
|
|
|
<tr>
|
|
|
|
<td>Mint Authority</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-07-20 09:43:17 -07:00
|
|
|
<Address pubkey={info.mintAuthority} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
{info.freezeAuthority && (
|
|
|
|
<tr>
|
|
|
|
<td>Freeze Authority</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-07-20 09:43:17 -07:00
|
|
|
<Address pubkey={info.freezeAuthority} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
2021-03-17 10:53:50 -05:00
|
|
|
<tr>
|
2021-07-20 09:43:17 -07:00
|
|
|
<td>Decimals</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">{info.decimals}</td>
|
2021-03-17 10:53:50 -05:00
|
|
|
</tr>
|
2021-07-20 09:43:17 -07:00
|
|
|
{!info.isInitialized && (
|
|
|
|
<tr>
|
|
|
|
<td>Status</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">Uninitialized</td>
|
2021-07-20 09:43:17 -07:00
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
{tokenInfo?.extensions?.bridgeContract && bridgeContractAddress && (
|
|
|
|
<tr>
|
|
|
|
<td>Bridge Contract</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-07-20 09:43:17 -07:00
|
|
|
<Copyable text={bridgeContractAddress}>
|
|
|
|
<a
|
|
|
|
href={tokenInfo.extensions.bridgeContract}
|
|
|
|
target="_blank"
|
|
|
|
rel="noreferrer"
|
|
|
|
>
|
|
|
|
{bridgeContractAddress}
|
|
|
|
</a>
|
|
|
|
</Copyable>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
{tokenInfo?.extensions?.assetContract && assetContractAddress && (
|
|
|
|
<tr>
|
|
|
|
<td>Bridged Asset Contract</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-07-20 09:43:17 -07:00
|
|
|
<Copyable text={assetContractAddress}>
|
|
|
|
<a
|
|
|
|
href={tokenInfo.extensions.bridgeContract}
|
|
|
|
target="_blank"
|
|
|
|
rel="noreferrer"
|
|
|
|
>
|
|
|
|
{assetContractAddress}
|
|
|
|
</a>
|
|
|
|
</Copyable>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
</TableCardBody>
|
|
|
|
</div>
|
|
|
|
</>
|
2020-08-08 23:02:01 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-10-05 14:30:05 -04:00
|
|
|
function NonFungibleTokenMintAccountCard({
|
|
|
|
account,
|
|
|
|
nftData,
|
|
|
|
mintInfo,
|
|
|
|
}: {
|
|
|
|
account: Account;
|
|
|
|
nftData: NFTData;
|
|
|
|
mintInfo: MintAccountInfo;
|
|
|
|
}) {
|
|
|
|
const fetchInfo = useFetchAccountInfo();
|
|
|
|
const refresh = () => fetchInfo(account.pubkey);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-header">
|
|
|
|
<h3 className="card-header-title mb-0 d-flex align-items-center">
|
|
|
|
Overview
|
|
|
|
</h3>
|
|
|
|
<button className="btn btn-white btn-sm" onClick={refresh}>
|
2021-11-28 14:49:22 -06:00
|
|
|
<span className="fe fe-refresh-cw me-2"></span>
|
2021-10-05 14:30:05 -04:00
|
|
|
Refresh
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<TableCardBody>
|
|
|
|
<tr>
|
|
|
|
<td>Address</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-10-05 14:30:05 -04:00
|
|
|
<Address pubkey={account.pubkey} alignRight raw />
|
|
|
|
</td>
|
|
|
|
</tr>
|
2021-10-16 19:14:50 -07:00
|
|
|
{nftData.editionInfo.masterEdition?.maxSupply && (
|
2021-10-05 14:30:05 -04:00
|
|
|
<tr>
|
|
|
|
<td>Max Total Supply</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-10-16 19:14:50 -07:00
|
|
|
{nftData.editionInfo.masterEdition.maxSupply.toNumber() === 0
|
2021-10-05 14:30:05 -04:00
|
|
|
? 1
|
2021-10-16 19:14:50 -07:00
|
|
|
: nftData.editionInfo.masterEdition.maxSupply.toNumber()}
|
2021-10-05 14:30:05 -04:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
2021-10-16 19:14:50 -07:00
|
|
|
{nftData?.editionInfo.masterEdition?.supply && (
|
2021-10-05 14:30:05 -04:00
|
|
|
<tr>
|
|
|
|
<td>Current Supply</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-10-16 19:14:50 -07:00
|
|
|
{nftData.editionInfo.masterEdition.supply.toNumber() === 0
|
2021-10-05 14:30:05 -04:00
|
|
|
? 1
|
2021-10-16 19:14:50 -07:00
|
|
|
: nftData.editionInfo.masterEdition.supply.toNumber()}
|
2021-10-05 14:30:05 -04:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
{mintInfo.mintAuthority && (
|
|
|
|
<tr>
|
|
|
|
<td>Mint Authority</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-10-05 14:30:05 -04:00
|
|
|
<Address pubkey={mintInfo.mintAuthority} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
<tr>
|
|
|
|
<td>Update Authority</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-10-05 14:30:05 -04:00
|
|
|
<Address
|
2021-10-16 19:14:50 -07:00
|
|
|
pubkey={new PublicKey(nftData.metadata.updateAuthority)}
|
2021-10-05 14:30:05 -04:00
|
|
|
alignRight
|
|
|
|
link
|
|
|
|
/>
|
|
|
|
</td>
|
|
|
|
</tr>
|
2021-11-28 16:22:27 -08:00
|
|
|
{nftData?.json && nftData.json.external_url && (
|
|
|
|
<tr>
|
|
|
|
<td>Website</td>
|
|
|
|
<td className="text-lg-end">
|
|
|
|
<a
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
target="_blank"
|
|
|
|
href={nftData.json.external_url}
|
|
|
|
>
|
|
|
|
{nftData.json.external_url}
|
|
|
|
<span className="fe fe-external-link ms-2"></span>
|
|
|
|
</a>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
2021-10-05 14:30:05 -04:00
|
|
|
{nftData?.metadata.data && (
|
|
|
|
<tr>
|
|
|
|
<td>Seller Fee</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2021-10-05 14:30:05 -04:00
|
|
|
{`${nftData?.metadata.data.sellerFeeBasisPoints / 100}%`}
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
|
|
|
</TableCardBody>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-08 23:02:01 +08:00
|
|
|
function TokenAccountCard({
|
|
|
|
account,
|
|
|
|
info,
|
|
|
|
}: {
|
|
|
|
account: Account;
|
|
|
|
info: TokenAccountInfo;
|
|
|
|
}) {
|
|
|
|
const refresh = useFetchAccountInfo();
|
2020-08-13 22:57:53 +08:00
|
|
|
const { cluster } = useCluster();
|
2021-02-24 12:30:55 -08:00
|
|
|
const { tokenRegistry } = useTokenRegistry();
|
|
|
|
const label = addressLabel(account.pubkey.toBase58(), cluster, tokenRegistry);
|
2020-09-08 08:57:17 -07:00
|
|
|
|
2020-08-29 20:50:45 +08:00
|
|
|
let unit, balance;
|
|
|
|
if (info.isNative) {
|
|
|
|
unit = "SOL";
|
|
|
|
balance = (
|
|
|
|
<>
|
|
|
|
◎
|
2021-11-28 14:49:22 -06:00
|
|
|
<span className="font-monospace">
|
2021-03-05 11:34:26 -08:00
|
|
|
{new BigNumber(info.tokenAmount.uiAmountString).toFormat(9)}
|
2020-08-29 20:50:45 +08:00
|
|
|
</span>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
} else {
|
2021-03-05 11:34:26 -08:00
|
|
|
balance = <>{info.tokenAmount.uiAmountString}</>;
|
2021-03-08 14:23:07 -08:00
|
|
|
unit = tokenRegistry.get(info.mint.toBase58())?.symbol || "tokens";
|
2020-08-29 20:50:45 +08:00
|
|
|
}
|
2020-08-08 23:02:01 +08:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-header">
|
|
|
|
<h3 className="card-header-title mb-0 d-flex align-items-center">
|
|
|
|
Token Account
|
|
|
|
</h3>
|
|
|
|
<button
|
|
|
|
className="btn btn-white btn-sm"
|
|
|
|
onClick={() => refresh(account.pubkey)}
|
|
|
|
>
|
2021-11-28 14:49:22 -06:00
|
|
|
<span className="fe fe-refresh-cw me-2"></span>
|
2020-08-08 23:02:01 +08:00
|
|
|
Refresh
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<TableCardBody>
|
|
|
|
<tr>
|
|
|
|
<td>Address</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2020-08-08 23:02:01 +08:00
|
|
|
<Address pubkey={account.pubkey} alignRight raw />
|
|
|
|
</td>
|
|
|
|
</tr>
|
2020-09-08 08:57:17 -07:00
|
|
|
{label && (
|
|
|
|
<tr>
|
|
|
|
<td>Address Label</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">{label}</td>
|
2020-09-08 08:57:17 -07:00
|
|
|
</tr>
|
|
|
|
)}
|
2020-08-08 23:02:01 +08:00
|
|
|
<tr>
|
|
|
|
<td>Mint</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2020-08-08 23:02:01 +08:00
|
|
|
<Address pubkey={info.mint} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Owner</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2020-08-08 23:02:01 +08:00
|
|
|
<Address pubkey={info.owner} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
2020-08-29 20:50:45 +08:00
|
|
|
<td>Token balance ({unit})</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">{balance}</td>
|
2020-08-08 23:02:01 +08:00
|
|
|
</tr>
|
2020-08-29 20:50:45 +08:00
|
|
|
{info.state === "uninitialized" && (
|
2020-08-13 22:57:53 +08:00
|
|
|
<tr>
|
|
|
|
<td>Status</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">Uninitialized</td>
|
2020-08-13 22:57:53 +08:00
|
|
|
</tr>
|
|
|
|
)}
|
2020-08-29 20:50:45 +08:00
|
|
|
{info.rentExemptReserve && (
|
|
|
|
<tr>
|
|
|
|
<td>Rent-exempt reserve (SOL)</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2020-08-29 20:50:45 +08:00
|
|
|
<>
|
|
|
|
◎
|
2021-11-28 14:49:22 -06:00
|
|
|
<span className="font-monospace">
|
2021-03-05 11:34:26 -08:00
|
|
|
{new BigNumber(
|
|
|
|
info.rentExemptReserve.uiAmountString
|
|
|
|
).toFormat(9)}
|
2020-08-29 20:50:45 +08:00
|
|
|
</span>
|
|
|
|
</>
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
)}
|
2020-08-08 23:02:01 +08:00
|
|
|
</TableCardBody>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function MultisigAccountCard({
|
|
|
|
account,
|
|
|
|
info,
|
|
|
|
}: {
|
|
|
|
account: Account;
|
|
|
|
info: MultisigAccountInfo;
|
|
|
|
}) {
|
|
|
|
const refresh = useFetchAccountInfo();
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="card">
|
|
|
|
<div className="card-header">
|
|
|
|
<h3 className="card-header-title mb-0 d-flex align-items-center">
|
|
|
|
Multisig Account
|
|
|
|
</h3>
|
|
|
|
<button
|
|
|
|
className="btn btn-white btn-sm"
|
|
|
|
onClick={() => refresh(account.pubkey)}
|
|
|
|
>
|
2021-11-28 14:49:22 -06:00
|
|
|
<span className="fe fe-refresh-cw me-2"></span>
|
2020-08-08 23:02:01 +08:00
|
|
|
Refresh
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<TableCardBody>
|
|
|
|
<tr>
|
|
|
|
<td>Address</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2020-08-08 23:02:01 +08:00
|
|
|
<Address pubkey={account.pubkey} alignRight raw />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Required Signers</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">{info.numRequiredSigners}</td>
|
2020-08-08 23:02:01 +08:00
|
|
|
</tr>
|
|
|
|
<tr>
|
|
|
|
<td>Valid Signers</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">{info.numValidSigners}</td>
|
2020-08-08 23:02:01 +08:00
|
|
|
</tr>
|
|
|
|
{info.signers.map((signer) => (
|
|
|
|
<tr key={signer.toString()}>
|
|
|
|
<td>Signer</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">
|
2020-08-08 23:02:01 +08:00
|
|
|
<Address pubkey={signer} alignRight link />
|
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
))}
|
2020-08-13 22:57:53 +08:00
|
|
|
{!info.isInitialized && (
|
|
|
|
<tr>
|
|
|
|
<td>Status</td>
|
2021-11-28 14:49:22 -06:00
|
|
|
<td className="text-lg-end">Uninitialized</td>
|
2020-08-13 22:57:53 +08:00
|
|
|
</tr>
|
|
|
|
)}
|
2020-08-08 23:02:01 +08:00
|
|
|
</TableCardBody>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|