Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Register
  • Sign in
  • A Ahad Mobile
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Terraform modules
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • holatech
  • Ahad Mobile
  • Merge requests
  • !155

fix(card,deposit,qr): resolve card limit persistence, pending feedback, wallet reconnect, and QR USD fiat transfer

  • Review changes

  • Download
  • Patches
  • Plain diff
Merged Hung Hoang requested to merge hunghoang/fix/card-limit-wallet-qr into develop Oct 29, 2026
  • Overview 30
  • Commits 6
  • Pipelines 7
  • Changes 25

Overview

Fix Card creation pending feedback, Card 5-card limit badge and add-button disable consistency across app restarts, Add funds wallet reconnect state synchronization, and QR payment USD currency selection with end-to-end fiat transfer support.

Bug Links & Detailed Changes

1. Card Creation Pending Message

  • Task Link: https://hola-tech.sg.larksuite.com/record/CmQgrVrWle0KcQck3p7l0Fd6g7b
  • Problem: When user confirms the card issuance fee (-2 USD), there is no visual feedback or message while card creation is processing in background.
  • Fix: Show immediate info flash message Creating your card... upon tapping confirmation in ApprovedCardView.
  • Affected files: fe/src/components/card-account/approved-card-view.tsx, fe/src/translations/en.json.

2 & 3. Card 5-Card Limit Badge and Add Button Disabled State Consistency

  • Task Links:
    • https://hola-tech.sg.larksuite.com/record/X0YQrSnaJeNavQcsKr2l212fgpc
    • https://hola-tech.sg.larksuite.com/record/DAFErzdP6efiEbcIjowlkrWsg9e
  • Problem: When user reaches the 5-card limit, killing and reopening the app resets the limitReached flag because it was only stored in a local React state variable set during an API error callback.
  • Fix: Evaluate limitReached as limitError || visible.length >= 5 || (summary.data?.cardCount ?? 0) >= 5. This ensures the + button is disabled with reduced opacity and the message "You've reached the limit of 5 cards." remains visible whenever 5 or more cards exist, persisting across app restarts and remounts.
  • Affected files: fe/src/components/card-account/approved-card-view.tsx, fe/src/components/card-account/approved-card-view.test.tsx.

4. Add Funds Wallet Connect Session Synchronization

  • Task Link: https://hola-tech.sg.larksuite.com/record/UprcrVWenetYNTc0tWflvyaegqP
  • Problem: In Add funds (/deposit-wallet-send), if MetaMask / AppKit has an active connection in AppKit's ConnectionsController while wagmi's useAccount() is still in a disconnected state, the screen failed to show the connected wallet and kept prompting "Connect Wallet".
  • Fix:
    • Read account state from AppKit (useAccount from @reown/appkit-react-native) as an authoritative fallback for address and isConnected.
    • Prevent auto-opening connect modal when an active AppKit session exists or while AppKit is restoring a session (useAppKitState().isLoading).
    • Gate the Send action strictly on signer readiness (signerReady = isConnected && !!address), rendering an explicit restoring state when AppKit is active but wagmi is still initializing, preventing orphan PENDING deposit creation.
    • Consistently display connected wallet address and Disconnect control in AppKit-only states via useAppKit().disconnect().
  • Affected files: fe/src/components/deposit/deposit-wallet-send-form.tsx, fe/src/components/deposit/deposit-wallet-send-form.test.tsx.

5. QR Payment Currency Selection: USD Support

  • Task Link: https://hola-tech.sg.larksuite.com/record/LkbjrLYa9ecif0cP4XFlwk1JgWb
  • Problem: When scanning a recipient QR code with USD amount and currency, the payment screen only displayed USDC and USDT selection buttons, preventing the user from transferring with USD.
  • Fix:
    • Made selectable currencies kind-aware in fe/src/app/payment.tsx: recipient QRs allow ['USD', 'USDC', 'USDT'], while on-chain address QRs strictly restrict to ['USDC', 'USDT'] (preventing withdrawal routing failures).
    • Routed direct USD recipient sends through the passcode-confirmed fiat transfer rail POST /transactions/transfer (useTransactionsControllerTransfer) with paymentMethod: 'fiat' instead of the crypto /fireblocks/internal-transfer endpoint (which only accepts USDC/USDT).
    • Added passcode pre-flight and PasscodeSheet invocation in ConfirmSendSheet for USD transfers.
    • Guarded group chat transfers against unsupported USD batch transfers.
    • Sourced USD balance from useFiatBalances() and rendered UsdIcon on send confirmation screen.
  • Affected files: fe/src/app/payment.tsx, fe/src/app/send/confirm.tsx, fe/src/app/send/index.tsx, fe/src/components/send/confirm-send-sheet.tsx, fe/src/components/send/confirm-send-sheet.test.tsx, fe/src/components/payment/payment-screen.test.tsx, fe/src/components/send/qr-recipient.test.tsx.

Verification

  • Unit & Integration Tests:
    • confirm-send-sheet.test.tsx (4/4 passed)
    • approved-card-view.test.tsx (27/27 passed)
    • deposit-wallet-send-form.test.tsx (36/36 passed)
    • payment-screen.test.tsx (35/35 passed)
    • Full Jest suite: 1647 passed across 155 test suites (0 failed).
  • TypeScript: pnpm type-check (0 errors).
  • ESLint: 0 errors on modified files.
  • Maestro CLI End-to-End: Verified on iOS simulator with local mock server:
    • Scanned QR code with USD currency -> Selected USD -> Navigated to Send -> Verified Balance: 2,500.00 USD -> Confirmed -> Typed passcode 1357 -> Verified completed transfer screen -> Mock backend recorded exact fiat transfer payload.
    • Scanned Address QR -> Verified Use USD is absent, only USDC and USDT offered.
    • Tapped Card + icon -> Verified Creating your card... toast appeared immediately.
    • Switched mock to 5 cards -> Relaunched app -> Navigated to Card tab -> Verified "You've reached the limit of 5 cards." persists on app launch with + disabled.

Review follow-up

Addressed all 10 review threads in c6cfca87 and 03c18969:

  • Blocked self-transfer on both FE and BE.
  • Rounded USD down to two decimals and rejected zero-after-rounding.
  • Added duplicate-submit ref guard and durable idempotency with concurrent replay.
  • Added code-aware passcode errors (401/409/429 and non-passcode 401).
  • Replaced the unsafe DTO cast with a typed payload.
  • Used paymentMethod: fiat for USD fee estimation.
  • Bounded AppKit restore to 10 seconds with Connect fallback, preserved submitting UI, and restricted fallback to eip155.
  • Reset card-limit state when fresh card count drops below five.

Additional verification

  • Frontend: 156 suites, 1664 tests passed; type-check and changed-file ESLint pass.
  • Backend targeted transfer suites: 64 tests passed; transfer service 9/9; backend production build and changed-file ESLint pass.
  • Maestro: USD 10.555 -> 10.55, fiat fee payload, idempotency key, self-transfer rejection, address QR has no USD, card creation toast, card limit at five, and add button re-enabled after count drops.
  • Full backend suite has unrelated pre-existing failures in lending/treasury configuration. Repo-wide be:lint also reports pre-existing errors outside the changed files; changed backend files are lint-clean.
Edited Oct 30, 2026 by Hung Hoang
Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: hunghoang/fix/card-limit-wallet-qr