Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fetching or use cached zcash balance properly. fix and add unit tests…
… for zcash account and balance.
  • Loading branch information
nuo-xu committed May 26, 2025
commit 2bd18deaf65a587acba7f2698a0675ed54fd41b9
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ extension WalletStore {
privateMode: privateMode
),
let zcashWalletService = BraveWallet.ZCashWalletServiceFactory.get(
privateMode: privateMode)
privateMode: privateMode
)
else {
Logger.module.error("Failed to load wallet. One or more services were unavailable")
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@ import SwiftUI
struct BraveWalletDebugMenu: View {

@ObservedObject var enableBitcoinTestnet = Preferences.Wallet.isBitcoinTestnetEnabled
@ObservedObject var enableZcashTestnet = Preferences.Wallet.isZcashTestnetEnabled

var body: some View {
Form {
Section {
Toggle("Enable Bitcoin Testnet", isOn: $enableBitcoinTestnet.value)
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}

Section {
Toggle("Enable Zcash Testnet", isOn: $enableZcashTestnet.value)
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
}
.listBackgroundColor(Color(UIColor.braveGroupedBackground))
.navigationTitle("Brave Wallet Debug")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class AccountActivityStore: ObservableObject, WalletObserverStore {
private let solTxManagerProxy: BraveWalletSolanaTxManagerProxy
private let ipfsApi: IpfsAPI
private let bitcoinWalletService: BraveWalletBitcoinWalletService
private let zcashWalletService: BraveWalletZCashWalletService
private let assetManager: WalletUserAssetManagerType
/// Cache for storing `BlockchainToken`s that are not in user assets or our token registry.
/// This could occur with a dapp creating a transaction.
Expand Down Expand Up @@ -78,6 +79,7 @@ class AccountActivityStore: ObservableObject, WalletObserverStore {
solTxManagerProxy: BraveWalletSolanaTxManagerProxy,
ipfsApi: IpfsAPI,
bitcoinWalletService: BraveWalletBitcoinWalletService,
zcashWalletService: BraveWalletZCashWalletService,
userAssetManager: WalletUserAssetManagerType
) {
self.account = account
Expand All @@ -92,6 +94,7 @@ class AccountActivityStore: ObservableObject, WalletObserverStore {
self.solTxManagerProxy = solTxManagerProxy
self.ipfsApi = ipfsApi
self.bitcoinWalletService = bitcoinWalletService
self.zcashWalletService = zcashWalletService
self.assetManager = userAssetManager
self._isSwapSupported = .init(
wrappedValue: account.coin == .eth || account.coin == .sol
Expand Down Expand Up @@ -262,6 +265,19 @@ class AccountActivityStore: ObservableObject, WalletObserverStore {
$0[tokenId] = Double($1.balance) ?? 0
}
} else {
if account.coin == .zec {
let zecNetworkAsset = allUserNetworkAssets.first {
$0.network.supportedKeyrings.contains(account.keyringId.rawValue as NSNumber)
}
if let zecToken = zecNetworkAsset?.tokens.first {
let zecBalance =
await self.zcashWalletService.fetchZECTransparentBalances(
networkId: zecToken.chainId,
accountId: account.accountId
) ?? 0
tokenBalances = [zecToken.id: zecBalance]
}
}
tokenBalances = await self.rpcService.fetchBalancesForTokens(
account: account,
networkAssets: allUserNetworkAssets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class AccountsStore: ObservableObject, WalletObserverStore {
private let walletService: BraveWalletBraveWalletService
private let assetRatioService: BraveWalletAssetRatioService
private let bitcoinWalletService: BraveWalletBitcoinWalletService
private let zcashWalletService: BraveWalletZCashWalletService
private let userAssetManager: WalletUserAssetManagerType

private var keyringServiceObserver: KeyringServiceObserver?
Expand All @@ -59,13 +60,15 @@ class AccountsStore: ObservableObject, WalletObserverStore {
walletService: BraveWalletBraveWalletService,
assetRatioService: BraveWalletAssetRatioService,
bitcoinWalletService: BraveWalletBitcoinWalletService,
zcashWalletService: BraveWalletZCashWalletService,
userAssetManager: WalletUserAssetManagerType
) {
self.keyringService = keyringService
self.rpcService = rpcService
self.walletService = walletService
self.assetRatioService = assetRatioService
self.bitcoinWalletService = bitcoinWalletService
self.zcashWalletService = zcashWalletService
self.userAssetManager = userAssetManager
self.setupObservers()

Expand Down Expand Up @@ -176,7 +179,34 @@ class AccountsStore: ObservableObject, WalletObserverStore {
}
}
}
// Update non-BTC account balance
// Update Zcash account balance
if accounts.contains(where: { $0.coin == .zec }) {
await withTaskGroup(
of: [String: [String: Double]].self
) { [zcashWalletService] group in
for account in accounts where account.coin == .zec {
group.addTask {
if let zecToken = allNetworkAssets.first(where: {
$0.network.supportedKeyrings.contains(
account.keyringId.rawValue as NSNumber
)
})?.tokens.first {
let zecBalance =
await zcashWalletService.fetchZECTransparentBalances(
networkId: zecToken.chainId,
accountId: account.accountId
) ?? 0
return [account.id: [zecToken.id: zecBalance]]
}
return [:]
}
}
for await accountBTCBalances in group {
tokenBalancesCache.merge(with: accountBTCBalances)
}
}
}
// Update non-BTC/ZEC account balance
let balancesForAccounts = await withTaskGroup(
of: TokenBalanceCache.self,
body: { group in
Expand All @@ -203,10 +233,25 @@ class AccountsStore: ObservableObject, WalletObserverStore {
// a mock `rpcService` and `bitcoinWalletService`
group.addTask {
var balancesForTokens: [String: Double] = [:]
balancesForTokens = await self.rpcService.fetchBalancesForTokens(
account: account,
networkAssets: allNetworkAssets
)
if account.coin == .zec {
if let zecToken = allNetworkAssets.first(where: {
$0.network.supportedKeyrings.contains(
account.keyringId.rawValue as NSNumber
)
})?.tokens.first {
let zecBalance =
await self.zcashWalletService.fetchZECTransparentBalances(
networkId: zecToken.chainId,
accountId: account.accountId
) ?? 0
balancesForTokens = [zecToken.id: zecBalance]
}
} else {
balancesForTokens = await self.rpcService.fetchBalancesForTokens(
account: account,
networkAssets: allNetworkAssets
)
}
return [account.id: balancesForTokens]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class AssetDetailStore: ObservableObject, WalletObserverStore {
private let ipfsApi: IpfsAPI
private let swapService: BraveWalletSwapService
private let bitcoinWalletService: BraveWalletBitcoinWalletService
private let zcashWalletService: BraveWalletZCashWalletService
private let assetManager: WalletUserAssetManagerType
/// A list of tokens that are supported with the current selected network for all supported
/// on-ramp providers.
Expand Down Expand Up @@ -138,6 +139,7 @@ class AssetDetailStore: ObservableObject, WalletObserverStore {
ipfsApi: IpfsAPI,
swapService: BraveWalletSwapService,
bitcoinWalletService: BraveWalletBitcoinWalletService,
zcashWalletService: BraveWalletZCashWalletService,
userAssetManager: WalletUserAssetManagerType,
assetDetailType: AssetDetailType
) {
Expand All @@ -151,6 +153,7 @@ class AssetDetailStore: ObservableObject, WalletObserverStore {
self.ipfsApi = ipfsApi
self.swapService = swapService
self.bitcoinWalletService = bitcoinWalletService
self.zcashWalletService = zcashWalletService
self.assetManager = userAssetManager
self.assetDetailType = assetDetailType

Expand Down Expand Up @@ -471,11 +474,18 @@ class AssetDetailStore: ObservableObject, WalletObserverStore {
)?.first {
tokenBalance = Double(assetBalancePerAccount.balance)
} else {
tokenBalance = await self.rpcService.balance(
for: token,
in: accountAssetViewModel.account,
network: network
)
if accountAssetViewModel.account.coin == .zec {
tokenBalance = await self.zcashWalletService.fetchZECTransparentBalances(
networkId: network.chainId,
accountId: accountAssetViewModel.account.accountId
)
} else {
tokenBalance = await self.rpcService.balance(
for: token,
in: accountAssetViewModel.account,
network: network
)
}
}
}
return [AccountBalance(accountAssetViewModel.account, tokenBalance)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
rpcService: rpcService,
walletService: walletService,
txService: txService,
bitcoinWalletService: bitcoinWalletService
bitcoinWalletService: bitcoinWalletService,
zcashWalletService: zcashWalletService
)
self.origin = origin

Expand All @@ -188,6 +189,7 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
blockchainRegistry: blockchainRegistry,
ipfsApi: ipfsApi,
bitcoinWalletService: bitcoinWalletService,
zcashWalletService: zcashWalletService,
userAssetManager: userAssetManager
)
self.nftStore = .init(
Expand Down Expand Up @@ -218,6 +220,7 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
walletService: walletService,
assetRatioService: assetRatioService,
bitcoinWalletService: bitcoinWalletService,
zcashWalletService: zcashWalletService,
userAssetManager: userAssetManager
)
self.marketStore = .init(
Expand Down Expand Up @@ -522,6 +525,7 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
ipfsApi: ipfsApi,
swapService: swapService,
bitcoinWalletService: bitcoinWalletService,
zcashWalletService: zcashWalletService,
userAssetManager: userAssetManager,
assetDetailType: assetDetailType
)
Expand Down Expand Up @@ -560,6 +564,7 @@ public class CryptoStore: ObservableObject, WalletObserverStore {
solTxManagerProxy: solTxManagerProxy,
ipfsApi: ipfsApi,
bitcoinWalletService: bitcoinWalletService,
zcashWalletService: zcashWalletService,
userAssetManager: userAssetManager
)
accountActivityStore = store
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ public class KeyringStore: ObservableObject, WalletObserverStore {
setupObservers()

Preferences.Wallet.isBitcoinTestnetEnabled.observe(from: self)
Preferences.Wallet.isZcashTestnetEnabled.observe(from: self)

updateInfo()

Expand Down Expand Up @@ -721,7 +722,9 @@ public class KeyringStore: ObservableObject, WalletObserverStore {

extension KeyringStore: PreferencesObserver {
public func preferencesDidChange(for key: String) {
if Preferences.Wallet.isBitcoinTestnetEnabled.value == false {
if key == Preferences.Wallet.isBitcoinTestnetEnabled.key,
Preferences.Wallet.isBitcoinTestnetEnabled.value == false
{
// user disabled Bitcoin Testnet
Task { @MainActor in
let allAccounts = await keyringService.allAccounts()
Expand All @@ -735,6 +738,22 @@ extension KeyringStore: PreferencesObserver {
setSelectedAccount(to: firstAvailableAccount)
}
}
} else if key == Preferences.Wallet.isZcashTestnetEnabled.key,
Preferences.Wallet.isZcashTestnetEnabled.value == false
{
// user disabled Zcash Testnet
Task { @MainActor in
let allAccounts = await keyringService.allAccounts()
if let currentlySelectedAccount = allAccounts.selectedAccount,
currentlySelectedAccount.keyringId == .zCashTestnet,
let firstAvailableAccount = allAccounts.accounts.first(where: {
$0.keyringId != currentlySelectedAccount.keyringId
})
{
// we need to switch to the first available account
setSelectedAccount(to: firstAvailableAccount)
}
}
}
}
}
59 changes: 43 additions & 16 deletions ios/brave-ios/Sources/BraveWallet/Crypto/Stores/NetworkStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public class NetworkStore: ObservableObject, WalletObserverStore {
}
}
Preferences.Wallet.isBitcoinTestnetEnabled.observe(from: self)
Preferences.Wallet.isZcashTestnetEnabled.observe(from: self)
}

func tearDown() {
Expand Down Expand Up @@ -500,25 +501,46 @@ extension NetworkStore: PreferencesObserver {
public func preferencesDidChange(for key: String) {
// only observe `Preferences.Wallet.isBitcoinTestnetEnabled`
Task { @MainActor in
guard key == Preferences.Wallet.isBitcoinTestnetEnabled.key else { return }
let btcDefaultNetwork = await rpcService.network(coin: .btc, origin: nil)
let isBitcoinTestnetEnabled = Preferences.Wallet.isBitcoinTestnetEnabled.value
if !isBitcoinTestnetEnabled, btcDefaultNetwork.chainId == BraveWallet.BitcoinTestnet {
// bitcoin testnet is disabled but the btc coin type
// default network is testnet. Need to change it to btc
// mainnet, to prevent user hide the default network
if hiddenChains.contains(where: { $0.chainId == BraveWallet.BitcoinMainnet }) {
// bitcoin mainnet is currently hidden. unhide it then set it to default network
await rpcService.removeHiddenNetwork(
if key == Preferences.Wallet.isBitcoinTestnetEnabled.key {
let btcDefaultNetwork = await rpcService.network(coin: .btc, origin: nil)
let isBitcoinTestnetEnabled = Preferences.Wallet.isBitcoinTestnetEnabled.value
if !isBitcoinTestnetEnabled, btcDefaultNetwork.chainId == BraveWallet.BitcoinTestnet {
// bitcoin testnet is disabled but the btc coin type
// default network is testnet. Need to change it to btc
// mainnet, to prevent user hide the default network
if hiddenChains.contains(where: { $0.chainId == BraveWallet.BitcoinMainnet }) {
// bitcoin mainnet is currently hidden. unhide it then set it to default network
await rpcService.removeHiddenNetwork(
coin: .btc,
chainId: BraveWallet.BitcoinMainnet
)
}
await rpcService.setNetwork(
chainId: BraveWallet.BitcoinMainnet,
coin: .btc,
chainId: BraveWallet.BitcoinMainnet
origin: nil
)
}
} else if key == Preferences.Wallet.isZcashTestnetEnabled.key {
let zcashDefaultNetwork = await rpcService.network(coin: .zec, origin: nil)
let isZcashTestnetEnabled = Preferences.Wallet.isZcashTestnetEnabled.value
if !isZcashTestnetEnabled, zcashDefaultNetwork.chainId == BraveWallet.ZCashTestnet {
// zcash testnet is disabled but the zcash coin type
// default network is testnet. Need to change it to zcash
// mainnet, to prevent user hide the default network
if hiddenChains.contains(where: { $0.chainId == BraveWallet.ZCashMainnet }) {
// zcash mainnet is currently hidden. unhide it then set it to default network
await rpcService.removeHiddenNetwork(
coin: .zec,
chainId: BraveWallet.ZCashMainnet
)
}
await rpcService.setNetwork(
chainId: BraveWallet.ZCashMainnet,
coin: .zec,
origin: nil
)
}
await rpcService.setNetwork(
chainId: BraveWallet.BitcoinMainnet,
coin: .btc,
origin: nil
)
}
}
}
Expand Down Expand Up @@ -546,6 +568,11 @@ extension Array where Element == BraveWallet.NetworkInfo {
{
return false
}
if !Preferences.Wallet.isZcashTestnetEnabled.value
&& $0.chainId == BraveWallet.ZCashTestnet
{
return false
}
return WalletConstants.supportedTestNetworkChainIds.contains($0.chainId)
}
}
Expand Down
Loading