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): show nft section in portfolio #16643

Merged
merged 1 commit into from
Jan 13, 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
2 changes: 2 additions & 0 deletions android/brave_java_sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ brave_java_sources = [
"../../brave/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java",
"../../brave/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java",
"../../brave/android/java/org/chromium/chrome/browser/app/domain/NetworkSelectorModel.java",
"../../brave/android/java/org/chromium/chrome/browser/app/domain/PortfolioModel.java",
"../../brave/android/java/org/chromium/chrome/browser/app/domain/SendModel.java",
"../../brave/android/java/org/chromium/chrome/browser/app/domain/SwapModel.java",
"../../brave/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java",
Expand Down Expand Up @@ -157,6 +158,7 @@ brave_java_sources = [
"../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/AsyncUtils.java",
"../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/BalanceHelper.java",
"../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/Blockies.java",
"../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/ImageLoader.java",
"../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/ItemOffsetDecoration.java",
"../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/JavaUtils.java",
"../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/KeystoreHelper.java",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public class CryptoModel {
private SendModel mSendModel;

private NetworkModel mNetworkModel;
// Todo: create a models for portfolio
private PortfolioModel mPortfolioModel;
// Todo: create method to create and return new models for Asset, Account,
// TransactionConfirmation, SwapModel, AssetModel, SendModel

Expand All @@ -100,6 +100,9 @@ public CryptoModel(Context context, TxService txService, KeyringService keyringS
mPendingTxHelper = new PendingTxHelper(mTxService, new AccountInfo[0], true, true);
mNetworkModel =
new NetworkModel(mJsonRpcService, mSharedData, mCryptoSharedActions, context);
mPortfolioModel = new PortfolioModel(context, mTxService, mKeyringService,
mBlockchainRegistry, mJsonRpcService, mEthTxManagerProxy, mSolanaTxManagerProxy,
mBraveWalletService, mAssetRatioService, mSharedData);
_mIsSwapEnabled = new MediatorLiveData<>();
mIsSwapEnabled = _mIsSwapEnabled;
_mIsSwapEnabled.addSource(mNetworkModel.mChainId, chainId -> {
Expand All @@ -124,6 +127,9 @@ public void resetServices(Context context, TxService mTxService, KeyringService
this.mAssetRatioService = mAssetRatioService;
mPendingTxHelper.setTxService(mTxService);
mNetworkModel.resetServices(mJsonRpcService);
mPortfolioModel.resetServices(context, mTxService, mKeyringService, mBlockchainRegistry,
mJsonRpcService, mEthTxManagerProxy, mSolanaTxManagerProxy, mBraveWalletService,
mAssetRatioService);
}
init();
}
Expand Down Expand Up @@ -263,6 +269,10 @@ public NetworkModel getNetworkModel() {
return mNetworkModel;
}

public PortfolioModel getPortfolioModel() {
return mPortfolioModel;
}

public SendModel createSendModel() {
if (mSendModel != null) return mSendModel;
mSendModel =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/* Copyright (c) 2022 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;
import android.text.TextUtils;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import org.json.JSONException;
import org.json.JSONObject;

import org.chromium.brave_wallet.mojom.AssetRatioService;
import org.chromium.brave_wallet.mojom.BlockchainRegistry;
import org.chromium.brave_wallet.mojom.BlockchainToken;
import org.chromium.brave_wallet.mojom.BraveWalletService;
import org.chromium.brave_wallet.mojom.EthTxManagerProxy;
import org.chromium.brave_wallet.mojom.JsonRpcService;
import org.chromium.brave_wallet.mojom.KeyringService;
import org.chromium.brave_wallet.mojom.NetworkInfo;
import org.chromium.brave_wallet.mojom.SolanaTxManagerProxy;
import org.chromium.brave_wallet.mojom.TxService;
import org.chromium.chrome.browser.crypto_wallet.util.AssetUtils;
import org.chromium.chrome.browser.crypto_wallet.util.AsyncUtils;
import org.chromium.chrome.browser.crypto_wallet.util.JavaUtils;
import org.chromium.chrome.browser.crypto_wallet.util.PortfolioHelper;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PortfolioModel {
public final LiveData<List<NftDataModel>> mNftModels;
private final CryptoSharedData mSharedData;
private final MutableLiveData<List<NftDataModel>> _mNftModels;
private final Object mLock = new Object();
public PortfolioHelper mPortfolioHelper;
private TxService mTxService;
private KeyringService mKeyringService;
private BlockchainRegistry mBlockchainRegistry;
private JsonRpcService mJsonRpcService;
private EthTxManagerProxy mEthTxManagerProxy;
private SolanaTxManagerProxy mSolanaTxManagerProxy;
private BraveWalletService mBraveWalletService;
private AssetRatioService mAssetRatioService;
private Context mContext;

public PortfolioModel(Context context, TxService txService, KeyringService keyringService,
BlockchainRegistry blockchainRegistry, JsonRpcService jsonRpcService,
EthTxManagerProxy ethTxManagerProxy, SolanaTxManagerProxy solanaTxManagerProxy,
BraveWalletService braveWalletService, AssetRatioService assetRatioService,
CryptoSharedData sharedData) {
mContext = context;
mTxService = txService;
mKeyringService = keyringService;
mBlockchainRegistry = blockchainRegistry;
mJsonRpcService = jsonRpcService;
mEthTxManagerProxy = ethTxManagerProxy;
mSolanaTxManagerProxy = solanaTxManagerProxy;
mBraveWalletService = braveWalletService;
mAssetRatioService = assetRatioService;
mSharedData = sharedData;
_mNftModels = new MutableLiveData<>(Collections.emptyList());
mNftModels = _mNftModels;
}

// TODO(pav): We should fetch and process all portfolio list here
public void prepareNftListMetaData(List<BlockchainToken> nftList, NetworkInfo networkInfo,
PortfolioHelper portfolioHelper) {
mPortfolioHelper = portfolioHelper;
List<BlockchainToken> ercNfts = JavaUtils.filter(nftList, nft -> nft.isErc721);
List<NftDataModel> nftDataModels = new ArrayList<>();
AsyncUtils.MultiResponseHandler nftMetaDataHandler =
new AsyncUtils.MultiResponseHandler(ercNfts.size());

ArrayList<AsyncUtils.GetNftMetaDataContext> nftMetaDatas = new ArrayList<>();
for (BlockchainToken userAsset : nftList) {
if (userAsset.isErc721) {
AsyncUtils.GetNftMetaDataContext nftMetaData = new AsyncUtils.GetNftMetaDataContext(
nftMetaDataHandler.singleResponseComplete);
nftMetaData.asset = userAsset;
mJsonRpcService.getErc721Metadata(userAsset.contractAddress, userAsset.tokenId,
userAsset.chainId, nftMetaData);
nftMetaDatas.add(nftMetaData);
} else if (userAsset.isNft) { // other nfts e.g. solana
nftDataModels.add(new NftDataModel(userAsset, networkInfo, null));
}
}
nftMetaDataHandler.setWhenAllCompletedAction(() -> {
for (AsyncUtils.GetNftMetaDataContext metaData : nftMetaDatas) {
nftDataModels.add(new NftDataModel(metaData.asset, networkInfo,
new Erc721MetaData(metaData.erc721Metadata, metaData.errorCode,
metaData.errorMessage)));
}
_mNftModels.postValue(nftDataModels);
});
}

void resetServices(Context context, TxService mTxService, KeyringService mKeyringService,
BlockchainRegistry mBlockchainRegistry, JsonRpcService mJsonRpcService,
EthTxManagerProxy mEthTxManagerProxy, SolanaTxManagerProxy mSolanaTxManagerProxy,
BraveWalletService mBraveWalletService, AssetRatioService mAssetRatioService) {
synchronized (mLock) {
mContext = context;
this.mTxService = mTxService;
this.mKeyringService = mKeyringService;
this.mBlockchainRegistry = mBlockchainRegistry;
this.mJsonRpcService = mJsonRpcService;
this.mEthTxManagerProxy = mEthTxManagerProxy;
this.mSolanaTxManagerProxy = mSolanaTxManagerProxy;
this.mBraveWalletService = mBraveWalletService;
this.mAssetRatioService = mAssetRatioService;
}
}

public class NftDataModel {
public BlockchainToken token;
public NetworkInfo networkInfo;
public Erc721MetaData erc721MetaData;

public NftDataModel(
BlockchainToken token, NetworkInfo networkInfo, Erc721MetaData erc721MetaData) {
this.token = token;
this.networkInfo = networkInfo;
this.erc721MetaData = erc721MetaData;
}
}

public class Erc721MetaData implements Serializable {
public String mDescription;
public String mImageUrl;
public String mName;
public int mErrCode;
public String mErrMsg;

public Erc721MetaData(String jsonString, int mErrCode, String mErrMsg) {
this.mErrCode = mErrCode;
this.mErrMsg = mErrMsg;
try {
JSONObject metaDataJObj = new JSONObject(jsonString);
Pavneet-Sing marked this conversation as resolved.
Show resolved Hide resolved
mDescription = metaDataJObj.optString("description");
mImageUrl = refineUrl(metaDataJObj.optString("image"));
mName = metaDataJObj.optString("name");
} catch (JSONException ignored) {
}
}

public Erc721MetaData(String mDescription, String mImageUrl, String mName) {
this.mDescription = mDescription;
this.mImageUrl = mImageUrl;
this.mName = mName;
}

private String refineUrl(String url) {
if (TextUtils.isEmpty(url)) return "";
if (url.startsWith("data:image"))
return url;
else
return AssetUtils.httpifyIpfsUrl(url);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ public void setSelectedNetwork(String networkName) {
if (networkName.equals(nestedItem.getNetworkName())) {
nestedItem.setIsSelected(true);
if (networkSelectorItem.mNestedNetworkSelectorAdapter != null) {
nestedItem.mNestedNetworkSelectorAdapter.notifyItemChanged(j);
networkSelectorItem.mNestedNetworkSelectorAdapter.notifyItemChanged(j);
} else {
notifyItemChanged(i);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
import org.chromium.brave_wallet.mojom.TransactionInfo;
import org.chromium.brave_wallet.mojom.TransactionStatus;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.app.domain.PortfolioModel;
import org.chromium.chrome.browser.crypto_wallet.listeners.OnWalletListItemClick;
import org.chromium.chrome.browser.crypto_wallet.model.WalletListItemModel;
import org.chromium.chrome.browser.crypto_wallet.util.ImageLoader;
import org.chromium.chrome.browser.crypto_wallet.util.Utils;

import java.util.ArrayList;
Expand Down Expand Up @@ -192,11 +194,18 @@ public void onCheckedChanged(
walletListItemModel.getIconPath(), walletListItemModel.getIcon(),
holder.iconImg, null, true);
} else {
Utils.setBlockiesBitmapCustomAsset(mExecutor, mHandler, holder.iconImg,
walletListItemModel.getBlockchainToken().contractAddress,
walletListItemModel.getBlockchainToken().symbol,
context.getResources().getDisplayMetrics().density, null, context, false,
(float) 0.9);
PortfolioModel.NftDataModel nftDataModel = walletListItemModel.getNftDataModel();
if (walletListItemModel.hasNftImageLink()
&& ImageLoader.isSupported(nftDataModel.erc721MetaData.mImageUrl)) {
String url = nftDataModel.erc721MetaData.mImageUrl;
ImageLoader.loadNft(url, holder.iconImg, context, false);
} else {
Utils.setBlockiesBitmapCustomAsset(mExecutor, mHandler, holder.iconImg,
walletListItemModel.getBlockchainToken().contractAddress,
walletListItemModel.getBlockchainToken().symbol,
context.getResources().getDisplayMetrics().density, null, context,
false, (float) 0.9);
}
if (mType == AdapterType.EDIT_VISIBLE_ASSETS_LIST) {
onWalletListItemClick.onMaybeShowTrashButton(
walletListItemModel, holder.iconTrash);
Expand Down
Loading