MPT Object page improvement - #1339
Conversation
There was a problem hiding this comment.
This is a well-scoped, well-tested fix for the four reported MPT object page display bugs plus a shared circulating-supply util extracted for both token pages. The BigInt-based supply math, RWA skip logic, registrable-domain parsing, and JsonView string-collapse fix all look correct and are backed by targeted unit tests that match the described before/after behavior. I did not find any high-confidence correctness or security issues in the added/changed lines.
…p as a registrable domain, keeping shortenDomain for NFT URLs
| @@ -1,48 +0,0 @@ | |||
| import { useMemo } from 'react' | |||
There was a problem hiding this comment.
Removed as it's dead code that isn't used anywhere.
| @@ -1,273 +0,0 @@ | |||
| import { renderHook } from '@testing-library/react' | |||
There was a problem hiding this comment.
Removed as it's dead code that isn't used anywhere.
| @@ -1,217 +0,0 @@ | |||
| import { | |||
There was a problem hiding this comment.
Removed as it's dead code that isn't used anywhere.
| @@ -1,38 +0,0 @@ | |||
| import { parseIntegerAmount } from '../../../shared/NumberFormattingUtils' | |||
There was a problem hiding this comment.
Removed as it's dead code that isn't used anywhere.
There was a problem hiding this comment.
Solid, well-tested fix for the MPT supply/circ-supply, issuer-name, metadata-truncation, and website-chip issues, with the shared BigInt-based circulating-supply util extracted cleanly from the IOU page. The one thing worth double-checking before merge is that the RWA detection (isRwaAssetClass) is a strict, case-sensitive equality check applied to two different data sources: a curated LOS field for IOU and raw on-chain metadata (written by arbitrary token issuers) for MPT. The tests explicitly lock in strict-only matching, so this looks intentional, but on-chain data isn't guaranteed to be spec-compliant the way a controlled backend field is — worth confirming with the author that this was a deliberate choice for the on-chain case specifically.
There was a problem hiding this comment.
Well-scoped fix for the four reported MPT object-page display bugs (supply/circ-supply, issuer name truncation, metadata clipping, website chip TLD destruction), plus a shared BigInt-based circulating-supply util extracted for both IOU and MPT pages with solid unit test coverage. The diff is clean and most of the changed code (MarketData, GeneralOverview, Metadata, DomainLink, domainUtils, circulatingSupply utils) matches its own tests and the described behavior. One spot worth a second look before merging: a new field in the MPT holders mapper references a bare balance identifier whose scope isn't visible in this diff — worth a quick confirmation it resolves to the intended unscaled BigInt rather than an undefined variable.
High Level Overview of Change
Fixes four reported display issues on the MPToken object page, and replaces the placeholder circulating-supply figure with a real calculation shared with the IOU page.
Supplyis now the on-chainOutstandingAmount;Circ Supplysubtracts holders owning ≥ 20% (skipped for RWA tokens). Fixes the reported "circulating supply > supply".franklintempleton.com) instead of a middle-truncated string that destroyed the TLD; all domain helpers are consolidated indomainUtils.Context of Change
Reported against livenet.xrpl.org/mpt/064E27366D15D1F5614B4D4E3183F835BCD62E7F6FD9FFD8 (Franklin
sgBENJI). Each root cause was confirmed against the liveledger_entry mpt_issuanceresponse rather than inferred.1. Circulating supply > supply. This issuance sets no
MaximumAmount, somaxAmtwasundefinedandMarketDatarenderedBigInt(maxAmt || '0')→ Supply = 0, while Circ Supply showed the real ~28.14. Per spec an unset maximum means the cap is2^63-1, which is meaningless to display.After product review the fix is: Supply =
OutstandingAmount, and Circ Supply = Supply minus holders ≥ 20% — the same rule the IOU page already applied. Large holders are issuer/treasury/whale wallets that are not meaningfully in circulation. The exclusion is skipped for RWA tokens (asset_class === 'rwa'), whose large holders are custodians; stablecoins are an RWA subclass and are covered by the same check.2. Truncated issuer name.
shortenAccount()— a 7…5 address truncator — was applied to the human-readable issuer name, rendering "Franklin Templeton Investments" as "Frankli…ments".3. Truncated metadata. The shared
JsonViewhard-codedcollapseStringsAfterLength={65}, clipping the 122-character URI in the metadata panel.4. Website chip destroyed the TLD.
shortenDomain(url, 12, 7)middle-truncates, producingwww.franklin…hnology. The TLD is the part users rely on to judge whether a link is safe, so website chips now show the registrable domain parsed with a real public-suffix list (tldts) — correctly keepingthing.co.ukrather than collapsing it toco.uk.tldtswas already in the tree as a transitive dependency and is promoted to a direct one. The same treatment is applied to the IOU issuer chip. The NFT URL column keepsshortenDomain— its per-NFT resource URIs need the path to stay visible, so domain-only display would collapse distinct rows. All three helpers (getRegistrableDomain,shortenDomainFromLeft,shortenDomain) now live together inshared/domainUtils.ts; non-HTTP schemes (ipfs://,ar://) fall back to the host/CID token.Shared logic. The ≥20% and RWA rules now live in
Token/shared/utils/circulatingSupply.tsand are used by both token pages. IOU's calculation was promoted out of its component into that module so it can be unit-tested directly.isRwaAssetClassacceptsunknownand strict-compares against'rwa', so untrusted, non-string issuer metadata compares unequal rather than throwing.Dead code.
IOU/hooks/useMarketCalculations.tsandIOU/utils/tokenCalculations.ts(plus their tests) were duplicates reachable only from their own tests — the shipping IOU page had its own copy.Type of Change
Codebase Modernization
All touched and new files are function components / TypeScript. New modules (
shared/domainUtils.ts,Token/shared/utils/circulatingSupply.ts,Token/MPT/utils/circulatingSupply.ts) are TypeScript.Before / After
Market Data box
0.00(noMaximumAmount)28.14(on-chainOutstandingAmount)28.14(> Supply)≤ Supply, excluding ≥20% holdersCirc Supply shows a spinner while holders load, and
--if that request fails — it never silently shows the unadjusted supply as if it were a real circulating figure.Header
Frankli…ments(truncated, in title)www.franklin…hnology(TLD destroyed)franklintempleton.com, full URL on hoverRule summary
asset_classsourceasset_class === 'rwa'asset_class === 'rwa'Stablecoins are an RWA subclass, so this single
asset_class === 'rwa'check covers them on both pages.Test Plan
Automated — all green:
npm run build-ts— no type errorsnpm run lint:ci— ESLint, Stylelint, Prettier (--max-warnings 0)npm run test:ci— 1713 tests pass, coverage above the 70/80 thresholdspre-commit run --all-filesnpm run build— production bundle builds with the new dependencyNew/updated tests:
Token/shared/test/utils/circulatingSupply.test.ts— threshold boundary (exactly 20%), large-holder subtraction,isRwaAssetClass(strict lowercase match + non-string/unknownsafety), andcalculateIouCirculatingSupply(reported supply, supply fallback, RWA skip)Token/MPT/test/utils/circulatingSupply.test.ts— asset-scale handling, RWA skip, negative floor, and two exact-integer regressions: float residue →0, and amounts beyond double precisionshared/test/domainUtils.test.ts— registrable domain (incl.thing.co.uk), non-URL fallback, left-truncation preserving the TLD, andshortenDomainmiddle-truncationMarketData/Header/Metadata/GeneralOverview/DomainLink— Supply vs Circ Supply, spinner and--states, untruncated issuer name and metadata,titletooltipManual:

npm start, open/mpt/064E27366D15D1F5614B4D4E3183F835BCD62E7F6FD9FFD8(see screenshot below) — Supply is the full outstanding amount, Circ Supply is ≤ Supply (cross-check excluded accounts against Holders table rows with % ≥ 20), the chip readsfranklintempleton.comwith the full URL on hover, the issuer name renders in full, and the metadata URI is not clipped. IOU token pages show unchanged supply and market-cap values after the refactor.