MPT Object page improvement - #1339
Open
kuan121 wants to merge 1 commit into
Open
Conversation
| // Circulating supply = outstanding amount minus large (>= 20%) holders, except | ||
| // for RWA tokens where those holders are custodians/treasuries (no exclusion). | ||
| const isRwa = isRwaAssetClass( | ||
| mptokenIssuance?.parsedMPTMetadata?.asset_class as string | undefined, |
There was a problem hiding this comment.
Unsafe cast of free-form issuer JSON. Add runtime type guard before calling .trim():
const isRwa = typeof mptokenIssuance?.parsedMPTMetadata?.asset_class === 'string'
? isRwaAssetClass(mptokenIssuance.parsedMPTMetadata.asset_class as string)
: false
Suggested change
| mptokenIssuance?.parsedMPTMetadata?.asset_class as string | undefined, | |
| typeof mptokenIssuance?.parsedMPTMetadata?.asset_class === 'string' | |
| ? mptokenIssuance.parsedMPTMetadata.asset_class | |
| : undefined, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.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 — analogous to the IOU stablecoin rule.No new data source was required: the page already fetches the full holder set on-chain via
mpt_holders, with each holder'spercentcomputed againstOutstandingAmount.The subtraction runs in BigInt on unscaled amounts. A
Number-based version left float residue — for a fully-held token it produced values like2.3283064365386963e-10, whichparseAmountrenders as< 0.0001instead of0.00(~1/3 of fully-concentrated cases when fuzzed). BigInt also avoids silent precision loss for amounts near UInt64 max (~9.2e18), well beyond exact double precision.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 the chip now shows 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.Shared logic. The ≥20% / RWA / stablecoin 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.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_subclass === 'stablecoin'ORasset_class === 'rwa'asset_class === 'rwa'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— 1709 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(incl. case/whitespace), andcalculateIouCirculatingSupply(reported supply, supply fallback, stablecoin and RWA skips)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 TLDMarketData/Header/Metadata/GeneralOverview/DomainLink— Supply vs Circ Supply, spinner and--states, untruncated issuer name and metadata,titletooltipManual:
npm start, open/mpt/064E27366D15D1F5614B4D4E3183F835BCD62E7F6FD9FFD8— 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.Future Tasks
MaximumAmountis no longer surfaced. DroppingmaxAmtfromMarketDatafixed theSupply = 0bug, but tokens that do set a cap no longer display it anywhere. Adding a "Max Amount" row (themax_amounti18n key already exists) was deliberately deferred as a separate product decision.asset_class === 'rwa'. FranklinsgBENJIcurrently tags"US Treasuries", so it is not yet recognized as RWA; the issuer would need to update its metadata (supported by Dynamic MPT). We deliberately avoid an XRPL Meta token call here..gitignoredoes not cover.env.devnet/.env.mainnet/.env.testnet(only.envand.env.*.local). Worth adding.env.*with a!.env.examplenegation to prevent accidental commits. Out of scope for this PR.