Skip to content

feat(#175): validate fiat code before submitting an order - #304

Open
codaMW wants to merge 1 commit into
MostroP2P:mainfrom
codaMW:feat/175-validate-fiat-code
Open

feat(#175): validate fiat code before submitting an order#304
codaMW wants to merge 1 commit into
MostroP2P:mainfrom
codaMW:feat/175-validate-fiat-code

Conversation

@codaMW

@codaMW codaMW commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Problem

create_order took the selected fiat code straight into the outgoing request with no submit-time validation. The currency picker constrains the happy path, but if the saved default fiat code becomes stale or is tampered with, the request could still go out with an unsupported code and come back as a daemon-side CantDo instead of being rejected locally.

Fix

A local preflight in create_order, reusing settings::validate_fiat_code (made pub(crate)):

  • orders.rs create_order validates the fiat code before publishing. This replaces the previous empty-only check and covers empty and malformed codes alike, failing with the stable InvalidFiatCode marker so every caller inherits the check (per @grunch's note, same pattern as BondRequired).
  • settings.rs validate_fiat_code is now pub(crate); added validate_fiat_code_marker_cases covering valid codes plus empty / short / long / lowercase / mixed / symbol / non-ASCII, all rejected with the marker.
  • daemon_errors.dart maps InvalidFiatCode to a localized message through the existing localizedDaemonError helper.
  • l10n invalidFiatCode in all five locales.

Testing

cargo test (256 pass) + cargo clippy clean; flutter analyze clean. Verified on device (Nokia C31): a normal order with a valid currency still creates successfully. The bad-code path is a defense-in-depth guard against a tampered/stale saved default it can't be reached through the picker in normal use, so it's covered by the Rust test rather than a device repro.

Scope question for @grunch

This validates the fiat code's format (ISO 4217 shape), which catches the stale/tampered cases the issue describes and emits the InvalidFiatCode marker as you suggested. Full membership validation (rejecting valid-format-but-unsupported codes like "XYZ") would mean porting the bundled fiat list into Rust, creating a second source of truth to keep in sync with the Dart asset. Happy to add that here or as a follow-up which would you prefer?

Closes #175.

Summary by CodeRabbit

  • Bug Fixes

    • Order creation now detects unsupported or incorrectly formatted fiat currencies before submission.
    • Clear localized guidance is shown when the selected currency must be changed.
  • Localization

    • Added messages for invalid fiat currencies in English, German, Spanish, French, and Italian.

create_order took the selected fiat code straight into the outgoing request
with no submit-time check. The currency picker constrains the happy path, but a
stale or tampered saved default could still send an unsupported code that only
came back as a daemon CantDo. This adds a local preflight so the request is
rejected on-device with a clear, actionable message instead.

- orders.rs: create_order now validates the fiat code before publishing,
  reusing settings::validate_fiat_code (made pub(crate)). This replaces the
  previous empty-only check and covers empty and malformed codes alike, failing
  with the stable InvalidFiatCode marker so every caller inherits the check
  (per grunch's note, same pattern as BondRequired).
- settings.rs: validate_fiat_code is pub(crate); added
  validate_fiat_code_marker_cases covering valid codes plus empty/short/long/
  lowercase/mixed/symbol/non-ASCII, all rejected with the InvalidFiatCode marker.
- daemon_errors.dart: map InvalidFiatCode to a localized message via the
  existing localizedDaemonError helper.
- l10n: add invalidFiatCode in all five locales.

Scope: format-level (ISO 4217 shape) validation, which catches the stale/
tampered cases the issue describes. Membership validation against the bundled
fiat list would require porting that list into Rust — raised as a question on
the PR.

Closes MostroP2P#175.
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 02e28990-4de1-40f1-a0c4-91336ed81000

📥 Commits

Reviewing files that changed from the base of the PR and between 7625b24 and 7bad547.

📒 Files selected for processing (8)
  • lib/core/daemon_errors.dart
  • lib/l10n/app_de.arb
  • lib/l10n/app_en.arb
  • lib/l10n/app_es.arb
  • lib/l10n/app_fr.arb
  • lib/l10n/app_it.arb
  • rust/src/api/orders.rs
  • rust/src/api/settings.rs

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.


Walkthrough

The order API now validates trimmed fiat codes before publication. The validator is reused across the crate and has expanded unit coverage. Invalid-code errors now map to dedicated English, German, Spanish, French, and Italian messages.

Changes

Fiat code validation

Layer / File(s) Summary
Fiat code validation contract
rust/src/api/settings.rs
validate_fiat_code is available within the crate. Tests cover valid ISO-shaped codes and invalid formats.
Order creation preflight
rust/src/api/orders.rs
create_order trims and validates fiat_code before publishing the order.
Localized invalid-code error
lib/core/daemon_errors.dart, lib/l10n/app_*.arb
InvalidFiatCode maps to a dedicated localized message in English, German, Spanish, French, and Italian.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: 🟡 Moderate · up to 7bad5

This PR adds submit-time fiat-format validation and a localized rejection path for malformed saved or tampered currency codes. The change is localized, but merge readiness remains moderate until the required binding, Flutter test, and localization regeneration checks are completed.

Suggested reviewers: grunch, catrya, andreadiazcorreia

Poem

A rabbit checked the coins with care,
And trimmed each code from hidden wear.
Bad fiat stayed outside the door,
While clear translations said what for.
Order paths now hop secure.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR validates format before publishing, but it does not reject valid-format codes that are unsupported or stale. Validate fiat-code membership against the supported currency set, or clarify that the create-order contract requires format validation only.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes submit-time fiat-code validation before order submission.
Out of Scope Changes check ✅ Passed The validation, tests, error mapping, and translations directly support the linked issue and its local rejection flow.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codaMW

codaMW commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate fiat code before submitting market-price orders

1 participant