Skip to content

Commit

Permalink
feat(wallet): Add a debug option to enable bitcoin testnet (#22971)
Browse files Browse the repository at this point in the history
  • Loading branch information
nuo-xu authored Apr 10, 2024
1 parent 63d4e30 commit 633320c
Show file tree
Hide file tree
Showing 15 changed files with 265 additions and 81 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2021 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

import BraveUI
import BraveWallet
import Preferences
import SwiftUI

struct BraveWalletDebugMenu: View {

@ObservedObject var enableBitcoinTestnet = Preferences.Wallet.isBitcoinTestnetEnabled

var body: some View {
List {
Section {
Toggle("Enable Bitcoin Testnet", isOn: $enableBitcoinTestnet.value)
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
}
}
.listBackgroundColor(Color(UIColor.braveGroupedBackground))
.navigationTitle("Brave Wallet Debug")
.navigationBarTitleDisplayMode(.inline)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ class SettingsViewController: TableViewController {
navigationController?.pushViewController(hostingController, animated: true)
}

private func displayBraveWalletDebugMenu() {
let hostingController =
UIHostingController(rootView: BraveWalletDebugMenu())

navigationController?.pushViewController(hostingController, animated: true)
}

/// The function for refreshing VPN status for menu
/// - Parameter notification: NEVPNStatusDidChange
@objc private func vpnConfigChanged(notification: NSNotification) {
Expand Down Expand Up @@ -1062,6 +1069,14 @@ class SettingsViewController: TableViewController {
accessory: .disclosureIndicator,
cellClass: MultilineValue1Cell.self
),
Row(
text: "View Brave Wallet Debug Menu",
selection: { [unowned self] in
self.displayBraveWalletDebugMenu()
},
accessory: .disclosureIndicator,
cellClass: MultilineValue1Cell.self
),
Row(
text: "Consolidate Privacy Report Data",
detailText:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import BraveCore
import BraveUI
import DesignSystem
import Preferences
import Strings
import SwiftUI

Expand Down Expand Up @@ -419,8 +420,14 @@ struct AddAccountView: View {

private var isKeyringSelectionRequired: Bool {
guard !selectedCoinNetworks.isEmpty else { return false }
return (selectedCoin == .fil || selectedCoin == .btc)
|| (preSelectedCoin == .fil || preSelectedCoin == .btc)
if selectedCoin == .fil || preSelectedCoin == .fil {
return true
} else if (selectedCoin == .btc || preSelectedCoin == .btc)
&& Preferences.Wallet.isBitcoinTestnetEnabled.value
{
return true
}
return false
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class AccountsStore: ObservableObject, WalletObserverStore {
}
let tokens = allTokensPerNetwork.flatMap(\.tokens)

var allAccounts = await keyringService.allAccounts().accounts
var allAccounts = await keyringService.allAccountInfos()
var accountDetails = buildAccountDetails(accounts: allAccounts, tokens: tokens)
self.primaryAccounts =
accountDetails
Expand All @@ -123,7 +123,7 @@ class AccountsStore: ObservableObject, WalletObserverStore {
)

// if new accounts added while balances were being fetched.
allAccounts = await keyringService.allAccounts().accounts
allAccounts = await keyringService.allAccountInfos()
accountDetails = buildAccountDetails(accounts: allAccounts, tokens: tokens)
self.primaryAccounts =
accountDetails
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ class DepositTokenStore: ObservableObject, WalletObserverStore {
accounts: allAccounts.filter({ $0.coin == .btc })
)
}
self.allNetworks = await rpcService.allNetworksForSupportedCoins(
respectTestnetPreference: true
)
self.allNetworks = await rpcService.allNetworksForSupportedCoins()
self.update()
}
}
Expand Down
23 changes: 23 additions & 0 deletions ios/brave-ios/Sources/BraveWallet/Crypto/Stores/KeyringStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ public class KeyringStore: ObservableObject, WalletObserverStore {
self.keychain = keychain

setupObservers()

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

updateInfo()

Task { @MainActor in
Expand Down Expand Up @@ -655,3 +658,23 @@ public class KeyringStore: ObservableObject, WalletObserverStore {
keychain.getPasswordFromKeychain(key: Self.passwordKeychainKey)
}
}

extension KeyringStore: PreferencesObserver {
public func preferencesDidChange(for key: String) {
if Preferences.Wallet.isBitcoinTestnetEnabled.value == false {
// user disabled Bitcoin Testnet
Task { @MainActor in
let allAccounts = await keyringService.allAccounts()
if let currentlySelectedAccount = allAccounts.selectedAccount,
currentlySelectedAccount.keyringId == .bitcoin84Testnet,
let firstAvailableAccount = allAccounts.accounts.first(where: {
$0.keyringId != currentlySelectedAccount.keyringId
})
{
// we need to switch to the first available account
setSelectedAccount(to: firstAvailableAccount)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ public class NFTStore: ObservableObject, WalletObserverStore {
let isLocked = await keyringService.isLocked()
guard !isLocked else { return } // `update() will be called after unlock`

self.allAccounts = await keyringService.allAccounts().accounts
self.allAccounts = await keyringService.allAccountInfos()
.filter { account in
WalletConstants.supportedCoinTypes().contains(account.coin)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,12 @@ extension Array where Element == BraveWallet.NetworkInfo {
/// Returns the known test networks in Self.
var testNetworks: [BraveWallet.NetworkInfo] {
filter {
WalletConstants.supportedTestNetworkChainIds.contains($0.chainId)
if !Preferences.Wallet.isBitcoinTestnetEnabled.value
&& $0.chainId == BraveWallet.BitcoinTestnet
{
return false
}
return WalletConstants.supportedTestNetworkChainIds.contains($0.chainId)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ public class PortfolioStore: ObservableObject, WalletObserverStore {
guard !isLocked else { return } // `update() will be called after unlock`

self.isLoadingBalances = true
self.allAccounts = await keyringService.allAccounts().accounts
self.allAccounts = await keyringService.allAccountInfos()
.filter { account in
WalletConstants.supportedCoinTypes().contains(account.coin)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import BraveCore
import Foundation
import OrderedCollections
import Preferences

extension BraveWalletKeyringService {

Expand All @@ -19,4 +20,14 @@ extension BraveWalletKeyringService {
let allAccountsForKeyring = await allAccounts().accounts.filter { $0.keyringId == keyringId }
return !allAccountsForKeyring.isEmpty
}

/// Return a list of all accounts with checking if Bitcoin testnet is enabled
/// The list of account will not include Bitcoin Testnet Accounts if Bitcoin testnet is disabled.
func allAccountInfos(checkBTCTestnet: Bool = true) async -> [BraveWallet.AccountInfo] {
var accounts = await self.allAccounts().accounts
if checkBTCTestnet, !Preferences.Wallet.isBitcoinTestnetEnabled.value {
accounts = accounts.filter({ $0.keyringId != BraveWallet.KeyringId.bitcoin84Testnet })
}
return accounts
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,11 @@ extension BraveWalletJsonRpcService {
$0 == network.chainId
})
}
if Preferences.Wallet.showTestNetworks.value && respectTestnetPreference
&& network.chainId == BraveWallet.BitcoinTestnet
{ // if testnets are enabled, we still need to check if bitcoin testnet is enabled
return Preferences.Wallet.isBitcoinTestnetEnabled.value
}
return true
}
return allChains.sorted { lhs, rhs in
Expand Down
6 changes: 6 additions & 0 deletions ios/brave-ios/Sources/BraveWallet/WalletPreferences.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ extension Preferences {
key: "wallet.show-wallet-is-onboarding-completed",
default: false
)

/// Used for Debug section for anyone wants to test with Bitcoin Testnet network or account
public static let isBitcoinTestnetEnabled = Option<Bool>(
key: "wallet.is-bitcoin-testnet-enabled",
default: false
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ public class WalletUserAssetManager: WalletUserAssetManagerType, WalletObserverS
public func refreshBalances(_ completion: (() -> Void)? = nil) {
refreshBalanceTask?.cancel()
refreshBalanceTask = Task { @MainActor in
let accounts = await keyringService.allAccounts().accounts
let accounts = await keyringService.allAccountInfos()
let allNetworks = await rpcService.allNetworksForSupportedCoins()
let allUserAssets: [NetworkAssets] = self.getAllUserAssetsInNetworkAssets(
networks: allNetworks,
Expand Down
29 changes: 21 additions & 8 deletions ios/brave-ios/Tests/BraveWalletTests/AccountsStoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import XCTest

@MainActor class AccountsStoreTests: XCTestCase {

override class func tearDown() {
super.tearDown()
Preferences.Wallet.showTestNetworks.reset()
Preferences.Wallet.isBitcoinTestnetEnabled.reset()
}

private var cancellables: Set<AnyCancellable> = .init()

let ethAccount1: BraveWallet.AccountInfo = .mockEthAccount
Expand Down Expand Up @@ -96,8 +102,9 @@ import XCTest

let formatter = WeiFormatter(decimalFormatStyle: .decimals(precision: 18))

func testUpdate() async {
func updateHelper(bitcoinTestnetEnabled: Bool) async {
Preferences.Wallet.showTestNetworks.value = true
Preferences.Wallet.isBitcoinTestnetEnabled.value = bitcoinTestnetEnabled
let ethBalanceWei =
formatter.weiString(
from: mockETHBalanceAccount1,
Expand Down Expand Up @@ -295,7 +302,8 @@ import XCTest
XCTFail("Expected account details models")
return
}
XCTAssertEqual(accountDetails.count, 7)
let accountNumber = bitcoinTestnetEnabled ? 7 : 6
XCTAssertEqual(accountDetails.count, accountNumber)

XCTAssertEqual(accountDetails[safe: 0]?.account, self.ethAccount1)
XCTAssertEqual(accountDetails[safe: 0]?.tokensWithBalance, self.ethMainnetTokens)
Expand Down Expand Up @@ -325,18 +333,23 @@ import XCTest
XCTAssertEqual(accountDetails[safe: 5]?.tokensWithBalance, []) // BTC 0 value
XCTAssertEqual(accountDetails[safe: 5]?.totalBalanceFiat, "$0.00")

XCTAssertEqual(accountDetails[safe: 6]?.account, self.btcTestnetAccount)
XCTAssertEqual(accountDetails[safe: 6]?.tokensWithBalance, []) // BTC 0 value
XCTAssertEqual(accountDetails[safe: 6]?.totalBalanceFiat, "$0.00")
if bitcoinTestnetEnabled {
XCTAssertEqual(accountDetails[safe: 6]?.account, self.btcTestnetAccount)
XCTAssertEqual(accountDetails[safe: 6]?.tokensWithBalance, []) // BTC 0 value
XCTAssertEqual(accountDetails[safe: 6]?.totalBalanceFiat, "$0.00")
}
}.store(in: &cancellables)

store.update()

await fulfillment(of: [updateExpectation], timeout: 1)
}

override class func tearDown() {
super.tearDown()
Preferences.Wallet.showTestNetworks.reset()
func testUpdate() async {
await updateHelper(bitcoinTestnetEnabled: false)
}

func testUpdateBitcoinTestnet() async {
await updateHelper(bitcoinTestnetEnabled: true)
}
}
Loading

0 comments on commit 633320c

Please sign in to comment.