diff --git a/android/brave_java_sources.gni b/android/brave_java_sources.gni index ebde83ac31aff..a4ef6430ab4bd 100644 --- a/android/brave_java_sources.gni +++ b/android/brave_java_sources.gni @@ -152,6 +152,7 @@ brave_java_sources = [ "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/ParsedTransactionFees.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/PendingTxHelper.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/PortfolioHelper.java", + "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/SelectedAccountResponsesCollector.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/SmoothLineChartEquallySpaced.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/SolanaTransactionsGasHelper.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/TokenUtils.java", diff --git a/android/java/org/chromium/chrome/browser/app/BraveActivity.java b/android/java/org/chromium/chrome/browser/app/BraveActivity.java index cabc5bfee0b37..1b737c3166e83 100644 --- a/android/java/org/chromium/chrome/browser/app/BraveActivity.java +++ b/android/java/org/chromium/chrome/browser/app/BraveActivity.java @@ -1302,18 +1302,30 @@ private void setupObservers() { networkInfo.symbolName)) .setPositiveButton(R.string.wallet_action_yes, (dialog, which) -> { - mWalletModel.getKeyringModel().addAccount( - WalletUtils.getUniqueNextAccountName(this, - mWalletModel.getKeyringModel() - .mAccountInfos.getValue() - .toArray( - new AccountInfo[0]), - networkInfo.symbolName, - networkInfo.coin), - networkInfo.coin, isAccountAdded -> {}); mWalletModel.getCryptoModel() .getNetworkModel() - .clearCreateAccountState(); + .setNetwork(networkInfo, success -> { + if (success) { + mWalletModel.getKeyringModel().addAccount( + WalletUtils.getUniqueNextAccountName( + this, + mWalletModel + .getKeyringModel() + .mAccountInfos + .getValue() + .toArray( + new AccountInfo + [0]), + networkInfo + .symbolName, + networkInfo.coin), + networkInfo.coin, + isAccountAdded -> {}); + } + mWalletModel.getCryptoModel() + .getNetworkModel() + .clearCreateAccountState(); + }); }) .setNegativeButton( R.string.wallet_action_no, (dialog, which) -> { diff --git a/android/java/org/chromium/chrome/browser/app/domain/CryptoModel.java b/android/java/org/chromium/chrome/browser/app/domain/CryptoModel.java index 9602940dd7df1..753ff00bf883c 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/CryptoModel.java +++ b/android/java/org/chromium/chrome/browser/app/domain/CryptoModel.java @@ -10,6 +10,7 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MediatorLiveData; import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Observer; import androidx.lifecycle.Transformations; import org.chromium.brave_wallet.mojom.AccountInfo; @@ -35,6 +36,7 @@ import org.chromium.chrome.browser.crypto_wallet.activities.BraveWalletDAppsActivity; import org.chromium.chrome.browser.crypto_wallet.model.CryptoAccountTypeInfo; import org.chromium.chrome.browser.crypto_wallet.util.PendingTxHelper; +import org.chromium.chrome.browser.crypto_wallet.util.SelectedAccountResponsesCollector; import org.chromium.chrome.browser.crypto_wallet.util.Utils; import org.chromium.chrome.browser.crypto_wallet.util.WalletUtils; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -133,12 +135,17 @@ public void init() { if (mKeyringService == null || mPendingTxHelper == null) { return; } - getPendingTxHelper().fetchTransactions(null); - mKeyringService.getKeyringsInfo(mSharedData.getEnabledKeyrings(), keyringInfos -> { - List accountInfos = - WalletUtils.getAccountInfosFromKeyrings(keyringInfos); - mPendingTxHelper.setAccountInfos(accountInfos); - }); + // TODO(pav): uncomment the below and mvoe to refreshTransactions. + // To process pending tx from all networks and full network name + + // mKeyringService.getKeyringsInfo(mSharedData.getEnabledKeyrings(), + // keyringInfos -> { + // List accountInfos = + // WalletUtils.getAccountInfosFromKeyrings(keyringInfos); + // mPendingTxHelper.setAccountInfos(accountInfos); + // }); + + refreshTransactions(); // Filter out a separate list of unapproved transactions mPendingTransactions = @@ -192,10 +199,19 @@ public void refreshTransactions() { if (mKeyringService == null || mPendingTxHelper == null) { return; } + List coins = new ArrayList<>(); + for (CryptoAccountTypeInfo cryptoAccountTypeInfo : + mSharedData.getSupportedCryptoAccountTypes()) { + coins.add(cryptoAccountTypeInfo.getCoinType()); + } + mKeyringService.getKeyringsInfo(mSharedData.getEnabledKeyrings(), keyringInfos -> { List accountInfos = WalletUtils.getAccountInfosFromKeyrings(keyringInfos); - mPendingTxHelper.setAccountInfos(accountInfos); + new SelectedAccountResponsesCollector(mKeyringService, coins, accountInfos) + .getAccounts(defaultAccountPerCoin -> { + mPendingTxHelper.setAccountInfos(accountInfos); + }); }); } } @@ -210,7 +226,7 @@ public LiveData getSelectedPendingRequest() { } public LiveData> getPendingTransactions() { - return mPendingTransactions; + return mPendingTxHelper.mPendingTransactionInfoLd; } public LiveData> getAllTransactions() { diff --git a/android/java/org/chromium/chrome/browser/app/domain/CryptoSharedActions.java b/android/java/org/chromium/chrome/browser/app/domain/CryptoSharedActions.java index e7107113ec72a..2dce21548553a 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/CryptoSharedActions.java +++ b/android/java/org/chromium/chrome/browser/app/domain/CryptoSharedActions.java @@ -14,4 +14,5 @@ public interface CryptoSharedActions { void updateCoinType(); void updateCoinAccountNetworkInfo(@CoinType.EnumType int coin); + void onNewAccountAdded(); } diff --git a/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java b/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java index b4ca275b565e2..9212f9ca5158d 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java +++ b/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java @@ -18,7 +18,9 @@ import org.chromium.brave_wallet.mojom.KeyringInfo; import org.chromium.brave_wallet.mojom.KeyringService; import org.chromium.brave_wallet.mojom.KeyringServiceObserver; +import org.chromium.chrome.browser.crypto_wallet.model.CryptoAccountTypeInfo; import org.chromium.chrome.browser.crypto_wallet.util.AccountsPermissionsHelper; +import org.chromium.chrome.browser.crypto_wallet.util.SelectedAccountResponsesCollector; import org.chromium.chrome.browser.crypto_wallet.util.Utils; import org.chromium.chrome.browser.crypto_wallet.util.WalletUtils; import org.chromium.mojo.bindings.Callbacks; @@ -232,6 +234,7 @@ public void addAccount(String accountName, @CoinType.EnumType int coinType, } } mCryptoSharedActions.updateCoinType(); + mCryptoSharedActions.onNewAccountAdded(); callback.call(result); }); } diff --git a/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java b/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java index 48fe08f18c916..734d36a343b2e 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java +++ b/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java @@ -171,7 +171,7 @@ public void init() { } } - public void setNetwork( + public void setNetworkWithAccountCheck( NetworkInfo networkToBeSetAsSelected, Callbacks.Callback1 callback) { List accountInfos = mSharedData.getAccounts().getValue(); boolean hasAccountOfNetworkType = false; @@ -199,6 +199,16 @@ public void setNetwork( } } + public void setNetwork( + NetworkInfo networkToBeSetAsSelected, Callbacks.Callback1 callback) { + mJsonRpcService.setNetwork( + networkToBeSetAsSelected.chainId, networkToBeSetAsSelected.coin, isSelected -> { + callback.call(isSelected); + mCryptoActions.updateCoinType(); + init(); + }); + } + public void clearCreateAccountState() { _mNeedToCreateAccountForNetwork.postValue(null); } diff --git a/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java b/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java index cd11b0ba5a756..ece5ce096611a 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java +++ b/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java @@ -203,5 +203,10 @@ public void updateCoinAccountNetworkInfo(@CoinType.EnumType int coin) { mCryptoModel.getNetworkModel().init(); }); } + + @Override + public void onNewAccountAdded() { + mCryptoModel.refreshTransactions(); + } } } diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BuySendSwapActivity.java b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BuySendSwapActivity.java index 58eaf4ff35f28..c63a85b9746a5 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BuySendSwapActivity.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/BuySendSwapActivity.java @@ -47,6 +47,7 @@ import com.google.android.gms.vision.MultiProcessor; import com.google.android.gms.vision.barcode.Barcode; import com.google.android.gms.vision.barcode.BarcodeDetector; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.chromium.base.Log; import org.chromium.brave_wallet.mojom.AccountInfo; @@ -90,7 +91,6 @@ import org.chromium.ui.text.NoUnderlineClickableSpan; import java.io.IOException; -import java.math.BigDecimal; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -307,12 +307,13 @@ public void onItemSelected(AdapterView parent, View view, int position, long mFromValueText.setText(""); mFromValueText.setHint("0"); - mWalletModel.getCryptoModel().getNetworkModel().setNetwork(networkInfo, success -> { - if (!success) { - return; - } - mSelectedNetwork = networkInfo; - }); + mWalletModel.getCryptoModel().getNetworkModel().setNetworkWithAccountCheck( + networkInfo, success -> { + if (!success) { + return; + } + mSelectedNetwork = networkInfo; + }); } } else if (parent.getId() == R.id.accounts_spinner) { @@ -1582,6 +1583,46 @@ mSelectedNetwork.symbol, getResources().getDisplayMetrics().density, resetSwapFromToAssets(); } }); + + mWalletModel.getCryptoModel().getNetworkModel().mNeedToCreateAccountForNetwork.observe(this, networkInfo -> { + if (networkInfo == null) return; + MaterialAlertDialogBuilder builder = + new MaterialAlertDialogBuilder(this, R.style.BraveWalletAlertDialogTheme) + .setMessage(getString(R.string.brave_wallet_create_account_description, + networkInfo.symbolName)) + .setPositiveButton(R.string.wallet_action_yes, + (dialog, which) -> { + mWalletModel.getCryptoModel().getNetworkModel().setNetwork( + networkInfo, success -> { + if (success) { + mWalletModel.getKeyringModel().addAccount( + WalletUtils.getUniqueNextAccountName( + this, + mWalletModel + .getKeyringModel() + .mAccountInfos + .getValue() + .toArray( + new AccountInfo + [0]), + networkInfo.symbolName, + networkInfo.coin), + networkInfo.coin, + isAccountAdded -> {}); + } + mWalletModel.getCryptoModel() + .getNetworkModel() + .clearCreateAccountState(); + }); + }) + .setNegativeButton(R.string.wallet_action_no, (dialog, which) -> { + mWalletModel.getCryptoModel() + .getNetworkModel() + .clearCreateAccountState(); + dialog.dismiss(); + }); + builder.show(); + }); } @Override diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/NetworkSelectorActivity.java b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/NetworkSelectorActivity.java index 3ab6ba50000b6..6f77738cf1d5f 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/NetworkSelectorActivity.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/NetworkSelectorActivity.java @@ -11,7 +11,6 @@ import com.google.android.material.appbar.MaterialToolbar; -import org.chromium.base.Log; import org.chromium.brave_wallet.mojom.NetworkInfo; import org.chromium.chrome.R; import org.chromium.chrome.browser.app.BraveActivity; @@ -71,16 +70,17 @@ private void setSelectedNetworkObserver() { @Override public void onNetworkItemSelected(NetworkInfo networkInfo) { - mWalletModel.getCryptoModel().getNetworkModel().setNetwork(networkInfo, isSelected -> { - if (!isSelected) { - Toast.makeText(this, - getString(R.string.brave_wallet_network_selection_error, - networkInfo.chainName), - Toast.LENGTH_SHORT) - .show(); - networkSelectorAdapter.setSelectedNetwork(mSelectedNetwork); - } - finish(); - }); + mWalletModel.getCryptoModel().getNetworkModel().setNetworkWithAccountCheck( + networkInfo, isSelected -> { + if (!isSelected) { + Toast.makeText(this, + getString(R.string.brave_wallet_network_selection_error, + networkInfo.chainName), + Toast.LENGTH_SHORT) + .show(); + networkSelectorAdapter.setSelectedNetwork(mSelectedNetwork); + } + finish(); + }); } } diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/PortfolioFragment.java b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/PortfolioFragment.java index d644810b0ddf4..89e7f7ef289af 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/PortfolioFragment.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/fragments/PortfolioFragment.java @@ -5,8 +5,6 @@ package org.chromium.chrome.browser.crypto_wallet.fragments; -import static org.chromium.chrome.browser.crypto_wallet.util.Utils.fromHexWei; - import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; @@ -14,11 +12,9 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; import android.widget.Button; import android.widget.RadioButton; import android.widget.RadioGroup; -import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; @@ -30,39 +26,35 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import org.chromium.base.Log; import org.chromium.base.task.PostTask; import org.chromium.brave_wallet.mojom.AccountInfo; -import org.chromium.brave_wallet.mojom.AssetPrice; import org.chromium.brave_wallet.mojom.AssetPriceTimeframe; import org.chromium.brave_wallet.mojom.AssetRatioService; import org.chromium.brave_wallet.mojom.BlockchainToken; -import org.chromium.brave_wallet.mojom.BraveWalletConstants; import org.chromium.brave_wallet.mojom.BraveWalletService; -import org.chromium.brave_wallet.mojom.CoinType; 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.TransactionInfo; +import org.chromium.brave_wallet.mojom.TransactionStatus; +import org.chromium.brave_wallet.mojom.TransactionType; import org.chromium.brave_wallet.mojom.TxService; import org.chromium.chrome.R; import org.chromium.chrome.browser.app.BraveActivity; import org.chromium.chrome.browser.app.domain.WalletModel; import org.chromium.chrome.browser.crypto_wallet.BlockchainRegistryFactory; import org.chromium.chrome.browser.crypto_wallet.activities.BraveWalletActivity; -import org.chromium.chrome.browser.crypto_wallet.adapters.NetworkSpinnerAdapter; import org.chromium.chrome.browser.crypto_wallet.adapters.WalletCoinAdapter; 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.observers.ApprovedTxObserver; import org.chromium.chrome.browser.crypto_wallet.util.PendingTxHelper; import org.chromium.chrome.browser.crypto_wallet.util.PortfolioHelper; import org.chromium.chrome.browser.crypto_wallet.util.SmoothLineChartEquallySpaced; +import org.chromium.chrome.browser.crypto_wallet.util.TransactionUtils; import org.chromium.chrome.browser.crypto_wallet.util.Utils; import org.chromium.chrome.browser.crypto_wallet.util.WalletUtils; import org.chromium.content_public.browser.UiThreadTaskTraits; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -79,6 +71,8 @@ public class PortfolioFragment private int mPreviousCheckedRadioId; private int mCurrentTimeframeType; private WalletModel mWalletModel; + private List mPendingTxs; + private TransactionInfo mCurrentPendingTx; PortfolioHelper mPortfolioHelper; @@ -157,7 +151,7 @@ public boolean onTouch(View v, MotionEvent event) { mBalance.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - updatePortfolioGetPendingTx(false); + updatePortfolioGetPendingTx(); } }); setUpObservers(); @@ -169,8 +163,17 @@ private void setUpObservers() { getViewLifecycleOwner(), networkInfo -> { if (networkInfo == null) return; mBtnChangeNetwork.setText(Utils.getShortNameOfNetwork(networkInfo.chainName)); - updatePortfolioGetPendingTx(true); + updatePortfolioGetPendingTx(); + }); + mWalletModel.getCryptoModel().getPendingTransactions().observe( + getViewLifecycleOwner(), transactionInfos -> { + mPendingTxs = transactionInfos; + if (mCurrentPendingTx == null && mPendingTxs.size() > 0) { + mCurrentPendingTx = mPendingTxs.get(0); + } + updatePendingTxNotification(); }); + mWalletModel.getCryptoModel().getNetworkModel().mNeedToCreateAccountForNetwork.observe( getViewLifecycleOwner(), networkInfo -> { if (networkInfo == null) return; @@ -182,19 +185,30 @@ private void setUpObservers() { networkInfo.symbolName)) .setPositiveButton(R.string.wallet_action_yes, (dialog, which) -> { - mWalletModel.getKeyringModel().addAccount( - WalletUtils.getUniqueNextAccountName( - requireContext(), - mWalletModel.getKeyringModel() - .mAccountInfos.getValue() - .toArray( - new AccountInfo[0]), - networkInfo.symbolName, - networkInfo.coin), - networkInfo.coin, isAccountAdded -> {}); mWalletModel.getCryptoModel() .getNetworkModel() - .clearCreateAccountState(); + .setNetwork(networkInfo, success -> { + if (success) { + mWalletModel.getKeyringModel().addAccount( + WalletUtils.getUniqueNextAccountName( + requireContext(), + mWalletModel + .getKeyringModel() + .mAccountInfos + .getValue() + .toArray( + new AccountInfo + [0]), + networkInfo + .symbolName, + networkInfo.coin), + networkInfo.coin, + isAccountAdded -> {}); + } + mWalletModel.getCryptoModel() + .getNetworkModel() + .clearCreateAccountState(); + }); }) .setNegativeButton( R.string.wallet_action_no, (dialog, which) -> { @@ -231,7 +245,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat @Override public void onDismiss(Boolean isAssetsListChanged) { if (isAssetsListChanged != null && isAssetsListChanged) { - updatePortfolioGetPendingTx(false); + updatePortfolioGetPendingTx(); } } }); @@ -351,7 +365,7 @@ private void updatePortfolioGraph() { AssetPriceTimeframe.validate(mCurrentTimeframeType); if (mPortfolioHelper == null) { - updatePortfolioGetPendingTx(false); + updatePortfolioGetPendingTx(); return; } @@ -367,7 +381,7 @@ private void updatePortfolioGraph() { }); } - private void updatePortfolioGetPendingTx(boolean getPendingTx) { + private void updatePortfolioGetPendingTx() { KeyringService keyringService = getKeyringService(); assert keyringService != null; @@ -403,80 +417,52 @@ private void updatePortfolioGetPendingTx(boolean getPendingTx) { updatePortfolioGraph(); }); }); - if (getPendingTx) { - getPendingTx(accountInfos, () -> { updatePendingTxNotification(); }); - } }); } @Override public void onTxPending(String accountName, String txId) { - updatePortfolioGetPendingTx(true); + updatePortfolioGetPendingTx(); } @Override public void onTxApprovedRejected(boolean approved, String accountName, String txId) { - assert mPendingTxInfos != null; - if (!hasPendingTx()) { - return; - } - TransactionInfo[] txInfos = mPendingTxInfos.get(accountName); - if (txInfos == null) { - return; - } - int index = -1; - for (int i = 0; i < txInfos.length; i++) { - if (txInfos[i].id.equals(txId)) { - index = i; - break; - } - } - if (index != -1) { - TransactionInfo[] copy = new TransactionInfo[txInfos.length - 1]; - // copy elements from original array from beginning till index into copy - System.arraycopy(txInfos, 0, copy, 0, index); - // copy elements from original array from index + 1 till end into copy - System.arraycopy(txInfos, index + 1, copy, index, txInfos.length - index - 1); - mPendingTxInfos.put(accountName, copy); - } updatePendingTxNotification(); + updateNextPendingTx(); callAnotherApproveDialog(); } public void callAnotherApproveDialog() { - assert mPendingTxInfos != null; if (!hasPendingTx()) { return; } - for (String key : mPendingTxInfos.keySet()) { - TransactionInfo[] txInfos = mPendingTxInfos.get(key); - if (txInfos.length == 0) { - continue; - } - ApproveTxBottomSheetDialogFragment approveTxBottomSheetDialogFragment = - ApproveTxBottomSheetDialogFragment.newInstance(txInfos[0], key); - approveTxBottomSheetDialogFragment.setApprovedTxObserver(this); - approveTxBottomSheetDialogFragment.show( - getFragmentManager(), ApproveTxBottomSheetDialogFragment.TAG_FRAGMENT); - break; - } + ApproveTxBottomSheetDialogFragment approveTxBottomSheetDialogFragment = + ApproveTxBottomSheetDialogFragment.newInstance(mCurrentPendingTx, + mWalletModel.getCryptoModel() + .getPendingTxHelper() + .getAccountNameForTransaction(mCurrentPendingTx)); + approveTxBottomSheetDialogFragment.setApprovedTxObserver(this); + approveTxBottomSheetDialogFragment.show( + getFragmentManager(), ApproveTxBottomSheetDialogFragment.TAG_FRAGMENT); } - private boolean hasPendingTx() { - if (mPendingTxInfos == null || mPendingTxInfos.size() == 0) { - return false; - } - - boolean pending = false; - for (String key : mPendingTxInfos.keySet()) { - TransactionInfo[] txInfos = mPendingTxInfos.get(key); - if (txInfos.length != 0) { - pending = true; - break; + private void updateNextPendingTx() { + if (mCurrentPendingTx != null) { + for (TransactionInfo info : mPendingTxs) { + if (!mCurrentPendingTx.id.equals(info.id) + && info.txStatus == TransactionStatus.UNAPPROVED) { + mCurrentPendingTx = info; + return; + } } + mCurrentPendingTx = null; + } else if (mPendingTxs.size() > 0) { + mCurrentPendingTx = mPendingTxs.get(0); } + } - return pending; + private boolean hasPendingTx() { + return mCurrentPendingTx != null; } private void getPendingTx(AccountInfo[] accountInfos, @Nullable Runnable callback) { diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/util/AsyncUtils.java b/android/java/org/chromium/chrome/browser/crypto_wallet/util/AsyncUtils.java index b4447fc86cd91..79ca109ed282e 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/util/AsyncUtils.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/util/AsyncUtils.java @@ -7,12 +7,14 @@ import static org.chromium.chrome.browser.crypto_wallet.util.Utils.warnWhenError; +import org.chromium.brave_wallet.mojom.AccountInfo; import org.chromium.brave_wallet.mojom.AssetPrice; import org.chromium.brave_wallet.mojom.AssetRatioService; import org.chromium.brave_wallet.mojom.AssetTimePrice; import org.chromium.brave_wallet.mojom.BlockchainToken; import org.chromium.brave_wallet.mojom.BraveWalletService; 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.TransactionInfo; @@ -325,4 +327,21 @@ public void call(Long fee, Integer error, String errorMessage) { super.fireResponseCompleteCallback(); } } + + public static class GetSelectedAccountResponseContext extends SingleResponseBaseContext + implements KeyringService.GetSelectedAccount_Response { + public String selectedAccount; + public int coin; + + public GetSelectedAccountResponseContext(Runnable responseCompleteCallback, int coin) { + super(responseCompleteCallback); + this.coin = coin; + } + + @Override + public void call(String selectedAccount) { + this.selectedAccount = selectedAccount; + super.fireResponseCompleteCallback(); + } + } } diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/util/PendingTxHelper.java b/android/java/org/chromium/chrome/browser/crypto_wallet/util/PendingTxHelper.java index 426cc8beb6ecf..3050724c8fa62 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/util/PendingTxHelper.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/util/PendingTxHelper.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; public class PendingTxHelper implements TxServiceObserver { private TxService mTxService; @@ -37,6 +38,8 @@ public class PendingTxHelper implements TxServiceObserver { private final MutableLiveData _mSelectedPendingRequest; private final MutableLiveData _mHasNoPendingTxAfterProcessing; private final MutableLiveData> _mTransactionInfos; + private final MutableLiveData> _mPendingTransactionInfoLd; + public LiveData> mPendingTransactionInfoLd; public LiveData> mTransactionInfoLd; public LiveData mSelectedPendingRequest; public LiveData mHasNoPendingTxAfterProcessing; @@ -53,6 +56,8 @@ public PendingTxHelper(TxService txService, AccountInfo[] accountInfos, boolean _mSelectedPendingRequest = new MutableLiveData<>(); _mHasNoPendingTxAfterProcessing = new MutableLiveData<>(); _mTransactionInfos = new MutableLiveData<>(Collections.emptyList()); + _mPendingTransactionInfoLd = new MutableLiveData<>(Collections.emptyList()); + mPendingTransactionInfoLd = _mPendingTransactionInfoLd; mTransactionInfoLd = _mTransactionInfos; mSelectedPendingRequest = _mSelectedPendingRequest; mHasNoPendingTxAfterProcessing = _mHasNoPendingTxAfterProcessing; @@ -125,6 +130,32 @@ public void fetchTransactions(Runnable runWhenDone) { }); } + public String getAccountNameForTransaction(TransactionInfo transactionInfo) { + for (Map.Entry entry : mTxInfos.entrySet()) { + for (TransactionInfo info : entry.getValue()) { + if (info.id.equals(transactionInfo.id)) { + return entry.getKey(); + } + } + } + return null; + } + + public void updateTxInfosMap(TransactionInfo transactionInfo) { + if (transactionInfo.txType != TransactionStatus.UNAPPROVED) { + for (Map.Entry entry : mTxInfos.entrySet()) { + TransactionInfo[] infos = entry.getValue(); + for (int i = 0; i < infos.length; i++) { + TransactionInfo info = infos[i]; + if (info.id.equals(transactionInfo.id)) { + infos[i] = transactionInfo; + return; + } + } + } + } + } + public void setAccountInfos(AccountInfo[] accountInfos) { this.mAccountInfos = accountInfos; fetchTransactions(null); @@ -137,17 +168,19 @@ public void setAccountInfos(List accountInfos) { @Override public void onNewUnapprovedTx(TransactionInfo txInfo) { - processTx(txInfo, TxActionType.NEW_UNAPPROVED_TRANSACTION); + fetchTransactions(null); } @Override public void onUnapprovedTxUpdated(TransactionInfo txInfo) { processTx(txInfo, TxActionType.UNAPPROVED_TRANSACTION_UPDATED); + updateTxInfosMap(txInfo); } @Override public void onTransactionStatusChanged(TransactionInfo txInfo) { processTx(txInfo, TxActionType.TRANSACTION_STATUS_CHANGED); + updateTxInfosMap(txInfo); } public List getPendingTransactions() { @@ -165,6 +198,7 @@ private void updateTransactionList() { processCachedTx(); Collections.sort(mTransactionInfos, sortByDateComparator); _mTransactionInfos.postValue(mTransactionInfos); + updatePending(mTransactionInfos); postTxUpdates(); } @@ -174,6 +208,7 @@ private void processTx(TransactionInfo txInfo, TxActionType txActionType) { } else { updateTransactionList(txInfo, txActionType); _mTransactionInfos.postValue(mTransactionInfos); + updatePending(mTransactionInfos); } } @@ -241,6 +276,16 @@ private void postTxUpdates() { } } + private void updatePending(List transactionInfos) { + List infos = new ArrayList<>(); + for (TransactionInfo info : transactionInfos) { + if (info.txStatus == TransactionStatus.UNAPPROVED) { + infos.add(info); + } + } + _mPendingTransactionInfoLd.postValue(infos); + } + /* * Make sure to use get the first unapproved transaction as source list may not have one due to * returnAll set to true diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/util/SelectedAccountResponsesCollector.java b/android/java/org/chromium/chrome/browser/crypto_wallet/util/SelectedAccountResponsesCollector.java new file mode 100644 index 0000000000000..ab6259b82c6af --- /dev/null +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/util/SelectedAccountResponsesCollector.java @@ -0,0 +1,72 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +package org.chromium.chrome.browser.crypto_wallet.util; + +import android.text.TextUtils; + +import org.chromium.brave_wallet.mojom.AccountInfo; +import org.chromium.brave_wallet.mojom.CoinType; +import org.chromium.brave_wallet.mojom.KeyringService; +import org.chromium.mojo.bindings.Callbacks; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; + +public class SelectedAccountResponsesCollector { + private KeyringService mKeyringService; + private List mCoinTypes; + private HashSet mSelectedAccountsPerCoin; + private List mAllAccountInfos; + + public SelectedAccountResponsesCollector(KeyringService keyringService, List coinTypes, + List allAccountInfos) { + assert keyringService != null; + mKeyringService = keyringService; + mCoinTypes = coinTypes; + mAllAccountInfos = allAccountInfos; + mSelectedAccountsPerCoin = new LinkedHashSet<>(); + } + + public void getAccounts(Callbacks.Callback1> runWhenDone) { + AsyncUtils.MultiResponseHandler selectedAccountInfosPerCoinMultiResponse = + new AsyncUtils.MultiResponseHandler(mCoinTypes.size()); + ArrayList accountsPermissionsContexts = + new ArrayList<>(); + for (int coin : mCoinTypes) { + AsyncUtils.GetSelectedAccountResponseContext accountContext = + new AsyncUtils.GetSelectedAccountResponseContext( + selectedAccountInfosPerCoinMultiResponse.singleResponseComplete, coin); + + accountsPermissionsContexts.add(accountContext); + if (CoinType.FIL == coin) { + } else { + mKeyringService.getSelectedAccount(coin, accountContext); + } + } + + selectedAccountInfosPerCoinMultiResponse.setWhenAllCompletedAction(() -> { + for (AsyncUtils.GetSelectedAccountResponseContext getSelectedAccountResponseContext : + accountsPermissionsContexts) { + if (TextUtils.isEmpty(getSelectedAccountResponseContext.selectedAccount)) { + continue; + } + AccountInfo selectedAccountInfo = null; + for (AccountInfo accountInfo : mAllAccountInfos) { + if (accountInfo.address.equals( + getSelectedAccountResponseContext.selectedAccount)) { + selectedAccountInfo = accountInfo; + break; + } + } + + mSelectedAccountsPerCoin.add(selectedAccountInfo); + } + runWhenDone.call(mSelectedAccountsPerCoin); + }); + } +} diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/util/TransactionUtils.java b/android/java/org/chromium/chrome/browser/crypto_wallet/util/TransactionUtils.java index 32553f9730878..49617af713e17 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/util/TransactionUtils.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/util/TransactionUtils.java @@ -6,9 +6,6 @@ package org.chromium.chrome.browser.crypto_wallet.util; import org.chromium.brave_wallet.mojom.CoinType; -import org.chromium.brave_wallet.mojom.FilTxData; -import org.chromium.brave_wallet.mojom.SolanaTxData; -import org.chromium.brave_wallet.mojom.TxData1559; import org.chromium.brave_wallet.mojom.TxDataUnion; public class TransactionUtils {