Skip to content

feat(walletui): rename accounts - #1588

Merged
sdbondi merged 2 commits into
tari-project:developmentfrom
NovaT82:walletui
Sep 29, 2025
Merged

feat(walletui): rename accounts#1588
sdbondi merged 2 commits into
tari-project:developmentfrom
NovaT82:walletui

Conversation

@NovaT82

@NovaT82 NovaT82 commented Sep 26, 2025

Copy link
Copy Markdown
Contributor

Description

Adds the ability to rename accounts.
Also some small UI / layout improvements to the Account Details page.

Screenshot 2025-09-26 at 12 55 15 Screenshot 2025-09-26 at 12 55 22

Motivation and Context

The wallet didn't previously have the ability to rename accounts.

How Has This Been Tested?

Manually

What process can a PR reviewer use to test or verify this change?

On the homepage and in account details, click on the pencil icon next to the account name.

Breaking Changes

x

  • None
  • Requires data directory to be deleted
  • Other - Please specify

Summary by CodeRabbit

  • New Features

    • Inline account renaming in Account Details and Asset Vault with Save/Cancel and Enter/Escape shortcuts.
  • Improvements

    • Balances now use localized currency formatting with better handling of various amount types.
    • Consistent styling for section headings.
    • Rename actions reflect immediately in the UI and surface errors when they occur.

@coderabbitai

coderabbitai Bot commented Sep 26, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds inline account rename capability to the web UI: new AccountName component with edit/save, a React Query mutation hook for accountsRename, a JSON-RPC client method, and UI wiring in Account Details screens. Also broadens formatCurrency to accept Amount-like inputs and updates balance rendering.

Changes

Cohort / File(s) Summary
UI Component: AccountName
applications/tari_walletd/web_ui/src/components/AccountName.tsx
New editable account name component using a rename mutation; supports save/cancel, keyboard shortcuts, pending state, and success/error callbacks.
Account Details UI Integration
applications/tari_walletd/web_ui/src/routes/AccountDetails/AccountDetails.tsx, applications/tari_walletd/web_ui/src/routes/AssetVault/Components/AccountDetails.tsx
Replaces static name display with AccountName; wraps headings with InnerHeading; applies formatCurrency to balances; updates local state on successful rename in AssetVault view.
API Hooks: Accounts Rename
applications/tari_walletd/web_ui/src/services/api/hooks/useAccounts.ts
Adds AccountsRenameMutate type and useAccountsRename hook; calls accountsRename and invalidates/refetches related queries on success.
JSON-RPC Client Expansion
applications/tari_walletd/web_ui/src/utils/json_rpc.ts
Exports accountsRename(request) using bindings’ AccountsRenameRequest/Response.
Utilities: Currency Formatting
applications/tari_walletd/web_ui/src/utils/helpers.tsx
Extends formatCurrency signature to accept number

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as AccountName (UI)
  participant Hook as useAccountsRename (RQ Mutation)
  participant RPC as json_rpc.accountsRename
  participant WD as Wallet Daemon Client
  participant RQ as React Query Cache

  UI->>Hook: mutate({ account, newName })
  Hook->>RPC: accountsRename(request)
  RPC->>WD: c.accountsRename(request)
  WD-->>RPC: AccountsRenameResponse
  RPC-->>Hook: response
  Hook->>RQ: invalidate(accounts list + account get)
  Hook->>RQ: refetch(accounts list)
  Hook-->>UI: onSuccess callback
  UI->>UI: exit edit mode, update displayed name
  Note over UI,Hook: On error: pending disabled, onRenameError invoked
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

P-acks_required, P-reviews_required

Suggested reviewers

  • sdbondi

Poem

A nibble of names, a hop to save,
I clicked my quill—so bold, so brave.
Balances shine with tidy flair,
Formats trimmed with rabbit care.
Rename whiskers twitch—success declared!
Thump-thump: accounts now finely paired. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly captures the primary change of the PR—adding account renaming to the wallet UI—and aligns with the provided objectives, making it clear and specific to the main feature introduced.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
applications/tari_walletd/web_ui/src/routes/AssetVault/Components/AccountDetails.tsx (1)

23-27: Incorrect source for substateIdToString (bindings are types-only).

@tari-project/typescript-bindings does not provide runtime helpers. Import substateIdToString from local utils.

Based on learnings
Apply:

-import { substateIdToString } from "@tari-project/typescript-bindings";
+import { substateIdToString } from "@utils/helpers";
🧹 Nitpick comments (3)
applications/tari_walletd/web_ui/src/services/api/hooks/useAccounts.ts (1)

98-115: Avoid redundant refetch; rely on invalidation.

invalidateQueries will refetch active observers; the extra refetchQueries is usually unnecessary and adds duplicate load.

Apply:

   onSuccess: (_data, variables) => {
     queryClient.invalidateQueries({ queryKey: ["accounts"] });
     queryClient.invalidateQueries({ queryKey: [`accounts_get_${variables.account}`] });
-    queryClient.refetchQueries({ queryKey: ["accounts"] });
   },
applications/tari_walletd/web_ui/src/components/AccountName.tsx (1)

111-142: Add accessible labels for icon buttons.

Improve a11y by adding aria-labels to IconButtons.

-<IconButton
+<IconButton
   size="small"
   onClick={handleSaveRename}
   disabled={renameAccountMutation.isPending}
-  title="Save"
+  title="Save"
+  aria-label="Save account name"
>
...
-<IconButton
+<IconButton
   size="small"
   onClick={handleCancelEdit}
   disabled={renameAccountMutation.isPending}
-  title="Cancel"
+  title="Cancel"
+  aria-label="Cancel edit account name"
>
...
-<IconButton size="small" onClick={handleStartEdit} title="Rename account">
+<IconButton size="small" onClick={handleStartEdit} title="Rename account" aria-label="Rename account">
applications/tari_walletd/web_ui/src/utils/helpers.tsx (1)

255-306: Reuse bigintToDecimalString to avoid Number() precision loss and duplicate logic.

Converting BigInt to Number can lose precision for large amounts; bigintToDecimalString already formats safely.

Apply:

   if (typeof amount === "bigint") {
-    const divisor = BigInt(CURRENCY.DIVISOR);
-    const integerPart = amount / divisor;
-    const remainder = amount % divisor;
-
-    const fractionalPart = remainder.toString().padStart(CURRENCY.DECIMALS, "0");
-
-    return `${Number(integerPart).toLocaleString("en-US")}.${fractionalPart} ${currencySymbol}`;
+    return `${bigintToDecimalString(amount, CURRENCY.DECIMALS)} ${currencySymbol}`;
   } else if (typeof amount === "number") {
     if (isNaN(amount)) {
       return `0 ${currencySymbol}`;
     }
     const convertedAmount = amount / CURRENCY.DIVISOR;
     return `${convertedAmount.toLocaleString("en-US", {
       minimumFractionDigits: 0,
       maximumFractionDigits: CURRENCY.DECIMALS,
     })} ${currencySymbol}`;
   } else if (typeof amount === "string") {
-    // Handle Amount type
-    try {
-      const numericAmount = BigInt(amount);
-      const divisor = BigInt(CURRENCY.DIVISOR);
-      const integerPart = numericAmount / divisor;
-      const remainder = numericAmount % divisor;
-
-      const fractionalPart = remainder.toString().padStart(CURRENCY.DECIMALS, "0");
-
-      return `${Number(integerPart).toLocaleString("en-US")}.${fractionalPart} ${currencySymbol}`;
-    } catch (error) {
+    try {
+      const numericAmount = BigInt(amount);
+      return `${bigintToDecimalString(numericAmount, CURRENCY.DECIMALS)} ${currencySymbol}`;
+    } catch (error) {
       console.error("Failed to parse Amount:", amount, error);
       return `0 ${currencySymbol}`;
     }
   } else {
-    // Handle any other type (object, etc.)
-    try {
-      const stringValue = String(amount);
-      const numericAmount = BigInt(stringValue);
-      const divisor = BigInt(CURRENCY.DIVISOR);
-      const integerPart = numericAmount / divisor;
-      const remainder = numericAmount % divisor;
-
-      const fractionalPart = remainder.toString().padStart(CURRENCY.DECIMALS, "0");
-
-      return `${Number(integerPart).toLocaleString("en-US")}.${fractionalPart} ${currencySymbol}`;
-    } catch (error) {
+    try {
+      const numericAmount = BigInt(String(amount));
+      return `${bigintToDecimalString(numericAmount, CURRENCY.DECIMALS)} ${currencySymbol}`;
+    } catch (error) {
       console.error("Failed to parse Amount:", amount, error);
       return `0 ${currencySymbol}`;
     }
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3950673 and ff2ecc6.

📒 Files selected for processing (6)
  • applications/tari_walletd/web_ui/src/components/AccountName.tsx (1 hunks)
  • applications/tari_walletd/web_ui/src/routes/AccountDetails/AccountDetails.tsx (6 hunks)
  • applications/tari_walletd/web_ui/src/routes/AssetVault/Components/AccountDetails.tsx (3 hunks)
  • applications/tari_walletd/web_ui/src/services/api/hooks/useAccounts.ts (2 hunks)
  • applications/tari_walletd/web_ui/src/utils/helpers.tsx (2 hunks)
  • applications/tari_walletd/web_ui/src/utils/json_rpc.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
applications/tari_walletd/web_ui/src/utils/json_rpc.ts (3)
clients/javascript/wallet_daemon_client/src/index.ts (1)
  • accountsRename (180-182)
bindings/src/types/wallet-daemon-client/AccountsRenameRequest.ts (1)
  • AccountsRenameRequest (4-4)
bindings/src/types/wallet-daemon-client/AccountsRenameResponse.ts (1)
  • AccountsRenameResponse (3-3)
applications/tari_walletd/web_ui/src/routes/AccountDetails/AccountDetails.tsx (2)
applications/tari_walletd/web_ui/src/utils/helpers.tsx (1)
  • formatCurrency (255-307)
applications/tari_walletd/web_ui/src/components/StyledComponents.ts (1)
  • InnerHeading (46-53)
applications/tari_walletd/web_ui/src/utils/helpers.tsx (2)
bindings/src/types/Amount.ts (1)
  • Amount (12-12)
applications/tari_walletd/web_ui/src/utils/constants.ts (1)
  • CURRENCY (23-27)
applications/tari_walletd/web_ui/src/services/api/hooks/useAccounts.ts (3)
bindings/src/types/ComponentAddress.ts (1)
  • ComponentAddress (6-6)
applications/tari_walletd/web_ui/src/utils/json_rpc.ts (1)
  • accountsRename (276-277)
applications/tari_walletd/web_ui/src/services/api/helpers/types.ts (1)
  • ApiError (23-27)
applications/tari_walletd/web_ui/src/routes/AssetVault/Components/AccountDetails.tsx (1)
applications/tari_walletd/web_ui/src/utils/helpers.tsx (1)
  • substateIdToString (100-109)
applications/tari_walletd/web_ui/src/components/AccountName.tsx (2)
bindings/src/types/ComponentAddress.ts (1)
  • ComponentAddress (6-6)
applications/tari_walletd/web_ui/src/services/api/hooks/useAccounts.ts (1)
  • useAccountsRename (98-115)
⏰ 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). (5)
  • GitHub Check: test
  • GitHub Check: check stable
  • GitHub Check: check nightly
  • GitHub Check: machete
  • GitHub Check: clippy
🔇 Additional comments (9)
applications/tari_walletd/web_ui/src/services/api/hooks/useAccounts.ts (1)

93-97: Type for rename payload is sensible and consistent.

applications/tari_walletd/web_ui/src/routes/AssetVault/Components/AccountDetails.tsx (2)

42-45: Local store update on rename is fine.


58-64: AccountName integration LGTM.

applications/tari_walletd/web_ui/src/routes/AccountDetails/AccountDetails.tsx (3)

57-59: Balance formatting with formatCurrency looks good.


171-173: Confirm param type matches ComponentAddress.

Passing accountAddr directly assumes the route param is a ComponentAddress string. If it’s a tagged SubstateId elsewhere, pass substateIdToString(accountAddr) for consistency.


197-197: Section heading improvements LGTM.

Also applies to: 221-221

applications/tari_walletd/web_ui/src/components/AccountName.tsx (2)

64-85: Save/cancel logic with trim and equality check is solid.


105-107: ‘isPending’ is correct for React Query v5
applications/tari_walletd/web_ui/package.json pins @tanstack/react-query v5.85.7, which exposes isPending. No change required.

applications/tari_walletd/web_ui/src/utils/json_rpc.ts (1)

33-35: Approve accountsRename wiring Client method accountsRename and its AccountsRenameRequest/AccountsRenameResponse types are present and correctly exported.

decodeOotleAddressOrNull,
substateIdToString,
} from "@tari-project/typescript-bindings";
import { BalanceEntry, decodeOotleAddressOrNull, substateIdToString } from "@tari-project/typescript-bindings";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Likely wrong imports from types-only package.

substateIdToString is a local util, not from @tari-project/typescript-bindings. Also verify decodeOotleAddressOrNull is coming from a runtime module.

Based on learnings
Suggested fix for substateIdToString:

-import { BalanceEntry, decodeOotleAddressOrNull, substateIdToString } from "@tari-project/typescript-bindings";
+import type { BalanceEntry } from "@tari-project/typescript-bindings";
+import { substateIdToString } from "@utils/helpers";
+import { decodeOotleAddressOrNull } from "@utils/helpers"; // update to the actual runtime module that provides this function

🏁 Script executed:

#!/bin/bash
# Confirm where substateIdToString and decodeOotleAddressOrNull are defined in the repo
rg -nP -C2 '\bexport\s+(function|const)\s+substateIdToString\b'
rg -nP -C2 '\bexport\s+(function|const)\s+decodeOotleAddressOrNull\b'
# Locate existing imports of these to see the correct module
rg -nP -C2 'substateIdToString.*from'
rg -nP -C2 'decodeOotleAddressOrNull.*from'

Length of output: 18528


🏁 Script executed:

#!/bin/bash
echo "Inspecting bindings entrypoint for decodeOotleAddressOrNull exports"
rg -nP 'decodeOotleAddressOrNull' -C1 bindings/src/index.ts || echo "decodeOotleAddressOrNull not found in index.ts"
echo
echo "Checking for re-export of ootleAddress module"
rg -nP 'export.*helpers/ootleAddress' -C1 bindings/src/index.ts || echo "No ootleAddress re-export in index.ts"

Length of output: 291


Correct imports in AccountDetails.tsx

-import { BalanceEntry, decodeOotleAddressOrNull, substateIdToString } from "@tari-project/typescript-bindings";
+import type { BalanceEntry } from "@tari-project/typescript-bindings";
+import { decodeOotleAddressOrNull } from "@tari-project/typescript-bindings";
+import { substateIdToString } from "@utils/helpers";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { BalanceEntry, decodeOotleAddressOrNull, substateIdToString } from "@tari-project/typescript-bindings";
import type { BalanceEntry } from "@tari-project/typescript-bindings";
import { decodeOotleAddressOrNull } from "@tari-project/typescript-bindings";
import { substateIdToString } from "@utils/helpers";
🤖 Prompt for AI Agents
In applications/tari_walletd/web_ui/src/routes/AccountDetails/AccountDetails.tsx
around line 39, the import line currently references symbols that are not
correctly imported from the package; update this import to use the actual
exported identifiers used in the file: remove or correct the non-exported
decodeOotleAddressOrNull (either import it from its proper module or drop it)
and ensure BalanceEntry and substateIdToString are imported exactly as exported
by @tari-project/typescript-bindings; then run the TypeScript compiler to
confirm there are no unresolved import errors and adjust the import path/names
accordingly.

@github-actions

Copy link
Copy Markdown

Test Results (CI)

418 tests   - 23   418 ✅  - 10   49m 5s ⏱️ - 32m 47s
 61 suites  - 12     0 💤 ± 0 
  1 files    -  1     0 ❌  - 13 

Results for commit ff2ecc6. ± Comparison against base commit 3950673.

This pull request removes 23 tests.
Scenario: Claim and transfer confidential assets via wallet daemon: tests/features/wallet_daemon.feature:55:3
Scenario: Claim base layer burn funds with wallet daemon: tests/features/claim_burn.feature:9:3
Scenario: Claim validator fees: tests/features/claim_fees.feature:8:3
Scenario: Concurrent calls to the Counter template: tests/features/concurrency.feature:7:3
Scenario: Confidential transfer to account that does not previously exist: tests/features/transfer.feature:115:3
Scenario: Counter template registration and invocation multiple times: tests/features/counter.feature:28:3
Scenario: Counter template registration and invocation once: tests/features/counter.feature:8:3
Scenario: Create account and transfer faucets via wallet daemon: tests/features/wallet_daemon.feature:8:3
Scenario: Create and mint account NFT: tests/features/wallet_daemon.feature:77:3
Scenario: Create resource and mint in one transaction: tests/features/nft.feature:61:3
…

@sdbondi
sdbondi merged commit 3873c11 into tari-project:development Sep 29, 2025
12 of 13 checks passed
@NovaT82
NovaT82 deleted the walletui branch September 29, 2025 09:18
@coderabbitai coderabbitai Bot mentioned this pull request Oct 6, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants