From 5122640f5c8e758060a9fa9d50de0769bac2aba6 Mon Sep 17 00:00:00 2001 From: Drew Stone Date: Thu, 7 May 2026 17:23:36 -0600 Subject: [PATCH] perf(tangle-cloud): zero @polkadot library code in bundle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tangle-cloud doesn't deal with substrate flows — those all live on tangle-dapp's claims/migration page. The four direct polkadot imports were leftovers from the Webb-era shared utilities. Replacements: - BlueprintInfoCard: isEthereumAddress(@polkadot/util-crypto) -> isAddress(viem) with strict: false to preserve regex-only semantics (accept non-checksummed mixed-case) - TxHistoryDrawer: BN(@polkadot/util) -> bigint. formatDisplayAmount signature narrowed to (bigint, ...). BN.isBN check replaced with typeof === 'bigint' (HistoryTxDetail union already excluded BN). - TotalValueLockedTable: type-only BN import dropped. Local BigIntish narrowing alias (bigint | { toString(): string }) avoids touching the shared StakingVault type that tangle-dapp also consumes. - rewards/page: BN -> bigint. Removed new BN(amount.toString()) wrappers that were round-tripping through string for no reason. Verified: zero @polkadot library bytes in any tangle-cloud chunk (grep '@polkadot\|x-global\|registerGlobal' dist/.../assets/*.js -> 0). The 1.99KB polkadot-*.js chunk that remains is just the Polkadot blockchain logo SVG from libs/icons; non-library, lazy-loaded only for chain selectors that show that ecosystem. tangle-dapp untouched — still depends on polkadot for substrate flows; its 697KB polkadot vendor chunk is unchanged. --- .../ServiceRequestDetails/BlueprintInfoCard.tsx | 4 ++-- apps/tangle-cloud/src/components/TxHistoryDrawer.tsx | 9 ++++----- .../TotalValueLocked/TotalValueLockedTable.tsx | 12 ++++++++---- apps/tangle-cloud/src/pages/rewards/page.tsx | 7 +++---- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/apps/tangle-cloud/src/components/ServiceRequestDetails/BlueprintInfoCard.tsx b/apps/tangle-cloud/src/components/ServiceRequestDetails/BlueprintInfoCard.tsx index 83c3061dd..1821a23cd 100644 --- a/apps/tangle-cloud/src/components/ServiceRequestDetails/BlueprintInfoCard.tsx +++ b/apps/tangle-cloud/src/components/ServiceRequestDetails/BlueprintInfoCard.tsx @@ -1,5 +1,5 @@ import { FC } from 'react'; -import { isEthereumAddress } from '@polkadot/util-crypto'; +import { isAddress } from 'viem'; import { twMerge } from 'tailwind-merge'; import { Text } from '../sandbox/SandboxUi'; @@ -25,7 +25,7 @@ const BlueprintInfoCard: FC = ({ instancesCount, operatorsCount, }) => { - const formattedAuthor = isEthereumAddress(author) + const formattedAuthor = isAddress(author, { strict: false }) ? shortenValue(author) : author.length > 24 ? shortenValue(author) diff --git a/apps/tangle-cloud/src/components/TxHistoryDrawer.tsx b/apps/tangle-cloud/src/components/TxHistoryDrawer.tsx index ccbf103d3..b8c89336e 100644 --- a/apps/tangle-cloud/src/components/TxHistoryDrawer.tsx +++ b/apps/tangle-cloud/src/components/TxHistoryDrawer.tsx @@ -1,4 +1,3 @@ -import { BN } from '@polkadot/util'; import * as Dialog from '@radix-ui/react-dialog'; import { CheckboxCircleLine, @@ -30,7 +29,7 @@ const shortenHex = (value: string) => value.length > 14 ? `${value.slice(0, 8)}...${value.slice(-6)}` : value; const shortenString = (value: string) => value.length > 14 ? `${value.slice(0, 8)}...${value.slice(-6)}` : value; -const formatDisplayAmount = (value: BN | bigint, decimals: number) => { +const formatDisplayAmount = (value: bigint, decimals: number) => { const raw = value.toString(); if (decimals <= 0) return addCommasToNumber(Number(raw)); const padded = raw.padStart(decimals + 1, '0'); @@ -203,7 +202,7 @@ const DetailRow: FC = ({ if (typeof value === 'number') { if (isAmountKey) { const decimals = tokenMetadata?.decimals ?? 18; - const formatted = formatDisplayAmount(new BN(value), decimals); + const formatted = formatDisplayAmount(BigInt(value), decimals); if (isSharesKey) { return formatted; } @@ -224,7 +223,7 @@ const DetailRow: FC = ({ if (typeof value === 'string') { if (isAmountKey && isNumericString(value)) { const decimals = tokenMetadata?.decimals ?? 18; - const formatted = formatDisplayAmount(new BN(value), decimals); + const formatted = formatDisplayAmount(BigInt(value), decimals); if (isSharesKey) { return formatted; } @@ -244,7 +243,7 @@ const DetailRow: FC = ({ }, [value, isAmountKey, isSharesKey, tokenMetadata, nativeTokenSymbol]); const rawValue = useMemo(() => { - if (BN.isBN(value)) { + if (typeof value === 'bigint') { return value.toString(); } diff --git a/apps/tangle-cloud/src/pages/instances/TotalValueLocked/TotalValueLockedTable.tsx b/apps/tangle-cloud/src/pages/instances/TotalValueLocked/TotalValueLockedTable.tsx index ae879cfed..c48b594d5 100644 --- a/apps/tangle-cloud/src/pages/instances/TotalValueLocked/TotalValueLockedTable.tsx +++ b/apps/tangle-cloud/src/pages/instances/TotalValueLocked/TotalValueLockedTable.tsx @@ -25,16 +25,20 @@ import type { } from '../../../components/tangleCloudTable/type'; import { Link } from 'react-router'; import { TangleDAppPagePath } from '../../../types'; -import type { BN } from '@polkadot/util'; -const toBigInt = (value: bigint | BN): bigint => +// Locally typed to avoid pulling in `@polkadot/util` for a type-only reference. +// The shared `StakingVault` shape uses BN for some amount fields; we only ever +// call `.toString()` on them, so a structural type is sufficient. +type BigIntish = bigint | { toString(): string }; + +const toBigInt = (value: BigIntish): bigint => typeof value === 'bigint' ? value : BigInt(value.toString()); const pluralize = (word: string, plural: boolean) => plural ? `${word}s` : word; const formatPercentage = (value: number) => `${(value * 100).toLocaleString(undefined, { maximumFractionDigits: 2 })}%`; -const formatAmount = (amount: bigint | BN, decimals: number): string => { +const formatAmount = (amount: BigIntish, decimals: number): string => { const formatted = formatUnits(toBigInt(amount), decimals); const num = parseFloat(formatted); if (num === 0) return '0'; @@ -46,7 +50,7 @@ const formatAmount = (amount: bigint | BN, decimals: number): string => { }); }; -const calculateRatio = (a: bigint | BN, b: bigint | BN): number => { +const calculateRatio = (a: BigIntish, b: BigIntish): number => { const aBigInt = toBigInt(a); const bBigInt = toBigInt(b); if (bBigInt === BigInt(0)) return 0; diff --git a/apps/tangle-cloud/src/pages/rewards/page.tsx b/apps/tangle-cloud/src/pages/rewards/page.tsx index 2c7f57e3e..ad1302057 100644 --- a/apps/tangle-cloud/src/pages/rewards/page.tsx +++ b/apps/tangle-cloud/src/pages/rewards/page.tsx @@ -24,7 +24,6 @@ import { TableHeader, TableRow, } from '@tangle-network/sandbox-ui/primitives'; -import { BN } from '@polkadot/util'; import { ExternalLinkLine, FileCopyLine, @@ -59,7 +58,7 @@ const shortenHex = (value: string, chars = 6) => ? `${value.slice(0, chars)}...${value.slice(-chars)}` : value; -const formatDisplayAmount = (value: BN, decimals: number) => { +const formatDisplayAmount = (value: bigint, decimals: number) => { const raw = value.toString(); const padded = raw.padStart(decimals + 1, '0'); const whole = padded.slice(0, -decimals); @@ -737,7 +736,7 @@ const PendingRewardAmountCell: FC<{ token: Address; amount: bigint }> = ({ return ( - {formatDisplayAmount(new BN(amount.toString()), decimals)} + {formatDisplayAmount(amount, decimals)} ); }; @@ -759,7 +758,7 @@ const RewardAmountCell: FC<{ token: Address; amount: bigint }> = ({ return ( - {formatDisplayAmount(new BN(amount.toString()), decimals)} + {formatDisplayAmount(amount, decimals)} ); };