Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Fix #6965: Duplicate add network requests can be shown #7047

Merged
merged 3 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
28 changes: 26 additions & 2 deletions Sources/BraveWallet/Crypto/Stores/CryptoStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -386,12 +386,31 @@ public class CryptoStore: ObservableObject {
return pendingRequest != nil
}

func handleWebpageRequestResponse(_ response: WebpageRequestResponse) {
// Helper to store the completion block of an Add Network dapp request.
typealias AddNetworkCompletion = (_ error: String?) -> Void
// The completion closure(s) are handled in `onAddEthereumChainRequestCompleted`
// when we determine if the chain was added successfully or not.
var addNetworkDappRequestCompletion: [String: AddNetworkCompletion] = [:]

func handleWebpageRequestResponse(
_ response: WebpageRequestResponse,
completion: ((_ error: String?) -> Void)? = nil
) {
switch response {
case let .switchChain(approved, originInfo):
rpcService.notifySwitchChainRequestProcessed(approved, origin: originInfo.origin)
case let .addNetwork(approved, chainId):
rpcService.addEthereumChainRequestCompleted(chainId, approved: approved)
// for add network request, approval requires network call so we must
// wait for `onAddEthereumChainRequestCompleted` to know success/failure
if approved, let completion {
// store `completion` closure until notified of `onAddEthereumChainRequestCompleted` event
addNetworkDappRequestCompletion[chainId] = completion
rpcService.addEthereumChainRequestCompleted(chainId, approved: approved)
} else { // not approved, or no completion closure provided.
completion?(nil)
rpcService.addEthereumChainRequestCompleted(chainId, approved: approved)
}
return
case let .addSuggestedToken(approved, contractAddresses):
walletService.notifyAddSuggestTokenRequestsProcessed(approved, contractAddresses: contractAddresses)
case let .signMessage(approved, id):
Expand All @@ -406,6 +425,7 @@ public class CryptoStore: ObservableObject {
walletService.notifySignAllTransactionsRequestProcessed(approved, id: id, signatures: nil, error: nil)
}
pendingRequest = nil
completion?(nil)
}

public func rejectAllPendingWebpageRequests() {
Expand Down Expand Up @@ -491,6 +511,10 @@ extension CryptoStore: BraveWalletJsonRpcServiceObserver {
}

public func onAddEthereumChainRequestCompleted(_ chainId: String, error: String) {
if let addNetworkDappRequestCompletion = addNetworkDappRequestCompletion[chainId] {
addNetworkDappRequestCompletion(error.isEmpty ? nil : error)
self.addNetworkDappRequestCompletion[chainId] = nil
}
}

public func onIsEip1559Changed(_ chainId: String, isEip1559: Bool) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct SuggestedNetworkView: View {

@State private var isPresentingNetworkDetails: CustomNetworkModel?
@State private var customNetworkError: CustomNetworkError?
@State private var isLoading: Bool = false

@ScaledMetric private var blockieSize = 24
private let maxBlockieSize: CGFloat = 72
Expand Down Expand Up @@ -253,10 +254,20 @@ struct SuggestedNetworkView: View {
Alert(
title: Text(error.errorTitle),
message: Text(error.errorDescription),
dismissButton: .default(Text(Strings.OKString))
dismissButton: .default(Text(Strings.OKString), action: onDismiss)
)
})
)
.onAppear {
// this can occur when Add Network is dismissed while still loading...
// we need to show loading state again, and handle success/failure response
if case let .addNetwork(network) = mode,
cryptoStore.addNetworkDappRequestCompletion[network.chainId] != nil {
self.isLoading = true
// overwrite the completion closure with a new one for this new view instance
cryptoStore.addNetworkDappRequestCompletion[network.chainId] = handleAddNetworkCompletion
}
}
}

private var actionButtonTitle: String {
Expand Down Expand Up @@ -288,29 +299,49 @@ struct SuggestedNetworkView: View {
}
}
.buttonStyle(BraveOutlineButtonStyle(size: .large))
Button(action: { // approve
handleAction(approved: true)
}) {
HStack {
Image(braveSystemName: "brave.checkmark.circle.fill")
Text(actionButtonTitle)
.multilineTextAlignment(.center)
.disabled(isLoading)
WalletLoadingButton(
isLoading: isLoading,
action: { // approve
handleAction(approved: true)
},
label: {
HStack {
Image(braveSystemName: "brave.checkmark.circle.fill")
Text(actionButtonTitle)
.multilineTextAlignment(.center)
}
}
}
)
.buttonStyle(BraveFilledButtonStyle(size: .large))
.disabled(isLoading)
}

private func handleAction(approved: Bool) {
isLoading = true
switch mode {
case let .addNetwork(networkInfo):
cryptoStore.handleWebpageRequestResponse(
.addNetwork(approved: approved, chainId: networkInfo.chainId)
.addNetwork(approved: approved, chainId: networkInfo.chainId),
completion: handleAddNetworkCompletion
)
case .switchNetworks:
cryptoStore.handleWebpageRequestResponse(
.switchChain(approved: approved, originInfo: originInfo)
.switchChain(approved: approved, originInfo: originInfo),
completion: { _ in
isLoading = false
onDismiss()
}
)
}
}

private func handleAddNetworkCompletion(_ error: String?) {
isLoading = false
if let error, !error.isEmpty {
customNetworkError = .failed(errorMessage: error)
return
}
onDismiss()
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/BraveWallet/WalletHostingViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ public class WalletHostingViewController: UIHostingController<CryptoView> {
presentingContext: presentingContext
)
)
rootView.dismissAction = { [unowned self] in
self.dismiss(animated: true)
rootView.dismissAction = { [weak self] in
self?.dismiss(animated: true)
}
rootView.openWalletURLAction = { [unowned self] url in
(self.presentingViewController ?? self).dismiss(animated: true) { [self] in
Expand Down