Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wallet): Implemented show all networks assets #17615

Closed
wants to merge 1 commit into from
Closed
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
20 changes: 17 additions & 3 deletions android/java/org/chromium/chrome/browser/app/BraveActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package org.chromium.chrome.browser.app;

import static org.chromium.chrome.browser.app.domain.NetworkSelectorModel.Mode.DEFAULT_WALLET_NETWORK;
import static org.chromium.chrome.browser.crypto_wallet.activities.NetworkSelectorActivity.NETWORK_SELECTOR_KEY;
import static org.chromium.chrome.browser.crypto_wallet.activities.NetworkSelectorActivity.NETWORK_SELECTOR_MODE;
import static org.chromium.ui.base.ViewUtils.dpToPx;

Expand Down Expand Up @@ -1245,15 +1246,28 @@ public void viewOnBlockExplorer(String address, @CoinType.EnumType int coinType)

// should only be called if the wallet is setup and unlocked
public void openNetworkSelection() {
openNetworkSelection(DEFAULT_WALLET_NETWORK);
openNetworkSelection(DEFAULT_WALLET_NETWORK, null);
}

// should only be called if the wallet is setup and unlocked
public void openNetworkSelection(NetworkSelectorModel.Mode mode) {
/**
* Open the network selector activity with key as an identifier to show the previously selected
* local network (if available otherwise All Networks as default) on {@link
* NetworkSelectorActivity}.
* @param mode Whether to open network selection for default/global network mode or
* in local network selection mode i.e.
* View <=> NetworkSelection state only with All Networks option.
* @param key as identifier to bind local state of NetworkSelection with the view. If null then
* use global/default network selection mode.
^ IMP: Should only be called if the wallet is setup and unlocked
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
^ IMP: Should only be called if the wallet is setup and unlocked
* IMP: Should only be called if the wallet is set up and unlocked.

*/
public void openNetworkSelection(NetworkSelectorModel.Mode mode, String key) {
Intent braveNetworkSelectionIntent = new Intent(this, NetworkSelectorActivity.class);
braveNetworkSelectionIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// Either in global or local network selection mode
braveNetworkSelectionIntent.putExtra(NETWORK_SELECTOR_MODE, mode);
// To bind selection between the caller and NetworkSelection Activity for local state of
// network selection
braveNetworkSelectionIntent.putExtra(NETWORK_SELECTOR_KEY, key);
startActivity(braveNetworkSelectionIntent);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class CryptoModel {
private TxService mTxService;
Expand Down Expand Up @@ -387,6 +388,14 @@ public List<CryptoAccountTypeInfo> getSupportedCryptoAccountTypes() {
return CryptoModel.this.getSupportedCryptoAccountTypes();
}

@Override
public List<Integer> getSupportedCryptoCoins() {
return getSupportedCryptoAccountTypes()
.stream()
.map(CryptoAccountTypeInfo::getCoinType)
.collect(Collectors.toList());
}

@Override
public LiveData<List<AccountInfo>> getAccounts() {
return mAccountInfosFromKeyRingModel;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/* Copyright (c) 2023 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/. */

package org.chromium.chrome.browser.app.domain;

import android.content.Context;
Expand All @@ -16,5 +21,6 @@ public interface CryptoSharedData {
LiveData<Integer> getCoinTypeLd();
String[] getEnabledKeyrings();
List<CryptoAccountTypeInfo> getSupportedCryptoAccountTypes();
List<Integer> getSupportedCryptoCoins();
LiveData<List<AccountInfo>> getAccounts();
}
127 changes: 98 additions & 29 deletions android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
import android.text.TextUtils;
import android.util.Pair;

import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MediatorLiveData;
import androidx.lifecycle.MutableLiveData;
Expand All @@ -24,41 +28,47 @@
import org.chromium.chrome.browser.crypto_wallet.model.CryptoAccountTypeInfo;
import org.chromium.chrome.browser.crypto_wallet.util.JavaUtils;
import org.chromium.chrome.browser.crypto_wallet.util.NetworkResponsesCollector;
import org.chromium.chrome.browser.crypto_wallet.util.NetworkUtils;
import org.chromium.chrome.browser.crypto_wallet.util.Utils;
import org.chromium.chrome.browser.crypto_wallet.util.WalletConstants;
import org.chromium.chrome.browser.util.Triple;
import org.chromium.mojo.bindings.Callbacks;
import org.chromium.mojo.system.MojoException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class NetworkModel implements JsonRpcServiceObserver {
private JsonRpcService mJsonRpcService;
private final Object mLock = new Object();
private final MediatorLiveData<String> _mChainId;
private final MediatorLiveData<NetworkInfo[]> _mDefaultCoinCryptoNetworks;
private final MutableLiveData<NetworkInfo[]> _mCryptoNetworks;
private final MutableLiveData<List<NetworkInfo>> _mCryptoNetworks;
private final CryptoSharedData mSharedData;
private final CryptoSharedActions mCryptoActions;
private final MediatorLiveData<Pair<String, NetworkInfo[]>> _mPairChainAndNetwork;
private final MediatorLiveData<NetworkInfo> _mNeedToCreateAccountForNetwork;
private final MediatorLiveData<NetworkInfo> _mDefaultNetwork;
private final MediatorLiveData<Triple<String, NetworkInfo, NetworkInfo[]>>
private final MediatorLiveData<Triple<String, NetworkInfo, List<NetworkInfo>>>
_mChainNetworkAllNetwork;
private final Context mContext;
private final MediatorLiveData<String[]> _mCustomNetworkIds;
private final MediatorLiveData<List<NetworkInfo>> _mPrimaryNetworks;
private final MediatorLiveData<List<NetworkInfo>> _mSecondaryNetworks;
private NetworkSelectorModel mNetworkSelectorModel;
private Map<String, NetworkSelectorModel> mNetworkSelectorMap;
public final LiveData<String[]> mCustomNetworkIds;
public LiveData<NetworkInfo> mNeedToCreateAccountForNetwork;
public final LiveData<Triple<String, NetworkInfo, NetworkInfo[]>> mChainNetworkAllNetwork;
public final LiveData<Triple<String, NetworkInfo, List<NetworkInfo>>> mChainNetworkAllNetwork;
public final LiveData<Pair<String, NetworkInfo[]>> mPairChainAndNetwork;
public final LiveData<String> mChainId;
public final LiveData<NetworkInfo[]> mDefaultCoinCryptoNetworks;
public final LiveData<NetworkInfo[]> mCryptoNetworks;
public final LiveData<List<NetworkInfo>> mCryptoNetworks;
public final LiveData<NetworkInfo> mDefaultNetwork;
public final LiveData<List<NetworkInfo>> mPrimaryNetworks;
public final LiveData<List<NetworkInfo>> mSecondaryNetworks;
Expand All @@ -74,7 +84,7 @@ public NetworkModel(JsonRpcService jsonRpcService, CryptoSharedData sharedData,
_mDefaultCoinCryptoNetworks = new MediatorLiveData<>();
mChainId = _mChainId;
mDefaultCoinCryptoNetworks = _mDefaultCoinCryptoNetworks;
_mCryptoNetworks = new MutableLiveData<>(new NetworkInfo[0]);
_mCryptoNetworks = new MutableLiveData<>(Collections.emptyList());
mCryptoNetworks = _mCryptoNetworks;
_mPairChainAndNetwork = new MediatorLiveData<>();
mPairChainAndNetwork = _mPairChainAndNetwork;
Expand All @@ -92,7 +102,7 @@ public NetworkModel(JsonRpcService jsonRpcService, CryptoSharedData sharedData,
_mSecondaryNetworks = new MediatorLiveData<>();
mSecondaryNetworks = _mSecondaryNetworks;
jsonRpcService.addObserver(this);
mNetworkSelectorModel = new NetworkSelectorModel(this, mContext);
mNetworkSelectorMap = new HashMap<>();
_mPairChainAndNetwork.setValue(Pair.create("", new NetworkInfo[] {}));
_mPairChainAndNetwork.addSource(_mChainId, chainId -> {
_mPairChainAndNetwork.setValue(
Expand All @@ -106,8 +116,7 @@ public NetworkModel(JsonRpcService jsonRpcService, CryptoSharedData sharedData,
NetworkInfo[] cryptoNetworks = chainIdAndInfosPair.second;
if (chainId == null || cryptoNetworks == null) return;
for (NetworkInfo networkInfo : cryptoNetworks) {
if (networkInfo.chainId.equals(chainId)
&& sharedData.getCoinType() == networkInfo.coin) {
if (networkInfo.chainId.equals(chainId)) {
_mDefaultNetwork.postValue(networkInfo);
break;
}
Expand All @@ -131,11 +140,19 @@ public NetworkModel(JsonRpcService jsonRpcService, CryptoSharedData sharedData,
});

_mChainNetworkAllNetwork.addSource(_mDefaultNetwork, networkInfo -> {
NetworkInfo currNetwork = null;
if (_mChainNetworkAllNetwork.getValue() != null) {
currNetwork = _mChainNetworkAllNetwork.getValue().second;
}
if (currNetwork != null && networkInfo != null
&& NetworkUtils.Filters.isSameNetwork(currNetwork, networkInfo)) {
return;
}
_mChainNetworkAllNetwork.postValue(
Triple.create(networkInfo.chainId, networkInfo, _mCryptoNetworks.getValue()));
});
_mChainNetworkAllNetwork.addSource(_mCryptoNetworks, networkInfos -> {
String chainId = _mChainId.getValue();
String chainId = null;
NetworkInfo networkInfo = _mDefaultNetwork.getValue();
if (networkInfo != null) {
chainId = networkInfo.chainId;
Expand Down Expand Up @@ -172,12 +189,43 @@ public NetworkModel(JsonRpcService jsonRpcService, CryptoSharedData sharedData,
* @return mNetworkSelectorModel object in DEFAULT_WALLET_NETWORK mode
*/
public NetworkSelectorModel openNetworkSelectorModel() {
return openNetworkSelectorModel(NetworkSelectorModel.Mode.DEFAULT_WALLET_NETWORK);
return new NetworkSelectorModel(this, mContext);
}

public NetworkSelectorModel openNetworkSelectorModel(NetworkSelectorModel.Mode mode) {
mNetworkSelectorModel.updateSelectorMode(mode);
return mNetworkSelectorModel;
/**
* Create a network model to handle either default or local state (onscreen e.g. {@link
* org.chromium.chrome.browser.crypto_wallet.fragments.PortfolioFragment}). Local network
* selection can be used by many views so make sure to use the same key which acts as a contract
* between the view and the selection activity.
* @param key acts as a binding key between caller and selection activity.
* @param mode to handle network selection event globally or locally.
* @param lifecycle to auto remove network-selection objects.
* @return NetworkSelectorModel object.
*/
Comment on lines +195 to +204
Copy link
Collaborator

Choose a reason for hiding this comment

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

❤️

public NetworkSelectorModel openNetworkSelectorModel(
String key, NetworkSelectorModel.Mode mode, Lifecycle lifecycle) {
NetworkSelectorModel networkSelectorModel;
if (key == null) {
return new NetworkSelectorModel(mode, this, mContext);
} else if (mNetworkSelectorMap.containsKey(key)) {
// Use existing NetworkSelector object to show the previously selected network
networkSelectorModel = mNetworkSelectorMap.get(key);
if (networkSelectorModel != null && mode != networkSelectorModel.getMode()) {
networkSelectorModel.updateSelectorMode(mode);
}
} else {
networkSelectorModel = new NetworkSelectorModel(mode, this, mContext);
mNetworkSelectorMap.put(key, networkSelectorModel);
}
if (lifecycle != null) {
lifecycle.addObserver(new DefaultLifecycleObserver() {
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
mNetworkSelectorMap.remove(key);
}
});
}
return networkSelectorModel;
}

public void setAccountInfosFromKeyRingModel(
Expand Down Expand Up @@ -212,22 +260,27 @@ public void refreshNetworks() {
init();
}

static void getAllNetworks(JsonRpcService jsonRpcService, List<Integer> supportedCoins,
Copy link
Collaborator

Choose a reason for hiding this comment

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

public? Or package private for a reason?

Copy link
Author

Choose a reason for hiding this comment

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

package accessible only, if there is no modifier then it is default

Callbacks.Callback1<Set<NetworkInfo>> callback) {
if (jsonRpcService == null) {
callback.call(Collections.emptySet());
return;
}

NetworkResponsesCollector networkResponsesCollector =
new NetworkResponsesCollector(jsonRpcService, supportedCoins);
networkResponsesCollector.getNetworks(networkInfos -> { callback.call(networkInfos); });
}

public void init() {
synchronized (mLock) {
if (mJsonRpcService == null) {
return;
}

List<Integer> coins = new ArrayList<>();
for (CryptoAccountTypeInfo cryptoAccountTypeInfo :
mSharedData.getSupportedCryptoAccountTypes()) {
coins.add(cryptoAccountTypeInfo.getCoinType());
}
NetworkResponsesCollector networkResponsesCollector =
new NetworkResponsesCollector(mJsonRpcService, coins);
networkResponsesCollector.getNetworks(networkInfos -> {
_mCryptoNetworks.postValue(
stripDebugNetwork(mContext, networkInfos.toArray(new NetworkInfo[0])));
getAllNetworks(mJsonRpcService, mSharedData.getSupportedCryptoCoins(), allNetworks -> {
_mCryptoNetworks.postValue(Arrays.asList(
stripDebugNetwork(mContext, allNetworks.toArray(new NetworkInfo[0]))));
});
}
}
Expand All @@ -250,6 +303,11 @@ public void setNetworkWithAccountCheck(
}
}

public void setNetworkWithAccountCheck(String chainId, Callbacks.Callback1<Boolean> callback) {
NetworkInfo networkToBeSetAsSelected = getNetwork(chainId);
setNetworkWithAccountCheck(networkToBeSetAsSelected, callback);
}

public void setNetwork(
NetworkInfo networkToBeSetAsSelected, Callbacks.Callback1<Boolean> callback) {
mJsonRpcService.setNetwork(
Expand All @@ -268,8 +326,8 @@ public void clearCreateAccountState() {
_mNeedToCreateAccountForNetwork.postValue(null);
}

public NetworkInfo[] stripNoBuySwapNetworks(
NetworkInfo[] networkInfos, BuySendSwapActivity.ActivityType type) {
public List<NetworkInfo> stripNoBuySwapNetworks(
List<NetworkInfo> networkInfos, BuySendSwapActivity.ActivityType type) {
List<NetworkInfo> networkInfosFiltered = new ArrayList<>();
for (NetworkInfo networkInfo : networkInfos) {
if (type == BuySendSwapActivity.ActivityType.BUY && Utils.allowBuy(networkInfo.chainId)
Expand All @@ -279,7 +337,18 @@ public NetworkInfo[] stripNoBuySwapNetworks(
}
}

return networkInfosFiltered.toArray(new NetworkInfo[networkInfosFiltered.size()]);
return networkInfosFiltered;
}

public NetworkInfo getNetwork(String chainId) {
if (TextUtils.isEmpty(chainId)) return null;
List<NetworkInfo> cryptoNws = JavaUtils.safeVal(_mCryptoNetworks.getValue());
for (NetworkInfo info : cryptoNws) {
if (info.chainId.equals(chainId)) {
return info;
}
}
return null;
}

private NetworkInfo[] stripDebugNetwork(Context context, NetworkInfo[] networkInfos) {
Expand All @@ -298,8 +367,8 @@ private NetworkInfo[] stripDebugNetwork(Context context, NetworkInfo[] networkIn
}

List<NetworkInfo> getSubTestNetworks(NetworkInfo networkInfo) {
NetworkInfo[] cryptoNws = _mCryptoNetworks.getValue();
if (cryptoNws == null || cryptoNws.length == 0
List<NetworkInfo> cryptoNws = _mCryptoNetworks.getValue();
if (cryptoNws == null || cryptoNws.size() == 0
|| !WalletConstants.SUPPORTED_TOP_LEVEL_CHAIN_IDS.contains(networkInfo.chainId))
return Collections.emptyList();
List<NetworkInfo> list = new ArrayList<>();
Expand Down
Loading