mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-27 06:18:50 +01:00
Add Robinhood Chain (#3398)
* fix android CI * feat: Add Robinhood Chain, all major flows done. minor issue now is our providers don't support it yet as its still pretty early, two weeks from launch * feat: Add Robinhood Chain, all major flows done. minor issue now is our providers don't support it yet as its still pretty early, two weeks from launch * Cleanup * auto-reformat * fix ui issue and contact listing for tokens * fix: missing icons and crash for fee priority in settings * chore: cleanup * fixes from feedbacks * fix: review issues and sync to latest dev feat: switch history api to etherscan, add history toggle to privacy settings, exclude robETH from exchange pickers, skip tokens discovery for chains that moralis hasn't indexed, add tests * fix: address Robinhood review comments * fix: show Solana token icons in history * fix: address review comments and default Robinhood to PublicNode * fix: revert filter and refuse unmapped networks in provider --------- Co-authored-by: Robert Malikowski <malikowskirobert@gmail.com>
This commit is contained in:
co-authored by
Robert Malikowski
parent
77e4b946eb
commit
046e57c598
@@ -56,6 +56,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
case WalletType.solana:
|
||||
case WalletType.tron:
|
||||
case WalletType.zcash:
|
||||
@@ -100,6 +101,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
|
||||
WalletType.base,
|
||||
WalletType.arbitrum,
|
||||
WalletType.bsc,
|
||||
WalletType.robinhood,
|
||||
WalletType.tron,
|
||||
WalletType.solana,
|
||||
WalletType.monero,
|
||||
|
||||
@@ -219,6 +219,7 @@ abstract class BalanceViewModelBase with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
case WalletType.solana:
|
||||
case WalletType.tron:
|
||||
return S.current.xmr_full_balance;
|
||||
|
||||
@@ -1300,6 +1300,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
case WalletType.solana:
|
||||
case WalletType.nano:
|
||||
case WalletType.banano:
|
||||
|
||||
@@ -194,10 +194,10 @@ abstract class HomeSettingsViewModelBase with Store {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isPotentialScamViaMoralis = await _isPotentialScamTokenViaMoralis(
|
||||
contractAddress,
|
||||
getChainNameBasedOnWalletType(_balanceViewModel.wallet.type),
|
||||
);
|
||||
final moralisChainName = evm!.getMoralisChainName(_balanceViewModel.wallet);
|
||||
|
||||
final isPotentialScamViaMoralis = moralisChainName != null &&
|
||||
await _isPotentialScamTokenViaMoralis(contractAddress, moralisChainName);
|
||||
|
||||
bool isUnverifiedContract = await _isContractUnverified(
|
||||
contractAddress,
|
||||
@@ -221,6 +221,7 @@ abstract class HomeSettingsViewModelBase with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
defaultTokenAddresses = evm!.getDefaultTokenContractAddresses(_balanceViewModel.wallet);
|
||||
break;
|
||||
case WalletType.solana:
|
||||
@@ -262,6 +263,7 @@ abstract class HomeSettingsViewModelBase with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
defaultTokenSymbols = evm!.getDefaultTokenSymbols(_balanceViewModel.wallet);
|
||||
break;
|
||||
case WalletType.solana:
|
||||
|
||||
@@ -207,6 +207,7 @@ class TransactionListItem extends ActionListItem with Keyable {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
final asset = assetOfTransaction;
|
||||
final price = balanceViewModel.fiatConversionStore.prices[asset];
|
||||
amount = calculateFiatAmountRaw(
|
||||
|
||||
@@ -277,7 +277,8 @@ abstract class ExchangeTradeViewModelBase with Store {
|
||||
_isTokenBelongingToWallet(CryptoCurrency.arbEth) ||
|
||||
_isTokenBelongingToWallet(CryptoCurrency.trx) ||
|
||||
_isTokenBelongingToWallet(CryptoCurrency.sol) ||
|
||||
_isTokenBelongingToWallet(CryptoCurrency.bnb);
|
||||
_isTokenBelongingToWallet(CryptoCurrency.bnb) ||
|
||||
_isTokenBelongingToWallet(CryptoCurrency.robEth);
|
||||
|
||||
if (!canSend) {
|
||||
return 'Wallet currency ${wallet.currency.title} does not match trade from currency ${tradeFrom.title} or is not a supported token for this wallet.';
|
||||
@@ -346,6 +347,7 @@ abstract class ExchangeTradeViewModelBase with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
return _createERC681URI(fromCurrency, inputAddress, amount);
|
||||
case WalletType.solana:
|
||||
return SolanaURI(
|
||||
|
||||
@@ -1547,6 +1547,10 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
|
||||
depositCurrency = CryptoCurrency.bnb;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
break;
|
||||
case WalletType.robinhood:
|
||||
depositCurrency = CryptoCurrency.robEth;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
break;
|
||||
case WalletType.solana:
|
||||
depositCurrency = CryptoCurrency.sol;
|
||||
receiveCurrency = CryptoCurrency.xmr;
|
||||
|
||||
@@ -126,6 +126,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
case WalletType.solana:
|
||||
case WalletType.banano:
|
||||
case WalletType.nano:
|
||||
|
||||
@@ -35,6 +35,7 @@ class WalletRestoreFromQRCode {
|
||||
'base-wallet': WalletType.base,
|
||||
'arbitrum-wallet': WalletType.arbitrum,
|
||||
'bsc-wallet': WalletType.bsc,
|
||||
"robinhood-wallet": WalletType.robinhood,
|
||||
'nano-wallet': WalletType.nano,
|
||||
'nano_wallet': WalletType.nano,
|
||||
'bitcoincash': WalletType.bitcoinCash,
|
||||
|
||||
@@ -109,6 +109,7 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
case WalletType.solana:
|
||||
case WalletType.tron:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.robinhood:
|
||||
case WalletType.zcash:
|
||||
return false;
|
||||
}
|
||||
@@ -128,8 +129,8 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
wallet.type != WalletType.banano &&
|
||||
wallet.type != WalletType.solana &&
|
||||
wallet.type != WalletType.tron &&
|
||||
wallet.chainId !=
|
||||
42161; // Wallet type is generic for all EVM chains, so we need to check the chainId
|
||||
wallet.chainId != 42161 &&
|
||||
wallet.chainId != 4663;
|
||||
|
||||
@computed
|
||||
bool get isElectrumWallet =>
|
||||
|
||||
@@ -189,12 +189,14 @@ abstract class OutputBase with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
final isNative = [
|
||||
CryptoCurrency.eth,
|
||||
CryptoCurrency.maticpoly,
|
||||
CryptoCurrency.baseEth,
|
||||
CryptoCurrency.arbEth,
|
||||
CryptoCurrency.bnb
|
||||
CryptoCurrency.bnb,
|
||||
CryptoCurrency.robEth
|
||||
].contains(cryptoCurrencyHandler());
|
||||
|
||||
final fee = isNative
|
||||
|
||||
@@ -293,6 +293,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
case WalletType.tron:
|
||||
case WalletType.solana:
|
||||
case WalletType.bitcoin:
|
||||
@@ -1273,6 +1274,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
WalletType.solana,
|
||||
WalletType.tron,
|
||||
WalletType.arbitrum,
|
||||
WalletType.robinhood,
|
||||
WalletType.zcash,
|
||||
].contains(wallet.type)) {
|
||||
throw Exception('Priority is null for wallet type: ${wallet.type}');
|
||||
@@ -1311,6 +1313,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
return evm!.createEVMTransactionCredentials(
|
||||
outputs,
|
||||
priority: priority,
|
||||
|
||||
@@ -205,6 +205,9 @@ abstract class ConnectionSyncViewModelBase with Store {
|
||||
@computed
|
||||
bool get useBaseScan => _settingsStore.useBaseScan;
|
||||
|
||||
@computed
|
||||
bool get useRobinhoodScan => _settingsStore.useRobinhoodScan;
|
||||
|
||||
@computed
|
||||
bool get useArbiScan => _settingsStore.useArbiScan;
|
||||
|
||||
@@ -223,6 +226,9 @@ abstract class ConnectionSyncViewModelBase with Store {
|
||||
@computed
|
||||
bool get canUseBaseScan => _wallet.chainId == 8453;
|
||||
|
||||
@computed
|
||||
bool get canUseRobinhoodScan => _wallet.chainId == 4663;
|
||||
|
||||
@computed
|
||||
bool get canUseArbiScan => _wallet.chainId == 42161;
|
||||
|
||||
@@ -271,6 +277,12 @@ abstract class ConnectionSyncViewModelBase with Store {
|
||||
evm!.updateScanProviderUsageState(_wallet, value);
|
||||
}
|
||||
|
||||
@action
|
||||
void setUseRobinhoodScan(bool value) {
|
||||
_settingsStore.useRobinhoodScan = value;
|
||||
evm!.updateScanProviderUsageState(_wallet, value);
|
||||
}
|
||||
|
||||
@action
|
||||
void setUseTronGrid(bool value) {
|
||||
_settingsStore.useTronGrid = value;
|
||||
|
||||
@@ -104,6 +104,7 @@ abstract class OtherSettingsViewModelBase with Store {
|
||||
WalletType.solana,
|
||||
WalletType.tron,
|
||||
WalletType.arbitrum,
|
||||
WalletType.robinhood,
|
||||
].contains(_wallet.type));
|
||||
|
||||
String getDisplayPriority(dynamic priority) {
|
||||
|
||||
@@ -476,6 +476,8 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return "https://arbiscan.io/tx/${txId}";
|
||||
case WalletType.bsc:
|
||||
return "https://bscscan.com/tx/${txId}";
|
||||
case WalletType.robinhood:
|
||||
return "https://robinhoodchain.blockscout.com/tx/${txId}";
|
||||
case WalletType.polygon:
|
||||
return "https://polygonscan.com/tx/${txId}";
|
||||
case WalletType.nano:
|
||||
|
||||
@@ -562,6 +562,12 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
|
||||
"assets/images/usdt_wallet_icon.svg",
|
||||
"assets/images/more_tokens.svg",
|
||||
];
|
||||
case 4663:
|
||||
return [
|
||||
"assets/new-ui/crypto_full_icons/robinhood.svg",
|
||||
"assets/images/usdg_icon.png",
|
||||
"assets/images/more_tokens.svg",
|
||||
];
|
||||
default:
|
||||
return [
|
||||
"assets/new-ui/crypto_full_icons/ethereum.svg",
|
||||
|
||||
@@ -171,6 +171,7 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
case WalletType.solana:
|
||||
case WalletType.tron:
|
||||
items.addAll([
|
||||
@@ -321,6 +322,8 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
return 'arbitrum-wallet';
|
||||
case WalletType.bsc:
|
||||
return 'bsc-wallet';
|
||||
case WalletType.robinhood:
|
||||
return "robinhood-wallet";
|
||||
case WalletType.solana:
|
||||
return 'solana-wallet';
|
||||
case WalletType.tron:
|
||||
|
||||
@@ -83,6 +83,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
return evm!.createEVMNewWalletCredentials(
|
||||
name: name,
|
||||
password: walletPassword,
|
||||
|
||||
@@ -54,6 +54,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
case WalletType.decred:
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
@@ -97,6 +98,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
WalletType.base,
|
||||
WalletType.arbitrum,
|
||||
WalletType.bsc,
|
||||
WalletType.robinhood,
|
||||
WalletType.nano,
|
||||
WalletType.banano,
|
||||
WalletType.solana,
|
||||
@@ -179,6 +181,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
return evm!.createEVMRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
@@ -288,6 +291,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
case WalletType.base:
|
||||
case WalletType.arbitrum:
|
||||
case WalletType.bsc:
|
||||
case WalletType.robinhood:
|
||||
return evm!.createEVMRestoreWalletFromPrivateKey(
|
||||
name: name,
|
||||
password: password,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:cake_wallet/reactions/wallet_connect.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/core/wallet_loading_service.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
@@ -32,13 +31,6 @@ abstract class WalletSwitcherViewModelBase with Store {
|
||||
Future<List<WalletInfo>> getWallets(WalletType? walletType) async {
|
||||
final wiList = await WalletInfo.getAll();
|
||||
if (walletType == null) return wiList;
|
||||
|
||||
// For EVM-compatible wallet types, show all EVM-compatible wallets
|
||||
// This allows users to switch between any EVM wallet regardless of the specific chain
|
||||
if (isEVMCompatibleChain(walletType)) {
|
||||
return wiList.where((wallet) => isEVMCompatibleChain(wallet.type)).toList();
|
||||
}
|
||||
|
||||
return wiList.where((wallet) => wallet.type == walletType).toList();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user