feat: show received amount for warp transfers with different scales#313
feat: show received amount for warp transfers with different scales#313
Conversation
- Add destAmount to WarpRouteDetails, computed when origin/dest scales differ - Show "Received amount" row in transfer details card with comma formatting - Update message list tooltip to show amount conversion (e.g. "1 VRA → 10 VRA") using formatAmountCompact on both sides - Tooltip now appears when amounts differ, not just when token symbols differ
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis pull request adds destination amount calculation and display to warp route messages. The Changes
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/features/messages/MessageTable.tsx (1)
261-261: Long inline template literal — consider extracting the tooltip string.This one-liner packs origin amount, arrow, destination amount, and two symbols into a single template and blows well past the 100-char line width. Pulling it into a local
const tooltipContent = ...(or a tiny helper) would make the conditional branch easier to scan and keep Prettier from producing a wrapped blob.♻️ Suggested extraction
- <div - className={styles.iconText} - data-tooltip-id="root-tooltip" - data-tooltip-content={`${formatAmountCompact(warpRouteDetails.amount)} ${warpRouteDetails.originToken.symbol}${showWarpTooltip ? ` → ${formatAmountCompact(warpRouteDetails.destAmount ?? warpRouteDetails.amount)} ${warpRouteDetails.destinationToken.symbol}` : ''}`} - > + <div + className={styles.iconText} + data-tooltip-id="root-tooltip" + data-tooltip-content={tooltipContent} + >With something like this computed alongside
showWarpTooltip:const originPart = `${formatAmountCompact(warpRouteDetails.amount)} ${warpRouteDetails.originToken.symbol}`; const destPart = showWarpTooltip ? ` → ${formatAmountCompact(warpRouteDetails.destAmount ?? warpRouteDetails.amount)} ${warpRouteDetails.destinationToken.symbol}` : ''; const tooltipContent = `${originPart}${destPart}`;As per coding guidelines: "Use single quotes, trailing commas, and maintain 100 character line width".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/features/messages/MessageTable.tsx` at line 261, Extract the long inline template used in the data-tooltip-content prop into a local const (e.g. tooltipContent) to improve readability and keep lines under 100 chars: compute originPart using formatAmountCompact(warpRouteDetails.amount) and warpRouteDetails.originToken.symbol, compute destPart conditionally based on showWarpTooltip using formatAmountCompact(warpRouteDetails.destAmount ?? warpRouteDetails.amount) and warpRouteDetails.destinationToken.symbol, then set tooltipContent to originPart + destPart and use that in the data-tooltip-content attribute; follow project style (single quotes, trailing commas) when adding the new const near the component render.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/features/messages/MessageTable.tsx`:
- Line 261: Extract the long inline template used in the data-tooltip-content
prop into a local const (e.g. tooltipContent) to improve readability and keep
lines under 100 chars: compute originPart using
formatAmountCompact(warpRouteDetails.amount) and
warpRouteDetails.originToken.symbol, compute destPart conditionally based on
showWarpTooltip using formatAmountCompact(warpRouteDetails.destAmount ??
warpRouteDetails.amount) and warpRouteDetails.destinationToken.symbol, then set
tooltipContent to originPart + destPart and use that in the data-tooltip-content
attribute; follow project style (single quotes, trailing commas) when adding the
new const near the component render.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 98be2a35-74ca-4425-87fe-8042cf8e243e
📒 Files selected for processing (4)
src/features/messages/MessageTable.tsxsrc/features/messages/cards/WarpTransferDetailsCard.tsxsrc/features/messages/utils.tssrc/types.ts
|
@claude review |
|
Claude finished @paulbalaji's task in 3m 9s —— View job Claude review complete
Posted a consolidated review (link) with 5 inline comments. Summary:
Plus a UX note in the body about same-symbol / different-scale routes showing origin amount in the cell but destination amount in the tooltip — worth confirming intent. Nothing blocking. |
There was a problem hiding this comment.
Review Summary
Clean, minimal implementation. The destination amount is computed only when scales diverge, reused via existing helpers (getEffectiveDecimals, getWarpRouteAmountParts), and surfaced in both the list tooltip and the details card. Nice incidental cleanup to shorthand property syntax in parseWarpRouteMessageDetails.
A few things to consider:
- The scale-divergence guard in
utils.tsis redundant withscalesEqualand obscures intent — see inline comment. - The new
destAmountpath inparseWarpRouteMessageDetailshas no test coverage. CLAUDE.md calls for unit tests on util changes, and the scale-difference branch is the whole point of this PR. A lightweight addition covering the VRA-style case would pin the math down. - The long template literal on
MessageTable.tsx:261is worth extracting for readability (also flagged by CodeRabbit — still unresolved). - UX note: when scales differ but token symbol/logo are identical (e.g. same-token scale-down), the row cell shows a single icon and a single amount (
formatAmountCompact(originAmount)), while the tooltip revealsX VRA → Y VRA. That's the stated intent, but some users will read the cell as the received amount. Worth confirming the cell should show the origin amount rather than the destination amount (or indicating the scale mismatch visually).
Nothing blocking — mostly polish and test coverage.
| if ( | ||
| (originToken.scale || destinationToken.scale) && | ||
| !scalesEqual(originToken.scale, destinationToken.scale) | ||
| ) { |
There was a problem hiding this comment.
The (originToken.scale || destinationToken.scale) guard is redundant: if both scales are undefined, scalesEqual(undefined, undefined) returns true (both normalize to 1:1), so !scalesEqual(...) already short-circuits. Suggest dropping the guard:
if (!scalesEqual(originToken.scale, destinationToken.scale)) {If you're guarding against a specific scalesEqual edge case (e.g. undefined vs undefined semantics in the SDK), add a comment explaining why — as written the combined condition reads like belt-and-braces and invites confusion next time someone touches it.
| decimals: destDecimals, | ||
| scale: destinationToken.scale, | ||
| }); | ||
| destAmount = fromWei(destAmountParts.amount.toString(), destAmountParts.decimals); |
There was a problem hiding this comment.
No test coverage for the new destAmount branch. Given the core promise of the PR is "correct destination amount across scales," a small unit test for parseWarpRouteMessageDetails covering the VRA-style case (origin scale=10, dest scale=1, same wireDecimals) would guard against regressions in the scale math. Per CLAUDE.md: "Unit tests for utils."
| className={styles.iconText} | ||
| data-tooltip-id="root-tooltip" | ||
| data-tooltip-content={`${warpRouteDetails.amount} ${warpRouteDetails.originToken.symbol}${isDifferentWarpToken ? ` → ${warpRouteDetails.destinationToken.symbol}` : ''}`} | ||
| data-tooltip-content={`${formatAmountCompact(warpRouteDetails.amount)} ${warpRouteDetails.originToken.symbol}${showWarpTooltip ? ` → ${formatAmountCompact(warpRouteDetails.destAmount ?? warpRouteDetails.amount)} ${warpRouteDetails.destinationToken.symbol}` : ''}`} |
There was a problem hiding this comment.
Already raised by CodeRabbit — still unresolved. The inline template is ~240 chars, well past the 100-char guideline in CLAUDE.md. Extracting into a tooltipContent const alongside showWarpTooltip would make this block legible:
const originPart = `${formatAmountCompact(warpRouteDetails.amount)} ${warpRouteDetails.originToken.symbol}`;
const destPart = showWarpTooltip
? ` → ${formatAmountCompact(warpRouteDetails.destAmount ?? warpRouteDetails.amount)} ${warpRouteDetails.destinationToken.symbol}`
: '';
const tooltipContent = `${originPart}${destPart}`;| className={styles.iconText} | ||
| data-tooltip-id="root-tooltip" | ||
| data-tooltip-content={`${warpRouteDetails.amount} ${warpRouteDetails.originToken.symbol}${isDifferentWarpToken ? ` → ${warpRouteDetails.destinationToken.symbol}` : ''}`} | ||
| data-tooltip-content={`${formatAmountCompact(warpRouteDetails.amount)} ${warpRouteDetails.originToken.symbol}${showWarpTooltip ? ` → ${formatAmountCompact(warpRouteDetails.destAmount ?? warpRouteDetails.amount)} ${warpRouteDetails.destinationToken.symbol}` : ''}`} |
There was a problem hiding this comment.
formatAmountCompact will truncate precision (e.g. <0.0001, 1.23K) on both sides of the arrow. Since the tooltip is the "reveal on hover" view, users might reasonably expect full precision here. Consider using formatAmountWithCommas for the tooltip content and reserving the compact format for the inline cell text. Minor — flag only, open to other takes.
| blurValue={blur} | ||
| showCopy | ||
| /> | ||
| {destAmount && ( |
There was a problem hiding this comment.
Nit: {destAmount && ...} — destAmount is typed string | null. Technically safe today (fromWei won't return ''), but {destAmount !== null && ...} reads more intentfully and won't bite if the type ever broadens. Take it or leave it.
Summary
Shows the destination received amount in the explorer when origin and destination tokens have different scales (e.g., VRA BSC scale=10 → ETH scale=1, or BSC USDT 18-dec scale-down).
Changes
Transfer details card
formatAmountWithCommasMessage list tooltip
1 VRA → 10 VRAformatAmountCompactfor both sides (K/M/B notation)Computation
destAmountcomputed inparseWarpRouteMessageDetailsusing existinggetWarpRouteAmountPartswith dest token's scale andgetEffectiveDecimalswith swapped token orderscalesEqual(originToken.scale, destinationToken.scale)is falsenullfor same-scale routes (no UI change)Files changed
src/types.ts— addeddestAmount: string | nulltoWarpRouteDetailssrc/features/messages/utils.ts— compute destAmount inparseWarpRouteMessageDetailssrc/features/messages/cards/WarpTransferDetailsCard.tsx— received amount row + comma formattingsrc/features/messages/MessageTable.tsx— tooltip with formatted amountsRelated
scalesEqual)🤖 Generated with Claude Code