Skip to content

feat(decimal): decimal precision on send/swap, and amount input display fix - #894

Open
raul-oliveira wants to merge 1 commit into
masterfrom
feat/amount-format-two-line-input
Open

feat(decimal): decimal precision on send/swap, and amount input display fix#894
raul-oliveira wants to merge 1 commit into
masterfrom
feat/amount-format-two-line-input

Conversation

@raul-oliveira

@raul-oliveira raul-oliveira commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Builds on #891 (amount format foundation) and extends the decimal-places fix to the send and token-swap screens. Aligns the amount input and amount displays with the Amounts Update Figma.

Acceptance Criteria

  • The amount input accepts up to 8 decimal places, independent of the selected token's precision — the value is still scaled to the token's decimal_places when the transaction is built.
  • Long amounts shrink to stay on one line and, once they reach the minimum size, wrap across up to 3 lines instead of shrinking indefinitely.
  • On the Send screen the token selector drops below the amount when it wraps, with no font-size jump at the transition.
  • Read-only balances (transaction details, home available and locked) shrink and wrap the same way — previously they stayed at full size and only wrapped on iOS.
  • The send flow (amount input and confirmation) and token swap (swap, review and token picker) render amounts using the network's decimal_places instead of the wallet-lib default of 2, extending the feat(decimal): add wallet-wide amount format preference #891 decimal fix to these screens.

Security Checklist

  • Make sure you do not include new dependencies in the project unless strictly necessary and do not include dev-dependencies as production ones. More dependencies increase the possibility of one of them being hijacked and affecting us.

Screenshots

Token swap
image
image
image

Send transaction

Decimal.Precision.Fix.PR.894.mov
image image

Summary by CodeRabbit

New Features

  • Added responsive amount displays that shrink or wrap values to fit available space.
  • Amount inputs now support controlled font sizing and optional single-line layouts.
  • Amount formatting consistently respects server-provided decimal precision across transfers, balances, fees, and swaps.

Bug Fixes

  • Improved amount layouts to prevent overflow across balance, token creation, and send screens.
  • Pasted line breaks are handled more reliably, with support for up to 8 decimal places.
  • External styling now applies correctly to token containers.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@raul-oliveira, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 8 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fb93cf32-1ba6-4f95-b72f-638c2ea193c4

📥 Commits

Reviewing files that changed from the base of the PR and between 5c2acaa and c50dbb0.

📒 Files selected for processing (13)
  • src/components/AmountDisplay.js
  • src/components/AmountTextInput.js
  • src/components/TokenBox.js
  • src/components/TxDetailsModal.js
  • src/constants.js
  • src/screens/CreateTokenAmount.js
  • src/screens/MainScreen.js
  • src/screens/SendAmountInput.js
  • src/screens/SendConfirmScreen.js
  • src/screens/TokenSwap.js
  • src/screens/TokenSwapReview.js
  • src/screens/TokenSwapTokenList.js
  • src/utils.js
📝 Walkthrough

Walkthrough

Amount rendering now uses shared font fitting and wrapping. Inputs support controlled sizing, single-line mode, newline removal, and capped decimal parsing. Balance, send, confirmation, and swap screens use shared sizing and server-provided decimal precision.

Changes

Amount rendering and input flow

Layer / File(s) Summary
Shared sizing and input contracts
src/constants.js, src/utils.js, src/components/AmountTextInput.js
Adds shared font-fitting utilities and decimal limits. Updates input parsing, controlled sizing, wrapping, and line-height behavior.
Read-only amount display integration
src/components/AmountDisplay.js, src/components/TxDetailsModal.js, src/screens/MainScreen.js
Adds AmountDisplay and uses it for fitted balance rendering with wrapping.
Send amount layout wiring
src/screens/SendAmountInput.js, src/components/TokenBox.js, src/screens/CreateTokenAmount.js
Measures the send amount area, switches between row and stacked layouts, passes computed sizing, and forwards related styles.
Server decimal precision propagation
src/screens/SendConfirmScreen.js, src/screens/TokenSwap.js, src/screens/TokenSwapReview.js, src/screens/TokenSwapTokenList.js
Passes server-provided decimal precision through send, fee, quote, conversion, slippage, and token-selection formatting paths.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SendAmountInput
  participant computeAmountFontFit
  participant AmountTextInput
  participant TokenBox
  SendAmountInput->>SendAmountInput: measure amount area width
  SendAmountInput->>computeAmountFontFit: calculate font size and wrapping
  computeAmountFontFit-->>SendAmountInput: return fontSize and wraps
  SendAmountInput->>AmountTextInput: pass fontSize and singleLine
  SendAmountInput->>TokenBox: apply row or stacked layout
Loading

Possibly related PRs

Suggested reviewers: pedroferreira1, tuliomir

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: decimal precision in send and swap flows, plus the amount input display fix.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/amount-format-two-line-input

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@raul-oliveira raul-oliveira self-assigned this Jul 14, 2026
@raul-oliveira raul-oliveira moved this from Todo to In Progress (WIP) in Hathor Network Jul 14, 2026
@raul-oliveira
raul-oliveira force-pushed the feat/amount-format-settings branch 2 times, most recently from 1db45fa to 172ba28 Compare July 14, 2026 20:28
@raul-oliveira
raul-oliveira force-pushed the feat/amount-format-two-line-input branch 2 times, most recently from aa14225 to 3ec25fa Compare July 27, 2026 16:06
@raul-oliveira
raul-oliveira force-pushed the feat/amount-format-two-line-input branch from 3ec25fa to 09eca73 Compare July 29, 2026 14:30
@raul-oliveira
raul-oliveira changed the base branch from feat/amount-format-settings to master July 30, 2026 14:42
@raul-oliveira
raul-oliveira force-pushed the feat/amount-format-two-line-input branch from 09eca73 to 73fe507 Compare July 30, 2026 15:00
@raul-oliveira raul-oliveira changed the title feat(decimal): 18-decimal amount entry and shrink-then-wrap amount display feat(decimal): decimal precision on send/swap, and amount input display fix Jul 30, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/AmountTextInput.js`:
- Around line 135-176: Update the props destructuring in AmountTextInput so
component-only fields value, decimalPlaces, allowOnlyInteger, and onAmountUpdate
are removed from restProps before the native TextInput spread. Keep the
sanitized local text state as the effective value by ensuring restProps cannot
override the explicit value={text}, while preserving forwarding of legitimate
native TextInput props.

In `@src/screens/TokenSwap.js`:
- Around line 170-172: Update the effect containing the quote amount assignments
to depend on decimalPlaces as well as quote, so renderValue recomputes both
input and output strings when precision changes after a quote arrives. Preserve
the existing numeric amount state updates and avoid changing quote-fetching
behavior.
- Line 426: The conversion-rate rendering in renderConversionRate must preserve
exact arithmetic for BigInt quote amounts instead of converting them to Number
or multiplying by a numeric oneToken. Update renderConversionRate and both call
sites in src/screens/TokenSwap.js (426-426) and src/screens/TokenSwapReview.js
(293-293) to calculate and format the rate using BigInt-compatible decimal
scaling, preserving correctness for values above Number.MAX_SAFE_INTEGER.

In `@src/screens/TokenSwapReview.js`:
- Line 320: Use connected server metadata for all native-token fee labels:
update TokenSwapReview.js:320 to use serverInfo.native_token.symbol instead of
the library default, and ensure SendConfirmScreen.js:277 and
SendConfirmScreen.js:362 derive nativeSymbol from
serverInfo.native_token.symbol.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f98c9fbc-8d52-4bb4-90b5-1a2f5816899e

📥 Commits

Reviewing files that changed from the base of the PR and between b9eb962 and 73fe507.

📒 Files selected for processing (13)
  • src/components/AmountDisplay.js
  • src/components/AmountTextInput.js
  • src/components/TokenBox.js
  • src/components/TxDetailsModal.js
  • src/constants.js
  • src/screens/CreateTokenAmount.js
  • src/screens/MainScreen.js
  • src/screens/SendAmountInput.js
  • src/screens/SendConfirmScreen.js
  • src/screens/TokenSwap.js
  • src/screens/TokenSwapReview.js
  • src/screens/TokenSwapTokenList.js
  • src/utils.js

Comment thread src/components/AmountTextInput.js
Comment thread src/screens/TokenSwap.js
Comment thread src/screens/TokenSwap.js
Comment thread src/screens/TokenSwapReview.js Outdated
@raul-oliveira raul-oliveira moved this from In Progress (WIP) to In Progress (Done) in Hathor Network Jul 30, 2026
@raul-oliveira raul-oliveira moved this from In Progress (Done) to In Progress (WIP) in Hathor Network Jul 30, 2026
@raul-oliveira
raul-oliveira requested a review from tuliomir July 30, 2026 22:20
@raul-oliveira
raul-oliveira force-pushed the feat/amount-format-two-line-input branch from 73fe507 to 5c2acaa Compare July 31, 2026 04:21

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/constants.js`:
- Around line 162-164: Update MAX_DECIMAL_PLACES in the constants module from 8
to 18 so getAmountParsed accepts the required fractional precision. Add boundary
tests covering amounts with 8, 9, and 18 fractional digits, verifying each is
accepted.

In `@src/screens/SendConfirmScreen.js`:
- Line 277: Update both fee display lines in SendConfirmScreen to use the
connected server metadata symbol from serverInfo.native_token.symbol instead of
the default hathorLib nativeSymbol, while keeping the existing fee value and
formatting unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f8195970-70e8-4653-a5dc-6b01d5ea9847

📥 Commits

Reviewing files that changed from the base of the PR and between 73fe507 and 5c2acaa.

📒 Files selected for processing (13)
  • src/components/AmountDisplay.js
  • src/components/AmountTextInput.js
  • src/components/TokenBox.js
  • src/components/TxDetailsModal.js
  • src/constants.js
  • src/screens/CreateTokenAmount.js
  • src/screens/MainScreen.js
  • src/screens/SendAmountInput.js
  • src/screens/SendConfirmScreen.js
  • src/screens/TokenSwap.js
  • src/screens/TokenSwapReview.js
  • src/screens/TokenSwapTokenList.js
  • src/utils.js
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/screens/CreateTokenAmount.js
  • src/utils.js
  • src/screens/TokenSwapTokenList.js
  • src/screens/TokenSwapReview.js
  • src/components/AmountDisplay.js
  • src/components/TokenBox.js
  • src/screens/SendAmountInput.js
  • src/screens/MainScreen.js
  • src/components/AmountTextInput.js
  • src/components/TxDetailsModal.js

Comment thread src/constants.js
Comment thread src/screens/SendConfirmScreen.js
Comment thread src/components/AmountTextInput.js Outdated
Comment thread src/components/AmountTextInput.js Outdated
Comment thread src/screens/MainScreen.js Outdated
Comment thread src/screens/SendAmountInput.js Outdated
Comment thread src/screens/SendAmountInput.js Outdated
Comment thread src/screens/SendAmountInput.js Outdated
Comment thread src/utils.js Outdated
Comment thread src/utils.js Outdated
@raul-oliveira
raul-oliveira force-pushed the feat/amount-format-two-line-input branch from 5c2acaa to e1cb665 Compare July 31, 2026 04:32
…splay

- Amount input accepts up to 18 decimal places, independent of the token's
  precision; the value is still scaled to the token's decimal_places when the
  transaction is built.
- Long amounts shrink to stay on one line and, at the minimum size, wrap across
  up to 3 lines instead of shrinking indefinitely (AmountDisplay + the
  computeAmountFontFit ladder).
- Read-only balances (transaction details, home available/locked) and the
  transaction-row amount shrink/wrap the same way.
- Thread the network's decimal_places through the send and token-swap amount
  displays so quotes and confirmations render with the correct precision.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G9asQ9EmwUmCpv34aM7v2v
@raul-oliveira
raul-oliveira force-pushed the feat/amount-format-two-line-input branch from e1cb665 to c50dbb0 Compare July 31, 2026 05:13
@raul-oliveira raul-oliveira moved this from In Progress (WIP) to In Progress (Done) in Hathor Network Jul 31, 2026
parsedText = getAmountParsed(parsedText, decimalPlaces);
// Accept up to MAX_DECIMAL_PLACES typed decimals regardless of the token's
// precision; the value below is still scaled to the token's decimalPlaces.
parsedText = getAmountParsed(parsedText, MAX_DECIMAL_PLACES);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue(blocking): typed decimals beyond the token's precision are silently truncated

getAmountParsed(parsedText, MAX_DECIMAL_PLACES) keeps 8 typed decimals, but line 97 scales with the token's decimalPlaces and getIntegerAmount slices the excess away.

On a 2-decimal network, typing 1.12345678 displays that string and sends 112n (1.12); 0.00000001 yields 0n, which isValid accepts, so the field shows a value while Continue stays disabled with no error.

Previously the text was clamped, so what you saw was what you sent. Consider getAmountParsed(parsedText, decimalPlaces ?? MAX_DECIMAL_PLACES), which keeps the undefined-serverInfo fallback without discarding entered precision.

Comment thread src/utils.js
* @param {number} [minFontSize] Floor font size below which it wraps instead of shrinking
* @return {{ fontSize: number, wraps: boolean }}
*/
export const computeAmountFontFit = (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue(non-blocking): new pure util computeAmountFontFit ships with no unit tests

Three-branch ladder (base / shrink / floor + wrap) with a boundary at minFontSize, and its wraps flag drives the Send screen's row→column switch. Flipping a >= to > at either boundary silently changes when the token box drops below the amount.

The function is pure and takes plain numbers — a small input/output table next to __tests__/utils/amountFormat.test.js pins the ladder cheaply. Worth noting the suite is a local gate only: .github/workflows/main.yml has no npm test step, so nothing here runs in CI.

Comment thread src/screens/TokenSwap.js
setOutputTokenAmountStr(renderValue(quote.amount_out, false, decimalPlaces));
setOutputTokenAmount(quote.amount_out);
}
}, [quote]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: effect reads decimalPlaces but doesn't list it as a dependency

If serverInfo ever resolved after a quote, the two amount strings would keep the precision they were formatted with. In practice serverInfo lands during wallet start, well before this screen mounts, so it's latent rather than live — but adding it costs nothing.

@tuliomir tuliomir moved this from In Progress (Done) to In Review (WIP) in Hathor Network Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Review (WIP)

Development

Successfully merging this pull request may close these issues.

2 participants