Skip to content

add display/hide balance#578

Merged
Agilulfo1820 merged 5 commits into
mainfrom
mike/display-hide-balance
Jan 12, 2026
Merged

add display/hide balance#578
Agilulfo1820 merged 5 commits into
mainfrom
mike/display-hide-balance

Conversation

@mikeredmond

@mikeredmond mikeredmond commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

Adding option to display/hide balances in main wallet

Closes #573

Screen.Recording.2026-01-05.at.18.51.20.mov

Summary by CodeRabbit

  • New Features

    • Toggle to show or hide wallet balance and individual assets via an eye icon.
    • Balances are masked when hidden (main balance shows partial masking; asset values show asterisks).
    • Asset visibility preference is saved locally and persists across sessions.
  • Style

    • Header and action controls layout adjusted for more compact spacing.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 5, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@mikeredmond has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 10 minutes and 57 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 2e77294 and 1990bd7.

📒 Files selected for processing (1)
  • packages/vechain-kit/src/components/common/AssetButton.tsx
📝 Walkthrough

Walkthrough

Adds a persisted show/hide-assets toggle and wiring: components read/write a LocalStorage key to conditionally mask or reveal balances across AccountModal balance section, profile content, and asset items.

Changes

Cohort / File(s) Summary
Balance Section UI
packages/vechain-kit/src/components/AccountModal/Components/BalanceSection.tsx
Added showAssets state persisted via LocalStorageKey.SHOW_ASSETS; introduced eye/eye-closed IconButton toggle; adjusted header layout and masked main balance when hidden.
Profile Content Rendering
packages/vechain-kit/src/components/AccountModal/Contents/Profile/ProfileContent.tsx
Uses useLocalStorage(LocalStorageKey.SHOW_ASSETS) to read/write visibility and renders formattedBalance masked (first char + asterisks) when disabled.
Asset Item / Button Rendering
packages/vechain-kit/src/components/common/AssetButton.tsx
Reads SHOW_ASSETS via getLocalStorageItem and conditionally renders amount / currencyValue (formatted vs '****'); updated token logo import path.
LocalStorage Key
packages/vechain-kit/src/hooks/cache/useLocalStorage.ts
Added LocalStorageKey.SHOW_ASSETS = 'vechain_kit_show_assets'.
Utilities / SSR-safe read
packages/vechain-kit/src/utils/ssrUtils.ts (usage)
Components use getLocalStorageItem for client-safe initialization of visibility state.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User as User
  participant UI as Account UI (Balance/Profile/Asset components)
  participant LS as LocalStorage

  Note right of UI: On mount/read
  UI->>LS: getItem(LocalStorageKey.SHOW_ASSETS)
  LS-->>UI: "true" / "false" / null
  UI-->>User: render balances (masked or full)

  Note over User,UI: Toggle interaction
  User->>UI: click eye toggle
  UI->>LS: setItem(LocalStorageKey.SHOW_ASSETS, newValue)
  LS-->>UI: confirm persist
  UI-->>User: re-render with updated visibility
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Fix/add new wallet #570 — Modifies ProfileContent balance rendering and is closely related to how wallet balances are retrieved/rendered.

Suggested reviewers

  • victorkl400

Poem

🐰 I twitch my nose and hide the sums,
A little wink before the drums.
Carrots tucked in secret rows,
Numbers hush where moonlight goes.
Hop — the toggle smiles and hums. 🎋

Pre-merge checks and finishing touches

✅ 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 'add display/hide balance' clearly and concisely summarizes the main change: adding functionality to toggle balance visibility in the wallet interface.
Linked Issues check ✅ Passed The PR successfully implements the requirement from issue #573 to provide users the ability to show or hide asset balances across multiple wallet components with persistent localStorage state.
Out of Scope Changes check ✅ Passed All changes are directly related to the display/hide balance feature: UI toggles, masking logic, localStorage integration, and affected components are all within the stated objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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 and usage tips.

@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

Fix all issues with AI Agents 🤖
In
@packages/vechain-kit/src/components/AccountModal/Components/BalanceSection.tsx:
- Line 125: Extract the masking logic into a shared utility named
maskBalance(formattedBalance: string, showAssets: boolean) that returns
formattedBalance unchanged when showAssets is true, and returns a safe masked
string when false (handle empty string by returning '' or a consistent
placeholder instead of using formattedBalance[0] which can be undefined).
Replace the inline expression in BalanceSection (the JSX that chooses between
formattedBalance and the masked version) with a call to
maskBalance(formattedBalance, showAssets), and do the same in ProfileContent to
remove duplication and avoid the "undefined***" issue.
- Around line 45-56: Replace the manual useState/useEffect localStorage logic
for showAssets with the existing useLocalStorage hook: remove the try/catch
initializer and effect that read/write LocalStorageKey.SHOW_ASSETS, and instead
call useLocalStorage(LocalStorageKey.SHOW_ASSETS, true) to get [showAssets,
setShowAssets]; this ensures consistent JSON parsing/stringifying and automatic
persistence handled by the hook.

In
@packages/vechain-kit/src/components/AccountModal/Contents/Profile/ProfileContent.tsx:
- Around line 140-145: Extract the masking logic into a shared utility function
named maskBalance that accepts formattedBalance (string) and returns an empty
string for falsy/empty input or the first char plus '*' for the rest; implement
it once (e.g., export const maskBalance = (balance: string) => { ... }) and
import and use maskBalance in ProfileContent (replace the inline
formattedBalance[0] + '*'.repeat(...)) and in BalanceSection where the same
duplication exists; ensure both places call maskBalance(formattedBalance) and
remove the duplicated inline logic.
- Line 52: Replace the one-time localStorage read storedShowAssets =
getLocalStorageItem(LocalStorageKey.SHOW_ASSETS) with the reactive hook const
[showAssets, setShowAssets] = useLocalStorage(LocalStorageKey.SHOW_ASSETS, true)
so the component updates when BalanceSection toggles visibility and defaults to
true for first-time users; then update any conditional that previously checked
storedShowAssets (e.g., storedShowAssets === 'false') to use the boolean
showAssets (or its falsy check) and ensure any state writes use setShowAssets to
keep localStorage in sync.
🧹 Nitpick comments (1)
packages/vechain-kit/src/components/AccountModal/Components/BalanceSection.tsx (1)

99-107: Consider enhancing the accessibility label to indicate current state.

While the button has an aria-label, it could be more descriptive by indicating the current state of the toggle.

🔎 Suggested improvement
                    <IconButton
-                        aria-label="Show/hide assets"
+                        aria-label={showAssets ? "Hide assets" : "Show assets"}
                        variant="ghost"
                        size="sm"
                        opacity={0.5}
                        _hover={{ opacity: 0.8 }}
                        onClick={() => setShowAssets(!showAssets)}
                        icon={<Icon as={showAssets ? GoEye : GoEyeClosed} boxSize={4} />}
                    />

This provides clearer feedback to screen reader users about what the button will do when activated.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb2990f and d48d146.

📒 Files selected for processing (3)
  • packages/vechain-kit/src/components/AccountModal/Components/BalanceSection.tsx
  • packages/vechain-kit/src/components/AccountModal/Contents/Profile/ProfileContent.tsx
  • packages/vechain-kit/src/hooks/cache/useLocalStorage.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/migration-guide-to-v2.mdc)

**/*.{ts,tsx}: In VeChain Kit Version 2, use useThor instead of useConnex for contract interactions
For single contract read operations, use the useCallClause hook with the pattern: import dependencies, define ABI and method as const, create query key function using getCallClauseQueryKeyWithArgs, and wrap with useCallClause including data transformation in the select option
For multiple parallel contract calls, use the executeMultipleClausesCall utility wrapped in a useQuery hook with the pattern: define query key function, use executeMultipleClausesCall in queryFn mapping items to clause objects, and transform results
For transaction building and sending, use the useBuildTransaction hook with a clauseBuilder function that returns an array of clauses with optional comment fields describing the transaction action
Always provide an arguments array for contract calls, even when no parameters are required - use an empty array for parameter-less functions to enable TypeScript type checking
Always conditionally enable queries using the enabled property to prevent unnecessary contract calls, checking for all required parameters: enabled: !!requiredParam && !!otherRequiredParam
Use the select option in useCallClause or transform data in queryFn to handle data transformation, particularly for converting BigInt values to strings and normalizing contract return data
Maintain consistent query key patterns: use getCallClauseQueryKeyWithArgs for contract calls with arguments and getCallClauseQueryKey for calls without arguments to ensure proper caching and invalidation
Use TypeScript as const assertions for method names and as 0x${string}`` assertions for Ethereum addresses to ensure type safety in contract interactions

Files:

  • packages/vechain-kit/src/hooks/cache/useLocalStorage.ts
  • packages/vechain-kit/src/components/AccountModal/Components/BalanceSection.tsx
  • packages/vechain-kit/src/components/AccountModal/Contents/Profile/ProfileContent.tsx
🧬 Code graph analysis (2)
packages/vechain-kit/src/components/AccountModal/Components/BalanceSection.tsx (1)
packages/vechain-kit/src/utils/ssrUtils.ts (2)
  • getLocalStorageItem (8-18)
  • setLocalStorageItem (23-32)
packages/vechain-kit/src/components/AccountModal/Contents/Profile/ProfileContent.tsx (1)
packages/vechain-kit/src/utils/ssrUtils.ts (1)
  • getLocalStorageItem (8-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Lint & Build
  • GitHub Check: deploy
  • GitHub Check: build-size-check
🔇 Additional comments (1)
packages/vechain-kit/src/hooks/cache/useLocalStorage.ts (1)

11-11: LGTM!

The new SHOW_ASSETS key follows the established naming convention and integrates cleanly with the existing enum.

Comment thread packages/vechain-kit/src/components/AccountModal/Components/BalanceSection.tsx Outdated
@github-actions

github-actions Bot commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

Size Change: +4.29 kB (+0.07%)

Total Size: 5.76 MB

Filename Size Change
packages/vechain-kit/dist/index-CqDpn2Nw.d.cts 0 B -151 kB (removed) 🏆
packages/vechain-kit/dist/index-CqDpn2Nw.d.cts.map 0 B -43.8 kB (removed) 🏆
packages/vechain-kit/dist/index-CWViOs1U.d.mts 0 B -5.63 kB (removed) 🏆
packages/vechain-kit/dist/index-CWViOs1U.d.mts.map 0 B -2.99 kB (removed) 🏆
packages/vechain-kit/dist/index-DMCHcGJm.d.mts 0 B -151 kB (removed) 🏆
packages/vechain-kit/dist/index-DMCHcGJm.d.mts.map 0 B -43.8 kB (removed) 🏆
packages/vechain-kit/dist/index.cjs.map 1.87 MB +1.76 kB (+0.09%)
packages/vechain-kit/dist/index.mjs.map 1.82 MB +1.69 kB (+0.09%)
packages/vechain-kit/dist/index--1KdlzUw.d.mts 151 kB +151 kB (new file) 🆕
packages/vechain-kit/dist/index--1KdlzUw.d.mts.map 43.8 kB +43.8 kB (new file) 🆕
packages/vechain-kit/dist/index--hSO7Xv4.d.mts 5.63 kB +5.63 kB (new file) 🆕
packages/vechain-kit/dist/index--hSO7Xv4.d.mts.map 2.99 kB +2.99 kB (new file) 🆕
packages/vechain-kit/dist/index-Bn3hoynk.d.cts 151 kB +151 kB (new file) 🆕
packages/vechain-kit/dist/index-Bn3hoynk.d.cts.map 43.8 kB +43.8 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
packages/vechain-kit/dist/assets 4.1 kB 0 B
packages/vechain-kit/dist/assets-aAdDxPJu.mjs 50.1 kB 0 B
packages/vechain-kit/dist/assets-aAdDxPJu.mjs.map 70.2 kB 0 B
packages/vechain-kit/dist/assets-DXVXPy3w.cjs 54.8 kB 0 B
packages/vechain-kit/dist/assets-DXVXPy3w.cjs.map 71.6 kB 0 B
packages/vechain-kit/dist/assets/index.cjs 716 B 0 B
packages/vechain-kit/dist/assets/index.d.cts 973 B 0 B
packages/vechain-kit/dist/assets/index.d.mts 973 B 0 B
packages/vechain-kit/dist/assets/index.mjs 718 B 0 B
packages/vechain-kit/dist/index-I8fe7GR2.d.cts 5.63 kB 0 B
packages/vechain-kit/dist/index-I8fe7GR2.d.cts.map 2.99 kB 0 B
packages/vechain-kit/dist/index.cjs 613 kB +412 B (+0.07%)
packages/vechain-kit/dist/index.d.cts 20.5 kB 0 B
packages/vechain-kit/dist/index.d.mts 20.5 kB 0 B
packages/vechain-kit/dist/index.mjs 578 kB +390 B (+0.07%)
packages/vechain-kit/dist/utils 4.1 kB 0 B
packages/vechain-kit/dist/utils-CNYVq6tT.mjs 21.2 kB 0 B
packages/vechain-kit/dist/utils-CNYVq6tT.mjs.map 63.4 kB 0 B
packages/vechain-kit/dist/utils-DcAJej3n.cjs 26.4 kB 0 B
packages/vechain-kit/dist/utils-DcAJej3n.cjs.map 63.7 kB 0 B
packages/vechain-kit/dist/utils/index.cjs 1.94 kB 0 B
packages/vechain-kit/dist/utils/index.d.cts 2.97 kB 0 B
packages/vechain-kit/dist/utils/index.d.mts 2.97 kB 0 B
packages/vechain-kit/dist/utils/index.mjs 1.96 kB 0 B

compressed-size-action

@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

Fix all issues with AI Agents 🤖
In @packages/vechain-kit/src/components/common/AssetButton.tsx:
- Line 41: AssetButton currently reads
getLocalStorageItem(LocalStorageKey.SHOW_ASSETS) directly on render which
defaults to hiding assets and is not reactive to changes made by BalanceSection;
extract a shared reactive state (either a context provider or a custom hook)
initialized like BalanceSection using useState with
getLocalStorageItem(LocalStorageKey.SHOW_ASSETS) so both AssetButton and
BalanceSection use the same showAssets and setShowAssets pair, ensure the
initializer parses stored JSON and falls back to true on error so defaults
match, and replace direct localStorage reads in AssetButton with the shared
showAssets state to get consistent defaults and automatic updates.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d48d146 and 1ff7107.

📒 Files selected for processing (1)
  • packages/vechain-kit/src/components/common/AssetButton.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/migration-guide-to-v2.mdc)

**/*.{ts,tsx}: In VeChain Kit Version 2, use useThor instead of useConnex for contract interactions
For single contract read operations, use the useCallClause hook with the pattern: import dependencies, define ABI and method as const, create query key function using getCallClauseQueryKeyWithArgs, and wrap with useCallClause including data transformation in the select option
For multiple parallel contract calls, use the executeMultipleClausesCall utility wrapped in a useQuery hook with the pattern: define query key function, use executeMultipleClausesCall in queryFn mapping items to clause objects, and transform results
For transaction building and sending, use the useBuildTransaction hook with a clauseBuilder function that returns an array of clauses with optional comment fields describing the transaction action
Always provide an arguments array for contract calls, even when no parameters are required - use an empty array for parameter-less functions to enable TypeScript type checking
Always conditionally enable queries using the enabled property to prevent unnecessary contract calls, checking for all required parameters: enabled: !!requiredParam && !!otherRequiredParam
Use the select option in useCallClause or transform data in queryFn to handle data transformation, particularly for converting BigInt values to strings and normalizing contract return data
Maintain consistent query key patterns: use getCallClauseQueryKeyWithArgs for contract calls with arguments and getCallClauseQueryKey for calls without arguments to ensure proper caching and invalidation
Use TypeScript as const assertions for method names and as 0x${string}`` assertions for Ethereum addresses to ensure type safety in contract interactions

Files:

  • packages/vechain-kit/src/components/common/AssetButton.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-01T13:01:33.771Z
Learnt from: CR
Repo: vechain/vechain-kit PR: 0
File: .cursor/rules/migration-guide-to-v2.mdc:0-0
Timestamp: 2025-12-01T13:01:33.771Z
Learning: Applies to **/*.{ts,tsx} : In VeChain Kit Version 2, use `useThor` instead of `useConnex` for contract interactions

Applied to files:

  • packages/vechain-kit/src/components/common/AssetButton.tsx
🧬 Code graph analysis (1)
packages/vechain-kit/src/components/common/AssetButton.tsx (2)
packages/vechain-kit/src/utils/ssrUtils.ts (1)
  • getLocalStorageItem (8-18)
packages/vechain-kit/src/utils/currencyUtils.ts (2)
  • formatCompactCurrency (37-51)
  • SupportedCurrency (4-4)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Lint & Build
  • GitHub Check: deploy
  • GitHub Check: build-size-check
🔇 Additional comments (1)
packages/vechain-kit/src/components/common/AssetButton.tsx (1)

11-11: LGTM: Import changes are appropriate.

The import path refactoring and new SSR-safe localStorage utilities are correctly imported.

Also applies to: 14-15

Comment thread packages/vechain-kit/src/components/common/AssetButton.tsx Outdated
Comment thread packages/vechain-kit/src/components/common/AssetButton.tsx
@Agilulfo1820 Agilulfo1820 merged commit 65dd2c9 into main Jan 12, 2026
7 checks passed
@Agilulfo1820 Agilulfo1820 deleted the mike/display-hide-balance branch January 12, 2026 14:22
@coderabbitai coderabbitai Bot mentioned this pull request Feb 10, 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.

💡 Display/hide assets

2 participants