Sitelet https://github.com/Quantus-Network/quantus-apps/pull/689
Skip to content

Offer swap on Android under its own flag, enableSwapAndroid - #689

Open
n13 wants to merge 15 commits into
mainfrom
n13/swap-android-flag
Open

n13 wants to merge 15 commits into
mainfrom
n13/swap-android-flag

Conversation

@n13

@n13 n13 commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Android gets its own swap flag so the two stores can be switched apart.

  • New remote flag enableSwapAndroid, default true. Nothing needs to be added to quersi unless Android swap should be turned off.
  • RemoteConfigModel.swapAvailable reads enableSwapAndroid on Android and enableSwap elsewhere, via defaultTargetPlatform. The per-launch location verdict (geoNearAllowed) still gates both.
  • Every swap entry point already goes through swapAvailable (home card, swap screen, review, progress), so no screen changes.
  • With quersi serving enableSwap: false today, Android shows swap and iOS does not.

Tests: Android offers swap on its own flag and ignores enableSwap; iOS keeps enableSwap and ignores the Android flag; cache round trip. Flutter's test binding reports Android, so the existing iOS-semantics test is pinned to iOS and the home gating test sets both flags together. melos run analyze clean; config, swap-flow and home-gating suites pass (47).

QTC listing recognised by its live chain code

1Click lists QTC as nep141:qtc.omft.near under chain code qtc (the app expected quantus), so the app never saw the listing and the swap screen reported swaps unavailable unless swapQuantusAssetId named the asset in quersi. SwapToken.quantusNetwork is now QTC, matching the live listing. The NEAR-native QTC listing (1cs_v1:near:nep141:qtc.omft.near, chain near) is neither the Quantus side nor a token to swap with, and a fixture for it proves it stays out. No quersi change needed.

Also in this PR

  • Debug-only --dart-define=SWAP_IGNORE_GEO=true skips the location verdict in swapAvailable (guarded by kDebugMode), for trying swap from anywhere on an emulator.
  • BottomSheetContainer.show lifts the sheet above the on-screen keyboard and scrolls it within the remaining height; the swap address sheet was unusable on Android without this. Test covers keyboard plus system inset.
  • The swap screen opens as a purchase of QTC (other token on top, QTC below); the arrows still turn it around. Flow tests flip explicitly where they swap out.
  • Every quote request carries confidentiality: basic and the echoed value is verified with the other request fields. QTC is quoted only as a Confidential Intents swap: the same request with public answers "No liquidity available" (verified live, correlation ids 64e46644-147b-46df-b94b-61d46db3e90d basic vs efa0ac49-28ff-410e-9cba-c4d9d305960a public).
  • The deposit screen names the token and network to deposit in two rows at the top ("Token: USDC", "Network: Ethereum"); the footer hint alone was too easy to miss.
  • One short form for addresses everywhere: AddressFormattingService.formatAddress takes no options any more (six characters at each end around seven dots). Activity rows, detail sheets, swap screens and hashes share it; AddressCheckphrase shortens with a plain shorten flag and takes a checkphraseColor. Detail-sheet address rows show the short form with the checkphrase in the text colour (new AddressDetailRow). The address input field keeps its own longer form.

Android reads enableSwapAndroid (default on) where iOS reads enableSwap, so
the two stores can be switched apart. The location verdict still gates both.
@n13 n13 added the bot-review Request automated review from review-bot label Oct 7, 2026

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewer model: GPT-6.1 Sol

Verdict (advisory): Approve

Reviewed head 2ac41f349de31bd5e315b2a7b1c8bf2bea10c1d0 against base eddbd77bdeb3e4ccd47fa0c35b2980243fded520. No blocking findings.

The Android flag is independent of the existing flag, defaults as described, and is preserved through parsing, cache serialization, equality, and copyWith. All swap entry points use swapAvailable, so the platform-specific flag applies consistently while retaining the per-launch location gate. The tests cover Android/iOS flag selection, cache round trips, home visibility, and location revocation during confirmation.

Validation:

  • dart run melos bootstrap: passed.
  • dart run melos exec --concurrency=1 --scope=resonance_network_wallet -- "flutter test --no-pub --reporter expanded test/unit/remote_config_notifier_test.dart test/screens/swap_flow_test.dart test/screens/home_intent_gating_test.dart": all 47 tests passed.
  • dart run melos exec -- dart format lib test --line-length=120 --output=none --set-exit-if-changed: passed; 809 files, zero changes.
  • git diff --check for the reviewed base/head diff: passed.
  • dart run melos run analyze: cold-wallet and miner passed; terminated at the required 10-second limit before SDK/mobile analysis completed. The focused tests compiled the changed model and affected mobile code.

GitHub's Analyze job was still running at posting; both dependency-cooldown checks passed.

@n13 n13 removed the bot-review Request automated review from review-bot label Oct 7, 2026
@n13 n13 added the bot-review Request automated review from review-bot label Oct 7, 2026
1Click lists QTC under chain code qtc, not quantus, so the app never saw the
listing and reported swaps unavailable unless swapQuantusAssetId named it.
The NEAR-native QTC listing on chain near stays out of both sides of a swap.
@n13 n13 added bot-review Request automated review from review-bot and removed bot-review Request automated review from review-bot labels Oct 7, 2026
@n13 n13 added bot-review Request automated review from review-bot and removed bot-review Request automated review from review-bot labels Oct 7, 2026
A sheet with a text field, such as the swap refund address, was covered by
the on-screen keyboard. The sheet now sits above the keyboard, scrolls within
what is left, and stops padding for the system inset the keyboard covers.
@n13 n13 added bot-review Request automated review from review-bot and removed bot-review Request automated review from review-bot labels Oct 7, 2026
The form now starts with the other token on top and QTC below; the arrows
still turn it around to swap out of QTC.
@n13 n13 added bot-review Request automated review from review-bot and removed bot-review Request automated review from review-bot labels Oct 7, 2026
QTC is quoted only as a Confidential Intents swap: a public quote answers
"No liquidity available" whatever the market holds. Every quote now carries
confidentiality: basic, and the echoed value is verified like the other
request fields.
@n13 n13 added bot-review Request automated review from review-bot and removed bot-review Request automated review from review-bot labels Oct 7, 2026

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewer model: GPT-6.1 Sol

Verdict (advisory): Approve

Reviewed head 3ff51784b09a49f439413e09851fdad594e726cd against base eddbd77bdeb3e4ccd47fa0c35b2980243fded520 in a detached worktree. No blocking findings.

The Android/iOS flags remain independent across parsing, caching, equality and copyWith; all swap entry points retain the location gate, and SWAP_IGNORE_GEO is guarded by kDebugMode. QTC discovery matches the live qtc listing and excludes the NEAR-side QTC representation. The default purchase direction preserves the refund/recipient mapping and explicit direction changes. Shared bottom sheets account for the keyboard while preserving dismissal and system-inset behavior.

The basic request matches the official confidential-swap integration. Live dry quotes succeeded in both directions using the partner key supplied by the current app remote config: USDC → QTC (24a38e7f-5831-4c1b-a2e6-f3970da28178) and QTC → USDC (86f61dcf-594c-4948-9dac-510c9df3f18b). The app's verifier accepted both signatures, and every sent request field matched the response. These previews sent no funds. Confidential quotes require authentication: the same request without the configured key returned HTTP 401, so that key must remain provisioned.

Validation:

  • dart run melos bootstrap: passed after creating the missing generated SourcePackages directories and empty test .env in the temporary worktree.
  • SDK: flutter test --no-pub --reporter expanded test/services/swap_service_test.dart test/services/one_click_service_test.dart test/ui/bottom_sheet_container_test.dart through pinned Melos: 57 tests passed.
  • Mobile: flutter test --no-pub --reporter expanded test/unit/remote_config_notifier_test.dart test/screens/swap_flow_test.dart test/screens/home_intent_gating_test.dart through pinned Melos: 50 tests passed.
  • Workspace formatting: 809 files, zero changes. Base/head git diff --check: passed.
  • dart run melos run analyze: cold-wallet and miner passed; terminated at the required 10-second limit before SDK/mobile analysis completed. A temporary launcher supplied the nested melos command.
  • GitHub CI and all dependency-cooldown checks passed at this head.

@n13 n13 removed the bot-review Request automated review from review-bot label Oct 7, 2026

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not reviewing again — no new commit or comment since the last review.

@n13 n13 added the bot-review Request automated review from review-bot label Oct 7, 2026
Every address row of the activity and multisig proposal sheets showed a
shortened address and, at best, a checkphrase. They now show the whole
address with its checkphrase underneath, through AddressDetailRow built on
the shared AddressCheckphrase.
@n13 n13 added bot-review Request automated review from review-bot and removed bot-review Request automated review from review-bot labels Oct 7, 2026
… colour

AddressCheckphrase can now shorten the address it shows (prefix, postfix,
ellipsis) and take a checkphrase colour. Detail-sheet rows show 6...6 with
the checkphrase in the text colour, which reads better than lilac there; the
checkphrase makes the short form safe.
@n13 n13 added bot-review Request automated review from review-bot and removed bot-review Request automated review from review-bot labels Oct 7, 2026
AddressFormattingService.formatAddress takes no options any more: six
characters at each end around seven dots, the style the account-ready screen
already used. Activity rows, detail sheets, swap screens and hashes all share
it, and AddressCheckphrase shortens with a plain flag. The address input
field keeps its own longer form.
@n13 n13 added bot-review Request automated review from review-bot and removed bot-review Request automated review from review-bot labels Oct 7, 2026

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewer model: GPT-6.1 Sol

Verdict (advisory): Approve

Reviewed the complete diff at head 9aab7d86dce7281c49c956aa2a84f33d1cb4b5cb against base eddbd77bdeb3e4ccd47fa0c35b2980243fded520 in a detached worktree, including the final address-format revert. No blocking findings.

The Android/iOS flags remain independent through parsing, caching, equality and location revocation. The debug location override is guarded by kDebugMode. QTC discovery matches the current /v0/tokens listing (nep141:qtc.omft.near, chain qtc, 12 decimals) and excludes its NEAR representation. The purchase default preserves refund/recipient mapping and direction changes. Confidential quotes retain signature validation and now require the echoed confidentiality field to match the request; basic follows the official NEAR integration.

The shared sheet accounts for the keyboard and system inset while preserving dismissal. Deposit token/network labels use the quote's origin token. Detail-row checkphrases are computed from the full address before display shortening, and the final head preserves the existing configurable formatting API.

Validation at the reviewed head:

  • dart run melos bootstrap: passed; generated SourcePackages directories and an empty test .env were created only in the temporary worktree.
  • SDK tests through pinned Melos: flutter test --no-pub --reporter expanded test/services/swap_service_test.dart test/services/one_click_service_test.dart test/ui/bottom_sheet_container_test.dart test/ui/address_checkphrase_test.dart test/ui/detail_summary_row_test.dart — 67 passed.
  • Mobile tests through pinned Melos: flutter test --no-pub --reporter expanded test/unit/remote_config_notifier_test.dart test/screens/swap_flow_test.dart test/screens/home_intent_gating_test.dart test/unit/address_input_field_test.dart test/unit/transaction_detail_sheet_test.dart test/unit/shared_address_action_sheet_test.dart — 61 passed.
  • dart run melos exec -- dart format lib test --line-length=120 --output=none --set-exit-if-changed: 809 files, zero changes.
  • Base/head git diff --check: passed.
  • dart run melos run analyze: cold-wallet and miner passed; stopped at the required 10-second limit during SDK analysis, before mobile analysis. Analysis remains incomplete.

GitHub's Analyze job is still running; the current dependency-cooldown check passed. No device or funded end-to-end swap was tested.

@n13 n13 removed the bot-review Request automated review from review-bot label Oct 7, 2026
n13 added 2 commits October 8, 2026 07:20
Minor fixes for the address format
@n13 n13 added the bot-review Request automated review from review-bot label Oct 7, 2026

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewer model: GPT-6.1 Sol

Verdict (advisory): Request changes

Reviewed the complete diff at head f285bd35c97e8817118eae4fb9c5ae2801d03e95 against base eddbd77bdeb3e4ccd47fa0c35b2980243fded520 in a detached worktree. Two reproducible validation failures need fixing:

  1. [P2] Align the transaction-detail test with shortened addresses — mobile-app/test/unit/transaction_detail_sheet_test.dart:67. This new assertion expects the full counterparty address, but AddressDetailRow now passes shortenAddress: true, which renders six characters at each end around seven dots. The received-transfer test fails with “Found 0 widgets” both in the affected mobile suites and when run alone. Assert the intended shortened display and retain the checkphrase assertion, or restore the full display if that is intended. CI runs this test, so fixing formatting alone will still leave the mobile suite failing.

  2. [P2] Format the changed address widget to unblock CI — quantus_sdk/lib/src/ui/components/address_checkphrase.dart:37. The new conditional expression fails the repository's required 120-column formatter check. The local check reports this as the only file requiring formatting; the current GitHub CI run fails at Check Formatting for exactly this file. Apply the standard formatter.

No other blocking findings in the platform flags, location gate, QTC discovery, confidential-quote validation, purchase direction, or keyboard handling. The live token listing confirms QTC on chain qtc with 12 decimals and a separate NEAR representation. confidentiality: basic matches the official NEAR integration.

Validation at this head:

  • dart run melos bootstrap: passed.
  • SDK: flutter test --no-pub --reporter expanded through pinned Melos for swap_service, one_click_service, bottom_sheet_container, address_checkphrase and detail_summary_row: 66 passed.
  • Mobile: the same command for remote_config_notifier, swap_flow, home_intent_gating, address_input_field, transaction_detail_sheet, shared_address_action_sheet and multisig_undecodable_proposal: 68 passed, 1 failed. The failing test also reproduces alone with --plain-name 'a received transfer is formatted as an inflow'.
  • dart run melos exec -- dart format lib test --line-length=120 --output=none --set-exit-if-changed: failed; 809 files checked, only the widget above requires formatting.
  • Base/head git diff --check: passed.
  • dart run melos run analyze: cold-wallet and miner passed; terminated at the required 10-second limit during SDK analysis, before mobile analysis. Analysis remains incomplete.

Both dependency-cooldown checks passed. No device or funded end-to-end swap was tested.

@n13 n13 removed the bot-review Request automated review from review-bot label Oct 7, 2026
AddressDetailRow shortens its address now, so the received-transfer test
looks for the short form; formatAddress already defaults to six at each end.
@n13 n13 added the bot-review Request automated review from review-bot label Oct 7, 2026

@n13 n13 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewer model: GPT-6.1 Sol

Verdict (advisory): Approve

Reviewed the complete diff at head 34f20ab5e7ccf585845152af58f9c86fa41c5d98 against base eddbd77bdeb3e4ccd47fa0c35b2980243fded520 in a detached worktree. No blocking findings. Both issues from the previous review are resolved: the received-transfer test asserts the shortened address while retaining the full-address checkphrase assertion, and the address widget passes formatting.

The Android/iOS flags remain independent through parsing, caching, equality and copyWith; swap entry points retain the per-launch location gate. The debug override is guarded by kDebugMode. QTC discovery matches the current 1Click token listing (nep141:qtc.omft.near, chain qtc, 12 decimals) and excludes its NEAR representation. The purchase default preserves refund/recipient mapping and direction changes. confidentiality: basic follows the official NEAR integration, retains signature validation and requires the echoed confidentiality to match. Keyboard handling and deposit token/network labels are covered by widget tests; address checkphrases are derived from full addresses before display shortening.

Validation at this head:

  • dart run melos bootstrap: passed. Generated SourcePackages directories and an empty test .env were created only in the temporary worktree.
  • SDK tests through pinned Melos: flutter test --no-pub --reporter expanded for swap_service, one_click_service, bottom_sheet_container, address_checkphrase and detail_summary_row — 66 passed.
  • Mobile tests through pinned Melos: the same command for remote_config_notifier, swap_flow, home_intent_gating, address_input_field, transaction_detail_sheet, shared_address_action_sheet and multisig_undecodable_proposal — 69 passed.
  • dart run melos exec -- dart format lib test --line-length=120 --output=none --set-exit-if-changed: passed; 809 files, zero changes. Base/head git diff --check: passed.
  • dart run melos run analyze: cold-wallet and miner passed; terminated at the required 10-second limit during SDK analysis, before mobile analysis. Local analysis remains incomplete.

At the latest CI check, GitHub's formatting and analysis steps passed, the mobile test step was running, and both dependency-cooldown checks passed. No physical-device or funded end-to-end swap was tested.

@n13 n13 removed the bot-review Request automated review from review-bot label Oct 7, 2026
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.

1 participant