PHANTOM
🇮🇳 IN
Skip to content

[ZCash] Finalize s->t transactions support#32580

Merged
wknapik merged 1 commit intomasterfrom
brave_45875_2
Dec 15, 2025
Merged

[ZCash] Finalize s->t transactions support#32580
wknapik merged 1 commit intomasterfrom
brave_45875_2

Conversation

@cypt4
Copy link
Collaborator

@cypt4 cypt4 commented Nov 27, 2025

This PR finalizes s->t transaction support, by integration ZCashCreateOrchardToTransparentTask to ZCashWalletService and adding s->t handling to the UI.
Resolves brave/brave-browser#45875

Resolves

@cypt4 cypt4 requested review from a team as code owners November 27, 2025 11:27
@cypt4 cypt4 requested a review from kdenhartog November 27, 2025 11:28
@github-actions github-actions bot added CI/storybook-url Deploy storybook and provide a unique URL for each build feature/web3/wallet feature/web3/wallet/core puLL-Merge labels Nov 27, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Nov 27, 2025

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@kdenhartog
Copy link
Member

UI Logic Change: The UI change inverts the disabled logic for account selection (!selectedAsset?.isShielded instead of !!selectedAsset?.isShielded). This means transparent assets can no longer be sent to the same account, which may be unintended.

Is this intentional or has it been tested to make sure we're not breaking it unintentionally?

Copy link
Member

@kdenhartog kdenhartog left a comment

Choose a reason for hiding this comment

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

Let's make sure we don't accidentally block the UI here, but the rest LGTM

@cypt4
Copy link
Collaborator Author

cypt4 commented Nov 28, 2025

UI Logic Change: The UI change inverts the disabled logic for account selection (!selectedAsset?.isShielded instead of !!selectedAsset?.isShielded). This means transparent assets can no longer be sent to the same account, which may be unintended.

Is this intentional or has it been tested to make sure we're not breaking it unintentionally?

I am still able to send t->s \ s->t inside an account.

image image

@kdenhartog
Copy link
Member

Cool thanks for double checking, probably an AI hallucination then.

This PR finalizes s->t transaction support, by integration
ZCashCreateOrchardToTransparentTask to ZCashWalletService and
adding s->t handling to the UI.
Resolves brave/brave-browser#45875
@cypt4 cypt4 requested a review from a team as a code owner December 9, 2025 12:01
@github-actions
Copy link
Contributor

github-actions bot commented Dec 9, 2025

[puLL-Merge] - brave/brave-core@32580

Description

This PR adds support for "unshielding" ZCash transactions, which allows users to transfer funds from their shielded (private) Orchard addresses back to transparent (public) addresses. The implementation mirrors the existing shielding functionality but operates in reverse. Key changes include:

  • Added new transaction type kUnshielding to differentiate unshielding from regular Orchard-to-transparent transfers
  • Created ZCashCreateOrchardToTransparentTransactionTask for handling the transaction creation
  • Updated UI components to display appropriate labels, buttons, and alerts for unshielding operations
  • Modified transaction validation logic to detect when sending to a transparent address from a shielded account
  • Added localized strings for all unshielding-related UI elements

Possible Issues

  1. Duplicate key in localization: Line 1718 in brave_wallet_constants.h has a duplicate key "braveWalletShielding" that's assigned different values (IDS_BRAVE_WALLET_SHIELDING and IDS_BRAVE_WALLET_UNSHIELDING). The second one should be "braveWalletUnshielding".

  2. Missing file: The PR references ZCashCreateOrchardToTransparentTransactionTask but doesn't include the implementation file. This suggests incomplete PR or missing files.

  3. UI logic complexity: The send screen now has three possible states (normal send, shielding, unshielding) which increases complexity. The condition checking in multiple places could lead to maintenance issues.

Security Hotspots

  1. Address validation bypass (Medium Risk): In zcash_wallet_service.cc lines 442-448, when sending from a shielded pool, the code first checks for Orchard addresses, then iterates through all accounts looking for matching transparent addresses. If an attacker can predict or manipulate account enumeration, they might influence transaction routing.

  2. Transaction type detection (Low-Medium Risk): The logic distinguishing between kUnshielding (to own transparent address) and kOrchardToTransparent (to external address) relies on matching against known account addresses. If account enumeration is incomplete or stale, funds could be misclassified and potentially sent without proper user awareness.

Privacy Hotspots

  1. Address enumeration (High Privacy Risk): Lines 448-457 in zcash_wallet_service.cc iterate through all account information to check if the destination address matches any known transparent addresses. This creates a correlation between transparent addresses across all accounts, reducing privacy by linking them together in the validation logic.

  2. Transaction metadata (Medium Privacy Risk): The new kUnshielding transaction type explicitly tags transactions that move from shielded to transparent pools, creating metadata that identifies the privacy characteristics of the transaction. While this is necessary for UI purposes, it does create an additional privacy fingerprint.

Changes

Changes

components/brave_wallet/browser/brave_wallet_constants.h

  • Added 5 new localized string mappings for unshielding UI labels: braveWalletConfirmUnshield, braveWalletUnshieldingAmount, braveWalletAmountHasBeenUnshielded, braveWalletReviewUnshield, and braveWalletUnshieldingFundsAlertDescription
  • Contains duplicate key bug on line 1718

components/brave_wallet/browser/internal/orchard_bundle_manager.cc

  • Added CHECK to ensure either outputs or inputs exist before creating bundle (line 28)

components/brave_wallet/browser/zcash/zcash_complete_transaction_task.cc

  • Modified condition to process Orchard parts when either inputs OR outputs exist (not just outputs)
  • Removed obsolete CHECK that prevented s->t transactions

components/brave_wallet/browser/zcash/zcash_tx_manager.cc

  • Added handling for kOrchardToTransparent and kUnshielding transaction types
  • Routes these to new CreateOrchardToTransparentTransaction method

components/brave_wallet/browser/zcash/zcash_wallet_service.cc

  • Extended GetTransactionType to distinguish between unshielding (to own address) and regular Orchard-to-transparent transfers
  • Checks if destination is a known account's transparent address to classify as unshielding
  • Added CreateOrchardToTransparentTransaction and callback method
  • Added validation for transparent addresses when using shielded pool

components/brave_wallet/browser/zcash/zcash_wallet_service.h

  • Added declarations for Orchard-to-transparent transaction handling methods
  • Added task container for tracking these transactions

components/brave_wallet/browser/zcash/zcash_wallet_service_unittest.cc

  • Added comprehensive test for unshielding validation (feature enabled/disabled, same account, different account)
  • Added end-to-end test MAYBE_UnshieldFunds with real transaction data and verification

components/brave_wallet/common/brave_wallet.mojom

  • Added kUnshielding = 6 enum value to ZCashTxType
  • Added kInvalidSenderType error to ZCashAddressError

UI Component Changes (various files)

  • Updated hooks to detect unshielding funds state
  • Added unshielding-specific UI labels, buttons, and alert messages throughout confirmation flows
  • Modified button text logic to show "Unshield ZEC" for unshielding transactions
  • Added conditional rendering for unshielding alerts and status messages
  • Updated select_address_modal to show transparent address of selected account when shielded asset is chosen (modified disabled condition)

components/resources/wallet_strings.grdp

  • Added all English resource strings for unshielding feature
sequenceDiagram
    participant User
    participant UI
    participant ZCashTxManager
    participant ZCashWalletService
    participant CreateTask as CreateOrchardToTransparent<br/>TransactionTask
    participant OrchardBundleManager
    participant ZCashRpc

    User->>UI: Selects shielded asset & transparent address
    UI->>ZCashWalletService: GetTransactionType(account, address)
    ZCashWalletService->>ZCashWalletService: Check if address is Orchard
    ZCashWalletService->>ZCashWalletService: Check if address matches known accounts
    alt Matches own transparent address
        ZCashWalletService-->>UI: kUnshielding
    else External transparent address
        ZCashWalletService-->>UI: kOrchardToTransparent
    end
    
    User->>UI: Confirms transaction
    UI->>ZCashTxManager: AddUnapprovedZCashTransaction()
    ZCashTxManager->>ZCashWalletService: CreateOrchardToTransparentTransaction()
    ZCashWalletService->>ZCashWalletService: Validate transparent address
    ZCashWalletService->>CreateTask: Start()
    CreateTask->>OrchardSyncState: GetSpendableNotes()
    OrchardSyncState-->>CreateTask: Shielded notes
    CreateTask->>OrchardSyncState: CalculateWitnessForCheckpoint()
    OrchardSyncState-->>CreateTask: Notes with witnesses
    CreateTask->>ZCashRpc: GetTreeState()
    ZCashRpc-->>CreateTask: Tree state
    CreateTask->>OrchardBundleManager: Create(inputs, outputs=[])
    OrchardBundleManager-->>CreateTask: Unsigned bundle
    CreateTask-->>ZCashWalletService: ZCashTransaction
    ZCashWalletService-->>ZCashTxManager: Transaction
    ZCashTxManager-->>UI: Transaction created
    
    User->>UI: Signs & sends
    UI->>ZCashWalletService: SignAndPostTransaction()
    ZCashWalletService->>OrchardBundleManager: Sign()
    OrchardBundleManager-->>ZCashWalletService: Signed transaction data
    ZCashWalletService->>ZCashRpc: SendTransaction()
    ZCashRpc-->>ZCashWalletService: Success
    ZCashWalletService-->>UI: Transaction submitted
    UI->>User: Shows "Amount has been unshielded"
Loading

@cypt4 cypt4 removed the request for review from a team December 9, 2025 12:44
@brave-builds
Copy link
Collaborator

Warning

You have got a presubmit warning. Please address it if possible.

A banned pattern was used.
    components/brave_wallet/browser/zcash/zcash_wallet_service_unittest.cc:3396:
      Do not RunUntilIdle. If possible, explicitly quit the run loop using run_loop.Quit() or run_loop.QuitClosure() if completion can be observed using a lambda or callback. Otherwise, wait for the condition to be true via base::test::RunUntil().

@brave-builds
Copy link
Collaborator

Warning

You have got a presubmit warning. Please address it if possible.

A banned pattern was used.
    components/brave_wallet/browser/zcash/zcash_wallet_service_unittest.cc:3416:
      Do not RunUntilIdle. If possible, explicitly quit the run loop using run_loop.Quit() or run_loop.QuitClosure() if completion can be observed using a lambda or callback. Otherwise, wait for the condition to be true via base::test::RunUntil().

@brave-builds
Copy link
Collaborator

Warning

You have got a presubmit warning. Please address it if possible.

A banned pattern was used.
    components/brave_wallet/browser/zcash/zcash_wallet_service_unittest.cc:3684:
      Do not RunUntilIdle. If possible, explicitly quit the run loop using run_loop.Quit() or run_loop.QuitClosure() if completion can be observed using a lambda or callback. Otherwise, wait for the condition to be true via base::test::RunUntil().

@brave-builds
Copy link
Collaborator

Warning

You have got a presubmit warning. Please address it if possible.

Found 1 lines longer than 80 characters (first 5 shown).

Items:

components/brave_wallet_ui/page/screens/send/components/select_address_modal/select_address_modal.tsx, line 623, 88 chars

@wknapik wknapik merged commit b8e2b0a into master Dec 15, 2025
19 checks passed
@wknapik wknapik deleted the brave_45875_2 branch December 15, 2025 12:58
@github-actions github-actions bot added this to the 1.87.x - Nightly milestone Dec 15, 2025
@brave-builds
Copy link
Collaborator

Released in v1.87.85

@srirambv
Copy link
Contributor

srirambv commented Jan 5, 2026

Verification passed on

Brave 1.87.143 Chromium: 144.0.7559.31 (Official Build) nightly (64-bit)
Revision 7c92d0e
OS Windows 11 Version 25H2 (Build 26200.7462)
  • Verified steps from PR description
  • Verified able to Unsheild ZEC in send transaction
  • Verified Unshield transaction shows correct set of inputs/outputs
  • Verified Unshield transaction generates correct transaction fee value
  • Verified once transaction is completed, the transparent address has the correct balance
brave_btfs5WyIqf.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/storybook-url Deploy storybook and provide a unique URL for each build feature/web3/wallet/core feature/web3/wallet puLL-Merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ZCash] Support S->T transactions

6 participants