From 3bf181d0f7527bc9b3911040f8a06012ce5d0cb8 Mon Sep 17 00:00:00 2001 From: daryl Date: Fri, 5 Jul 2024 10:27:41 +0800 Subject: [PATCH] feat(holder-allocation): add new api (#392) * feat(holder-allocation): add new api * style(holder-allocation): use ellipsis and match tag in frontend * fix(xudt-allocation): wrong name * feat(xudt-holder): add btc to list * fix(holder-allocation): style * fix(holder): fix for mobile --- src/models/Xudt/index.ts | 18 ++--- src/pages/Xudt/HolderAllocation.module.scss | 2 + src/pages/Xudt/HolderAllocation.tsx | 80 ++++++++++++--------- src/pages/Xudt/UDTComp.tsx | 55 +++++--------- src/pages/Xudt/index.tsx | 15 +++- src/pages/Xudts/index.tsx | 10 +-- src/services/ExplorerService/fetcher.ts | 4 +- src/utils/util.ts | 10 ++- 8 files changed, 104 insertions(+), 90 deletions(-) diff --git a/src/models/Xudt/index.ts b/src/models/Xudt/index.ts index 80b1613c9..b1fb44233 100644 --- a/src/models/Xudt/index.ts +++ b/src/models/Xudt/index.ts @@ -1,6 +1,16 @@ import { Script } from '../Script' +export interface XUDTHolderAllocation { + btcHolderCount: string + lockHashes: { + name: string + holderCount: string + codeHash: string + }[] +} + export interface XUDT { + addressesCount: string createdAt: string h24CkbTransactionsCount: string issuerAddress: string @@ -13,14 +23,6 @@ export interface XUDT { typeScript: Script udtType: 'xudt' xudtTags?: string[] - holderAllocation?: { - ckbHoldersCount: string - btcHoldersCount: string - lockHoderAmount: { - lock: string - holderAmount: string - }[] - } iconFile: string operatorWebsite: string email: string diff --git a/src/pages/Xudt/HolderAllocation.module.scss b/src/pages/Xudt/HolderAllocation.module.scss index 6f6560979..d7ba89c74 100644 --- a/src/pages/Xudt/HolderAllocation.module.scss +++ b/src/pages/Xudt/HolderAllocation.module.scss @@ -29,8 +29,10 @@ flex-direction: column; align-items: center; gap: 24px; + min-width: 397px; @media (max-width: $mobileBreakPoint) { + min-width: 0; align-items: flex-start; p { diff --git a/src/pages/Xudt/HolderAllocation.tsx b/src/pages/Xudt/HolderAllocation.tsx index e43b38cd8..15154ef95 100644 --- a/src/pages/Xudt/HolderAllocation.tsx +++ b/src/pages/Xudt/HolderAllocation.tsx @@ -4,59 +4,75 @@ import styles from './HolderAllocation.module.scss' import { localeNumberString } from '../../utils/number' import CloseIcon from '../../assets/modal_close.png' import SimpleButton from '../../components/SimpleButton' +import { matchScript } from '../../utils/util' +import EllipsisMiddle from '../../components/EllipsisMiddle' const HolderAllocation = ({ - allocation, + ckbHolderAmount, + btcHolderAmount, + lockHoderAmount, onClose, }: { - allocation: Record + ckbHolderAmount: string + btcHolderAmount: string + lockHoderAmount?: { + name: string + holderCount: string + codeHash: string + }[] onClose: MouseEventHandler }) => { const [t] = useTranslation() - const total = Object.values(allocation).reduce((acc, cur) => acc + cur, 0) - const btc = +(allocation.BTC ?? 0) - const ckb = total - btc - return (

{t('xudt.holder_allocation')}

{t('xudt.holder_allocation_description', { - ckb: localeNumberString(ckb), - btc: localeNumberString(btc), + ckb: ckbHolderAmount, + btc: localeNumberString(btcHolderAmount), })}

-
- - - - - - - - - {Object.entries(allocation) - .sort((a, b) => b[1] - a[1]) - .map(([label, count]) => { - return ( + {lockHoderAmount && ( +
+
-
{t('xudt.category')}
-
-
{t('xudt.count')}
-
+ + + + + + + + {parseInt(btcHolderAmount, 10) > 0 && ( + + + + + )} + {lockHoderAmount + .sort((a, b) => +b.holderCount - +a.holderCount) + .map(amount => ( - ) - })} - -
+
{t('xudt.lock_hash')}
+
+
{t('xudt.count')}
+
+
BTC
+
+
{localeNumberString(btcHolderAmount)}
+
-
{label}
+ {matchScript(amount.codeHash)?.tag ?? amount.codeHash}
-
{localeNumberString(count)}
+
{localeNumberString(amount.holderCount)}
-
+ ))} + + +
+ )}
close icon diff --git a/src/pages/Xudt/UDTComp.tsx b/src/pages/Xudt/UDTComp.tsx index 3ad42b07c..abfcb36b1 100644 --- a/src/pages/Xudt/UDTComp.tsx +++ b/src/pages/Xudt/UDTComp.tsx @@ -20,16 +20,14 @@ import { SubmitTokenInfo, TokenInfo } from '../../components/SubmitTokenInfo' import { useIsMobile } from '../../hooks' import Script from '../../components/Script' import { RawBtcRPC } from '../../services/ExplorerService' -import { XUDT } from '../../models/Xudt' +import { XUDT, XUDTHolderAllocation } from '../../models/Xudt' import { getBtcTxList } from '../../services/ExplorerService/fetcher' -import { getHolderAllocation } from '../../services/MetricsService' import XUDTTag from '../../components/XUDTTag' import SimpleButton from '../../components/SimpleButton' import SimpleModal from '../../components/Modal' import HolderAllocation from './HolderAllocation' import { ReactComponent as EditIcon } from '../../assets/edit.svg' import XUDTTokenIcon from '../../assets/sudt_token.png' -import { IS_MAINNET } from '../../constants/common' const IssuerContent: FC<{ address: string }> = ({ address }) => { const { t } = useTranslation() @@ -62,10 +60,12 @@ const IssuerContent: FC<{ address: string }> = ({ address }) => { export const UDTOverviewCard = ({ typeHash, xudt, + holderAllocation, refetchUDT, }: { typeHash: string - xudt: XUDT | undefined + holderAllocation?: XUDTHolderAllocation + xudt?: XUDT refetchUDT: () => void }) => { const { t } = useTranslation() @@ -109,32 +109,8 @@ export const UDTOverviewCard = ({ }, ) - const { data: holderAllocation = {}, isLoading: isHolderAllocationLoading } = useQuery({ - queryKey: ['xudt-holder-allocation', typeHash], - queryFn: () => - xudt - ? getHolderAllocation({ - code_hash: xudt.typeScript.codeHash, - hash_type: xudt.typeScript.hashType, - args: xudt.typeScript.args, - }) - : ({} as Record), - enabled: IS_MAINNET && !!xudt, - }) - - const holderCountFromBackend = xudt - ? +(xudt.holderAllocation?.ckbHoldersCount ?? 0) + +(xudt.holderAllocation?.btcHoldersCount ?? 0) - : 0 - const holderCountFromNode = Object.values(holderAllocation ?? {}).reduce((acc, cur) => acc + cur, 0) - - const holderCount = IS_MAINNET ? holderCountFromNode : holderCountFromBackend - - const allocationDisplay = IS_MAINNET - ? holderAllocation - : { - BTC: +(xudt?.holderAllocation?.btcHoldersCount ?? 0), - others: +(xudt?.holderAllocation?.ckbHoldersCount ?? 0), - } + const ckbHolderAmount = holderAllocation?.lockHashes.reduce((acc, cur) => acc + +cur.holderCount, 0) ?? 0 + const holderCount = holderAllocation ? ckbHolderAmount + +(holderAllocation?.btcHolderCount ?? 0) : 0 const items: CardCellInfo<'left' | 'right'>[] = [ { @@ -148,14 +124,14 @@ export const UDTOverviewCard = ({ }, { title: t('xudt.holders'), - content: xudt?.holderAllocation ? ( + content: holderAllocation ? ( { setShowHolderAmountModal(true) }} > - {IS_MAINNET && isHolderAllocationLoading ? '-' : localeNumberString(holderCount)} + {localeNumberString(holderCount)} ) : ( '-' @@ -219,14 +195,21 @@ export const UDTOverviewCard = ({
{xudt?.xudtTags?.map(tag => ( - + ))}
- - setShowHolderAmountModal(false)} /> - + {holderAllocation && ( + + setShowHolderAmountModal(false)} + /> + + )} {isScriptDisplayed ? ( diff --git a/src/pages/Xudt/index.tsx b/src/pages/Xudt/index.tsx index db94bed7e..19c72ea75 100644 --- a/src/pages/Xudt/index.tsx +++ b/src/pages/Xudt/index.tsx @@ -23,10 +23,13 @@ export const Xudt = () => { const { filter } = useSearchParams('filter') const updateSearchParams = useUpdateSearchParams<'filter' | 'page'>() - const queryUDT = useQuery(['udt', typeHash], () => explorerService.api.fetchSimpleUDT(typeHash)) const queryXudt = useQuery(['xudt', typeHash], () => explorerService.api.fetchXudt(typeHash)) const xudt = queryXudt.data + const queryXudtHolderAllocation = useQuery(['xudt-holder-allocation', typeHash], () => + explorerService.api.fetchXudtHolderAllocation(typeHash), + ) + const holderAllocation = queryXudtHolderAllocation.data const querySimpleUDTTransactions = useQuery( ['xudt-transactions', typeHash, currentPage, _pageSize, filter], @@ -69,7 +72,15 @@ export const Xudt = () => { return (
- + { + queryXudt.refetch() + queryXudtHolderAllocation.refetch() + }} + />
diff --git a/src/pages/Xudts/index.tsx b/src/pages/Xudts/index.tsx index 3ccc0fafc..05a50151d 100644 --- a/src/pages/Xudts/index.tsx +++ b/src/pages/Xudts/index.tsx @@ -30,9 +30,6 @@ const TokenInfo: FC<{ token: XUDT }> = ({ token }) => { const { t } = useTranslation() const symbol = token.symbol || `#${token.typeHash.substring(token.typeHash.length - 4)}` - const holderCount = token.holderAllocation - ? +token.holderAllocation.btcHoldersCount + +token.holderAllocation.ckbHoldersCount - : 0 const fields: { name: string; value: ReactNode }[] = [ { @@ -41,7 +38,7 @@ const TokenInfo: FC<{ token: XUDT }> = ({ token }) => { }, { name: t('xudt.unique_addresses'), - value: localeNumberString(holderCount), + value: localeNumberString(token.addressesCount), }, { name: t('xudt.created_time'), @@ -203,10 +200,7 @@ const TokenTable: FC<{ ), className: styles.colAddressCount, - render: (_, token) => - token.holderAllocation - ? localeNumberString(+token.holderAllocation.btcHoldersCount + +token.holderAllocation.ckbHoldersCount) - : 0, + render: (_, token) => localeNumberString(token.addressesCount), }, { title: ( diff --git a/src/services/ExplorerService/fetcher.ts b/src/services/ExplorerService/fetcher.ts index 37b6834d6..79e8ac156 100644 --- a/src/services/ExplorerService/fetcher.ts +++ b/src/services/ExplorerService/fetcher.ts @@ -24,7 +24,7 @@ import { Block } from '../../models/Block' import { BtcTx, Transaction } from '../../models/Transaction' import { Address, AddressType } from '../../models/Address' import { OmigaInscriptionCollection, UDT } from '../../models/UDT' -import { XUDT } from '../../models/Xudt' +import { XUDT, XUDTHolderAllocation } from '../../models/Xudt' import { HashType } from '../../constants/common' import { Dob, getDobs } from '../DobsService' import { isDob0 } from '../../utils/spore' @@ -795,6 +795,8 @@ export const apiFetcher = { }, fetchXudt: (typeHash: string) => v1GetUnwrapped(`/xudts/${typeHash}`), + fetchXudtHolderAllocation: (typeHash: string) => + requesterV1.get(`/udts/${typeHash}/holder_allocation`).then(res => toCamelcase(res.data)), fetchXudts: (page: number, size: number, sort?: string, tags?: string) => v1GetUnwrappedPagedList(`/xudts`, { diff --git a/src/utils/util.ts b/src/utils/util.ts index 111ef80bd..0b4fb68bd 100644 --- a/src/utils/util.ts +++ b/src/utils/util.ts @@ -103,14 +103,18 @@ export const getContractHashTag = (script: Script): ContractHashTag | undefined return contractHashTag } -export const matchScript = (contractHash: string, hashType: string): ContractHashTag | undefined => { +export const matchScript = (contractHash: string, hashType?: string): ContractHashTag | undefined => { if (isMainnet()) { return MainnetContractHashTags.find( - scriptTag => scriptTag.codeHashes.find(codeHash => codeHash === contractHash) && scriptTag.hashType === hashType, + scriptTag => + scriptTag.codeHashes.find(codeHash => codeHash === contractHash) && + (!hashType || scriptTag.hashType === hashType), ) } return TestnetContractHashTags.find( - scriptTag => scriptTag.codeHashes.find(codeHash => codeHash === contractHash) && scriptTag.hashType === hashType, + scriptTag => + scriptTag.codeHashes.find(codeHash => codeHash === contractHash) && + (!hashType || scriptTag.hashType === hashType), ) }