Skip to content

feat(settings): Crypto + Notifications hubs, wallet send/receive & multi-network balances#3027

Merged
senamakel merged 9 commits into
tinyhumansai:mainfrom
senamakel:feat/settings-crypto-hub
May 30, 2026
Merged

feat(settings): Crypto + Notifications hubs, wallet send/receive & multi-network balances#3027
senamakel merged 9 commits into
tinyhumansai:mainfrom
senamakel:feat/settings-crypto-hub

Conversation

@senamakel
Copy link
Copy Markdown
Member

@senamakel senamakel commented May 30, 2026

Summary

  • Settings → Crypto hub: consolidates the scattered Recovery Phrase and Wallet Balances pages under one section page, mirroring the Agents hub pattern.
  • Settings → Advanced → Notifications hub: gathers the Alerts inbox and Notification preferences/routing under one section page and removes the two top-level home-menu entries.
  • Wallet Balances no longer gated on setup: when no recovery phrase exists, shows a non-blocking hint + placeholder rows instead of a blocking error.
  • Wallet send/receive: every balance row gains Send (prepare → review → execute, local signing) and Receive (address QR + copy) actions.
  • Per-network EVM balances: the EVM account now renders as separate Ethereum, Base, and BNB Chain rows.
  • i18n added across all 14 locales for every new string.

Problem

Crypto-related settings were scattered (recovery phrase and wallet balances lived under Account), Alerts/Notifications duplicated top-level menu space, the Wallet Balances panel hard-errored before a wallet was set up, there was no way to send/receive funds from the UI, and the single EVM balance row hid Base/BSC holdings.

Solution

  • New SettingsSectionPage-based hubs routed at /settings/crypto and /settings/notifications-hub, registered in the Settings home menu / Developer Options, with breadcrumbs reparented accordingly. SettingsSectionItem gained an optional onClick so a hub item can link to a top-level route (the Alerts inbox).
  • WalletBalancesPanel checks wallet_status first; unconfigured wallets get an amber hint + a "Set up recovery phrase" CTA and placeholder rows that mirror the configured layout.
  • Core balances() fans the EVM account into one native-balance row per displayed network (EVM_BALANCE_NETWORKS = Ethereum/Base/BNB Chain), read live; BTC/Solana/Tron unchanged.
  • New ReceiveModal (QR + copy + same-network warning) and SendCryptoModal (drives the existing wallet.prepare_transferwallet.execute_prepared primitives; native asset only). Signing stays local in the core.
  • walletDisplay helper for EVM network labels/badges and lossless BigInt amount conversion.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — Vitest (panel, modal, walletDisplay, nav/home) + a Rust balances fan-out test cover the changed lines.
  • N/A: behaviour-only / UI-reorg change; no coverage-matrix feature rows affected.
  • N/A: no matrix feature IDs affected by this change.
  • No new external network dependencies introduced (wallet RPC primitives already existed; tests mock the wallet API).
  • N/A: does not touch release-cut smoke surfaces.
  • N/A: no linked issue.

Impact

  • Desktop (the shipped target): Settings navigation reorganised; Wallet Balances gains send/receive and per-network EVM rows. Send signs locally in-core and broadcasts to the configured/default RPC — no private keys cross the wire.
  • No migrations. Frontend-only except the additive balances() fan-out in the Rust core (existing transfer RPCs reused). Verified live in the desktop app (Crypto/Notifications hubs, the setup hint, send & receive modals, and the ETH/Base/BNB Chain rows).

Related

  • Closes:
  • Follow-up PR(s)/TODOs: token (ERC-20/SPL/TRC20) sends in the Send modal; surface remaining EVM networks (Arbitrum/Optimism/Polygon) in EVM_BALANCE_NETWORKS.

AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/settings-crypto-hub
  • Commit SHA: c7de843

Validation Run

  • pnpm --filter openhuman-app format:check
  • pnpm typecheck
  • Focused tests: pnpm debug unit wallet (30/30), useSettingsNavigation, SettingsHome; pnpm debug rust balances_fans_evm
  • Rust fmt/check (if changed): cargo fmt + cargo check --lib
  • Tauri fmt/check (if changed): N/A — no Tauri shell changes

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: reorganise crypto/notification settings into hubs; add wallet send/receive; show per-network EVM balances.
  • User-visible effect: new Settings → Crypto and Advanced → Notifications pages; Send/Receive on each balance row; separate Ethereum/Base/BNB Chain balance rows.

Parity Contract

  • Legacy behavior preserved: recovery-phrase / wallet-balances / notifications panels unchanged and still reachable at their existing routes; deep links (#routing) intact.
  • Guard/fallback/dispatch parity checks: unconfigured wallet now shows a hint instead of erroring; configured behaviour unchanged.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: N/A
  • Resolution (closed/superseded/updated): N/A

Summary by CodeRabbit

Release Notes

  • New Features

    • Added dedicated Crypto settings section for managing recovery phrases and viewing wallet balances
    • Introduced Send and Receive modals for cryptocurrency transfers
    • Enhanced wallet balances display with separate rows for each blockchain network (Ethereum, Base, BSC)
  • Refactor

    • Improved settings navigation structure with better organization of wallet and notification features

Review Change Stack

senamakel added 6 commits May 30, 2026 00:24
Recovery Phrase and Wallet Balances were scattered under the Account
section. Mirror the Agents settings hub pattern and gather both under a
dedicated Settings > Crypto section page.

- Add a Crypto section page (cryptoSettingsItems) routed at /settings/crypto
- Move recovery-phrase + wallet-balances out of accountSettingsItems
- Register the Crypto hub on the Settings home menu
- Reparent recovery-phrase/wallet-balances breadcrumbs under Crypto
- Add settings.cryptoSection.* i18n keys across all 14 locales
- Update about_app capability how_to strings to the new nav path
- Extend useSettingsNavigation + SettingsHome tests for crypto
The Settings home menu carried two adjacent notification-related entries:
'Alerts' (the /notifications inbox) and 'Notifications' (the preferences
+ routing panel). Mirror the Crypto hub: gather both under a single
'Notifications' section page placed under Advanced (Developer Options),
and drop the two top-level entries from the home menu.

- Add a Notifications section hub routed at /settings/notifications-hub
  with two items: Alerts (-> /notifications inbox) and Notification
  settings (-> existing NotificationsTabbedPanel)
- SettingsSectionItem gains optional onClick (route is now optional) so a
  hub item can link to a top-level route outside /settings
- Register the hub on the Advanced (Developer Options) page
- Remove Alerts + Notifications from the Settings home menu
- Reparent the notifications panel breadcrumb under
  Settings > Developer Options > Notifications; hub sits under Advanced
- Add settings.notificationsHub.* i18n keys across all 14 locales
- Update useSettingsNavigation + SettingsHome tests
Wallet Balances previously hard-errored (red 'unable to load' + Retry)
whenever no recovery phrase was configured, because the core errors
wallet_balances until a wallet exists. That made the panel look broken
before setup.

Now the panel checks wallet_status first: when the wallet isn't
configured it drops the blocking error in favour of a non-blocking amber
hint ('set up your recovery phrase…') with a 'Set up recovery phrase'
CTA, and still renders the wallet layout as muted placeholder rows for
all four supported chains (EVM/BTC/SOL/TRX). Genuine fetch failures
while configured keep the error/retry path.

- WalletBalancesPanel checks fetchWalletStatus before fetchWalletBalances
- Add ChainPlaceholderRow + setupHint/setupCta/notSetUp i18n (14 locales)
- SettingsSectionItem already supports onClick; CTA routes to recovery-phrase
- Update WalletBalancesPanel tests (status mock + not-configured cases)
Wallet Balances now shows the EVM account on Ethereum, Base, and BNB
Chain as separate rows, and each balance row gains Send / Receive
actions.

Core:
- balances() fans the EVM account into one native-balance row per
  displayed network (EVM_BALANCE_NETWORKS = Ethereum/Base/BNB Chain),
  reading each live; BTC/Solana/Tron unchanged. Extract balance_row /
  native_asset helpers. Update the balances schema + add a unit test.

Frontend:
- walletApi: EvmNetwork/PreparedTransaction/ExecutionResult types +
  prepareTransfer / executePrepared; BalanceInfo.evmNetwork typed.
- walletDisplay: EVM network labels/badges, balanceKey, and lossless
  toSmallestUnit/fromSmallestUnit (BigInt) helpers.
- ReceiveModal: address QR + copy + same-network warning.
- SendCryptoModal: prepare -> review (simulated fee) -> execute, with
  local-signing copy and explorer link. Native asset; tokens are a
  follow-up.
- WalletBalancesPanel: per-network rows + Send/Receive; placeholders now
  mirror the configured layout (6 rows).
- i18n: walletBalances.send/receive + walletReceive.*/walletSend.* across
  all 14 locales.

Tests: Rust balances fan-out; walletDisplay conversions; SendCryptoModal
flow; panel send/receive modal-open.
@senamakel senamakel requested a review from a team May 30, 2026 15:26
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 30, 2026

Warning

Review limit reached

@senamakel, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 34 minutes and 48 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

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.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9f9fdb76-7dbe-4142-8385-f0adc2c302ce

📥 Commits

Reviewing files that changed from the base of the PR and between e27a8cd and 926dab1.

📒 Files selected for processing (15)
  • app/src/components/settings/panels/wallet/ReceiveModal.tsx
  • app/src/components/settings/panels/wallet/SendCryptoModal.tsx
  • app/src/features/wallet/walletDisplay.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
📝 Walkthrough

Walkthrough

This PR adds interactive send/receive crypto functionality to the wallet UI while reorganizing Settings navigation to include a new "Crypto" section with recovery phrase and wallet balances, and moving notifications to a hub under Developer Options. Changes span frontend settings wiring, wallet API contracts, interactive modal components, Rust-side balance fanning across EVM networks, and comprehensive internationalization updates.

Changes

Crypto wallet send/receive and settings reorganization

Layer / File(s) Summary
Settings navigation routing and breadcrumbs
app/src/components/settings/hooks/useSettingsNavigation.ts, app/src/components/settings/hooks/__tests__/useSettingsNavigation.test.tsx
SettingsRoute extended with crypto and notifications-hub routes. URL resolution updated with ordered path checks to distinguish /settings/notifications-hub from /settings/notifications. Breadcrumb generation treats crypto as a top-level section and nests recovery-phrase/wallet-balances underneath it, while placing notifications-hub under Developer Options.
Settings menu items and page structure
app/src/pages/Settings.tsx, app/src/components/settings/SettingsHome.tsx, app/src/components/settings/SettingsSectionPage.tsx
SettingsSectionItem interface made route optional and added optional onClick callback for flexible navigation wiring. Settings.tsx reorganized to remove "recovery-phrase" from accountSettingsItems and add it to new cryptoSettingsItems array; new notificationsHubItems array created with Alerts entry navigating to /notifications. SettingsHome menu refactored to remove standalone alerts/notifications entries and add crypto item that uses navigateToSettings('crypto').
Developer Options panel with Notifications Hub menu
app/src/components/settings/panels/DeveloperOptionsPanel.tsx
New notifications-hub entry added to developerItems menu with i18n keys settings.notificationsHub.title/menuDesc, routed to notifications-hub settings path.
Settings navigation and UI tests
app/test/playwright/specs/settings-account-preferences.spec.ts
Account settings route test updated to verify specific navigation items (team, privacy, migration) and assert recovery phrase absent on Account route. New Crypto route test added asserting Crypto heading and presence of recovery phrase and wallet balances navigation entries.
Wallet display and formatting utilities
app/src/features/wallet/walletDisplay.ts, app/src/features/wallet/__tests__/walletDisplay.test.ts
New utility module exports balanceNetworkLabel(), balanceBadge(), and balanceKey() for deriving human-readable labels and stable React keys from balance info. toSmallestUnit() and fromSmallestUnit() converters handle decimal precision normalization for cross-chain amounts. Comprehensive test coverage validates labeling, keying, and amount conversions.
Wallet API types and transfer RPC wrappers
app/src/services/walletApi.ts
BalanceInfo.evmNetwork typed as EvmNetwork union instead of generic string. New transfer domain model adds PreparedTransaction, ExecutionResult, PrepareTransferParams interfaces. prepareTransfer(params) RPC wrapper calls openhuman.wallet_prepare_transfer to obtain quote with fees; executePrepared(quoteId) calls openhuman.wallet_execute_prepared to broadcast transaction.
Rust-side EVM balance expansion per network
src/openhuman/wallet/execution.rs, src/openhuman/wallet/execution_tests.rs
balances() rewritten to fan out EVM native-asset rows across Ethereum, Base, and BSC networks per account via new EVM_BALANCE_NETWORKS constant. Introduces helper functions to construct BalanceInfo rows and resolve per-network asset metadata. Non-EVM chains continue emitting single rows. New integration test verifies 3 EVM rows per account with correct per-network symbols and provider status.
WalletBalancesPanel with interactive Send/Receive
app/src/components/settings/panels/WalletBalancesPanel.tsx
Panel expanded from read-only list to interactive component. New BalanceRow and ChainPlaceholderRow sub-components with Send/Receive action buttons. Panel state tracks tri-state wallet configuration and active modal target (sendTarget/receiveTarget). loadBalances() calls fetchWalletStatus() first; if wallet unconfigured, sets flag and renders setup hint + placeholder rows instead of balances. Modal wiring conditionally renders SendCryptoModal (with onSuccess reload) and ReceiveModal (with close handler).
ReceiveModal component for address display
app/src/components/settings/panels/wallet/ReceiveModal.tsx
New component displays receiving address as QR code and copyable text. Derives network label from balance using display helpers. Implements clipboard copy with UI state and timeout reset. Shows chain-specific warning message. Wrapped in ModalShell with localized titles/subtitles.
SendCryptoModal component for multi-step transfer
app/src/components/settings/panels/wallet/SendCryptoModal.tsx
New component implements form → review → sending → done state machine. Form step collects recipient and amount with validation. Review step displays prepared quote with estimated fee from prepareTransfer(). Confirm step calls executePrepared() to broadcast. Done step shows transaction hash and optional explorer link. Back button returns to form; errors display via alerts.
Tests for wallet panels and modals
app/src/components/settings/panels/__tests__/WalletBalancesPanel.test.tsx, app/src/components/settings/panels/wallet/__tests__/SendCryptoModal.test.tsx
WalletBalancesPanel tests extended to mock fetchWalletStatus and verify "wallet not configured" UI path with setup hint and placeholder rows, plus Send/Receive modal opening with appropriate content. SendCryptoModal tests cover end-to-end user flow with amount/recipient entry, prepareTransfer/executePrepared mocking, input validation, and error handling.
Internationalization updates across all languages
app/src/lib/i18n/{ar,bn,de,en,es,fr,hi,id,it,ko,pl,pt,ru,zh-CN}.ts
All i18n files extended with new walletBalances.* and walletSend.*/walletReceive.* keys covering wallet setup messaging, send/receive flows, transaction details, and generic transfer errors. New settings.cryptoSection.* and settings.notificationsHub.* keys added for Settings navigation labels across all supported languages.
Backend catalog and schema documentation
src/openhuman/about_app/catalog_data.rs, src/openhuman/wallet/schemas.rs
Catalog help text updated to reference "Settings > Crypto > Recovery Phrase" and "Settings > Crypto > Wallet Balances" navigation paths. Wallet balances schema documentation clarified to describe EVM fanning behavior across multiple networks and document optional evmNetwork field in balance rows.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • tinyhumansai/openhuman#2686: Modifies the same WalletBalancesPanel component to surface multi-chain balances that this PR builds interactive send/receive modals on top of.
  • tinyhumansai/openhuman#2519: Extends wallet balance handling with per-EVM-network (evm_network) support in wallet/execution.rs, directly related to the PR's EVM balance fanning changes.
  • tinyhumansai/openhuman#2250: Refactors DeveloperOptionsPanel menu item data structure (titleKey/descriptionKey + t() rendering) that may interact with this PR's added notifications-hub menu entry.

Suggested labels

feature, rust-core, working

Suggested reviewers

  • graycyrus

Poem

🐰 Hops through settings with crypto flair,
Send and receive, a modal pair,
EVM fans to three bright chains,
While notifications find their lanes!
Labels translated, the world aligned,
One wallet feature, fully refined!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main features introduced: Crypto and Notifications hubs for settings reorganization, plus wallet send/receive and multi-network balance support.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% 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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

senamakel added 2 commits May 30, 2026 08:39
The Settings reorg moved Recovery Phrase + Wallet Balances out of the
Account section into the new Settings > Crypto hub. Update the account
section spec to assert the remaining account items (team/privacy/
migration) and add a crypto-section spec covering recovery phrase +
wallet balances.
balances() now returns one row per displayed EVM network (Ethereum,
Base, BNB Chain) plus BTC/Solana/Tron, so the json_rpc_e2e wallet
surface round-trip expects 6 rows (3 EVM) instead of 4.
@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. working A PR that is being worked on by the team. labels May 30, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 12

🧹 Nitpick comments (2)
app/src/components/settings/SettingsSectionPage.tsx (1)

56-56: 💤 Low value

Consider explicit handling for items without onClick or route.

The current logic item.onClick ?? (() => item.route && navigateToSettings(item.route)) will always assign a function to onClick, even when both item.onClick and item.route are undefined. This causes SettingsMenuItem to render a button (per context snippet) that does nothing when clicked.

While no current items appear to lack both properties, an explicit check would be clearer and more defensive:

onClick={item.onClick ?? (item.route ? () => navigateToSettings(item.route) : undefined)}

This way, items without navigation render as non-interactive divs (per SettingsMenuItem contract).

🤖 Prompt for 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.

In `@app/src/components/settings/SettingsSectionPage.tsx` at line 56, Replace the
current fallback that always supplies a no-op function for the onClick prop in
SettingsSectionPage (the expression using item.onClick and navigateToSettings)
with an explicit conditional: if item.onClick exists use it; else if item.route
exists supply a handler that calls navigateToSettings(item.route); otherwise
pass undefined so SettingsMenuItem renders non-interactive. Update the onClick
assignment in the SettingsSectionPage component to reference item.onClick,
item.route and navigateToSettings accordingly so items without either property
are not rendered as clickable.
tests/json_rpc_e2e.rs (1)

4007-4013: ⚡ Quick win

Assert the exact EVM networks, not just the EVM row count.

The new fan-out contract is network-specific (Ethereum/Base/BNB). count() == 3 can still pass with the wrong networks. Please pin evmNetwork values too.

🔧 Suggested test hardening
     assert_eq!(
         rows.iter()
             .filter(|r| r.get("chain").and_then(Value::as_str) == Some("evm"))
             .count(),
         3,
         "expected 3 EVM network rows: {result}"
     );
+    let evm_networks: Vec<&str> = rows
+        .iter()
+        .filter(|r| r.get("chain").and_then(Value::as_str) == Some("evm"))
+        .filter_map(|r| r.get("evmNetwork").and_then(Value::as_str))
+        .collect();
+    for expected in ["ethereum_mainnet", "base_mainnet", "bsc_mainnet"] {
+        assert!(
+            evm_networks.iter().any(|n| *n == expected),
+            "expected balances row for {expected}, got {evm_networks:?}"
+        );
+    }
🤖 Prompt for 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.

In `@tests/json_rpc_e2e.rs` around lines 4007 - 4013, The test currently only
asserts the EVM row count; modify the assertion to verify the actual evm
networks returned. In the block using rows.iter().filter(|r|
r.get("chain").and_then(Value::as_str) == Some("evm")), collect the evm network
identifiers via r.get("evmNetwork").and_then(Value::as_str) (or the correct key
used in the rows), build a set or sorted Vec of those strings, and assert it
equals the expected set/Vec (e.g., ["ethereum","base","bnb"]) instead of only
asserting count() == 3; update the assertion message to include the actual
collected networks for easier debugging.
🤖 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 `@app/src/components/settings/hooks/useSettingsNavigation.ts`:
- Around line 201-209: The breadcrumb labels (e.g., cryptoCrumb and
notificationsHubCrumb) are hardcoded and must use useT() for i18n; import useT
from app/src/lib/i18n/I18nContext, call const t = useT() in
useSettingsNavigation, replace label: 'Crypto' and label: 'Notifications' with
label: t('settings.breadcrumbs.crypto') and label:
t('settings.breadcrumbs.notifications') (and similarly update accountCrumb,
featuresCrumb, aiCrumb, teamCrumb, developerCrumb, agentsCrumb), then add the
corresponding keys to app/src/lib/i18n/en.ts and other locale files.

In `@app/src/components/settings/panels/wallet/ReceiveModal.tsx`:
- Around line 23-34: The timeout stored in copyTimerRef (set in handleCopy)
isn’t cleared on unmount; add a useEffect with an empty dependency array that
returns a cleanup function which clears copyTimerRef.current (and sets it to
null) to avoid calling setCopied on an unmounted component; reference
copyTimerRef, handleCopy, setCopied and ensure the cleanup uses clearTimeout
when copyTimerRef.current is not null.

In `@app/src/components/settings/panels/WalletBalancesPanel.tsx`:
- Around line 9-15: The current import block mixes type-only symbols with
runtime functions; change BalanceInfo, EvmNetwork, and WalletChain to type-only
imports using "import type" while keeping fetchWalletBalances and
fetchWalletStatus as regular imports so runtime behavior is unchanged—update the
import statement in WalletBalancesPanel.tsx to import type BalanceInfo,
EvmNetwork, WalletChain and import fetchWalletBalances, fetchWalletStatus
normally.

In `@app/src/features/wallet/walletDisplay.ts`:
- Around line 64-76: toSmallestUnit currently throws hard-coded English
messages; change it to throw well-defined, machine-readable error identifiers
(e.g., a typed Error subclass or an error.code string like
AmountValidationError.INVALID_FORMAT and AmountValidationError.EXCESS_DECIMALS)
instead of human text so callers (e.g., SendCryptoModal) can call useT() and map
those error codes to localized messages; update toSmallestUnit to throw these
error objects (preserve the same validation logic in toSmallestUnit) and update
the calling component to catch the errors and translate via useT() using the
decimals param for the EXCESS_DECIMALS case.

In `@app/src/lib/i18n/ar.ts`:
- Line 4100: Replace the English placeholder for the i18n key
settings.cryptoSection.title with a proper Arabic translation (e.g., "التشفير")
in the Arabic locale file; locate the entry with the symbol
settings.cryptoSection.title and update its value from "Crypto" to the correct
Arabic text so the Arabic locale contains a real translation for that key.

In `@app/src/lib/i18n/bn.ts`:
- Line 4173: The Bengali locale entry for settings.cryptoSection.title is still
in English; update the value in app/src/lib/i18n/bn.ts for the key
"settings.cryptoSection.title" to a proper Bengali translation (e.g.,
"ক্রিপ্টো") so the non-English locale mirrors the key added/changed in en.ts and
adheres to the i18n guideline.

In `@app/src/lib/i18n/hi.ts`:
- Line 4181: The key 'settings.cryptoSection.title' in the Hindi locale file
(hi.ts) is still in English; replace the English value 'Crypto' with an
appropriate Hindi translation (e.g., 'क्रिप्टो') so the locale is fully
localized; update the string for the settings.cryptoSection.title entry and
ensure formatting/quoting matches surrounding entries in hi.ts.

In `@app/src/lib/i18n/pl.ts`:
- Line 4245: Replace the English value for the i18n key
'settings.cryptoSection.title' in the Polish locale so it contains a proper
Polish translation (e.g., "Krypto") instead of "Crypto"; update the string in
pl.ts where the 'settings.cryptoSection.title' entry is defined to a correct
Polish word and save the file.

In `@app/src/lib/i18n/pt.ts`:
- Line 4244: Update the Portuguese translation for the key
'settings.cryptoSection.title' in the pt locale: replace the English value
'Crypto' with the Portuguese translation (e.g., 'Cripto') so the key reads
'settings.cryptoSection.title': 'Cripto'; ensure the change is applied in the
pt.ts i18n file where that key is defined.
- Around line 4249-4250: Update the Portuguese translation for the key
'settings.notificationsHub.description' to use the idiomatic verb "gerencie"
instead of "gira"; locate the string value for
'settings.notificationsHub.description' and replace "gira as preferências de
notificação e o encaminhamento" with "gerencie as preferências de notificação e
o encaminhamento" so the description reads naturally.

In `@app/src/lib/i18n/ru.ts`:
- Line 4214: The key settings.cryptoSection.title is still English in the
Russian locale; update the ru translation for settings.cryptoSection.title to a
proper Russian string (e.g., "Криптовалюта" or another accurate localized term)
in the ru.ts file, ensuring the value replaces 'Crypto' and matches neighboring
key style and punctuation.

In `@app/src/lib/i18n/zh-CN.ts`:
- Line 3972: The i18n key 'settings.cryptoSection.title' is left in English;
update its value in zh-CN.ts to a proper Chinese translation (for example '加密货币'
or '加密') so the entry reads 'settings.cryptoSection.title': '加密货币'; ensure the
key exists and uses a correct Chinese string in zh-CN.ts to match the en.ts
addition.

---

Nitpick comments:
In `@app/src/components/settings/SettingsSectionPage.tsx`:
- Line 56: Replace the current fallback that always supplies a no-op function
for the onClick prop in SettingsSectionPage (the expression using item.onClick
and navigateToSettings) with an explicit conditional: if item.onClick exists use
it; else if item.route exists supply a handler that calls
navigateToSettings(item.route); otherwise pass undefined so SettingsMenuItem
renders non-interactive. Update the onClick assignment in the
SettingsSectionPage component to reference item.onClick, item.route and
navigateToSettings accordingly so items without either property are not rendered
as clickable.

In `@tests/json_rpc_e2e.rs`:
- Around line 4007-4013: The test currently only asserts the EVM row count;
modify the assertion to verify the actual evm networks returned. In the block
using rows.iter().filter(|r| r.get("chain").and_then(Value::as_str) ==
Some("evm")), collect the evm network identifiers via
r.get("evmNetwork").and_then(Value::as_str) (or the correct key used in the
rows), build a set or sorted Vec of those strings, and assert it equals the
expected set/Vec (e.g., ["ethereum","base","bnb"]) instead of only asserting
count() == 3; update the assertion message to include the actual collected
networks for easier debugging.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9214d12c-6ce2-4ba1-b372-9e16fa40edd9

📥 Commits

Reviewing files that changed from the base of the PR and between fb8068e and e27a8cd.

📒 Files selected for processing (35)
  • app/src/components/settings/SettingsHome.tsx
  • app/src/components/settings/SettingsSectionPage.tsx
  • app/src/components/settings/__tests__/SettingsHome.test.tsx
  • app/src/components/settings/hooks/__tests__/useSettingsNavigation.test.tsx
  • app/src/components/settings/hooks/useSettingsNavigation.ts
  • app/src/components/settings/panels/DeveloperOptionsPanel.tsx
  • app/src/components/settings/panels/WalletBalancesPanel.tsx
  • app/src/components/settings/panels/__tests__/WalletBalancesPanel.test.tsx
  • app/src/components/settings/panels/wallet/ReceiveModal.tsx
  • app/src/components/settings/panels/wallet/SendCryptoModal.tsx
  • app/src/components/settings/panels/wallet/__tests__/SendCryptoModal.test.tsx
  • app/src/features/wallet/__tests__/walletDisplay.test.ts
  • app/src/features/wallet/walletDisplay.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/pages/Settings.tsx
  • app/src/services/walletApi.ts
  • app/test/playwright/specs/settings-account-preferences.spec.ts
  • src/openhuman/about_app/catalog_data.rs
  • src/openhuman/wallet/execution.rs
  • src/openhuman/wallet/execution_tests.rs
  • src/openhuman/wallet/schemas.rs
  • tests/json_rpc_e2e.rs

Comment thread app/src/components/settings/hooks/useSettingsNavigation.ts
Comment thread app/src/components/settings/panels/wallet/ReceiveModal.tsx
Comment thread app/src/components/settings/panels/WalletBalancesPanel.tsx
Comment thread app/src/features/wallet/walletDisplay.ts
Comment thread app/src/lib/i18n/ar.ts Outdated
Comment thread app/src/lib/i18n/pl.ts Outdated
Comment thread app/src/lib/i18n/pt.ts Outdated
Comment thread app/src/lib/i18n/pt.ts Outdated
Comment thread app/src/lib/i18n/ru.ts Outdated
Comment thread app/src/lib/i18n/zh-CN.ts Outdated
- ReceiveModal: clear the copy-reset timer on unmount (useEffect cleanup).
- SendCryptoModal: surface a translated invalid-amount message instead of
  toSmallestUnit's raw English throw; toSmallestUnit now throws internal
  sentinel codes (dev-facing, caught + replaced at the call site).
- i18n: translate settings.cryptoSection.title in all non-English locales
  (was left as the English 'Crypto' placeholder); fix pt notificationsHub
  description grammar (gira -> gerencie).
@senamakel senamakel merged commit 29f8806 into tinyhumansai:main May 30, 2026
30 of 32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant