Skip to content

Commit

Permalink
Merge pull request #14527 from brave/pr14458_android_solana_tx_screen…
Browse files Browse the repository at this point in the history
…_1.43.x

Fixes approve/reject dialog for Solana transactions on Android (uplift to 1.43.x)
  • Loading branch information
srirambv authored Aug 8, 2022
2 parents 4d092d5 + e8effa8 commit d8911ae
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 53 deletions.
1 change: 1 addition & 0 deletions android/brave_java_sources.gni
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ brave_java_sources = [
"../../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/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",
"../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/TransactionUtils.java",
"../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/util/Utils.java",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@ public class ApproveTxFragmentPageAdapter extends FragmentStatePagerAdapter {
private HashMap<String, Double> mNativeAssetsBalances;
private HashMap<String, HashMap<String, Double>> mBlockchainTokensBalances;
private boolean mUpdateTxObjectManually;
private long mSolanaEstimatedTxFee;

public ApproveTxFragmentPageAdapter(FragmentManager fm, TransactionInfo txInfo,
NetworkInfo selectedNetwork, AccountInfo[] accounts,
HashMap<String, Double> assetPrices, BlockchainToken[] fullTokenList,
HashMap<String, Double> nativeAssetsBalances,
HashMap<String, HashMap<String, Double>> blockchainTokensBalances, Activity activity,
boolean updateTxObjectManually) {
boolean updateTxObjectManually, long solanaEstimatedTxFee) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
mTxInfo = txInfo;
mSelectedNetwork = selectedNetwork;
Expand All @@ -54,6 +55,7 @@ public ApproveTxFragmentPageAdapter(FragmentManager fm, TransactionInfo txInfo,
mTitles = new ArrayList<>(Arrays.asList(activity.getText(R.string.transaction).toString(),
activity.getText(R.string.transaction_details).toString()));
mUpdateTxObjectManually = updateTxObjectManually;
mSolanaEstimatedTxFee = solanaEstimatedTxFee;
}

@NonNull
Expand All @@ -62,7 +64,7 @@ public Fragment getItem(int position) {
if (position == 0) {
return TxFragment.newInstance(mTxInfo, mSelectedNetwork, mAccounts, mAssetPrices,
mFullTokenList, mNativeAssetsBalances, mBlockchainTokensBalances,
mUpdateTxObjectManually);
mUpdateTxObjectManually, mSolanaEstimatedTxFee);
} else {
return TxDetailsFragment.newInstance(mTxInfo);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.chromium.chrome.browser.crypto_wallet.listeners.TransactionConfirmationListener;
import org.chromium.chrome.browser.crypto_wallet.observers.ApprovedTxObserver;
import org.chromium.chrome.browser.crypto_wallet.util.ParsedTransaction;
import org.chromium.chrome.browser.crypto_wallet.util.SolanaTransactionsGasHelper;
import org.chromium.chrome.browser.crypto_wallet.util.TokenUtils;
import org.chromium.chrome.browser.crypto_wallet.util.TransactionUtils;
import org.chromium.chrome.browser.crypto_wallet.util.Utils;
Expand Down Expand Up @@ -80,6 +81,7 @@ public class ApproveTxBottomSheetDialogFragment extends BottomSheetDialogFragmen
private List<TransactionInfo> mTransactionInfos;
private Button mRejectAllTx;
private int mCoinType;
private long mSolanaEstimatedTxFee;

public static ApproveTxBottomSheetDialogFragment newInstance(
List<TransactionInfo> transactionInfos, TransactionInfo txInfo, String accountName,
Expand All @@ -105,6 +107,7 @@ private ApproveTxBottomSheetDialogFragment(TransactionInfo txInfo, String accoun
// TODO (Wengling): To support other networks, all hard-coded chainSymbol, etc. need to be
// get from current network instead.
mTransactionInfos = Collections.emptyList();
mSolanaEstimatedTxFee = 0;
}

ApproveTxBottomSheetDialogFragment(List<TransactionInfo> transactionInfos,
Expand Down Expand Up @@ -240,31 +243,44 @@ public void setupDialog(@NonNull Dialog dialog, int style) {
TokenUtils.getAllTokensFiltered(getBraveWalletService(), getBlockchainRegistry(),
selectedNetwork, selectedNetwork.coin, TokenUtils.TokenType.ALL,
tokenList -> {
ParsedTransaction parsedTx = fillAssetDependentControls(view,
selectedNetwork, accounts, new HashMap<String, Double>(),
tokenList, new HashMap<String, Double>(),
new HashMap<String, HashMap<String, Double>>());

// Get tokens involved in this transaction
List<BlockchainToken> tokens = new ArrayList<>();
tokens.add(Utils.makeNetworkAsset(
selectedNetwork)); // Always add native asset
if (parsedTx.getIsSwap()) {
tokens.add(parsedTx.getSellToken());
tokens.add(parsedTx.getBuyToken());
} else if (parsedTx.getToken() != null)
tokens.add(parsedTx.getToken());
BlockchainToken[] filterByTokens =
tokens.toArray(new BlockchainToken[0]);

Utils.getTxExtraInfo((BraveWalletBaseActivity) getActivity(),
selectedNetwork, accounts, filterByTokens, false,
(assetPrices, fullTokenList, nativeAssetsBalances,
blockchainTokensBalances) -> {
fillAssetDependentControls(view, selectedNetwork, accounts,
assetPrices, fullTokenList, nativeAssetsBalances,
blockchainTokensBalances);
});
SolanaTransactionsGasHelper solanaTransactionsGasHelper =
new SolanaTransactionsGasHelper(
(BraveWalletBaseActivity) getActivity(),
new TransactionInfo[] {mTxInfo});
solanaTransactionsGasHelper.maybeGetSolanaGasEstimations(() -> {
HashMap<String, Long> perTxFee =
solanaTransactionsGasHelper.getPerTxFee();
if (perTxFee.get(mTxInfo.id) != null) {
mSolanaEstimatedTxFee = perTxFee.get(mTxInfo.id);
}
ParsedTransaction parsedTx = fillAssetDependentControls(view,
selectedNetwork, accounts, new HashMap<String, Double>(),
tokenList, new HashMap<String, Double>(),
new HashMap<String, HashMap<String, Double>>(),
mSolanaEstimatedTxFee);

// Get tokens involved in this transaction
List<BlockchainToken> tokens = new ArrayList<>();
tokens.add(Utils.makeNetworkAsset(
selectedNetwork)); // Always add native asset
if (parsedTx.getIsSwap()) {
tokens.add(parsedTx.getSellToken());
tokens.add(parsedTx.getBuyToken());
} else if (parsedTx.getToken() != null)
tokens.add(parsedTx.getToken());
BlockchainToken[] filterByTokens =
tokens.toArray(new BlockchainToken[0]);

Utils.getTxExtraInfo((BraveWalletBaseActivity) getActivity(),
selectedNetwork, accounts, filterByTokens, false,
(assetPrices, fullTokenList, nativeAssetsBalances,
blockchainTokensBalances) -> {
fillAssetDependentControls(view, selectedNetwork,
accounts, assetPrices, fullTokenList,
nativeAssetsBalances, blockchainTokensBalances,
mSolanaEstimatedTxFee);
});
});
});
});
});
Expand Down Expand Up @@ -330,10 +346,11 @@ private void refreshListContentUi() {
private ParsedTransaction fillAssetDependentControls(View view, NetworkInfo selectedNetwork,
AccountInfo[] accounts, HashMap<String, Double> assetPrices,
BlockchainToken[] fullTokenList, HashMap<String, Double> nativeAssetsBalances,
HashMap<String, HashMap<String, Double>> blockchainTokensBalances) {
ParsedTransaction parsedTx =
ParsedTransaction.parseTransaction(mTxInfo, selectedNetwork, accounts, assetPrices,
null, fullTokenList, nativeAssetsBalances, blockchainTokensBalances);
HashMap<String, HashMap<String, Double>> blockchainTokensBalances,
long solanaEstimatedTxFee) {
ParsedTransaction parsedTx = ParsedTransaction.parseTransaction(mTxInfo, selectedNetwork,
accounts, assetPrices, solanaEstimatedTxFee, fullTokenList, nativeAssetsBalances,
blockchainTokensBalances);
TextView txType = view.findViewById(R.id.tx_type);
if (parsedTx.getType() == TransactionType.ERC20_APPROVE) {
txType.setText(String.format(
Expand All @@ -349,7 +366,7 @@ private ParsedTransaction fillAssetDependentControls(View view, NetworkInfo sele
parsedTx.formatValueToDisplay(), parsedTx.getSymbol());
TextView fromTo = view.findViewById(R.id.from_to);
fromTo.setText(String.format(getResources().getString(R.string.crypto_wallet_from_to),
mAccountName, parsedTx.getSenderLabel(), parsedTx.getRecipientLabel()));
mAccountName, parsedTx.getSender(), parsedTx.getRecipient()));
TextView amountAsset = view.findViewById(R.id.amount_asset);
TextView amountFiat = view.findViewById(R.id.amount_fiat);
amountFiat.setText(
Expand All @@ -374,7 +391,7 @@ private void setupPager(View view, NetworkInfo selectedNetwork, AccountInfo[] ac
ApproveTxFragmentPageAdapter adapter = new ApproveTxFragmentPageAdapter(
getChildFragmentManager(), mTxInfo, selectedNetwork, accounts, assetPrices,
fullTokenList, nativeAssetsBalances, blockchainTokensBalances, getActivity(),
mTransactionConfirmationListener == null);
mTransactionConfirmationListener == null, mSolanaEstimatedTxFee);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(adapter.getCount() - 1);
TabLayout tabLayout = view.findViewById(R.id.tabs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class TxFragment extends Fragment {
private HashMap<String, HashMap<String, Double>> mBlockchainTokensBalances;
private int mCheckedPriorityId;
private int mPreviousCheckedPriorityId;
private long mSolanaEstimatedTxFee;

// mUpdateTxObjectManually is used to detect do we need to update dialog values
// manually after we change gas for example or do we have it updated automatically
Expand All @@ -68,9 +69,10 @@ public static TxFragment newInstance(TransactionInfo txInfo, NetworkInfo selecte
AccountInfo[] accounts, HashMap<String, Double> assetPrices,
BlockchainToken[] fullTokenList, HashMap<String, Double> nativeAssetsBalances,
HashMap<String, HashMap<String, Double>> blockchainTokensBalances,
boolean updateTxObjectManually) {
boolean updateTxObjectManually, long solanaEstimatedTxFee) {
return new TxFragment(txInfo, selectedNetwork, accounts, assetPrices, fullTokenList,
nativeAssetsBalances, blockchainTokensBalances, updateTxObjectManually);
nativeAssetsBalances, blockchainTokensBalances, updateTxObjectManually,
solanaEstimatedTxFee);
}

private EthTxManagerProxy getEthTxManagerProxy() {
Expand All @@ -85,7 +87,7 @@ private TxFragment(TransactionInfo txInfo, NetworkInfo selectedNetwork, AccountI
HashMap<String, Double> assetPrices, BlockchainToken[] fullTokenList,
HashMap<String, Double> nativeAssetsBalances,
HashMap<String, HashMap<String, Double>> blockchainTokensBalances,
boolean updateTxObjectManually) {
boolean updateTxObjectManually, long solanaEstimatedTxFee) {
mTxInfo = txInfo;
mSelectedNetwork = selectedNetwork;
mAccounts = accounts;
Expand All @@ -96,6 +98,7 @@ private TxFragment(TransactionInfo txInfo, NetworkInfo selectedNetwork, AccountI
mCheckedPriorityId = -1;
mPreviousCheckedPriorityId = -1;
mUpdateTxObjectManually = updateTxObjectManually;
mSolanaEstimatedTxFee = solanaEstimatedTxFee;
}

@Override
Expand Down Expand Up @@ -390,16 +393,18 @@ private void fillMaxFee(TextView textView, String gasLimit, String maxFeePerGas)
final double[] gasFeeArr = ParsedTransactionFees.calcGasFee(mSelectedNetwork,
Utils.getOrDefault(mAssetPrices,
mSelectedNetwork.symbol.toLowerCase(Locale.getDefault()), 0.0d),
true, gasLimit, "0", maxFeePerGas, false, null);
true, gasLimit, "0", maxFeePerGas, false, mSolanaEstimatedTxFee);
textView.setText(String.format(getResources().getString(R.string.wallet_maximum_fee),
String.format(Locale.getDefault(), "%.2f", gasFeeArr[1]),
String.format(Locale.getDefault(), "%.8f", gasFeeArr[0])));
}

private void setupView(View view) {
// Re-parse transaction for mUpdateTxObjectManually
// TODO(sergz): Not really sure do we need to re-parse here as we parse it in the
// parent fragment
mParsedTx = ParsedTransaction.parseTransaction(mTxInfo, mSelectedNetwork, mAccounts,
mAssetPrices, null, mFullTokenList, mNativeAssetsBalances,
mAssetPrices, mSolanaEstimatedTxFee, mFullTokenList, mNativeAssetsBalances,
mBlockchainTokensBalances);

TextView gasFeeAmount = view.findViewById(R.id.gas_fee_amount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.chromium.brave_wallet.mojom.BraveWalletService;
import org.chromium.brave_wallet.mojom.JsonRpcService;
import org.chromium.brave_wallet.mojom.NetworkInfo;
import org.chromium.brave_wallet.mojom.SolanaTxManagerProxy;
import org.chromium.brave_wallet.mojom.TransactionInfo;
import org.chromium.brave_wallet.mojom.TxService;
import org.chromium.mojo.bindings.Callbacks;
Expand Down Expand Up @@ -304,4 +305,24 @@ public void call(HashMap<String, HashMap<String, Double>> blockchainTokensBalanc
super.fireResponseCompleteCallback();
}
}

public static class GetSolanaEstimatedTxFeeResponseContext extends SingleResponseBaseContext
implements SolanaTxManagerProxy.GetEstimatedTxFee_Response {
public Long fee;
public Integer error;
public String errorMessage;
public String txMetaId;

public GetSolanaEstimatedTxFeeResponseContext(Runnable responseCompleteCallback) {
super(responseCompleteCallback);
}

@Override
public void call(Long fee, Integer error, String errorMessage) {
this.fee = fee;
this.error = error;
this.errorMessage = errorMessage;
super.fireResponseCompleteCallback();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ private static String checkForSameAddressError(String from, String to) {

public static ParsedTransaction parseTransaction(TransactionInfo txInfo,
NetworkInfo selectedNetwork, AccountInfo[] accounts,
HashMap<String, Double> assetPrices, BigInteger solFeeEstimatesFee,
HashMap<String, Double> assetPrices, long solFeeEstimatesFee,
BlockchainToken[] fullTokenList, HashMap<String, Double> nativeAssetsBalances,
HashMap<String, HashMap<String, Double>> blockchainTokensBalances) {
BlockchainToken nativeAsset = Utils.makeNetworkAsset(selectedNetwork);
Expand Down Expand Up @@ -398,21 +398,21 @@ public static ParsedTransaction parseTransaction(TransactionInfo txInfo,
.SOLANA_SPL_TOKEN_TRANSFER_WITH_ASSOCIATED_TOKEN_ACCOUNT_CREATION) {
final int decimals = token != null ? token.decimals : Utils.SOL_DEFAULT_DECIMALS;
final double price = Utils.getOrDefault(assetPrices, tokenSymbolLower, 0.0d);
final double sendAmountFiat = Utils.fromHexWei(value, decimals) * price;
final double sendAmount = Utils.fromWei(value, decimals);
final double sendAmountFiat = sendAmount * price;

final double totalAmountFiat = parsedTransaction.getGasFeeFiat() + sendAmountFiat;

final boolean insufficientNativeFunds =
parsedTransaction.getGasFee() > accountNativeBalance;
final boolean insufficientTokenFunds =
Utils.fromHexWei(value, decimals) > accountTokenBalance;
final boolean insufficientTokenFunds = sendAmount > accountTokenBalance;

parsedTransaction.recipient = to;
parsedTransaction.recipientLabel = getAddressLabel(accounts, to);
parsedTransaction.fiatValue = sendAmountFiat;
parsedTransaction.fiatTotal = totalAmountFiat;
parsedTransaction.nativeCurrencyTotal = sendAmountFiat / networkSpotPrice;
parsedTransaction.value = Utils.fromHexWei(value, decimals);
parsedTransaction.value = sendAmount;
parsedTransaction.symbol = token != null ? token.symbol : "";
parsedTransaction.decimals = decimals;
parsedTransaction.insufficientFundsError = insufficientTokenFunds;
Expand Down Expand Up @@ -484,8 +484,14 @@ public static ParsedTransaction parseTransaction(TransactionInfo txInfo,
for (String k : assetPrices.keySet()) {
String v = String.valueOf(assetPrices.get(k));
}
double sendAmount = 0;
if (txInfo.txType == TransactionType.SOLANA_SYSTEM_TRANSFER) {
sendAmount = Utils.fromWei(value, selectedNetwork.decimals);
} else {
sendAmount = Utils.fromHexWei(value, selectedNetwork.decimals);
}

final double sendAmountFiat = Utils.fromHexWei(value, selectedNetwork.decimals) * price;
final double sendAmountFiat = sendAmount * price;

final double totalAmountFiat = parsedTransaction.getGasFeeFiat() + sendAmountFiat;

Expand All @@ -494,7 +500,7 @@ public static ParsedTransaction parseTransaction(TransactionInfo txInfo,
parsedTransaction.fiatValue = sendAmountFiat;
parsedTransaction.fiatTotal = totalAmountFiat;
parsedTransaction.nativeCurrencyTotal = sendAmountFiat / networkSpotPrice;
parsedTransaction.value = Utils.fromHexWei(value, selectedNetwork.decimals);
parsedTransaction.value = sendAmount;
parsedTransaction.symbol = selectedNetwork.symbol;
parsedTransaction.decimals = selectedNetwork.decimals;
parsedTransaction.insufficientFundsError =
Expand Down
Loading

0 comments on commit d8911ae

Please sign in to comment.