Nuke Solana/Tron/Zano/Decred/Zcash/Haven from the codebase entirely #11

Merged
such-gitea merged 1 commits from github-such-software/hash-wallet:dev into dev 2026-05-17 12:34:54 -04:00
94 changed files with 228 additions and 6154 deletions

View File

@@ -16,8 +16,6 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type, {bool isTestnet = fal
return CryptoCurrency.btc;
case WalletType.litecoin:
return CryptoCurrency.ltc;
case WalletType.haven:
return CryptoCurrency.xhv;
case WalletType.ethereum:
return CryptoCurrency.eth;
case WalletType.base:
@@ -34,20 +32,10 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type, {bool isTestnet = fal
return CryptoCurrency.banano;
case WalletType.polygon:
return CryptoCurrency.maticpoly;
case WalletType.solana:
return CryptoCurrency.sol;
case WalletType.tron:
return CryptoCurrency.trx;
case WalletType.wownero:
return CryptoCurrency.wow;
case WalletType.zano:
return CryptoCurrency.zano;
case WalletType.decred:
return CryptoCurrency.dcr;
case WalletType.dogecoin:
return CryptoCurrency.doge;
case WalletType.zcash:
return CryptoCurrency.zec;
case WalletType.none:
throw Exception(
'Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');

View File

@@ -113,8 +113,6 @@ class Node extends HiveObject with Keyable {
Uri get uri {
switch (type) {
case WalletType.monero:
case WalletType.zcash:
case WalletType.haven:
case WalletType.wownero:
return Uri.http(uriRaw, '');
case WalletType.bitcoin:
@@ -129,10 +127,6 @@ class Node extends HiveObject with Keyable {
case WalletType.base:
case WalletType.bsc:
case WalletType.arbitrum:
case WalletType.solana:
case WalletType.tron:
case WalletType.zano:
case WalletType.decred:
return Uri.parse(
"http${isSSL ? "s" : ""}://$uriRaw${path!.startsWith("/") || path!.isEmpty ? path : "/$path"}");
case WalletType.none:
@@ -183,7 +177,6 @@ class Node extends HiveObject with Keyable {
try {
switch (type) {
case WalletType.monero:
case WalletType.haven:
case WalletType.wownero:
return requestMoneroNode();
case WalletType.nano:
@@ -197,15 +190,8 @@ class Node extends HiveObject with Keyable {
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.tron:
case WalletType.dogecoin:
case WalletType.zcash:
return requestElectrumServer();
case WalletType.zano:
return requestZanoNode();
case WalletType.decred:
return requestDecredNode();
case WalletType.none:
return false;
}
@@ -214,30 +200,6 @@ class Node extends HiveObject with Keyable {
}
}
Future<bool> requestZanoNode() async {
final path = '/json_rpc';
final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path);
final body = {'jsonrpc': '2.0', 'id': '0', 'method': "getinfo"};
try {
final jsonBody = json.encode(body);
final response = await ProxyWrapper().post(
clearnetUri: rpcUri,
headers: {'Content-Type': 'application/json'},
body: jsonBody,
);
final resBody = json.decode(response.body) as Map<String, dynamic>;
return resBody['result']['height'] != null;
} catch (e) {
printV("error: $e");
return false;
}
}
Future<bool> requestMoneroNode({String methodName = 'get_info'}) async {
if (useSocksProxy) {
return await requestNodeWithProxy();
@@ -384,20 +346,6 @@ class Node extends HiveObject with Keyable {
}
}
Future<bool> requestDecredNode() async {
if (uri.host == "default-spv-nodes") {
// Just show default port as ok. The wallet will connect to a list of known
// nodes automatically.
return true;
}
try {
final socket = await Socket.connect(uri.host, uri.port, timeout: Duration(seconds: 5));
socket.destroy();
return true;
} catch (_) {
return false;
}
}
}
/// https://github.com/ManyMath/digest_auth/

View File

@@ -548,10 +548,7 @@ class WalletInfo {
String get yatEmojiId => yatEid ?? '';
bool get isShowIntroCakePayCard {
if (showIntroCakePayCard == null) {
return type != WalletType.haven;
}
return showIntroCakePayCard!;
return showIntroCakePayCard ?? false;
}
bool get isHardwareWallet => [

View File

@@ -224,10 +224,7 @@ class WalletInfo extends HiveObject {
String get yatEmojiId => yatEid ?? '';
bool get isShowIntroCakePayCard {
if (showIntroCakePayCard == null) {
return type != WalletType.haven;
}
return showIntroCakePayCard!;
return showIntroCakePayCard ?? false;
}
bool get isHardwareWallet => hardwareWalletType != null;

View File

@@ -8,21 +8,16 @@ const walletTypes = [
WalletType.monero,
WalletType.bitcoin,
WalletType.litecoin,
WalletType.haven,
WalletType.ethereum,
WalletType.bitcoinCash,
WalletType.nano,
WalletType.banano,
WalletType.polygon,
WalletType.solana,
WalletType.tron,
WalletType.zano,
WalletType.decred,
WalletType.dogecoin,
WalletType.base,
WalletType.arbitrum,
WalletType.zcash,
WalletType.bsc,
WalletType.wownero,
];
const electrumWalletTypes = [
@@ -40,6 +35,10 @@ const evmWalletTypes = [
WalletType.bsc
];
// HiveField IDs are pinned — never renumber. Existing user wallets persist
// type via the int ID, so changing assignments here would re-interpret saved
// wallet types on next launch. To remove a type, drop its enum entry; do not
// re-use its old ID.
@HiveType(typeId: WALLET_TYPE_TYPE_ID)
enum WalletType {
@HiveField(0)
@@ -54,9 +53,6 @@ enum WalletType {
@HiveField(3)
litecoin,
@HiveField(4)
haven,
@HiveField(5)
ethereum,
@@ -72,21 +68,9 @@ enum WalletType {
@HiveField(9)
polygon,
@HiveField(10)
solana,
@HiveField(11)
tron,
@HiveField(12)
wownero,
@HiveField(13)
zano,
@HiveField(14)
decred,
@HiveField(15)
dogecoin,
@@ -96,9 +80,6 @@ enum WalletType {
@HiveField(17)
arbitrum,
@HiveField(18)
zcash,
@HiveField(19)
bsc,
}
@@ -111,8 +92,6 @@ int serializeToInt(WalletType type) {
return 1;
case WalletType.litecoin:
return 2;
case WalletType.haven:
return 3;
case WalletType.ethereum:
return 4;
case WalletType.nano:
@@ -123,24 +102,14 @@ int serializeToInt(WalletType type) {
return 7;
case WalletType.polygon:
return 8;
case WalletType.solana:
return 9;
case WalletType.tron:
return 10;
case WalletType.wownero:
return 11;
case WalletType.zano:
return 12;
case WalletType.decred:
return 13;
case WalletType.dogecoin:
return 14;
case WalletType.base:
return 15;
case WalletType.arbitrum:
return 16;
case WalletType.zcash:
return 17;
case WalletType.bsc:
return 18;
case WalletType.none:
@@ -156,8 +125,6 @@ WalletType deserializeFromInt(int raw) {
return WalletType.bitcoin;
case 2:
return WalletType.litecoin;
case 3:
return WalletType.haven;
case 4:
return WalletType.ethereum;
case 5:
@@ -168,24 +135,14 @@ WalletType deserializeFromInt(int raw) {
return WalletType.bitcoinCash;
case 8:
return WalletType.polygon;
case 9:
return WalletType.solana;
case 10:
return WalletType.tron;
case 11:
return WalletType.wownero;
case 12:
return WalletType.zano;
case 13:
return WalletType.decred;
case 14:
return WalletType.dogecoin;
case 15:
return WalletType.base;
case 16:
return WalletType.arbitrum;
case 17:
return WalletType.zcash;
case 18:
return WalletType.bsc;
default:
@@ -201,8 +158,6 @@ String walletTypeToString(WalletType type) {
return 'Bitcoin';
case WalletType.litecoin:
return 'Litecoin';
case WalletType.haven:
return 'Haven';
case WalletType.ethereum:
return 'Ethereum';
case WalletType.bitcoinCash:
@@ -213,24 +168,14 @@ String walletTypeToString(WalletType type) {
return 'Banano';
case WalletType.polygon:
return 'Polygon';
case WalletType.solana:
return 'Solana';
case WalletType.tron:
return 'Tron';
case WalletType.wownero:
return 'Wownero';
case WalletType.zano:
return 'Zano';
case WalletType.decred:
return 'Decred';
case WalletType.dogecoin:
return 'Dogecoin';
case WalletType.base:
return 'Base';
case WalletType.arbitrum:
return 'Arbitrum';
case WalletType.zcash:
return 'Zcash';
case WalletType.bsc:
return 'BNB Smart Chain';
case WalletType.none:
@@ -246,8 +191,6 @@ String walletTypeToDisplayName(WalletType type) {
return 'Bitcoin (BTC)';
case WalletType.litecoin:
return 'Litecoin (LTC)';
case WalletType.haven:
return 'Haven (XHV)';
case WalletType.ethereum:
return 'Ethereum (ETH)';
case WalletType.bitcoinCash:
@@ -258,24 +201,14 @@ String walletTypeToDisplayName(WalletType type) {
return 'Banano (BAN)';
case WalletType.polygon:
return 'Polygon (POL)';
case WalletType.solana:
return 'Solana (SOL)';
case WalletType.tron:
return 'Tron (TRX)';
case WalletType.wownero:
return 'Wownero (WOW)';
case WalletType.zano:
return 'Zano (ZANO)';
case WalletType.decred:
return 'Decred (DCR)';
case WalletType.dogecoin:
return 'Dogecoin (DOGE)';
case WalletType.base:
return 'Base';
case WalletType.arbitrum:
return 'Arbitrum (ARB)';
case WalletType.zcash:
return 'Zcash (ZEC)';
case WalletType.bsc:
return 'BNB Smart Chain (BNB)';
case WalletType.none:
@@ -292,8 +225,6 @@ WalletType? _cryptoCurrencyToWalletType(CryptoCurrency type) {
return WalletType.bitcoin;
case CryptoCurrency.ltc:
return WalletType.litecoin;
case CryptoCurrency.xhv:
return WalletType.haven;
case CryptoCurrency.eth:
return WalletType.ethereum;
case CryptoCurrency.maticpoly:
@@ -311,20 +242,10 @@ WalletType? _cryptoCurrencyToWalletType(CryptoCurrency type) {
return WalletType.nano;
case CryptoCurrency.banano:
return WalletType.banano;
case CryptoCurrency.sol:
return WalletType.solana;
case CryptoCurrency.trx:
return WalletType.tron;
case CryptoCurrency.wow:
return WalletType.wownero;
case CryptoCurrency.zano:
return WalletType.zano;
case CryptoCurrency.dcr:
return WalletType.decred;
case CryptoCurrency.doge:
return WalletType.dogecoin;
case CryptoCurrency.zec:
return WalletType.zcash;
default:
return null;
}

View File

@@ -46,9 +46,6 @@ class DFXBuyProvider extends BuyProvider {
CryptoCurrency.btc,
CryptoCurrency.eth,
CryptoCurrency.maticpoly,
CryptoCurrency.sol,
CryptoCurrency.zano,
CryptoCurrency.trx,
];
static final List<CryptoCurrency> _notSupportedCrypto = CryptoCurrency.all
.where((crypto) => !_supportedCrypto.contains(crypto) || ["ETH", "POL"].contains(crypto.tag))
@@ -77,8 +74,6 @@ class DFXBuyProvider extends BuyProvider {
switch (wallet.type) {
case WalletType.bitcoin:
return 'Bitcoin';
case WalletType.zano:
return 'Zano';
default:
return walletTypeToString(wallet.type);
}
@@ -138,14 +133,11 @@ class DFXBuyProvider extends BuyProvider {
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.tron:
return wallet.signMessage(message);
case WalletType.monero:
case WalletType.litecoin:
case WalletType.bitcoin:
case WalletType.bitcoinCash:
case WalletType.zano:
return wallet.signMessage(message, address: walletAddress);
default:
throw Exception("WalletType is not available for DFX ${wallet.type}");

View File

@@ -108,8 +108,6 @@ class RobinhoodBuyProvider extends BuyProvider {
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.tron:
case WalletType.dogecoin:
return wallet.signMessage(message);
case WalletType.litecoin:
@@ -118,13 +116,9 @@ class RobinhoodBuyProvider extends BuyProvider {
return wallet.signMessage(message, address: wallet.walletAddresses.address);
case WalletType.monero:
case WalletType.none:
case WalletType.haven:
case WalletType.nano:
case WalletType.banano:
case WalletType.wownero:
case WalletType.zano:
case WalletType.zcash:
case WalletType.decred:
throw Exception("Wallet Type ${wallet.type.name} is not available for Robinhood");
}
}

View File

@@ -1,8 +1,6 @@
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/core/validator.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart';
@@ -29,9 +27,7 @@ class AddressValidator extends TextValidator {
: LitecoinNetwork.mainnet,
);
}
: type == CryptoCurrency.zano
? zano?.validateAddress
: null,
: null,
pattern: getPattern(type, isTestnet: isTestnet),
length: getLength(type),
);
@@ -187,11 +183,6 @@ class AddressValidator extends TextValidator {
return [42];
}
if (solana != null) {
final length = solana!.getValidationLength(type);
if (length != null) return length;
}
switch (type) {
case CryptoCurrency.xmr:
case CryptoCurrency.wow:

View File

@@ -112,7 +112,6 @@ class BackgroundSync {
final List<WalletListItem> moneroWallets = walletListViewModel.wallets
.where((element) => !element.isHardware)
.where((element) => ![WalletType.haven, WalletType.decred].contains(element.type))
.toList();
for (int i = 0; i < moneroWallets.length; i++) {
final wallet = await walletLoadingService.load(moneroWallets[i].type, moneroWallets[i].name,

View File

@@ -4,13 +4,8 @@ import 'package:hash_wallet/entities/mnemonic_item.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/nano/nano.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/utils/language_list.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/wallet_type.dart';
class SeedValidator extends Validator<MnemonicItem> {
@@ -44,20 +39,9 @@ class SeedValidator extends Validator<MnemonicItem> {
case WalletType.nano:
case WalletType.banano:
return nano!.getNanoWordList(language);
case WalletType.solana:
return solana!.getSolanaWordList(language);
case WalletType.tron:
return tron!.getTronWordList(language);
case WalletType.wownero:
return wownero!.getWowneroWordList(language);
case WalletType.zano:
return zano!.getWordList(language);
case WalletType.decred:
return decred!.getDecredWordList();
case WalletType.zcash:
return zcash!.getZcashWordList(language);
case WalletType.none:
case WalletType.haven:
return [];
}
}

View File

@@ -80,19 +80,13 @@ class WalletCreationService {
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.tron:
case WalletType.dogecoin:
case WalletType.nano:
case WalletType.zcash:
return true;
case WalletType.monero:
case WalletType.wownero:
case WalletType.none:
case WalletType.haven:
case WalletType.banano:
case WalletType.zano:
case WalletType.decred:
return false;
}
}

View File

@@ -1,113 +0,0 @@
part of 'decred.dart';
class CWDecred extends Decred {
CWDecred() {}
@override
WalletCredentials createDecredNewWalletCredentials(
{required String name, WalletInfo? walletInfo}) =>
DecredNewWalletCredentials(name: name, walletInfo: walletInfo);
@override
WalletCredentials createDecredRestoreWalletFromSeedCredentials(
{required String name, required String mnemonic, required String password}) =>
DecredRestoreWalletFromSeedCredentials(name: name, mnemonic: mnemonic, password: password);
@override
WalletCredentials createDecredRestoreWalletFromPubkeyCredentials(
{required String name, required String pubkey, required String password}) =>
DecredRestoreWalletFromPubkeyCredentials(name: name, pubkey: pubkey, password: password);
@override
WalletService createDecredWalletService(Box<UnspentCoinsInfo> unspentCoinSource) {
return DecredWalletService(unspentCoinSource);
}
@override
List<TransactionPriority> getTransactionPriorities() => DecredTransactionPriority.all;
@override
TransactionPriority getDecredTransactionPriorityMedium() => DecredTransactionPriority.medium;
@override
TransactionPriority getDecredTransactionPrioritySlow() => DecredTransactionPriority.slow;
@override
TransactionPriority deserializeDecredTransactionPriority(int raw) =>
DecredTransactionPriority.deserialize(raw: raw);
@override
Object createDecredTransactionCredentials(List<Output> outputs, TransactionPriority priority) =>
DecredTransactionCredentials(
outputs
.map((out) => OutputInfo(
fiatAmount: out.fiatAmount,
cryptoAmount: out.cryptoAmount,
address: out.address,
note: out.note,
sendAll: out.sendAll,
extractedAddress: out.extractedAddress,
isParsedAddress: out.isParsedAddress,
formattedCryptoAmount: out.formattedCryptoAmount))
.toList(),
priority: priority as DecredTransactionPriority);
List<WalletInfoAddressInfo> getAddressInfos(Object wallet) {
final decredWallet = wallet as DecredWallet;
return decredWallet.walletAddresses.getAddressInfos();
}
@override
Future<void> updateAddress(Object wallet, String address, String label) async {
final decredWallet = wallet as DecredWallet;
await decredWallet.walletAddresses.updateAddress(address, label);
}
@override
Future<void> generateNewAddress(Object wallet, String label) async {
final decredWallet = wallet as DecredWallet;
await decredWallet.walletAddresses.generateNewAddress(label);
}
@override
String formatterDecredAmountToString({required int amount}) =>
decredAmountToString(amount: amount);
@override
double formatterDecredAmountToDouble({required int amount}) =>
decredAmountToDouble(amount: amount);
@override
int formatterStringDoubleToDecredAmount(String amount) => stringDoubleToDecredAmount(amount);
@override
List<Unspent> getUnspents(Object wallet) {
final decredWallet = wallet as DecredWallet;
return decredWallet.unspents();
}
@override
void updateUnspents(Object wallet) {
final decredWallet = wallet as DecredWallet;
decredWallet.unspents();
}
@override
int heightByDate(DateTime date) {
final genesisBlocktime = DateTime.fromMillisecondsSinceEpoch(1454954400 * 1000);
final minutesDiff = date.difference(genesisBlocktime).inMinutes;
// Decred has five minute blocks on mainnet.
// NOTE: This is off by about a day but is currently unused by decred as we
// rescan from the wallet birthday.
return minutesDiff ~/ 5;
}
@override
List<String> getDecredWordList() => wordlist;
@override
String pubkey(Object wallet) {
final decredWallet = wallet as DecredWallet;
return decredWallet.pubkey;
}
}

View File

@@ -30,7 +30,6 @@ import 'package:hash_wallet/core/trade_monitor.dart';
import 'package:hash_wallet/core/wallet_creation_service.dart';
import 'package:hash_wallet/core/wallet_loading_service.dart';
import 'package:hash_wallet/core/yat_service.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/entities/biometric_auth.dart';
import 'package:hash_wallet/entities/bridge_transfer.dart';
import 'package:hash_wallet/entities/contact.dart';
@@ -47,7 +46,6 @@ import 'package:hash_wallet/entities/wallet_manager.dart';
import 'package:hash_wallet/exchange/exchange_template.dart';
import 'package:hash_wallet/exchange/provider/trocador_exchange_provider.dart';
import 'package:hash_wallet/exchange/trade.dart';
import 'package:hash_wallet/haven/cw_haven.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/nano/nano.dart';
import 'package:hash_wallet/new-ui/new_dashboard.dart';
@@ -70,7 +68,6 @@ import 'package:hash_wallet/new-ui/pages/swap_page.dart';
import 'package:hash_wallet/order/order.dart';
import 'package:hash_wallet/reactions/on_authentication_state_change.dart';
import 'package:hash_wallet/routes.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/src/screens/anonpay_details/anonpay_details_page.dart';
import 'package:hash_wallet/src/screens/auth/auth_page.dart';
import 'package:hash_wallet/src/screens/backup/backup_page.dart';
@@ -200,7 +197,6 @@ import 'package:hash_wallet/store/templates/send_template_store.dart';
import 'package:hash_wallet/store/wallet_list_store.dart';
import 'package:hash_wallet/store/yat/yat_store.dart';
import 'package:hash_wallet/themes/core/theme_store.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/utils/device_info.dart';
import 'package:hash_wallet/utils/payment_request.dart';
import 'package:hash_wallet/view_model/advanced_privacy_settings_view_model.dart';
@@ -295,8 +291,6 @@ import 'package:hash_wallet/view_model/wallet_switcher_view_model.dart';
import 'package:hash_wallet/view_model/wallet_unlock_loadable_view_model.dart';
import 'package:hash_wallet/view_model/wallet_unlock_verifiable_view_model.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/nano_account.dart';
import 'package:cw_core/node.dart';
@@ -1006,8 +1000,7 @@ Future<void> setup({
getIt.registerFactory<MoneroAccountListViewModel>(() {
final wallet = getIt.get<AppStore>().wallet!;
if (wallet.type == WalletType.monero ||
wallet.type == WalletType.wownero ||
wallet.type == WalletType.haven) {
wallet.type == WalletType.wownero) {
return MoneroAccountListViewModel(wallet,getIt.get<SettingsStore>());
}
throw Exception(
@@ -1337,20 +1330,8 @@ Future<void> setup({
case WalletType.nano:
case WalletType.banano:
return nano!.createNanoWalletService(SettingsStoreBase.walletPasswordDirectInput);
case WalletType.solana:
return solana!.createSolanaWalletService(SettingsStoreBase.walletPasswordDirectInput);
case WalletType.tron:
return tron!.createTronWalletService(SettingsStoreBase.walletPasswordDirectInput);
case WalletType.wownero:
return wownero!.createWowneroWalletService(_unspentCoinsInfoSource);
case WalletType.zano:
return zano!.createZanoWalletService();
case WalletType.decred:
return decred!.createDecredWalletService(_unspentCoinsInfoSource);
case WalletType.haven:
return HavenWalletService();
case WalletType.zcash:
return zcash!.createZcashWalletService(SettingsStoreBase.walletPasswordDirectInput);
case WalletType.none:
throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService');
}

View File

@@ -9,7 +9,6 @@ import 'package:hash_wallet/entities/exchange_api_mode.dart';
import 'package:hash_wallet/entities/fiat_api_mode.dart';
import 'package:hash_wallet/entities/fiat_currency.dart';
import 'package:hash_wallet/entities/fs_migration.dart';
import 'package:hash_wallet/entities/haven_seed_store.dart';
import 'package:hash_wallet/entities/node_list.dart';
import 'package:hash_wallet/entities/preferences_key.dart';
import 'package:hash_wallet/entities/secret_store_key.dart';
@@ -20,7 +19,6 @@ import 'package:cw_core/node.dart';
import 'package:hash_wallet/entities/sync_status_display_mode.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/root_dir.dart';
import 'package:cw_core/spl_token.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
@@ -63,8 +61,7 @@ Future<void> defaultSettingsMigration(
required SecureStorage secureStorage,
required Box<Node> nodes,
required Box<Node> powNodes,
required Box<Contact> contactSource,
required Box<HavenSeedStore> havenSeedStore}) async {
required Box<Contact> contactSource}) async {
if (Platform.isIOS) {
await ios_migrate_v1(contactSource);
}
@@ -127,12 +124,6 @@ Future<void> defaultSettingsMigration(
currentNodePreferenceKey: PreferencesKey.currentLitecoinElectrumSererIdKey,
useSSL: true,
);
await _changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.haven,
currentNodePreferenceKey: PreferencesKey.currentHavenNodeIdKey,
);
break;
case 2:
await replaceNodesMigration(nodes: nodes);
@@ -215,23 +206,10 @@ Future<void> defaultSettingsMigration(
break;
case 16:
await addWalletNodeList(nodes: nodes, type: WalletType.haven);
await _changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.haven,
currentNodePreferenceKey: PreferencesKey.currentHavenNodeIdKey,
);
await checkCurrentNodes(nodes, powNodes, sharedPreferences);
break;
case 17:
await _changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.haven,
currentNodePreferenceKey: PreferencesKey.currentHavenNodeIdKey,
);
break;
case 18:
@@ -299,13 +277,6 @@ Future<void> defaultSettingsMigration(
// await insecureStorageMigration(secureStorage: secureStorage, sharedPreferences: sharedPreferences);
break;
case 27:
await addWalletNodeList(nodes: nodes, type: WalletType.solana);
await _changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.solana,
currentNodePreferenceKey: PreferencesKey.currentSolanaNodeIdKey,
);
break;
case 28:
@@ -332,13 +303,6 @@ Future<void> defaultSettingsMigration(
await updateBtcNanoWalletInfos();
break;
case 33:
await addWalletNodeList(nodes: nodes, type: WalletType.tron);
await _changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.tron,
currentNodePreferenceKey: PreferencesKey.currentTronNodeIdKey,
);
break;
case 34:
addWalletNodeList(nodes: nodes, type: WalletType.bitcoin);
@@ -391,7 +355,6 @@ Future<void> defaultSettingsMigration(
enabled: false,
);
addWalletNodeList(nodes: nodes, type: WalletType.bitcoin);
addWalletNodeList(nodes: nodes, type: WalletType.tron);
break;
case 42:
_fixNodesUseSSLFlag(nodes);
@@ -420,62 +383,14 @@ Future<void> defaultSettingsMigration(
useSSL: true,
oldUri: ['cakewallet.com'],
);
_changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.tron,
newDefaultUri: tronDefaultNodeUri,
currentNodePreferenceKey: PreferencesKey.currentTronNodeIdKey,
useSSL: true,
oldUri: [
'tron-rpc.publicnode.com:443',
'api.trongrid.io',
],
);
break;
case 45:
// await _backupHavenSeeds(havenSeedStore);
addWalletNodeList(nodes: nodes, type: WalletType.polygon);
addWalletNodeList(nodes: nodes, type: WalletType.ethereum);
_changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.tron,
newDefaultUri: tronDefaultNodeUri,
currentNodePreferenceKey: PreferencesKey.currentTronNodeIdKey,
useSSL: true,
oldUri: [
'tron-rpc.publicnode.com:443',
'trx.nownodes.io',
],
);
_changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.solana,
newDefaultUri: solanaDefaultNodeUri,
currentNodePreferenceKey: PreferencesKey.currentSolanaNodeIdKey,
useSSL: true,
oldUri: ['rpc.ankr.com'],
);
break;
case 46:
await _fixNodesUseSSLFlag(nodes);
await addWalletNodeList(nodes: nodes, type: WalletType.litecoin);
await _changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.solana,
newDefaultUri: solanaDefaultNodeUri,
currentNodePreferenceKey: PreferencesKey.currentSolanaNodeIdKey,
useSSL: true,
oldUri: [
'rpc.ankr.com',
'api.mainnet-beta.solana.com:443',
'solana-rpc.publicnode.com:443',
],
);
await _updateNode(
nodes: nodes,
currentUri: "ethereum.publicnode.com",
@@ -489,13 +404,6 @@ Future<void> defaultSettingsMigration(
useSSL: true,
);
case 47:
await addWalletNodeList(nodes: nodes, type: WalletType.zano);
await _changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.zano,
currentNodePreferenceKey: PreferencesKey.currentZanoNodeIdKey,
);
_changeExchangeProviderAvailability(
sharedPreferences,
providerName: "SimpleSwap",
@@ -508,13 +416,6 @@ Future<void> defaultSettingsMigration(
);
break;
case 48:
await addWalletNodeList(nodes: nodes, type: WalletType.decred);
await _changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.decred,
currentNodePreferenceKey: PreferencesKey.currentDecredNodeIdKey,
);
break;
case 49:
_changeExchangeProviderAvailability(
@@ -527,12 +428,6 @@ Future<void> defaultSettingsMigration(
migrateExistingNodesToUseAutoSwitching(nodes: nodes, powNodes: powNodes);
break;
case 51:
_changeDefaultNode(
nodes: nodes,
sharedPreferences: sharedPreferences,
type: WalletType.zano,
currentNodePreferenceKey: PreferencesKey.currentZanoNodeIdKey,
);
await addWalletNodeList(nodes: nodes, type: WalletType.dogecoin);
await _changeDefaultNode(
nodes: nodes,
@@ -560,7 +455,6 @@ Future<void> defaultSettingsMigration(
);
break;
case 54:
await _backupWowneroSeeds(havenSeedStore);
break;
case 55:
// Hash Wallet: zcash removed. The original migration here added
@@ -604,10 +498,8 @@ Future<void> defaultSettingsMigration(
);
break;
case 63:
await _addXaut0TokenToExistingSolanaWallets();
break;
case 64:
await _backupWowneroSeeds(havenSeedStore);
_changeExchangeProviderAvailability(
sharedPreferences,
providerName: "LetsExchange",
@@ -714,8 +606,6 @@ String _getDefaultNodeUri(WalletType type) {
return newCakeWalletBitcoinUri;
case WalletType.litecoin:
return cakeWalletLitecoinElectrumUri;
case WalletType.haven:
return havenDefaultNodeUri;
case WalletType.ethereum:
return ethereumDefaultNodeUri;
case WalletType.nano:
@@ -724,16 +614,8 @@ String _getDefaultNodeUri(WalletType type) {
return cakeWalletBitcoinCashDefaultNodeUri;
case WalletType.polygon:
return polygonDefaultNodeUri;
case WalletType.solana:
return solanaDefaultNodeUri;
case WalletType.tron:
return tronDefaultNodeUri;
case WalletType.wownero:
return wowneroDefaultNodeUri;
case WalletType.zano:
return zanoDefaultNodeUri;
case WalletType.decred:
return decredDefaultUri;
case WalletType.dogecoin:
return dogecoinDefaultNodeUri;
case WalletType.base:
@@ -742,8 +624,6 @@ String _getDefaultNodeUri(WalletType type) {
return arbitrumDefaultNodeUri;
case WalletType.bsc:
return bscDefaultNodeUri;
case WalletType.zcash:
return zcashDefaultNodeUri;
case WalletType.banano:
case WalletType.none:
return '';
@@ -816,12 +696,6 @@ Future<void> disableServiceStatusFiatDisabled(SharedPreferences sharedPreference
}
}
Future<void> _backupWowneroSeeds(Box<HavenSeedStore> havenSeedStore) async {
final future = wownero?.backupSeeds(havenSeedStore);
if (future != null) await future;
return;
}
Future<void> _updateMoneroPriority(SharedPreferences sharedPreferences) async {
final currentPriority =
await sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority) ??
@@ -867,7 +741,7 @@ Future<void> _validateWalletInfoBoxData() async {
continue;
}
if (type == WalletType.monero || type == WalletType.haven) {
if (type == WalletType.monero) {
final hasKeysFile = walletFiles.any((element) => element.path.contains(".keys"));
if (!hasKeysFile) {
@@ -1150,7 +1024,6 @@ Future<void> checkCurrentNodes(
sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
final currentLitecoinElectrumSeverId =
sharedPreferences.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
final currentHavenNodeId = sharedPreferences.getInt(PreferencesKey.currentHavenNodeIdKey);
final currentEthereumNodeId = sharedPreferences.getInt(PreferencesKey.currentEthereumNodeIdKey);
final currentPolygonNodeId = sharedPreferences.getInt(PreferencesKey.currentPolygonNodeIdKey);
final currentBaseNodeId = sharedPreferences.getInt(PreferencesKey.currentBaseNodeIdKey);
@@ -1158,23 +1031,16 @@ Future<void> checkCurrentNodes(
final currentBscNodeId = sharedPreferences.getInt(PreferencesKey.currentBscNodeIdKey);
final currentNanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
final currentNanoPowNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoPowNodeIdKey);
final currentDecredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
final currentBitcoinCashNodeId =
sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
final currentDogecoinNodeId = sharedPreferences.getInt(PreferencesKey.currentDogecoinNodeIdKey);
final currentSolanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
final currentTronNodeId = sharedPreferences.getInt(PreferencesKey.currentTronNodeIdKey);
final currentWowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
final currentZanoNodeId = sharedPreferences.getInt(PreferencesKey.currentZanoNodeIdKey);
final currentZcashNodeId = sharedPreferences.getInt(PreferencesKey.currentZcashNodeIdKey);
final currentMoneroNode =
nodeSource.values.firstWhereOrNull((node) => node.key == currentMoneroNodeId);
final currentBitcoinElectrumServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentBitcoinElectrumSeverId);
final currentLitecoinElectrumServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentLitecoinElectrumSeverId);
final currentHavenNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentHavenNodeId);
final currentEthereumNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentEthereumNodeId);
final currentPolygonNodeServer =
@@ -1187,24 +1053,14 @@ Future<void> checkCurrentNodes(
nodeSource.values.firstWhereOrNull((node) => node.key == currentBscNodeId);
final currentNanoNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentNanoNodeId);
final currentDecredNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentDecredNodeId);
final currentNanoPowNodeServer =
powNodeSource.values.firstWhereOrNull((node) => node.key == currentNanoPowNodeId);
final currentBitcoinCashNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentBitcoinCashNodeId);
final currentDogecoinNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentDogecoinNodeId);
final currentSolanaNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentSolanaNodeId);
final currentTronNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentTronNodeId);
final currentWowneroNodeServer =
nodeSource.values.firstWhereOrNull((node) => node.key == currentWowneroNodeId);
final currentZanoNode =
nodeSource.values.firstWhereOrNull((node) => node.key == currentZanoNodeId);
final currentZcashNode =
nodeSource.values.firstWhereOrNull((node) => node.key == currentZcashNodeId);
if (currentMoneroNode == null) {
final newCakeWalletNode = Node(uri: newCakeWalletMoneroUri, type: WalletType.monero);
@@ -1234,12 +1090,6 @@ Future<void> checkCurrentNodes(
PreferencesKey.currentLitecoinElectrumSererIdKey, cakeWalletElectrum.key as int);
}
if (currentHavenNodeServer == null) {
final node = Node(uri: havenDefaultNodeUri, type: WalletType.haven);
await nodeSource.add(node);
await sharedPreferences.setInt(PreferencesKey.currentHavenNodeIdKey, node.key as int);
}
if (currentEthereumNodeServer == null) {
final node = Node(uri: ethereumDefaultNodeUri, type: WalletType.ethereum);
await nodeSource.add(node);
@@ -1299,41 +1149,11 @@ Future<void> checkCurrentNodes(
await sharedPreferences.setInt(PreferencesKey.currentBscNodeIdKey, node.key as int);
}
if (currentSolanaNodeServer == null) {
final node = Node(uri: solanaDefaultNodeUri, type: WalletType.solana);
await nodeSource.add(node);
await sharedPreferences.setInt(PreferencesKey.currentSolanaNodeIdKey, node.key as int);
}
if (currentTronNodeServer == null) {
final node = Node(uri: tronDefaultNodeUri, type: WalletType.tron);
await nodeSource.add(node);
await sharedPreferences.setInt(PreferencesKey.currentTronNodeIdKey, node.key as int);
}
if (currentWowneroNodeServer == null) {
final node = Node(uri: wowneroDefaultNodeUri, type: WalletType.wownero);
await nodeSource.add(node);
await sharedPreferences.setInt(PreferencesKey.currentWowneroNodeIdKey, node.key as int);
}
if (currentZanoNode == null) {
final node = Node(uri: zanoDefaultNodeUri, type: WalletType.zano);
await nodeSource.add(node);
await sharedPreferences.setInt(PreferencesKey.currentZanoNodeIdKey, node.key as int);
}
if (currentDecredNodeServer == null) {
final node = Node(uri: decredDefaultUri, type: WalletType.decred);
await nodeSource.add(node);
await sharedPreferences.setInt(PreferencesKey.currentDecredNodeIdKey, node.key as int);
}
if (currentZcashNode == null) {
final node = Node(uri: zcashDefaultNodeUri, type: WalletType.zcash, useSSL: true);
await nodeSource.add(node);
await sharedPreferences.setInt(PreferencesKey.currentZcashNodeIdKey, node.key as int);
}
}
Future<void> resetBitcoinElectrumServer(
@@ -1506,39 +1326,3 @@ Future<void> _addXautTokenToExistingEthereumWallets() async {
printV('Error in XAUT migration: $e');
}
}
Future<void> _addXaut0TokenToExistingSolanaWallets() async {
try {
final xaut0Token = SPLToken(
name: "Tether Gold",
symbol: "XAUT0",
mintAddress: "AymATz4TCL9sWNEEV9Kvyz45CHVhDZ6kUgjTJPzLpU9P",
decimal: 6,
mint: 'xaut0',
enabled: false,
iconPath: "assets/images/xau_sol.png",
);
final allWallets = await WalletInfo.getAll();
final solanaWallets = allWallets.where((wallet) => wallet.type == WalletType.solana).toList();
for (final walletInfo in solanaWallets) {
final sanitizedName = walletInfo.name.replaceAll(' ', '_');
final boxName = '${sanitizedName}_${SPLToken.boxName}';
Box<SPLToken> tokenBox;
if (CakeHive.isBoxOpen(boxName)) {
tokenBox = CakeHive.box<SPLToken>(boxName);
} else {
tokenBox = await CakeHive.openBox<SPLToken>(boxName);
}
final xaut0Address = xaut0Token.mintAddress;
if (!tokenBox.containsKey(xaut0Address)) {
await tokenBox.put(xaut0Address, xaut0Token);
}
}
} catch (e) {
printV('Error in XAUT0 migration: $e');
}
}

View File

@@ -32,8 +32,6 @@ class EnsRecord {
return await ens.withName(name).getCoinAddress(CoinType.BTC);
case WalletType.litecoin:
return await ens.withName(name).getCoinAddress(CoinType.LTC);
case WalletType.haven:
return await ens.withName(name).getCoinAddress(CoinType.XHV);
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.base:

View File

@@ -1,19 +0,0 @@
import 'package:cw_core/hive_type_ids.dart';
import 'package:hive/hive.dart';
part 'haven_seed_store.g.dart';
@HiveType(typeId: HavenSeedStore.typeId)
class HavenSeedStore extends HiveObject {
HavenSeedStore({required this.id, this.seed});
static const typeId = HAVEN_SEED_STORE_TYPE_ID;
static const boxName = 'HavenSeedStore';
static const boxKey = 'havenSeedStoreKey';
@HiveField(0, defaultValue: '')
String id;
@HiveField(2)
String? seed;
}

View File

@@ -16,9 +16,6 @@ Future<List<Node>> loadDefaultNodes(WalletType type) async {
case WalletType.litecoin:
path = 'assets/litecoin_electrum_server_list.yml';
break;
case WalletType.haven:
path = 'assets/haven_node_list.yml';
break;
// TODO: (refactoring) each wallet would have its path, so `wallet.nodePath` would be decided based on chain id in Evm wallet
case WalletType.ethereum:
path = 'assets/ethereum_server_list.yml';
@@ -32,21 +29,9 @@ Future<List<Node>> loadDefaultNodes(WalletType type) async {
case WalletType.polygon:
path = 'assets/polygon_node_list.yml';
break;
case WalletType.solana:
path = 'assets/solana_node_list.yml';
break;
case WalletType.tron:
path = 'assets/tron_node_list.yml';
break;
case WalletType.wownero:
path = 'assets/wownero_node_list.yml';
break;
case WalletType.zano:
path = 'assets/zano_node_list.yml';
break;
case WalletType.decred:
path = 'assets/decred_node_list.yml';
break;
case WalletType.dogecoin:
path = 'assets/dogecoin_electrum_server_list.yml';
break;
@@ -56,9 +41,6 @@ Future<List<Node>> loadDefaultNodes(WalletType type) async {
case WalletType.arbitrum:
path = 'assets/arbitrum_node_list.yml';
break;
case WalletType.zcash:
path = 'assets/zcash_node_list.yml';
break;
case WalletType.bsc:
path = 'assets/bsc_node_list.yml';
break;
@@ -104,34 +86,21 @@ Future<void> resetToDefault(Box<Node> nodeSource) async {
final bitcoinElectrumServerList = await loadDefaultNodes(WalletType.bitcoin);
final litecoinElectrumServerList = await loadDefaultNodes(WalletType.litecoin);
final bitcoinCashElectrumServerList = await loadDefaultNodes(WalletType.bitcoinCash);
final havenNodes = await loadDefaultNodes(WalletType.haven);
final ethereumNodes = await loadDefaultNodes(WalletType.ethereum);
final nanoNodes = await loadDefaultNodes(WalletType.nano);
final polygonNodes = await loadDefaultNodes(WalletType.polygon);
final solanaNodes = await loadDefaultNodes(WalletType.solana);
final tronNodes = await loadDefaultNodes(WalletType.tron);
final decredNodes = await loadDefaultNodes(WalletType.decred);
final zanoNodes = await loadDefaultNodes(WalletType.zano);
final dogecoinElectrumServerList = await loadDefaultNodes(WalletType.dogecoin);
final baseNodes = await loadDefaultNodes(WalletType.base);
final arbitrumNodes = await loadDefaultNodes(WalletType.arbitrum);
// Hash Wallet: zcash node list deleted with the chain. Skip the load,
// skip the concat — stops the first-launch popup "Unable to load asset:
// assets/zcash_node_list.yml".
final bscNodes = await loadDefaultNodes(WalletType.bsc);
final nodes = moneroNodes +
bitcoinElectrumServerList +
litecoinElectrumServerList +
havenNodes +
ethereumNodes +
bitcoinCashElectrumServerList +
nanoNodes +
polygonNodes +
solanaNodes +
tronNodes +
zanoNodes +
decredNodes +
dogecoinElectrumServerList +
baseNodes +
arbitrumNodes +

View File

@@ -406,10 +406,8 @@ class AddressResolver {
}
if (text.hasOnlyEmojis) {
if (settingsStore.lookupsYatService) {
if (walletType != WalletType.haven) {
final addresses = await yatService.fetchYatAddress(text, ticker);
return ParsedAddress.fetchEmojiAddress(addresses: addresses, name: text);
}
final addresses = await yatService.fetchYatAddress(text, ticker);
return ParsedAddress.fetchEmojiAddress(addresses: addresses, name: text);
}
}

View File

@@ -4,9 +4,6 @@ import 'package:hash_wallet/dogecoin/dogecoin.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/wallet_type.dart';
@@ -32,17 +29,8 @@ List<TransactionPriority> priorityForWalletType(WalletType type) {
case WalletType.arbitrum:
case WalletType.nano:
case WalletType.banano:
case WalletType.solana:
case WalletType.tron:
return [];
case WalletType.zano:
return zano!.getTransactionPriorities();
case WalletType.decred:
return decred!.getTransactionPriorities();
case WalletType.zcash:
return zcash!.getTransactionPriorities();
case WalletType.none:
case WalletType.haven:
return [];
}
}

View File

@@ -1,482 +0,0 @@
import 'dart:convert';
import 'package:hash_wallet/.secrets.g.dart' as secrets;
import 'package:hash_wallet/exchange/exchange_provider_description.dart';
import 'package:hash_wallet/exchange/limits.dart';
import 'package:hash_wallet/exchange/provider/exchange_provider.dart';
import 'package:hash_wallet/exchange/trade.dart';
import 'package:hash_wallet/exchange/trade_not_created_exception.dart';
import 'package:hash_wallet/exchange/trade_request.dart';
import 'package:hash_wallet/exchange/trade_state.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/utils/exchange_provider_logger.dart';
import 'package:cw_core/amount_converter.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
class JupiterExchangeProvider extends ExchangeProvider {
JupiterExchangeProvider();
// Jupiter only supports Solana native SOL and Solana tokens
bool _isSolanaCurrency(CryptoCurrency currency) =>
currency == CryptoCurrency.sol || currency.tag == 'SOL';
static const _baseUrl = 'api.jup.ag';
static const _orderPath = '/ultra/v1/order';
static const _executePath = '/ultra/v1/execute';
// Wrapped SOL address (native SOL)
static const _nativeSolMint = 'So11111111111111111111111111111111111111112';
@override
String get title => 'Jupiter';
@override
bool get isAvailable => true;
@override
bool get isEnabled => true;
@override
bool get supportsFixedRate => false; // Jupiter doesn't support fixed rate
@override
ExchangeProviderDescription get description => ExchangeProviderDescription.jupiter;
@override
Future<bool> checkIsAvailable() async => true;
String _getTokenMint(CryptoCurrency currency) {
// Handle native SOL
if (currency == CryptoCurrency.sol) return _nativeSolMint;
// Check if currency tag is SOL (indicating it's a Solana token)
if (currency.tag != 'SOL') {
throw Exception('Unsupported currency: ${currency.title} (not a Solana token)');
}
// Use solana proxy to get token address
// The proxy will handle both SPLToken instances and CryptoCurrency
// by searching through default tokens
if (solana != null) {
try {
return solana!.getTokenAddress(currency);
} catch (e) {
printV('Error getting token address: $e');
throw Exception('Unsupported currency: ${currency.title} (mint address not found: $e)');
}
}
throw Exception('Unsupported currency: ${currency.title} (Solana proxy not available)');
}
@override
Future<Limits?> fetchLimits({
required CryptoCurrency from,
required CryptoCurrency to,
required bool isFixedRateMode,
}) async {
// The Ultra Swap API doesn't have a dedicated limits endpoint
// The /order endpoint validates amounts and returns error codes:
// - errorCode 1: Insufficient funds
// - errorCode 2: Top up SOL for gas
// - errorCode 3: Minimum amount for gasless
// only return null for supported currencies
if (_isSolanaCurrency(from) && _isSolanaCurrency(to)) {
return Limits(min: null, max: null);
} else {
throw Exception('not supported');
}
}
Map<String, String> _getHeaders() {
final headers = <String, String>{};
final apiKey = secrets.jupiterApiKey;
if (apiKey.isNotEmpty) {
headers['x-api-key'] = apiKey;
}
return headers;
}
Map<String, String>? _getReferralFeeConfig() {
try {
final referralFeeBpsStr = secrets.jupiterReferralFeeBps;
final referralFeeBps = int.tryParse(referralFeeBpsStr) ?? 0;
final referralAccount = secrets.jupiterReferralAccount;
// Only enable if both are configured and valid
if (referralFeeBps <= 0 || referralFeeBps > 10000 || referralAccount.isEmpty) {
return null;
}
return {
'referralFee': referralFeeBps.toString(),
'referralAccount': referralAccount,
};
} catch (e) {
return null;
}
}
@override
Future<double> fetchRate({
required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount,
}) async {
try {
// must support both
if (!_isSolanaCurrency(from) || !_isSolanaCurrency(to)) {
return 0.0;
}
final inputMint = _getTokenMint(from);
final outputMint = _getTokenMint(to);
final amountInBaseUnits = AmountConverter.toBaseUnits(amount.toString(), from.decimals);
final params = {
'inputMint': inputMint,
'outputMint': outputMint,
'amount': amountInBaseUnits,
// Note: taker is optional for quote-only requests
};
final uri = Uri.https(_baseUrl, _orderPath, params);
final headers = _getHeaders();
final response = await ProxyWrapper().get(
clearnetUri: uri,
headers: headers,
);
if (response.statusCode != 200) {
ExchangeProviderLogger.logError(
provider: description,
function: 'fetchRate',
error: Exception('Failed to fetch quote: ${response.statusCode}'),
stackTrace: StackTrace.current,
requestData: {
'from': from.title,
'to': to.title,
'amount': amount,
'isFixedRateMode': isFixedRateMode,
'isReceiveAmount': isReceiveAmount,
},
);
return 0.0;
}
final orderData = json.decode(response.body) as Map<String, dynamic>;
final outAmount = BigInt.parse(orderData['outAmount'] as String);
final outputAmount = AmountConverter.fromBaseUnits(outAmount.toString(), to.decimals);
final rate = double.parse(outputAmount) / amount;
ExchangeProviderLogger.logSuccess(
provider: description,
function: 'fetchRate',
requestData: {
'from': from.title,
'to': to.title,
'amount': amount,
'isFixedRateMode': isFixedRateMode,
'isReceiveAmount': isReceiveAmount,
},
responseData: {
'rate': rate,
'outputAmount': outputAmount,
},
);
return rate;
} catch (e, s) {
ExchangeProviderLogger.logError(
provider: description,
function: 'fetchRate',
error: e,
stackTrace: s,
requestData: {
'from': from.title,
'to': to.title,
'amount': amount,
'isFixedRateMode': isFixedRateMode,
'isReceiveAmount': isReceiveAmount,
},
);
printV('fetchRate error: $e');
return 0.0;
}
}
@override
Future<Trade> createTrade({
required TradeRequest request,
required bool isFixedRateMode,
required bool isSendAll,
}) async {
try {
// must support both
if (!_isSolanaCurrency(request.fromCurrency) ||
!_isSolanaCurrency(request.toCurrency)) {
throw 'not supported currencies';
}
final inputMint = _getTokenMint(request.fromCurrency);
final outputMint = _getTokenMint(request.toCurrency);
final amountInBaseUnits =
AmountConverter.toBaseUnits(request.fromAmount, request.fromCurrency.decimals);
final isInternalTransfer = request.refundAddress == request.toAddress;
final orderParams = <String, String>{
'inputMint': inputMint,
'outputMint': outputMint,
'amount': amountInBaseUnits,
'taker': request.refundAddress,
if (!isInternalTransfer) 'receiver': request.toAddress,
};
final referralFeeConfig = _getReferralFeeConfig();
if (referralFeeConfig != null) {
orderParams['referralFee'] = referralFeeConfig['referralFee']!;
orderParams['referralAccount'] = referralFeeConfig['referralAccount']!;
}
final orderUri = Uri.https(_baseUrl, _orderPath, orderParams);
final headers = _getHeaders();
final orderResponse = await ProxyWrapper().get(clearnetUri: orderUri, headers: headers);
if (orderResponse.statusCode != 200) {
final errorBody = orderResponse.body;
ExchangeProviderLogger.logError(
provider: description,
function: 'createTrade',
error: Exception('Failed to get order: ${orderResponse.statusCode} $errorBody'),
stackTrace: StackTrace.current,
requestData: {
'from': request.fromCurrency.title,
'to': request.toCurrency.title,
'fromAmount': request.fromAmount,
'toAmount': request.toAmount,
'toAddress': request.toAddress,
'refundAddress': request.refundAddress,
'isFixedRateMode': isFixedRateMode,
'isSendAll': isSendAll,
},
);
throw TradeNotCreatedException(description);
}
final orderData = json.decode(orderResponse.body) as Map<String, dynamic>;
// Check for errors in response
if (orderData.containsKey('errorCode') || orderData.containsKey('errorMessage')) {
final errorCode = orderData['errorCode'];
final errorMessage = orderData['errorMessage'] ?? 'Unknown error';
ExchangeProviderLogger.logError(
provider: description,
function: 'createTrade',
error: Exception('Order error: $errorCode - $errorMessage'),
stackTrace: StackTrace.current,
requestData: {
'from': request.fromCurrency.title,
'to': request.toCurrency.title,
'fromAmount': request.fromAmount,
'toAmount': request.toAmount,
'toAddress': request.toAddress,
'refundAddress': request.refundAddress,
'isFixedRateMode': isFixedRateMode,
'isSendAll': isSendAll,
},
);
throw TradeNotCreatedException(description);
}
// Extract response data
final transaction = orderData['transaction'] as String?;
final requestId = orderData['requestId'] as String?;
final outAmount = orderData['outAmount'] as String? ?? '0.0';
// Extract network fees from order response (in lamports)
final signatureFeeLamports = (orderData['signatureFeeLamports'] as num?)?.toInt() ?? 0;
final prioritizationFeeLamports =
(orderData['prioritizationFeeLamports'] as num?)?.toInt() ?? 0;
final rentFeeLamports = (orderData['rentFeeLamports'] as num?)?.toInt() ?? 0;
final integratorFeeLamports = (orderData['integratorFeeLamports'] as num?)?.toInt() ?? 0;
final networkFeeLamports = signatureFeeLamports + prioritizationFeeLamports + rentFeeLamports;
final networkFeeInSol = networkFeeLamports / 1000000000.0;
final integratorFeeInSol = integratorFeeLamports / 1000000000.0;
final totalFeeInSol = networkFeeInSol + integratorFeeInSol;
if (transaction == null || transaction.isEmpty) {
throw Exception('No transaction returned from Jupiter order endpoint');
}
if (requestId == null || requestId.isEmpty) {
throw Exception('No requestId returned from Jupiter order endpoint');
}
final receiveAmount = AmountConverter.fromBaseUnits(outAmount, request.toCurrency.decimals);
ExchangeProviderLogger.logSuccess(
provider: description,
function: 'createTrade',
requestData: {
'from': request.fromCurrency.title,
'to': request.toCurrency.title,
'fromAmount': request.fromAmount,
'toAmount': request.toAmount,
'toAddress': request.toAddress,
'refundAddress': request.refundAddress,
'isFixedRateMode': isFixedRateMode,
'isSendAll': isSendAll,
},
responseData: {
'tradeId': requestId,
'receiveAmount': receiveAmount,
'hasTransaction': transaction.isNotEmpty,
'requestId': requestId,
},
);
return Trade(
id: requestId,
from: request.fromCurrency,
to: request.toCurrency,
provider: description,
inputAddress: request.toAddress,
refundAddress: request.refundAddress,
state: TradeState.created,
createdAt: DateTime.now(),
amount: request.fromAmount,
receiveAmount: receiveAmount,
payoutAddress: request.toAddress,
isSendAll: isSendAll,
routerData: transaction,
routerValue: requestId,
fee: totalFeeInSol,
);
} catch (e, s) {
ExchangeProviderLogger.logError(
provider: description,
function: 'createTrade',
error: e,
stackTrace: s,
requestData: {
'from': request.fromCurrency.title,
'to': request.toCurrency.title,
'fromAmount': request.fromAmount,
'toAmount': request.toAmount,
'toAddress': request.toAddress,
'refundAddress': request.refundAddress,
'isFixedRateMode': isFixedRateMode,
'isSendAll': isSendAll,
},
);
printV('createTrade error: $e');
throw TradeNotCreatedException(description);
}
}
/// Executes a signed Jupiter swap transaction via Jupiter's /execute endpoint
Future<Map<String, dynamic>> executeSwap({
required String signedTransaction,
required String requestId,
}) async {
try {
final executeUri = Uri.https(_baseUrl, _executePath);
final headers = _getHeaders();
headers['Content-Type'] = 'application/json';
final body = json.encode({
'signedTransaction': signedTransaction,
'requestId': requestId,
});
final response = await ProxyWrapper().post(
clearnetUri: executeUri,
headers: headers,
body: body,
);
if (response.statusCode != 200) {
final errorBody = response.body;
ExchangeProviderLogger.logError(
provider: description,
function: 'executeSwap',
error: Exception('Failed to execute swap: ${response.statusCode} $errorBody'),
stackTrace: StackTrace.current,
requestData: {
'requestId': requestId,
'hasSignedTransaction': signedTransaction.isNotEmpty,
},
);
throw Exception('Failed to execute swap: ${response.statusCode} $errorBody');
}
final executeData = json.decode(response.body) as Map<String, dynamic>;
ExchangeProviderLogger.logSuccess(
provider: description,
function: 'executeSwap',
requestData: {
'requestId': requestId,
'hasSignedTransaction': signedTransaction.isNotEmpty,
},
responseData: executeData,
);
return executeData;
} catch (e, s) {
ExchangeProviderLogger.logError(
provider: description,
function: 'executeSwap',
error: e,
stackTrace: s,
requestData: {
'requestId': requestId,
'hasSignedTransaction': signedTransaction.isNotEmpty,
},
);
rethrow;
}
}
@override
Future<Trade> findTradeById({required String id}) async {
// Jupiter Ultra Swap API doesn't track trades by our trade ID
//
// Status tracking options:
// 1. Use /execute endpoint with requestId + signedTransaction (requires storing signed tx)
// 2. Check on-chain via transaction signature (txId) after transaction is sent
//
// Current implementation: We track status on-chain via transaction signature
// The txId field in Trade is set after the transaction is sent and can be
// used to check transaction status via Solana RPC.
//
// Note: To use /execute endpoint for status polling, we would need to:
// - Store the signed transaction (not currently stored)
// - Use requestId from routerValue
// - Poll /ultra/v1/execute with both signedTransaction and requestId
//
// For now, throw exception to indicate status must be checked on-chain
throw Exception(
'Jupiter trade status must be checked on-chain using transaction signature (txId). '
'After transaction is sent, txId will contain the signature for status checking.');
}
}

View File

@@ -1,79 +0,0 @@
import 'dart:io';
import 'package:cw_core/balance.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:hive/hive.dart';
class HavenWalletService extends WalletService {
HavenWalletService();
@override
WalletType getType() => WalletType.haven;
@override
Future<void> remove(String wallet) async {
final path = await pathForWalletDir(name: wallet, type: getType());
final file = Directory(path);
final isExist = file.existsSync();
if (isExist) {
await file.delete(recursive: true);
}
final walletInfo = await WalletInfo.get(wallet, getType());
if (walletInfo == null) {
throw Exception('Wallet not found');
}
await WalletInfo.delete(walletInfo);
}
@override
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> create(
WalletCredentials credentials,
{bool? isTestnet}) {
throw UnimplementedError();
}
@override
Future<bool> isWalletExit(String name) {
throw UnimplementedError();
}
@override
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> openWallet(
String name, String password) {
throw UnimplementedError();
}
@override
Future<void> rename(String currentName, String password, String newName) {
throw UnimplementedError();
}
@override
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
restoreFromHardwareWallet(WalletCredentials credentials) {
throw UnimplementedError();
}
@override
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
restoreFromKeys(WalletCredentials credentials, {bool? isTestnet}) {
throw UnimplementedError();
}
@override
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
restoreFromSeed(WalletCredentials credentials, {bool? isTestnet}) {
throw UnimplementedError();
}
}

View File

@@ -14,7 +14,6 @@ import 'package:hash_wallet/di.dart';
import 'package:hash_wallet/entities/contact.dart';
import 'package:hash_wallet/entities/default_settings_migration.dart';
import 'package:hash_wallet/entities/get_encryption_key.dart';
import 'package:hash_wallet/entities/haven_seed_store.dart';
import 'package:hash_wallet/entities/language_service.dart';
import 'package:hash_wallet/entities/template.dart';
import 'package:hash_wallet/entities/transaction_description.dart';
@@ -37,7 +36,6 @@ import 'package:hash_wallet/utils/exception_handler.dart';
import 'package:hash_wallet/utils/feature_flag.dart';
import 'package:hash_wallet/utils/responsive_layout_util.dart';
import 'package:hash_wallet/view_model/link_view_model.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/address_info.dart';
import 'package:cw_core/cake_hive.dart';
import 'package:cw_core/db/sqlite.dart';
@@ -164,17 +162,6 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {
ProxyWrapper.logger = MemoryProxyLogger();
}
if (!Platform.isWindows) {
var zcashPassword = await secureStorageShared.read(
key: "com.cakewallet.cw_zcash/zec.db");
if (zcashPassword == null || zcashPassword.isEmpty) {
zcashPassword = generateKey().substring(0, 32);
secureStorageShared.write(
key: "com.cakewallet.cw_zcash/zec.db", value: zcashPassword);
}
zcash?.unlockDatabase(zcashPassword);
}
// Basically when we're running a test
if (topLevelKey != null) {
runApp(
@@ -256,10 +243,6 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter());
}
if (!CakeHive.isAdapterRegistered(HavenSeedStore.typeId)) {
CakeHive.registerAdapter(HavenSeedStoreAdapter());
}
if (!CakeHive.isAdapterRegistered(MwebUtxo.typeId)) {
CakeHive.registerAdapter(MwebUtxoAdapter());
}
@@ -301,11 +284,6 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
final unspentCoinsInfoSource = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
final payjoinSessionSource = await CakeHive.openBox<PayjoinSession>(PayjoinSession.boxName);
final havenSeedStoreBoxKey =
await getEncryptionKey(secureStorage: secureStorage, forKey: HavenSeedStore.boxKey);
final havenSeedStore = await CakeHive.openBox<HavenSeedStore>(HavenSeedStore.boxName,
encryptionKey: havenSeedStoreBoxKey);
await initialSetup(
loadWallet: loadWallet,
sharedPreferences: await SharedPreferences.getInstance(),
@@ -321,7 +299,6 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
secureStorage: secureStorage,
payjoinSessionSource: payjoinSessionSource,
anonpayInvoiceInfo: anonpayInvoiceInfo,
havenSeedStore: havenSeedStore,
initialMigrationVersion: 65,
);
}
@@ -341,7 +318,6 @@ Future<void> initialSetup({
required Box<AnonpayInvoiceInfo> anonpayInvoiceInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
required Box<PayjoinSession> payjoinSessionSource,
required Box<HavenSeedStore> havenSeedStore,
required int initialMigrationVersion,
}) async {
LanguageService.loadLocaleList();
@@ -352,7 +328,6 @@ Future<void> initialSetup({
contactSource: contactSource,
nodes: nodes,
powNodes: powNodes,
havenSeedStore: havenSeedStore,
);
await setup(
nodeSource: nodes,

View File

@@ -17,11 +17,9 @@ import 'package:hash_wallet/utils/share_util.dart';
import 'package:hash_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:hash_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:hash_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/payment_uris.dart';
import 'package:cw_core/receive_page_option.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
@@ -103,10 +101,6 @@ class _NewReceivePageState extends State<NewReceivePage> {
widget.addressListViewModel.setAddressType(bitcoin!.getOptionToType(option));
return;
}
if (widget.dashboardViewModel.type == WalletType.zcash) {
widget.addressListViewModel.setAddressType(zcash!.getOptionToType(option));
return;
}
switch (option) {
case ReceivePageOption.anonPayInvoice:
@@ -151,10 +145,6 @@ class _NewReceivePageState extends State<NewReceivePage> {
.contains(widget.addressListViewModel.type)) {
widget.addressListViewModel.setAddressType(bitcoin!.getBitcoinAddressType(option));
}
if (widget.addressListViewModel.type == WalletType.zcash) {
printV("help me i'll kms if that wont work: ${zcash!.getZcashAddressType(option)}");
widget.addressListViewModel.setAddressType(zcash!.getZcashAddressType(option));
}
}
});
}

View File

@@ -875,23 +875,6 @@ class _NewSendPageState extends State<NewSendPage> {
paymentRequest,
fixedNetwork: result.walletType,
);
break;
case PaymentFlowType.solanaTokenSelection:
await _showTokenSelectionFlow(
widget.paymentViewModel,
widget.walletSwitcherViewModel,
paymentRequest,
fixedNetwork: WalletType.solana,
);
break;
case PaymentFlowType.tronTokenSelection:
await _showTokenSelectionFlow(
widget.paymentViewModel,
widget.walletSwitcherViewModel,
paymentRequest,
fixedNetwork: WalletType.tron,
);
break;
case PaymentFlowType.currentWalletCompatible:
case PaymentFlowType.error:

View File

@@ -17,11 +17,8 @@ class ReceiveInfoBox extends StatelessWidget {
return null;
case WalletType.ethereum:
case WalletType.base:
case WalletType.solana:
case WalletType.arbitrum:
case WalletType.tron:
case WalletType.polygon:
case WalletType.zano:
case WalletType.bsc:
if(autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.disabled)
return null;

View File

@@ -21,9 +21,6 @@ void startCheckConnectionReaction(WalletBase wallet, SettingsStore settingsStore
if (wallet.type == WalletType.bitcoin && wallet.syncStatus is SyncingSyncStatus) {
return;
}
if (wallet.type == WalletType.decred && wallet.syncStatus is ProcessingSyncStatus) {
return;
}
try {
final connectivityResult = await (Connectivity().checkConnectivity());

View File

@@ -3,11 +3,9 @@ import 'package:hash_wallet/core/fiat_conversion_service.dart';
import 'package:hash_wallet/entities/fiat_api_mode.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:hash_wallet/store/settings_store.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_type.dart';
@@ -39,16 +37,6 @@ Future<void> startFiatRateUpdate(
evm!.getERC20Currencies(appStore.wallet!).where((element) => element.enabled);
}
if (appStore.wallet!.type == WalletType.solana) {
currencies =
solana!.getSPLTokenCurrencies(appStore.wallet!).where((element) => element.enabled);
}
if (appStore.wallet!.type == WalletType.tron) {
currencies =
tron!.getTronTokenCurrencies(appStore.wallet!).where((element) => element.enabled);
}
if (currencies != null) {
for (final currency in currencies) {
// skip potential scams:

View File

@@ -5,8 +5,6 @@ import 'package:hash_wallet/entities/fiat_api_mode.dart';
import 'package:hash_wallet/entities/wallet_manager.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/utils/tor.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/sync_status.dart';
@@ -82,8 +80,7 @@ void startCurrentWalletChangeReaction(
wallet.type == WalletType.bitcoin ||
wallet.type == WalletType.litecoin ||
wallet.type == WalletType.bitcoinCash ||
wallet.type == WalletType.dogecoin ||
wallet.type == WalletType.decred) {
wallet.type == WalletType.dogecoin) {
_setAutoGenerateSubaddressStatus(wallet, settingsStore);
}
@@ -111,11 +108,6 @@ void startCurrentWalletChangeReaction(
if (isEVMCompatibleChain(wallet.type)) {
await evm!.discoverAndAddWalletTokens(wallet);
}
if (wallet.type == WalletType.solana) {
await solana!
.discoverAndAddWalletTokens(wallet);
}
} catch (e) {
printV(e.toString());
}
@@ -139,14 +131,6 @@ void startCurrentWalletChangeReaction(
if (isEVMCompatibleChain(wallet.type)) {
currencies = evm!.getERC20Currencies(appStore.wallet!).where((element) => element.enabled);
}
if (wallet.type == WalletType.solana) {
currencies =
solana!.getSPLTokenCurrencies(appStore.wallet!).where((element) => element.enabled);
}
if (wallet.type == WalletType.tron) {
currencies =
tron!.getTronTokenCurrencies(appStore.wallet!).where((element) => element.enabled);
}
if (currencies != null) {
for (final currency in currencies) {

View File

@@ -1,7 +1,5 @@
import 'package:hash_wallet/src/screens/wallet_connect/services/chain_service/eth/evm_chain_id.dart';
import 'package:hash_wallet/src/screens/wallet_connect/services/chain_service/eth/evm_supported_methods.dart';
import 'package:hash_wallet/src/screens/wallet_connect/services/chain_service/solana/solana_chain_id.dart';
import 'package:hash_wallet/src/screens/wallet_connect/services/chain_service/solana/solana_supported_methods.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:hash_wallet/evm/evm.dart';
@@ -40,8 +38,6 @@ bool isNFTACtivatedChain(WalletType walletType, {int? chainId}) {
}
switch (walletType) {
case WalletType.solana:
return true;
default:
return false;
}
@@ -49,7 +45,6 @@ bool isNFTACtivatedChain(WalletType walletType, {int? chainId}) {
bool isWalletConnectCompatibleChain(WalletType walletType) {
switch (walletType) {
case WalletType.solana:
case WalletType.polygon:
case WalletType.ethereum:
case WalletType.base:
@@ -77,8 +72,6 @@ String getChainNameSpaceAndIdBasedOnWalletType(WalletType walletType, {int? chai
return EVMChainId.arbitrum.chain();
case WalletType.bsc:
return EVMChainId.bsc.chain();
case WalletType.solana:
return SolanaChainId.mainnet.chain();
default:
return '';
}
@@ -92,18 +85,12 @@ List<String> getChainSupportedMethodsOnWalletType(WalletType walletType) {
case WalletType.arbitrum:
case WalletType.bsc:
return EVMSupportedMethods.values.map((e) => e.name).toList();
case WalletType.solana:
return SolanaSupportedMethods.values.map((e) => e.name).toList();
default:
return [];
}
}
String getChainNameBasedOnWalletType(WalletType walletType, {int? chainId}) {
if (walletType == WalletType.solana) {
return 'mainnet';
}
if (chainId != null) {
return evm!.getChainNameByChainId(chainId);
}
@@ -112,10 +99,6 @@ String getChainNameBasedOnWalletType(WalletType walletType, {int? chainId}) {
}
String getTokenNameBasedOnWalletType(WalletType walletType, {int? chainId}) {
if (walletType == WalletType.solana) {
return 'SOL';
}
if (chainId != null) {
return evm!.getTokenNameByChainId(chainId);
}

View File

@@ -7,8 +7,6 @@ bool isBIP39Wallet(WalletType walletType) {
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.tron:
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.bitcoinCash:
@@ -16,12 +14,8 @@ bool isBIP39Wallet(WalletType walletType) {
case WalletType.banano:
case WalletType.monero:
case WalletType.dogecoin:
case WalletType.zcash:
return true;
case WalletType.wownero:
case WalletType.haven:
case WalletType.zano:
case WalletType.decred:
case WalletType.none:
return false;
}
@@ -42,9 +36,6 @@ bool hasTokens(WalletType walletType) {
switch (walletType) {
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.solana:
case WalletType.tron:
case WalletType.zano:
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:

View File

@@ -1,412 +0,0 @@
part of 'solana.dart';
class CWSolana extends Solana {
@override
List<String> getSolanaWordList(String language) => SolanaMnemonics.englishWordlist;
WalletService createSolanaWalletService(bool isDirect) => SolanaWalletService(isDirect);
@override
WalletCredentials createSolanaNewWalletCredentials({
required String name,
String? mnemonic,
WalletInfo? walletInfo,
String? password,
String? passphrase,
}) =>
SolanaNewWalletCredentials(
name: name,
walletInfo: walletInfo,
password: password,
mnemonic: mnemonic,
passphrase: passphrase,
);
@override
WalletCredentials createSolanaRestoreWalletFromSeedCredentials({
required String name,
required String mnemonic,
required String password,
String? passphrase,
}) =>
SolanaRestoreWalletFromSeedCredentials(
name: name,
password: password,
mnemonic: mnemonic,
passphrase: passphrase,
);
@override
WalletCredentials createSolanaRestoreWalletFromPrivateKey({
required String name,
required String privateKey,
required String password,
}) =>
SolanaRestoreWalletFromPrivateKey(name: name, password: password, privateKey: privateKey);
@override
String getAddress(WalletBase wallet) => (wallet as SolanaWallet).walletAddresses.address;
@override
String getPrivateKey(WalletBase wallet) => (wallet as SolanaWallet).privateKey;
@override
String getPublicKey(WalletBase wallet) =>
(wallet as SolanaWallet).solanaPublicKey.toAddress().address;
Object createSolanaTransactionCredentials(
List<Output> outputs, {
required CryptoCurrency currency,
}) =>
SolanaTransactionCredentials(
outputs
.map((out) => OutputInfo(
fiatAmount: out.fiatAmount,
cryptoAmount: out.cryptoAmount,
address: out.address,
note: out.note,
sendAll: out.sendAll,
extractedAddress: out.extractedAddress,
isParsedAddress: out.isParsedAddress,
formattedCryptoAmount: out.formattedCryptoAmount))
.toList(),
currency: currency,
);
Object createSolanaTransactionCredentialsRaw(
List<OutputInfo> outputs, {
required CryptoCurrency currency,
}) =>
SolanaTransactionCredentials(outputs, currency: currency);
@override
List<SPLToken> getSPLTokenCurrencies(WalletBase wallet) {
final solanaWallet = wallet as SolanaWallet;
return solanaWallet.splTokenCurrencies;
}
@override
Future<void> addSPLToken(
WalletBase wallet,
CryptoCurrency token,
String contractAddress,
) async {
final splToken = SPLToken(
name: token.name,
symbol: token.title,
mintAddress: contractAddress,
decimal: token.decimals,
mint: token.name.toUpperCase(),
enabled: token.enabled,
iconPath: token.iconPath,
isPotentialScam: token.isPotentialScam,
);
await (wallet as SolanaWallet).addSPLToken(splToken);
}
@override
Future<void> deleteSPLToken(WalletBase wallet, CryptoCurrency token) async =>
await (wallet as SolanaWallet).deleteSPLToken(token as SPLToken);
@override
Future<SPLToken?> getSPLToken(WalletBase wallet, String mintAddress) async {
final solanaWallet = wallet as SolanaWallet;
return await solanaWallet.getSPLToken(mintAddress);
}
@override
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) {
transaction as SolanaTransactionInfo;
if (transaction.tokenSymbol == CryptoCurrency.sol.title) {
return CryptoCurrency.sol;
}
wallet as SolanaWallet;
return wallet.splTokenCurrencies.firstWhere(
(element) => transaction.tokenSymbol == element.symbol,
);
}
@override
double getTransactionAmountRaw(TransactionInfo transactionInfo) {
return (transactionInfo as SolanaTransactionInfo).solAmount.toDouble();
}
@override
String getTokenAddress(CryptoCurrency asset) {
// If it's already an SPLToken, use its mint address
if (asset is SPLToken) return asset.mintAddress;
// If it's not an SPLToken but has SOL tag, try to find matching SPLToken
if (asset.tag == 'SOL') {
final symbol = asset.title.toUpperCase();
// Search through default tokens to find matching symbol
final defaultTokens = DefaultSPLTokens().initialSPLTokens;
try {
final matchingToken = defaultTokens.firstWhere(
(token) => token.symbol.toUpperCase() == symbol,
);
return matchingToken.mintAddress;
} catch (_) {
// Token not found in default tokens
}
}
// Fallback - try to cast (will throw if not SPLToken)
return (asset as SPLToken).mintAddress;
}
@override
List<int>? getValidationLength(CryptoCurrency type) {
if (type is SPLToken) {
return [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44];
}
return null;
}
@override
double? getEstimateFees(WalletBase wallet) {
return (wallet as SolanaWallet).estimatedFee;
}
@override
List<SPLToken> getDefaultSPLTokens() => DefaultSPLTokens().initialSPLTokens;
@override
List<String> getDefaultTokenContractAddresses() {
return DefaultSPLTokens().initialSPLTokens.map((e) => e.mintAddress).toList();
}
@override
List<String> getDefaultTokenSymbols() {
return DefaultSPLTokens().initialSPLTokens.map((e) => e.symbol.toUpperCase()).toList();
}
@override
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress) {
final solanaWallet = wallet as SolanaWallet;
return solanaWallet.splTokenCurrencies.any((element) => element.mintAddress == contractAddress);
}
@override
Future<PendingTransaction> signAndPrepareJupiterSwapTransaction(
WalletBase wallet,
String base64Transaction,
String requestId,
String destinationAddress,
double amount,
double fee,
) async {
final solanaWallet = wallet as SolanaWallet;
final privateKey = solanaWallet.solanaPrivateKey;
final solanaProvider = solanaWallet.solanaProvider;
if (solanaProvider == null) {
throw Exception('Solana provider not available');
}
final unsignedTransactionBytes = base64.decode(base64Transaction);
final unsignedTransaction = SolanaTransaction.deserialize(unsignedTransactionBytes);
final signedMessage = privateKey.sign(unsignedTransaction.serializeMessage());
unsignedTransaction.addSignature(privateKey.publicKey().toAddress(), signedMessage);
final signedTransactionBytes = unsignedTransaction.serialize();
final signedTransactionBase64 = base64.encode(Uint8List.fromList(signedTransactionBytes));
Future<String> sendTx() async {
try {
if (signedTransactionBase64.isEmpty) {
throw Exception('Invalid transaction: transaction is empty');
}
if (requestId.isEmpty) {
throw Exception('Invalid requestId: requestId is empty');
}
final jupiterProvider = JupiterExchangeProvider();
final executeResponse = await jupiterProvider.executeSwap(
signedTransaction: signedTransactionBase64,
requestId: requestId,
);
final status = executeResponse['status'] as String?;
final signature = executeResponse['signature'] as String?;
final errorCode = executeResponse['code'] as num?;
final errorMessage = executeResponse['error'] as String? ?? 'Unknown error';
// Handle different status cases
switch (status) {
case 'Success':
if (signature == null ||
signature.isEmpty ||
signature == '1111111111111111111111111111111111111111111111111111111111111111') {
throw Exception(
'Invalid transaction signature received from Jupiter. '
'Status: $status',
);
}
return signature;
case 'Failed':
String userFriendlyError = _getJupiterErrorMessage(errorCode, errorMessage);
// Even when failed, Jupiter may return a signature for solscan
if (signature != null && signature.isNotEmpty) {
throw JupiterSwapFailedException(
message: userFriendlyError,
signature: signature,
errorCode: errorCode,
errorMessage: errorMessage,
);
} else {
throw Exception(userFriendlyError);
}
case 'Pending':
case 'Processing':
throw Exception(
'Jupiter swap is still processing. Please wait and try checking the transaction status.',
);
default:
throw Exception(
'Jupiter swap returned unknown status: $status. Error: $errorMessage. Code: $errorCode',
);
}
} catch (e) {
throw Exception('Failed to execute Jupiter swap: $e');
}
}
return PendingSolanaTransaction(
amount: amount,
serializedTransaction: signedTransactionBase64,
destinationAddress: destinationAddress,
sendTransaction: sendTx,
fee: fee,
);
}
/// Get user-friendly error message based on Jupiter error code
String _getJupiterErrorMessage(num? errorCode, String errorMessage) {
if (errorCode == null) {
return 'Jupiter swap failed: $errorMessage';
}
switch (errorCode.toInt()) {
case -2000:
return 'Transaction failed to land on the network. Please try again.';
case -2001:
return 'Unknown error occurred. Please try again.';
case -2002:
return 'Invalid transaction. Please try creating a new swap.';
case -2003:
return 'Quote expired. The swap quote is no longer valid. Please create a new swap.';
case -2004:
return 'Swap was rejected. This may be due to:\n'
'- Insufficient funds for the swap or fees\n'
'- Slippage tolerance exceeded (price moved too much)\n'
'- Network congestion\n'
'Please check your balance and try again with a new quote.';
case -2005:
return 'Internal error occurred. Please try again.';
default:
// Check for common program errors
if (errorMessage.contains('SlippageToleranceExceeded') ||
errorMessage.contains('slippage')) {
return 'Slippage tolerance exceeded. The price moved too much during the swap. '
'Please try again with a new quote.';
}
if (errorMessage.contains('InsufficientFunds') || errorMessage.contains('insufficient')) {
return 'Insufficient funds. Please ensure you have enough SOL for the swap and fees.';
}
if (errorMessage.contains('Blockhash') || errorMessage.contains('expired')) {
return 'Transaction expired. Please create a new swap.';
}
return 'Jupiter swap failed (code: $errorCode): $errorMessage. Please try again.';
}
}
@override
Future<void> pollForTransaction(
WalletBase wallet,
String signature, {
Duration initialDelay = const Duration(seconds: 1),
int maxRetries = 5,
}) async {
final solanaWallet = wallet as SolanaWallet;
await solanaWallet.pollForTransaction(
signature: signature,
initialDelay: initialDelay,
maxRetries: maxRetries,
);
}
@override
Future<void> updateTokenBalances(
WalletBase wallet, {
List<String>? tokenMints,
}) async {
final solanaWallet = wallet as SolanaWallet;
await solanaWallet.updateTokenBalance(tokenMints: tokenMints);
}
static const _minTokenUsdValue = 0.1;
Future<({double usdValue, bool hasValidFiatPrice})> _getTokenUsdValueAndFiatCheck(
SPLToken token,
double balance,
) async {
try {
final settingsStore = getIt.get<SettingsStore>();
final torOnly = settingsStore.fiatApiMode == FiatApiMode.torOnly;
final price = await FiatConversionService.fetchPrice(
crypto: token,
fiat: FiatCurrency.usd,
torOnly: torOnly,
);
final hasValidFiatPrice = price > 0;
final usdValue = balance * price;
return (usdValue: usdValue, hasValidFiatPrice: hasValidFiatPrice);
} catch (e) {
return (usdValue: 0.0, hasValidFiatPrice: false);
}
}
@override
Future<void> discoverAndAddWalletTokens(WalletBase wallet) async {
if (wallet is! SolanaWallet) return;
try {
final result = await wallet.discoverTokensFromMoralis();
if (result.newTokens.isEmpty) return;
final List<Future<void>> tokenChecks = [];
for (final item in result.newTokens) {
tokenChecks.add((() async {
final token = item.token;
final fiatResult = await _getTokenUsdValueAndFiatCheck(token, item.balance);
final isSpam = !fiatResult.hasValidFiatPrice;
token.isPotentialScam = isSpam;
token.enabled = (fiatResult.usdValue >= _minTokenUsdValue) && !isSpam;
await wallet.addSPLToken(token);
})());
}
await Future.wait(tokenChecks);
} catch (_) {}
}
}

View File

@@ -35,7 +35,6 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
final bitcoinIcon = Image.asset('assets/images/crypto/bitcoin.webp', height: 24, width: 24);
final tBitcoinIcon = Image.asset('assets/images/tbtc.png', height: 24, width: 24);
final litecoinIcon = Image.asset('assets/images/crypto/litecoin.webp', height: 24, width: 24);
final havenIcon = Image.asset('assets/images/haven_logo.webp', height: 24, width: 24);
final ethereumIcon = Image.asset('assets/images/crypto/ethereum.webp', height: 24, width: 24);
final polygonIcon = Image.asset('assets/images/crypto/polygon.webp', height: 24, width: 24);
final bitcoinCashIcon = Image.asset('assets/images/crypto/bitcoin-cash.webp', height: 24, width: 24);
@@ -44,13 +43,8 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
final bscIcon = Image.asset('assets/images/crypto/BNB.webp', height: 24, width: 24);
final nanoIcon = Image.asset('assets/images/crypto/nano.webp', height: 24, width: 24);
final bananoIcon = Image.asset('assets/images/crypto/nano.webp', height: 24, width: 24);
final solanaIcon = Image.asset('assets/images/crypto/solana.webp', height: 24, width: 24);
final tronIcon = Image.asset('assets/images/crypto/tron.webp', height: 24, width: 24);
final wowneroIcon = Image.asset('assets/images/crypto/wownero.webp', height: 24, width: 24);
final zanoIcon = Image.asset('assets/images/crypto/zano.webp', height: 24, width: 24);
final decredIcon = Image.asset('assets/images/crypto/decred.webp', height: 24, width: 24);
final dogeIcon = Image.asset('assets/images/crypto/dogecoin.webp', height: 24, width: 24);
final zcashIcon = Image.asset('assets/images/crypto/zcash.webp', height: 24, width: 24);
final nonWalletTypeIcon = Image.asset('assets/images/close.png', height: 24, width: 24);
Image _newWalletImage(BuildContext context) => Image.asset(
@@ -167,8 +161,6 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
return wowneroIcon;
case WalletType.litecoin:
return litecoinIcon;
case WalletType.haven:
return havenIcon;
case WalletType.ethereum:
return ethereumIcon;
case WalletType.bitcoinCash:
@@ -179,14 +171,6 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
return bananoIcon;
case WalletType.polygon:
return polygonIcon;
case WalletType.solana:
return solanaIcon;
case WalletType.tron:
return tronIcon;
case WalletType.zano:
return zanoIcon;
case WalletType.decred:
return decredIcon;
case WalletType.dogecoin:
return dogeIcon;
case WalletType.base:
@@ -195,8 +179,6 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
return arbitrumIcon;
case WalletType.bsc:
return bscIcon;
case WalletType.zcash:
return zcashIcon;
case WalletType.none:
return nonWalletTypeIcon;
}

View File

@@ -15,7 +15,6 @@ import 'package:hash_wallet/utils/show_pop_up.dart';
import 'package:hash_wallet/view_model/dashboard/home_settings_view_model.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/homoglyph_normalizer.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -349,13 +348,12 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
if (!mounted) return;
if (token != null) {
final isZano = widget.homeSettingsViewModel.walletType == WalletType.zano;
if (_tokenNameController.text.isEmpty || isZano) _tokenNameController.text = token.name;
if (_tokenSymbolController.text.isEmpty || isZano)
if (_tokenNameController.text.isEmpty) _tokenNameController.text = token.name;
if (_tokenSymbolController.text.isEmpty)
_tokenSymbolController.text = token.title;
if (_tokenIconPathController.text.isEmpty)
_tokenIconPathController.text = token.iconPath ?? '';
if (_tokenDecimalController.text.isEmpty || isZano)
if (_tokenDecimalController.text.isEmpty)
_tokenDecimalController.text = token.decimals.toString();
_checkIfTokenIsVerified(_contractAddressController.text);
@@ -432,9 +430,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
placeholder: S.of(context).contract_address,
copyImagePath: 'assets/images/copy.png',
options: [AddressTextFieldOption.paste],
validator: widget.homeSettingsViewModel.walletType == WalletType.zano
? null
: AddressValidator(type: widget.homeSettingsViewModel.nativeToken).call,
validator: AddressValidator(type: widget.homeSettingsViewModel.nativeToken).call,
onPushPasteButton: (_) {
_pasteText();
},

View File

@@ -6,7 +6,6 @@ import 'package:hash_wallet/anonpay/anonpay_donation_link_info.dart';
import 'package:hash_wallet/entities/preferences_key.dart';
import 'package:hash_wallet/src/screens/receive/anonpay_receive_page.dart';
import 'package:hash_wallet/src/widgets/cake_image_widget.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/receive_page_option.dart';
import 'package:hash_wallet/src/screens/dashboard/widgets/present_receive_option_picker.dart';
import 'package:hash_wallet/src/widgets/gradient_background.dart';
@@ -15,7 +14,6 @@ import 'package:hash_wallet/utils/responsive_layout_util.dart';
import 'package:hash_wallet/utils/share_util.dart';
import 'package:hash_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:hash_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:hash_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
@@ -271,10 +269,6 @@ class AddressPage extends BasePage {
addressListViewModel.setAddressType(bitcoin!.getOptionToType(option));
return;
}
if (dashboardViewModel.type == WalletType.zcash) {
addressListViewModel.setAddressType(zcash!.getOptionToType(option));
return;
}
switch (option) {
case ReceivePageOption.anonPayInvoice:
@@ -318,10 +312,6 @@ class AddressPage extends BasePage {
if ([WalletType.bitcoin, WalletType.litecoin].contains(addressListViewModel.type)) {
addressListViewModel.setAddressType(bitcoin!.getBitcoinAddressType(option));
}
if (addressListViewModel.type == WalletType.zcash) {
printV("help me i'll kms if that wont work: ${zcash!.getZcashAddressType(option)}");
addressListViewModel.setAddressType(zcash!.getZcashAddressType(option));
}
}
});

View File

@@ -3,15 +3,12 @@ import 'dart:io';
import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/new-ui/widgets/apps_widget.dart';
import 'package:hash_wallet/routes.dart';
import 'package:hash_wallet/src/widgets/alert_with_one_action.dart';
import 'package:hash_wallet/src/widgets/cake_image_widget.dart';
import 'package:hash_wallet/src/widgets/dashboard_card_widget.dart';
import 'package:hash_wallet/utils/feature_flag.dart';
import 'package:hash_wallet/utils/show_pop_up.dart';
import 'package:hash_wallet/view_model/dashboard/cake_features_view_model.dart';
import 'package:hash_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:url_launcher/url_launcher.dart';
@@ -122,18 +119,6 @@ class CakeFeaturesPage extends StatelessWidget {
}
void _navigatorToGiftCardsPage(BuildContext context) {
if (dashboardViewModel.type == WalletType.haven) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: S.of(context).gift_cards_unavailable,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
} else {
Navigator.pushNamed(context, Routes.cakePayCardsPage);
}
Navigator.pushNamed(context, Routes.cakePayCardsPage);
}
}

View File

@@ -3,7 +3,6 @@ import 'package:hash_wallet/src/screens/base_page.dart';
import 'package:hash_wallet/src/widgets/address_text_field.dart';
import 'package:hash_wallet/src/widgets/primary_button.dart';
import 'package:hash_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@@ -97,39 +96,37 @@ class _ImportNFTPage extends BasePage {
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
if (nftViewModel.appStore.wallet!.type != WalletType.solana) ...[
SizedBox(height: 48),
Text(
S.current.tokenID,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w800,
color: Theme.of(context).colorScheme.onSurfaceVariant,
height: 1,
),
),
SizedBox(height: 8),
AddressTextField(
controller: tokenIDController,
options: [AddressTextFieldOption.paste],
onPushPasteButton: (context) async {
final clipboard = await Clipboard.getData('text/plain');
final tokenID = clipboard?.text ?? '';
SizedBox(height: 48),
Text(
S.current.tokenID,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w800,
color: Theme.of(context).colorScheme.onSurfaceVariant,
height: 1,
),
),
SizedBox(height: 8),
AddressTextField(
controller: tokenIDController,
options: [AddressTextFieldOption.paste],
onPushPasteButton: (context) async {
final clipboard = await Clipboard.getData('text/plain');
final tokenID = clipboard?.text ?? '';
if (tokenID.isNotEmpty) {
tokenIDController.text = tokenID;
}
},
iconColor: Theme.of(context).colorScheme.primary,
placeholder: S.current.enterTokenID,
textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurface,
),
hintStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
],
if (tokenID.isNotEmpty) {
tokenIDController.text = tokenID;
}
},
iconColor: Theme.of(context).colorScheme.primary,
placeholder: S.current.enterTokenID,
textStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurface,
),
hintStyle: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
Spacer(),
Observer(builder: (context) {
return LoadingPrimaryButton(

View File

@@ -3,10 +3,8 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/routes.dart';
import 'package:hash_wallet/src/screens/dashboard/widgets/nft_tile_widget.dart';
import 'package:hash_wallet/src/screens/dashboard/widgets/solana_nft_tile_widget.dart';
import 'package:hash_wallet/src/widgets/primary_button.dart';
import 'package:hash_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:cw_core/wallet_type.dart';
class NFTListingPage extends StatefulWidget {
final NFTViewModel nftViewModel;
@@ -78,8 +76,6 @@ class NFTListWidget extends StatelessWidget {
Widget build(BuildContext context) {
return Observer(
builder: (context) {
final isSolana = nftViewModel.appStore.wallet!.type == WalletType.solana;
final emptyMessage = Center(
child: Text(
S.current.noNFTYet,
@@ -90,43 +86,23 @@ class NFTListWidget extends StatelessWidget {
),
);
if (isSolana) {
if (nftViewModel.solanaNftAssetModels.isEmpty) return emptyMessage;
if (nftViewModel.nftAssetByWalletModels.isEmpty) return emptyMessage;
return Padding(
padding: EdgeInsets.only(
bottom: 64),
child: ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 16),
separatorBuilder: (context, index) => const SizedBox(height: 8),
itemCount: nftViewModel.solanaNftAssetModels.length,
itemBuilder: (context, index) {
final nftAsset = nftViewModel.solanaNftAssetModels[index];
return SolanaNFTTileWidget(nftAsset: nftAsset);
},
),
);
} else {
if (nftViewModel.nftAssetByWalletModels.isEmpty) return emptyMessage;
return Padding(
padding: EdgeInsets.only(
bottom: 64),
child: ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 16),
separatorBuilder: (context, index) => const SizedBox(height: 8),
itemCount: nftViewModel.nftAssetByWalletModels.length,
itemBuilder: (context, index) {
final nftAsset = nftViewModel.nftAssetByWalletModels[index];
return NFTTileWidget(nftAsset: nftAsset);
},
),
);
}
return Padding(
padding: EdgeInsets.only(
bottom: 64),
child: ListView.separated(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 16),
separatorBuilder: (context, index) => const SizedBox(height: 8),
itemCount: nftViewModel.nftAssetByWalletModels.length,
itemBuilder: (context, index) {
final nftAsset = nftViewModel.nftAssetByWalletModels[index];
return NFTTileWidget(nftAsset: nftAsset);
},
),
);
},
);
}

View File

@@ -27,7 +27,6 @@ class MenuWidgetState extends State<MenuWidget> {
this.moneroIcon = Image.asset('assets/images/crypto/monero.webp'),
this.bitcoinIcon = Image.asset('assets/images/crypto/bitcoin.webp'),
this.litecoinIcon = Image.asset('assets/images/crypto/litecoin.webp'),
this.havenIcon = Image.asset('assets/images/haven_menu.webp'),
this.ethereumIcon = Image.asset('assets/images/crypto/ethereum.webp'),
this.nanoIcon = Image.asset('assets/images/crypto/nano.webp'),
this.bananoIcon = Image.asset('assets/images/crypto/nano.webp'),
@@ -36,13 +35,8 @@ class MenuWidgetState extends State<MenuWidget> {
this.baseIcon = Image.asset('assets/images/crypto/base_icon.webp'),
this.arbitrumIcon = Image.asset('assets/images/crypto/arbitrum.webp'),
this.bscIcon = Image.asset('assets/images/crypto/BNB.webp'),
this.solanaIcon = Image.asset('assets/images/crypto/solana.webp'),
this.tronIcon = Image.asset('assets/images/crypto/tron.webp'),
this.wowneroIcon = Image.asset('assets/images/crypto/wownero.webp'),
this.zanoIcon = Image.asset('assets/images/crypto/zano.webp'),
this.decredIcon = Image.asset('assets/images/crypto/decred.webp'),
this.dogecoinIcon = Image.asset('assets/images/crypto/dogecoin.webp'),
this.zcashIcon = Image.asset('assets/images/crypto/zcash.webp');
this.dogecoinIcon = Image.asset('assets/images/crypto/dogecoin.webp');
final largeScreen = 731;
@@ -58,7 +52,6 @@ class MenuWidgetState extends State<MenuWidget> {
Image moneroIcon;
Image bitcoinIcon;
Image litecoinIcon;
Image havenIcon;
Image ethereumIcon;
Image bitcoinCashIcon;
Image nanoIcon;
@@ -67,13 +60,8 @@ class MenuWidgetState extends State<MenuWidget> {
Image baseIcon;
Image arbitrumIcon;
Image bscIcon;
Image solanaIcon;
Image tronIcon;
Image wowneroIcon;
Image zanoIcon;
Image decredIcon;
Image dogecoinIcon;
Image zcashIcon;
@override
void initState() {
@@ -241,8 +229,6 @@ class MenuWidgetState extends State<MenuWidget> {
return bitcoinIcon;
case WalletType.litecoin:
return litecoinIcon;
case WalletType.haven:
return havenIcon;
case WalletType.ethereum:
return ethereumIcon;
case WalletType.bitcoinCash:
@@ -253,26 +239,16 @@ class MenuWidgetState extends State<MenuWidget> {
return bananoIcon;
case WalletType.polygon:
return polygonIcon;
case WalletType.solana:
return solanaIcon;
case WalletType.base:
return baseIcon;
case WalletType.arbitrum:
return arbitrumIcon;
case WalletType.bsc:
return bscIcon;
case WalletType.tron:
return tronIcon;
case WalletType.wownero:
return wowneroIcon;
case WalletType.zano:
return zanoIcon;
case WalletType.decred:
return decredIcon;
case WalletType.dogecoin:
return dogecoinIcon;
case WalletType.zcash:
return zcashIcon;
default:
throw Exception('No icon for ${type.toString()}');
}

View File

@@ -7,7 +7,6 @@ import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/src/widgets/primary_button.dart';
import 'package:hash_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:hash_wallet/src/screens/base_page.dart';
@@ -36,7 +35,6 @@ class PerformanceDebug extends StatefulWidget {
enum ProfilableWallet {
monero,
wownero,
zano,
}
class _PerformanceDebugState extends State<PerformanceDebug> {
@@ -47,7 +45,6 @@ class _PerformanceDebugState extends State<PerformanceDebug> {
late ProfilableWallet wallet = switch (dashboardViewModel.wallet.type) {
WalletType.monero => ProfilableWallet.monero,
WalletType.wownero => ProfilableWallet.wownero,
WalletType.zano => ProfilableWallet.zano,
_ => throw Exception("Unknown wallet type"),
};
final precalc = 1700298;
@@ -55,7 +52,6 @@ class _PerformanceDebugState extends State<PerformanceDebug> {
late Map<String, List<int>> debugCallLength = switch (wallet) {
ProfilableWallet.monero => monero!.debugCallLength(),
ProfilableWallet.wownero => wownero!.debugCallLength(),
ProfilableWallet.zano => zano!.debugCallLength(),
};
int getOpenWalletTime() {

View File

@@ -281,8 +281,7 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
],
);
}),
if (widget.privacySettingsViewModel.type == WalletType.bitcoin ||
widget.privacySettingsViewModel.type == WalletType.decred)
if (widget.privacySettingsViewModel.type == WalletType.bitcoin)
Builder(builder: (_) {
final val = testnetValue ?? false;
return SettingsSwitcherCell(

View File

@@ -7,13 +7,11 @@ import 'package:hash_wallet/reactions/wallet_utils.dart';
import 'package:hash_wallet/routes.dart';
import 'package:hash_wallet/src/screens/base_page.dart';
import 'package:hash_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:hash_wallet/src/screens/setup_2fa/widgets/popup_cancellable_alert.dart';
import 'package:hash_wallet/src/widgets/cake_image_widget.dart';
import 'package:hash_wallet/src/widgets/primary_button.dart';
import 'package:hash_wallet/src/widgets/scrollable_with_bottom_section.dart';
import 'package:hash_wallet/src/widgets/search_bar_widget.dart';
import 'package:hash_wallet/utils/responsive_layout_util.dart';
import 'package:hash_wallet/utils/show_pop_up.dart';
import 'package:hash_wallet/wallet_types.g.dart';
import 'package:cw_core/currency_for_wallet_type.dart';
import 'package:cw_core/hardware/device_connection_type.dart';
@@ -176,17 +174,6 @@ class WalletTypeFormState extends State<WalletTypeForm> {
Future<void> onTypeSelected() async {
if (selected == null) throw Exception('Wallet Type is not selected yet.');
if (selected == WalletType.haven && widget.isCreate) {
return await showPopUp<void>(
context: context,
builder: (BuildContext context) => PopUpCancellableAlertDialog(
contentText: S.of(context).pause_wallet_creation,
actionButtonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
),
);
}
// If it's a restore flow, trigger the external callback
// If it's not a BIP39 Wallet or if there are no other wallets, route to the newWallet page
// Any other scenario, route to pre-existing seed page

View File

@@ -9,7 +9,6 @@ import 'package:hash_wallet/utils/feature_flag.dart';
import 'package:hash_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mobx/mobx.dart';
@@ -75,9 +74,7 @@ class NodeFormState extends State<NodeForm> {
keyValue: vm.nodeAddressUIKey,
label: S.current.node_address,
initialValue: vm.address,
validator: vm.walletType == WalletType.decred
? NodeAddressValidatorDecredBlankException()
: NodeAddressValidator(),
validator: NodeAddressValidator(),
),
if (vm.hasPathSupport)
ListItemTextField(

View File

@@ -83,8 +83,7 @@ class _AddressListState extends State<AddressList> {
walletAddressListViewModel: widget.addressListViewModel,
trailingButtonTap: () async {
if (widget.addressListViewModel.type == WalletType.monero ||
widget.addressListViewModel.type == WalletType.wownero ||
widget.addressListViewModel.type == WalletType.haven) {
widget.addressListViewModel.type == WalletType.wownero) {
await showPopUp<void>(
context: context,
builder: (_) => getIt.get<MoneroAccountListPage>(),

View File

@@ -10,7 +10,6 @@ import 'package:hash_wallet/view_model/rescan_view_model.dart';
import 'package:hash_wallet/src/widgets/blockchain_height_widget.dart';
import 'package:hash_wallet/src/widgets/primary_button.dart';
import 'package:hash_wallet/generated/i18n.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
class RescanPage extends StatefulWidget {
@@ -28,79 +27,52 @@ class _RescanPageState extends State<RescanPage> {
@override
Widget build(BuildContext context) {
Widget child;
if (widget._rescanViewModel.wallet.type != WalletType.decred) {
child = Padding(
padding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Observer(
builder: (_) => SingleChildScrollView(
controller: ModalScrollController.of(context),
child: BlockchainHeightWidget(
// key: _blockchainHeightWidgetKey,
onHeightOrDateEntered: (value) => widget._rescanViewModel.isButtonEnabled = value,
isSilentPaymentsScan: widget._rescanViewModel.isSilentPaymentsScan,
isMwebScan: widget._rescanViewModel.isMwebScan,
doSingleScan: widget._rescanViewModel.doSingleScan,
hasDatePicker: !widget._rescanViewModel.isMwebScan,
// disable date picker for mweb for now
toggleSingleScan: () =>
widget._rescanViewModel.doSingleScan = !widget._rescanViewModel.doSingleScan,
walletType: widget._rescanViewModel.wallet.type,
heightController: _heightController,
bitcoinMempoolAPIEnabled: widget._rescanViewModel.isBitcoinMempoolAPIEnabled,
),
Widget child = Padding(
padding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Observer(
builder: (_) => SingleChildScrollView(
controller: ModalScrollController.of(context),
child: BlockchainHeightWidget(
// key: _blockchainHeightWidgetKey,
onHeightOrDateEntered: (value) => widget._rescanViewModel.isButtonEnabled = value,
isSilentPaymentsScan: widget._rescanViewModel.isSilentPaymentsScan,
isMwebScan: widget._rescanViewModel.isMwebScan,
doSingleScan: widget._rescanViewModel.doSingleScan,
hasDatePicker: !widget._rescanViewModel.isMwebScan,
// disable date picker for mweb for now
toggleSingleScan: () =>
widget._rescanViewModel.doSingleScan = !widget._rescanViewModel.doSingleScan,
walletType: widget._rescanViewModel.wallet.type,
heightController: _heightController,
bitcoinMempoolAPIEnabled: widget._rescanViewModel.isBitcoinMempoolAPIEnabled,
),
),
Observer(
builder: (_) => LoadingPrimaryButton(
isLoading: widget._rescanViewModel.state == RescanWalletState.rescaning,
text: S.of(context).rescan,
onPressed: () async {
if (widget._rescanViewModel.isSilentPaymentsScan) {
return _toggleSilentPaymentsScanning(context);
}
widget._rescanViewModel.rescanCurrentWallet(
restoreHeight: int.tryParse(_heightController.text) ?? 0);
Navigator.of(context).pop();
},
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
isDisabled: !widget._rescanViewModel.isButtonEnabled,
),
)
],
),
);
} else {
child = Center(
child: Padding(
padding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Spacer(),
Observer(
builder: (_) => LoadingPrimaryButton(
isLoading: widget._rescanViewModel.state == RescanWalletState.rescaning,
text: S.of(context).rescan,
onPressed: () async {
await widget._rescanViewModel.rescanCurrentWallet(restoreHeight: 0);
Navigator.of(context).pop();
},
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
),
)
],
),
),
);
}
Observer(
builder: (_) => LoadingPrimaryButton(
isLoading: widget._rescanViewModel.state == RescanWalletState.rescaning,
text: S.of(context).rescan,
onPressed: () async {
if (widget._rescanViewModel.isSilentPaymentsScan) {
return _toggleSilentPaymentsScanning(context);
}
widget._rescanViewModel.rescanCurrentWallet(
restoreHeight: int.tryParse(_heightController.text) ?? 0);
Navigator.of(context).pop();
},
color: Theme.of(context).colorScheme.primary,
textColor: Theme.of(context).colorScheme.onPrimary,
isDisabled: !widget._rescanViewModel.isButtonEnabled,
),
)
],
),
);
return GestureDetector(
behavior: HitTestBehavior.opaque,
// onTap: () => FocusScope.of(context).unfocus(),

View File

@@ -246,7 +246,7 @@ class WalletRestoreFromKeysFormState extends State<WalletRestoreFromKeysForm> {
if (widget.walletRestoreViewModel.hasBlockchainHeightSelector)
BlockchainHeightWidget(
key: blockchainHeightKey,
hasDatePicker: widget.walletRestoreViewModel.type != WalletType.haven,
hasDatePicker: true,
onHeightChange: (_) => null,
onHeightOrDateEntered: widget.onHeightOrDateEntered,
walletType: widget.walletRestoreViewModel.type,
@@ -299,7 +299,7 @@ class WalletRestoreFromKeysFormState extends State<WalletRestoreFromKeysForm> {
if (widget.walletRestoreViewModel.hasBlockchainHeightSelector)
BlockchainHeightWidget(
key: blockchainHeightKey,
hasDatePicker: widget.walletRestoreViewModel.type != WalletType.haven,
hasDatePicker: true,
onHeightChange: (_) => null,
onHeightOrDateEntered: widget.onHeightOrDateEntered,
walletType: widget.walletRestoreViewModel.type,

View File

@@ -286,7 +286,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
'wallet_restore_from_seed_blockheight_textfield_key',
),
onHeightOrDateEntered: widget.onHeightOrDateEntered,
hasDatePicker: [WalletType.monero, WalletType.wownero, WalletType.zcash].contains(
hasDatePicker: [WalletType.monero, WalletType.wownero].contains(
widget.type,
),
walletType: widget.type,

View File

@@ -601,7 +601,6 @@ class _WalletRestorePageBodyState extends State<_WalletRestorePageBody>
final seedWords = seedPhrase.split(' ');
if (seedWords.length == 14 && walletRestoreViewModel.type == WalletType.wownero) return true;
if (seedWords.length == 26 && walletRestoreViewModel.type == WalletType.zano) return true;
if (seedWords.length == 12 && walletRestoreViewModel.type == WalletType.monero) {
return walletRestoreFromSeedFormKey.currentState?.blockchainHeightKey.currentState
@@ -609,7 +608,7 @@ class _WalletRestorePageBodyState extends State<_WalletRestorePageBody>
true;
}
if ([WalletType.monero, WalletType.wownero, WalletType.haven]
if ([WalletType.monero, WalletType.wownero]
.contains(walletRestoreViewModel.type) &&
seedWords.length == WalletRestoreViewModelBase.moneroSeedMnemonicLength) {
return true;
@@ -617,18 +616,13 @@ class _WalletRestorePageBodyState extends State<_WalletRestorePageBody>
// bip39:
final validBip39SeedLengths = [12, 18, 24];
final nonBip39WalletTypes = [WalletType.wownero, WalletType.haven, WalletType.decred];
final nonBip39WalletTypes = [WalletType.wownero];
// if it's a bip39 wallet and the length is not valid return false
if (!nonBip39WalletTypes.contains(walletRestoreViewModel.type) &&
!(validBip39SeedLengths.contains(seedWords.length))) {
return false;
}
if ((walletRestoreViewModel.type == WalletType.decred) &&
seedWords.length != WalletRestoreViewModelBase.decredSeedMnemonicLength) {
return false;
}
final words =
walletRestoreFromSeedFormKey.currentState!.seedWidgetStateKey.currentState!.words.toSet();
return seedWords.toSet().difference(words).toSet().isEmpty;

View File

@@ -185,23 +185,6 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
paymentRequest,
fixedNetwork: result.walletType,
);
break;
case PaymentFlowType.solanaTokenSelection:
await _showTokenSelectionFlow(
paymentViewModel,
walletSwitcherViewModel,
paymentRequest,
fixedNetwork: WalletType.solana,
);
break;
case PaymentFlowType.tronTokenSelection:
await _showTokenSelectionFlow(
paymentViewModel,
walletSwitcherViewModel,
paymentRequest,
fixedNetwork: WalletType.tron,
);
break;
case PaymentFlowType.currentWalletCompatible:
case PaymentFlowType.error:

View File

@@ -161,7 +161,7 @@ class OtherSettingsPage extends BasePage {
keyValue: "[dev] monero background sync",
label: "[dev] monero background sync",
onTap: () => Navigator.of(context).pushNamed(Routes.devMoneroBackgroundSync)),
if ([WalletType.monero, WalletType.wownero, WalletType.zano]
if ([WalletType.monero, WalletType.wownero]
.contains(_otherSettingsViewModel.walletType))
ListItemRegularRow(
keyValue: "[dev] xmr call profiler",

View File

@@ -1,6 +1,5 @@
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/src/screens/wallet_connect/services/key_service/chain_key_model.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart';
@@ -24,8 +23,6 @@ class KeyServiceImpl implements WalletConnectKeyService {
case WalletType.arbitrum:
case WalletType.bsc:
return evm!.getPrivateKey(wallet);
case WalletType.solana:
return solana!.getPrivateKey(wallet);
default:
return '';
}
@@ -39,8 +36,6 @@ class KeyServiceImpl implements WalletConnectKeyService {
case WalletType.arbitrum:
case WalletType.bsc:
return evm!.getPublicKey(wallet);
case WalletType.solana:
return solana!.getPublicKey(wallet);
default:
return '';
}

View File

@@ -2,7 +2,6 @@ import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:cw_core/wallet_type.dart';
import 'package:eth_sig_util/util/utils.dart';
import 'package:flutter/material.dart';
import 'package:mobx/mobx.dart';
@@ -26,8 +25,6 @@ import 'package:hash_wallet/src/screens/wallet_connect/widgets/wc_session_auth_r
import 'package:hash_wallet/store/app_store.dart';
import 'bottom_sheet_service.dart';
import 'chain_service/solana/solana_chain_id.dart';
import 'chain_service/solana/solana_chain_service.dart';
part 'walletkit_service.g.dart';
@@ -167,17 +164,6 @@ abstract class WalletKitServiceBase with Store {
}
}
if (appStore.wallet!.type == WalletType.solana) {
for (final cId in SolanaChainId.values) {
SolanaChainService(
reference: cId,
appStore: appStore,
wcKeyService: walletKeyService,
bottomSheetService: _bottomSheetHandler,
walletKit: _walletKit,
);
}
}
}
@action

View File

@@ -2,14 +2,12 @@ import 'package:hash_wallet/bitcoin/bitcoin.dart';
import 'package:hash_wallet/src/widgets/standard_switch.dart';
import 'package:hash_wallet/utils/date_picker.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/src/widgets/base_text_form_field.dart';
import 'package:hash_wallet/decred/decred.dart';
class BlockchainHeightWidget extends StatefulWidget {
BlockchainHeightWidget({
@@ -191,14 +189,10 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
bitcoinMempoolAPIEnabled: await widget.bitcoinMempoolAPIEnabled,
);
} else {
if (widget.walletType == WalletType.decred) {
height = decred!.heightByDate(date);
} else if (widget.walletType == WalletType.monero) {
if (widget.walletType == WalletType.monero) {
height = monero!.getHeightByDate(date: date);
} else if (widget.walletType == WalletType.wownero){
height = wownero!.getHeightByDate(date: date);
} else if (widget.walletType == WalletType.zcash) {
height = await zcash!.getHeightByDate(date);
} else {
throw Exception("unknown currency in BlockchainHeightWidget");
}

View File

@@ -129,22 +129,10 @@ class _TokenSelectionContentState extends State<_TokenSelectionContent> {
}
String _getEcosystemTitle() {
if (selectedNetwork == WalletType.solana) {
return 'Solana\n${S.current.address_detected.toLowerCase()}';
}
if (selectedNetwork == WalletType.tron) {
return 'Tron\n${S.current.address_detected.toLowerCase()}';
}
return '${S.current.ethereum_ecosystem}\n${S.current.address_detected.toLowerCase()}';
}
String _getEcosystemDescription() {
if (selectedNetwork == WalletType.solana) {
return 'Select a token to send on Solana network';
}
if (selectedNetwork == WalletType.tron) {
return 'Select a token to send on Tron network';
}
return S.current.evm_ecosystem_description;
}
@@ -339,60 +327,22 @@ class _TokenSelectionContentState extends State<_TokenSelectionContent> {
final compatibleWallets = await widget.paymentViewModel.getWalletsByType(selectedNetwork!);
PaymentFlowResult newResult;
if (selectedNetwork == WalletType.solana) {
newResult = PaymentFlowResult.solanaTokenSelection(
AddressDetectionResult(
address: widget.paymentRequest.address,
detectedWalletType: WalletType.solana,
detectedCurrency: selectedToken!,
isValid: true,
amount: widget.paymentRequest.amount,
note: widget.paymentRequest.note,
scheme: widget.paymentRequest.scheme,
pjUri: widget.paymentRequest.pjUri,
callbackUrl: widget.paymentRequest.callbackUrl,
callbackMessage: widget.paymentRequest.callbackMessage,
),
compatibleWallets: compatibleWallets,
wallet: compatibleWallets.isNotEmpty ? compatibleWallets.first : null,
);
} else if (selectedNetwork == WalletType.tron) {
newResult = PaymentFlowResult.tronTokenSelection(
AddressDetectionResult(
address: widget.paymentRequest.address,
detectedWalletType: WalletType.tron,
detectedCurrency: selectedToken!,
isValid: true,
amount: widget.paymentRequest.amount,
note: widget.paymentRequest.note,
scheme: widget.paymentRequest.scheme,
pjUri: widget.paymentRequest.pjUri,
callbackUrl: widget.paymentRequest.callbackUrl,
callbackMessage: widget.paymentRequest.callbackMessage,
),
compatibleWallets: compatibleWallets,
wallet: compatibleWallets.isNotEmpty ? compatibleWallets.first : null,
);
} else {
newResult = PaymentFlowResult.evmNetworkSelection(
AddressDetectionResult(
address: widget.paymentRequest.address,
detectedWalletType: selectedNetwork!,
detectedCurrency: selectedToken!,
isValid: true,
amount: widget.paymentRequest.amount,
note: widget.paymentRequest.note,
scheme: widget.paymentRequest.scheme,
pjUri: widget.paymentRequest.pjUri,
callbackUrl: widget.paymentRequest.callbackUrl,
callbackMessage: widget.paymentRequest.callbackMessage,
),
compatibleWallets: compatibleWallets,
wallet: compatibleWallets.isNotEmpty ? compatibleWallets.first : null,
);
}
PaymentFlowResult newResult = PaymentFlowResult.evmNetworkSelection(
AddressDetectionResult(
address: widget.paymentRequest.address,
detectedWalletType: selectedNetwork!,
detectedCurrency: selectedToken!,
isValid: true,
amount: widget.paymentRequest.amount,
note: widget.paymentRequest.note,
scheme: widget.paymentRequest.scheme,
pjUri: widget.paymentRequest.pjUri,
callbackUrl: widget.paymentRequest.callbackUrl,
callbackMessage: widget.paymentRequest.callbackMessage,
),
compatibleWallets: compatibleWallets,
wallet: compatibleWallets.isNotEmpty ? compatibleWallets.first : null,
);
widget.paymentViewModel.detectedWalletType = selectedNetwork!;
widget.onNext(newResult);

View File

@@ -4,7 +4,6 @@ import 'dart:io';
import 'package:hash_wallet/bitcoin/bitcoin.dart';
import 'package:hash_wallet/core/utilities.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/bitcoin_cash/bitcoin_cash.dart';
import 'package:hash_wallet/core/secure_storage.dart';
import 'package:hash_wallet/di.dart';
@@ -30,8 +29,6 @@ import 'package:hash_wallet/entities/wallet_list_order_types.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:hash_wallet/exchange/provider/trocador_exchange_provider.dart';
import 'package:hash_wallet/monero/monero.dart';
@@ -149,7 +146,6 @@ abstract class SettingsStoreBase with Store {
TransactionPriority? initialBitcoinTransactionPriority,
TransactionPriority? initialMoneroTransactionPriority,
TransactionPriority? initialWowneroTransactionPriority,
TransactionPriority? initialHavenTransactionPriority,
TransactionPriority? initialLitecoinTransactionPriority,
TransactionPriority? initialEthereumTransactionPriority,
TransactionPriority? initialEVMTransactionPriority,
@@ -157,9 +153,6 @@ abstract class SettingsStoreBase with Store {
TransactionPriority? initialBaseTransactionPriority,
TransactionPriority? initialBscTransactionPriority,
TransactionPriority? initialBitcoinCashTransactionPriority,
TransactionPriority? initialZanoTransactionPriority,
TransactionPriority? initialDecredTransactionPriority,
TransactionPriority? initialZcashTransactionPriority,
Country? initialCakePayCountry})
: nodes = ObservableMap<WalletType, Node>.of(nodes),
powNodes = ObservableMap<WalletType, Node>.of(powNodes),
@@ -228,10 +221,6 @@ abstract class SettingsStoreBase with Store {
priority[WalletType.bitcoin] = initialBitcoinTransactionPriority;
}
if (initialHavenTransactionPriority != null) {
priority[WalletType.haven] = initialHavenTransactionPriority;
}
if (initialLitecoinTransactionPriority != null) {
priority[WalletType.litecoin] = initialLitecoinTransactionPriority;
}
@@ -257,16 +246,6 @@ abstract class SettingsStoreBase with Store {
priority[WalletType.bitcoinCash] = initialBitcoinCashTransactionPriority;
}
if (initialZanoTransactionPriority != null) {
priority[WalletType.zano] = initialZanoTransactionPriority;
}
if (initialDecredTransactionPriority != null) {
priority[WalletType.decred] = initialDecredTransactionPriority;
}
if (initialZcashTransactionPriority != null) {
priority[WalletType.zcash] = initialZcashTransactionPriority;
}
if (initialCakePayCountry != null) {
selectedCakePayCountry = initialCakePayCountry;
}
@@ -310,9 +289,6 @@ abstract class SettingsStoreBase with Store {
case WalletType.litecoin:
key = PreferencesKey.litecoinTransactionPriority;
break;
case WalletType.haven:
key = PreferencesKey.havenTransactionPriority;
break;
case WalletType.ethereum:
key = PreferencesKey.ethereumTransactionPriority;
break;
@@ -328,15 +304,6 @@ abstract class SettingsStoreBase with Store {
case WalletType.bsc:
key = PreferencesKey.bscTransactionPriority;
break;
case WalletType.zano:
key = PreferencesKey.zanoTransactionPriority;
break;
case WalletType.decred:
key = PreferencesKey.decredTransactionPriority;
break;
case WalletType.zcash:
key = PreferencesKey.zcashTransactionPriority;
break;
default:
key = null;
}
@@ -1115,7 +1082,6 @@ abstract class SettingsStoreBase with Store {
bitcoin?.deserializeBitcoinTransactionPriority(
sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority)!);
TransactionPriority? havenTransactionPriority;
TransactionPriority? litecoinTransactionPriority;
TransactionPriority? ethereumTransactionPriority;
TransactionPriority? evmTransactionPriority;
@@ -1124,14 +1090,7 @@ abstract class SettingsStoreBase with Store {
TransactionPriority? bscTransactionPriority;
TransactionPriority? bitcoinCashTransactionPriority;
TransactionPriority? wowneroTransactionPriority;
TransactionPriority? zanoTransactionPriority;
TransactionPriority? decredTransactionPriority;
TransactionPriority? zcashTransactionPriority;
if (sharedPreferences.getInt(PreferencesKey.havenTransactionPriority) != null) {
havenTransactionPriority = monero?.deserializeMoneroTransactionPriority(
raw: sharedPreferences.getInt(PreferencesKey.havenTransactionPriority)!);
}
if (sharedPreferences.getInt(PreferencesKey.litecoinTransactionPriority) != null) {
litecoinTransactionPriority = bitcoin?.deserializeLitecoinTransactionPriority(
sharedPreferences.getInt(PreferencesKey.litecoinTransactionPriority)!);
@@ -1162,33 +1121,17 @@ abstract class SettingsStoreBase with Store {
wowneroTransactionPriority = wownero?.deserializeWowneroTransactionPriority(
raw: sharedPreferences.getInt(PreferencesKey.wowneroTransactionPriority)!);
}
if (sharedPreferences.getInt(PreferencesKey.zanoTransactionPriority) != null) {
zanoTransactionPriority = monero?.deserializeMoneroTransactionPriority(
raw: sharedPreferences.getInt(PreferencesKey.zanoTransactionPriority)!);
}
if (sharedPreferences.getInt(PreferencesKey.decredTransactionPriority) != null) {
decredTransactionPriority = decred?.deserializeDecredTransactionPriority(
sharedPreferences.getInt(PreferencesKey.decredTransactionPriority)!);
}
if (sharedPreferences.getInt(PreferencesKey.zcashTransactionPriority) != null) {
zcashTransactionPriority = zcash?.deserializeZcashTransactionPriority(
raw: sharedPreferences.getInt(PreferencesKey.zcashTransactionPriority)!);
}
moneroTransactionPriority ??= monero?.getDefaultTransactionPriority();
bitcoinTransactionPriority ??= bitcoin?.getMediumTransactionPriority();
havenTransactionPriority ??= monero?.getDefaultTransactionPriority();
litecoinTransactionPriority ??= bitcoin?.getLitecoinTransactionPriorityMedium();
ethereumTransactionPriority ??= evm?.getDefaultTransactionPriority();
evmTransactionPriority ??= evm?.getDefaultTransactionPriority();
bitcoinCashTransactionPriority ??= bitcoinCash?.getDefaultTransactionPriority();
wowneroTransactionPriority ??= wownero?.getDefaultTransactionPriority();
decredTransactionPriority ??= decred?.getDecredTransactionPriorityMedium();
polygonTransactionPriority ??= evm?.getDefaultTransactionPriority();
baseTransactionPriority ??= evm?.getDefaultTransactionPriority();
bscTransactionPriority ??= evm?.getDefaultTransactionPriority();
zanoTransactionPriority ??= zano?.getDefaultTransactionPriority();
zcashTransactionPriority ??= zcash?.getDefaultTransactionPriority();
final currentBalanceDisplayMode = BalanceDisplayMode.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey)!);
@@ -1299,12 +1242,7 @@ abstract class SettingsStoreBase with Store {
final bscNodeId = sharedPreferences.getInt(PreferencesKey.currentBscNodeIdKey);
final nanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
final nanoPowNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoPowNodeIdKey);
final solanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
final tronNodeId = sharedPreferences.getInt(PreferencesKey.currentTronNodeIdKey);
final wowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
final zanoNodeId = sharedPreferences.getInt(PreferencesKey.currentZanoNodeIdKey);
final zcashNodeId = sharedPreferences.getInt(PreferencesKey.currentZcashNodeIdKey);
final decredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
final dogecoinNodeId = sharedPreferences.getInt(PreferencesKey.currentDogecoinNodeIdKey);
/// get the selected node, if null, then use the default
@@ -1328,20 +1266,10 @@ abstract class SettingsStoreBase with Store {
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == cakeWalletBitcoinCashDefaultNodeUri);
final nanoNode = nodeSource.get(nanoNodeId) ??
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == nanoDefaultNodeUri);
final decredNode = nodeSource.get(decredNodeId) ??
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == decredDefaultUri);
final nanoPowNode = powNodeSource.get(nanoPowNodeId) ??
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == nanoDefaultPowNodeUri);
final solanaNode = nodeSource.get(solanaNodeId) ??
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == solanaDefaultNodeUri);
final tronNode = nodeSource.get(tronNodeId) ??
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == tronDefaultNodeUri);
final wowneroNode = nodeSource.get(wowneroNodeId) ??
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == wowneroDefaultNodeUri);
final zanoNode = nodeSource.get(zanoNodeId) ??
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == zanoDefaultNodeUri);
final zcashNode = nodeSource.get(zcashNodeId) ??
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == zcashDefaultNodeUri);
final dogecoinNode = nodeSource.get(dogecoinNodeId) ??
nodeSource.values.firstWhereOrNull((e) => e.uriRaw == dogecoinDefaultNodeUri);
@@ -1424,30 +1352,10 @@ abstract class SettingsStoreBase with Store {
powNodes[WalletType.nano] = nanoPowNode;
}
if (solanaNode != null) {
nodes[WalletType.solana] = solanaNode;
}
if (tronNode != null) {
nodes[WalletType.tron] = tronNode;
}
if (wowneroNode != null) {
nodes[WalletType.wownero] = wowneroNode;
}
if (zanoNode != null) {
nodes[WalletType.zano] = zanoNode;
}
if (zcashNode != null) {
nodes[WalletType.zcash] = zcashNode;
}
if (decredNode != null) {
nodes[WalletType.decred] = decredNode;
}
if (dogecoinNode != null) {
nodes[WalletType.dogecoin] = dogecoinNode;
}
@@ -1642,13 +1550,9 @@ abstract class SettingsStoreBase with Store {
initialBackgroundImage: backgroundImage,
initialMoneroTransactionPriority: moneroTransactionPriority,
initialWowneroTransactionPriority: wowneroTransactionPriority,
initialZanoTransactionPriority: zanoTransactionPriority,
initialBitcoinTransactionPriority: bitcoinTransactionPriority,
initialHavenTransactionPriority: havenTransactionPriority,
initialLitecoinTransactionPriority: litecoinTransactionPriority,
initialBitcoinCashTransactionPriority: bitcoinCashTransactionPriority,
initialDecredTransactionPriority: decredTransactionPriority,
initialZcashTransactionPriority: zcashTransactionPriority,
initialShouldRequireTOTP2FAForAccessingWallet: shouldRequireTOTP2FAForAccessingWallet,
initialShouldRequireTOTP2FAForSendsToContact: shouldRequireTOTP2FAForSendsToContact,
initialShouldRequireTOTP2FAForSendsToNonContact: shouldRequireTOTP2FAForSendsToNonContact,
@@ -1700,11 +1604,6 @@ abstract class SettingsStoreBase with Store {
sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority)!);
}
if (monero != null &&
sharedPreferences.getInt(PreferencesKey.havenTransactionPriority) != null) {
priority[WalletType.haven] = monero!.deserializeMoneroTransactionPriority(
raw: sharedPreferences.getInt(PreferencesKey.havenTransactionPriority)!);
}
if (bitcoin != null &&
sharedPreferences.getInt(PreferencesKey.litecoinTransactionPriority) != null) {
priority[WalletType.litecoin] = bitcoin!.deserializeLitecoinTransactionPriority(
@@ -1733,20 +1632,6 @@ abstract class SettingsStoreBase with Store {
priority[WalletType.bitcoinCash] = bitcoinCash!.deserializeBitcoinCashTransactionPriority(
sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority)!);
}
if (zano != null && sharedPreferences.getInt(PreferencesKey.zanoTransactionPriority) != null) {
priority[WalletType.zano] = zano!.deserializeMoneroTransactionPriority(
raw: sharedPreferences.getInt(PreferencesKey.zanoTransactionPriority)!);
}
if (decred != null &&
sharedPreferences.getInt(PreferencesKey.decredTransactionPriority) != null) {
priority[WalletType.decred] = decred!.deserializeDecredTransactionPriority(
sharedPreferences.getInt(PreferencesKey.decredTransactionPriority)!);
}
if (zcash != null &&
sharedPreferences.getInt(PreferencesKey.zcashTransactionPriority) != null) {
priority[WalletType.zcash] = zcash!.deserializeZcashTransactionPriority(
raw: sharedPreferences.getInt(PreferencesKey.zcashTransactionPriority)!);
}
final generateSubaddresses =
sharedPreferences.getInt(PreferencesKey.autoGenerateSubaddressStatusKey);
@@ -1867,24 +1752,17 @@ abstract class SettingsStoreBase with Store {
sharedPreferences.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
final bitcoinCashElectrumServerId =
sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
final havenNodeId = sharedPreferences.getInt(PreferencesKey.currentHavenNodeIdKey);
final ethereumNodeId = sharedPreferences.getInt(PreferencesKey.currentEthereumNodeIdKey);
final polygonNodeId = sharedPreferences.getInt(PreferencesKey.currentPolygonNodeIdKey);
final baseNodeId = sharedPreferences.getInt(PreferencesKey.currentBaseNodeIdKey);
final arbitrumNodeId = sharedPreferences.getInt(PreferencesKey.currentArbitrumNodeIdKey);
final bscNodeId = sharedPreferences.getInt(PreferencesKey.currentBscNodeIdKey);
final nanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
final solanaNodeId = sharedPreferences.getInt(PreferencesKey.currentSolanaNodeIdKey);
final tronNodeId = sharedPreferences.getInt(PreferencesKey.currentTronNodeIdKey);
final wowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
final zanoNodeId = sharedPreferences.getInt(PreferencesKey.currentZanoNodeIdKey);
final zcashNodeId = sharedPreferences.getInt(PreferencesKey.currentZcashNodeIdKey);
final decredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
final dogecoinNodeId = sharedPreferences.getInt(PreferencesKey.currentDogecoinNodeIdKey);
final moneroNode = nodeSource.get(nodeId);
final bitcoinElectrumServer = nodeSource.get(bitcoinElectrumServerId);
final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId);
final havenNode = nodeSource.get(havenNodeId);
final ethereumNode = nodeSource.get(ethereumNodeId);
final polygonNode = nodeSource.get(polygonNodeId);
final baseNode = nodeSource.get(baseNodeId);
@@ -1892,12 +1770,7 @@ abstract class SettingsStoreBase with Store {
final bscNode = nodeSource.get(bscNodeId);
final bitcoinCashNode = nodeSource.get(bitcoinCashElectrumServerId);
final nanoNode = nodeSource.get(nanoNodeId);
final solanaNode = nodeSource.get(solanaNodeId);
final tronNode = nodeSource.get(tronNodeId);
final wowneroNode = nodeSource.get(wowneroNodeId);
final zanoNode = nodeSource.get(zanoNodeId);
final zcashNode = nodeSource.get(zcashNodeId);
final decredNode = nodeSource.get(decredNodeId);
final dogecoinNode = nodeSource.get(dogecoinNodeId);
if (moneroNode != null) {
@@ -1912,10 +1785,6 @@ abstract class SettingsStoreBase with Store {
nodes[WalletType.litecoin] = litecoinElectrumServer;
}
if (havenNode != null) {
nodes[WalletType.haven] = havenNode;
}
if (ethereumNode != null) {
nodes[WalletType.ethereum] = ethereumNode;
}
@@ -1944,30 +1813,10 @@ abstract class SettingsStoreBase with Store {
nodes[WalletType.nano] = nanoNode;
}
if (solanaNode != null) {
nodes[WalletType.solana] = solanaNode;
}
if (tronNode != null) {
nodes[WalletType.tron] = tronNode;
}
if (wowneroNode != null) {
nodes[WalletType.wownero] = wowneroNode;
}
if (zanoNode != null) {
nodes[WalletType.zano] = zanoNode;
}
if (zcashNode != null) {
nodes[WalletType.zcash] = zcashNode;
}
if (decredNode != null) {
nodes[WalletType.decred] = decredNode;
}
if (dogecoinNode != null) {
nodes[WalletType.dogecoin] = dogecoinNode;
}
@@ -2083,9 +1932,6 @@ abstract class SettingsStoreBase with Store {
case WalletType.monero:
await _sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, node.key as int);
break;
case WalletType.haven:
await _sharedPreferences.setInt(PreferencesKey.currentHavenNodeIdKey, node.key as int);
break;
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.base:
@@ -2103,27 +1949,12 @@ abstract class SettingsStoreBase with Store {
case WalletType.nano:
await _sharedPreferences.setInt(PreferencesKey.currentNanoNodeIdKey, node.key as int);
break;
case WalletType.solana:
await _sharedPreferences.setInt(PreferencesKey.currentSolanaNodeIdKey, node.key as int);
break;
case WalletType.tron:
await _sharedPreferences.setInt(PreferencesKey.currentTronNodeIdKey, node.key as int);
break;
case WalletType.wownero:
await _sharedPreferences.setInt(PreferencesKey.currentWowneroNodeIdKey, node.key as int);
break;
case WalletType.decred:
await _sharedPreferences.setInt(PreferencesKey.currentDecredNodeIdKey, node.key as int);
break;
case WalletType.zano:
await _sharedPreferences.setInt(PreferencesKey.currentZanoNodeIdKey, node.key as int);
break;
case WalletType.dogecoin:
await _sharedPreferences.setInt(PreferencesKey.currentDogecoinNodeIdKey, node.key as int);
break;
case WalletType.zcash:
await _sharedPreferences.setInt(PreferencesKey.currentZcashNodeIdKey, node.key as int);
break;
case WalletType.none:
throw UnimplementedError();
case WalletType.banano:

View File

@@ -1,156 +0,0 @@
part of 'tron.dart';
class CWTron extends Tron {
@override
List<String> getTronWordList(String language) => EVMChainMnemonics.englishWordlist;
@override
WalletService createTronWalletService(bool isDirect) =>
TronWalletService(client: TronClient(), isDirect: isDirect);
@override
WalletCredentials createTronNewWalletCredentials({
required String name,
WalletInfo? walletInfo,
String? password,
String? mnemonic,
String? passphrase,
}) =>
TronNewWalletCredentials(
name: name,
walletInfo: walletInfo,
password: password,
mnemonic: mnemonic,
passphrase: passphrase,
);
@override
WalletCredentials createTronRestoreWalletFromSeedCredentials({
required String name,
required String mnemonic,
required String password,
String? passphrase,
}) =>
TronRestoreWalletFromSeedCredentials(
name: name,
password: password,
mnemonic: mnemonic,
passphrase: passphrase,
);
@override
WalletCredentials createTronRestoreWalletFromPrivateKey({
required String name,
required String privateKey,
required String password,
}) =>
TronRestoreWalletFromPrivateKey(name: name, password: password, privateKey: privateKey);
@override
String getAddress(WalletBase wallet) => (wallet as TronWallet).walletAddresses.address;
Object createTronTransactionCredentials(
List<Output> outputs, {
required CryptoCurrency currency,
}) =>
TronTransactionCredentials(
outputs
.map(
(out) => OutputInfo(
fiatAmount: out.fiatAmount,
cryptoAmount: out.cryptoAmount,
address: out.address,
note: out.note,
sendAll: out.sendAll,
extractedAddress: out.extractedAddress,
isParsedAddress: out.isParsedAddress,
formattedCryptoAmount: out.formattedCryptoAmount,
),
)
.toList(),
currency: currency,
);
@override
List<TronToken> getTronTokenCurrencies(WalletBase wallet) =>
(wallet as TronWallet).tronTokenCurrencies;
@override
Future<void> addTronToken(WalletBase wallet, CryptoCurrency token, String contractAddress) async {
final tronToken = TronToken(
name: token.name,
symbol: token.title,
contractAddress: contractAddress,
decimal: token.decimals,
enabled: token.enabled,
iconPath: token.iconPath,
isPotentialScam: token.isPotentialScam,
);
await (wallet as TronWallet).addTronToken(tronToken);
}
@override
Future<void> deleteTronToken(WalletBase wallet, CryptoCurrency token) async =>
await (wallet as TronWallet).deleteTronToken(token as TronToken);
@override
Future<TronToken?> getTronToken(WalletBase wallet, String contractAddress) async =>
(wallet as TronWallet).getTronToken(contractAddress);
@override
double getTransactionAmountRaw(TransactionInfo transactionInfo) {
final amount = (transactionInfo as TronTransactionInfo).rawTronAmount();
return double.parse(amount);
}
@override
CryptoCurrency assetOfTransaction(WalletBase wallet, TransactionInfo transaction) {
transaction as TronTransactionInfo;
if (transaction.tokenSymbol == CryptoCurrency.trx.title) {
return CryptoCurrency.trx;
}
wallet as TronWallet;
return wallet.tronTokenCurrencies.firstWhere(
(element) => transaction.tokenSymbol.toLowerCase() == element.symbol.toLowerCase());
}
@override
String getTokenAddress(CryptoCurrency asset) => (asset as TronToken).contractAddress;
@override
String getTronBase58Address(String hexAddress, WalletBase wallet) =>
(wallet as TronWallet).getTronBase58AddressFromHex(hexAddress);
@override
String? getTronNativeEstimatedFee(WalletBase wallet) =>
(wallet as TronWallet).nativeTxEstimatedFee;
@override
String? getTronTRC20EstimatedFee(WalletBase wallet) => (wallet as TronWallet).trc20EstimatedFee;
@override
void updateTronGridUsageState(WalletBase wallet, bool isEnabled) {
(wallet as TronWallet).updateScanProviderUsageState(isEnabled);
}
@override
List<TronToken> getDefaultTronTokens() => DefaultTronTokens().initialTronTokens;
@override
List<String> getDefaultTokenContractAddresses() {
return DefaultTronTokens().initialTronTokens.map((e) => e.contractAddress).toList();
}
@override
List<String> getDefaultTokenSymbols() {
return DefaultTronTokens().initialTronTokens.map((e) => e.symbol.toUpperCase()).toList();
}
@override
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress) {
final tronWallet = wallet as TronWallet;
return tronWallet.tronTokenCurrencies
.any((element) => element.contractAddress == contractAddress);
}
}

View File

@@ -157,7 +157,6 @@ class AddressFormatter {
switch (walletType) {
case WalletType.monero:
case WalletType.wownero:
case WalletType.zano:
return 6;
default:
return 4;

View File

@@ -12,12 +12,6 @@ String getQrImage(WalletType type) {
return 'assets/images/arbitrum_chain_QR.svg';
case WalletType.bsc:
return 'assets/images/bnb_chain_QR.svg';
case WalletType.solana:
return 'assets/images/sol_chain_qr.svg';
case WalletType.tron:
return 'assets/images/trx_chain_qr.svg';
case WalletType.zano:
return 'assets/images/zano_chain_qr.svg';
case WalletType.monero:
return 'assets/images/xmr_chain_qr.svg';
case WalletType.wownero:
@@ -30,14 +24,9 @@ String getQrImage(WalletType type) {
return 'assets/images/bch_chain_qr.svg';
case WalletType.nano:
return 'assets/images/xno_chain_qr.svg';
case WalletType.decred:
return 'assets/images/dcr_chain_qr.svg';
case WalletType.dogecoin:
return 'assets/images/doge_chain_qr.svg';
case WalletType.zcash:
return 'assets/images/zec_icon_qr.svg';
case WalletType.banano:
case WalletType.haven:
case WalletType.none:
return 'assets/images/qr-cake.png';
}
@@ -55,12 +44,6 @@ String getChainMonoImage(WalletType type) {
return 'assets/images/arbitrum_chain_mono.svg';
case WalletType.bsc:
return 'assets/images/bnb_chain_mono.svg';
case WalletType.solana:
return 'assets/images/sol_chain_mono.svg';
case WalletType.tron:
return 'assets/images/trx_chain_mono.svg';
case WalletType.zano:
return 'assets/images/zano_chain_mono.svg';
default:
return 'assets/images/eth_chain_mono.svg';
}

View File

@@ -1,7 +1,5 @@
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:cw_core/cake_hive.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/currency_for_wallet_type.dart';
@@ -39,42 +37,11 @@ class TokenUtilities {
}
static Future<List<SPLToken>> loadAllUniqueSolTokens() async {
final allWi = await WalletInfo.getAll();
final solWallets = allWi.where(
(w) => w.type == WalletType.solana,
);
final tokens = <SPLToken>[];
for (final wallet in solWallets) {
final box = await _openSolTokensBoxFor(wallet);
tokens.addAll(box.values.where((t) => t.enabled));
}
final seen = <String>{};
final unique = <SPLToken>[];
for (final token in tokens) {
final key = token.mintAddress.toLowerCase();
if (seen.add(key)) unique.add(token);
}
return unique;
return <SPLToken>[];
}
static Future<List<TronToken>> loadAllUniqueTronTokens() async {
final allWi = await WalletInfo.getAll();
final tronWallets = allWi.where(
(w) => w.type == WalletType.tron,
);
final seen = <String>{};
final unique = <TronToken>[];
for (final wallet in tronWallets) {
final box = await _openTronTokensBoxFor(wallet);
for (final t in box.values.where((t) => t.enabled)) {
final key = t.contractAddress.toLowerCase();
if (seen.add(key)) unique.add(t);
}
}
return unique;
return <TronToken>[];
}
static List<Erc20Token> loadDefaultEvmTokensForSwap() {
@@ -93,11 +60,9 @@ class TokenUtilities {
return tokens;
}
static List<SPLToken> loadDefaultSolTokensForSwap() =>
solana != null ? solana!.getDefaultSPLTokens() : [];
static List<SPLToken> loadDefaultSolTokensForSwap() => <SPLToken>[];
static List<TronToken> loadDefaultTronTokensForSwap() =>
tron != null ? tron!.getDefaultTronTokens() : [];
static List<TronToken> loadDefaultTronTokensForSwap() => <TronToken>[];
static Future<List<Erc20Token>> loadEvmTokensForSwap() async {
final defaultTokens = loadDefaultEvmTokensForSwap();
@@ -146,8 +111,6 @@ class TokenUtilities {
/// Finds a token by address across wallets depending on [walletType]
/// - EVM chains: match by contractAddress
/// - Solana: match by mintAddress
/// - Tron: match by contractAddress
static Future<CryptoCurrency?> findTokenByAddress({
required WalletType walletType,
required String address,
@@ -165,18 +128,6 @@ class TokenUtilities {
if (t.contractAddress.toLowerCase() == lower) return t;
}
return null;
case WalletType.solana:
final solTokens = await loadAllUniqueSolTokens();
for (final t in solTokens) {
if (t.mintAddress.toLowerCase() == lower) return t;
}
return null;
case WalletType.tron:
final tronTokens = await loadAllUniqueTronTokens();
for (final t in tronTokens) {
if (t.contractAddress.toLowerCase() == lower) return t;
}
return null;
default:
return null;
}
@@ -203,22 +154,6 @@ class TokenUtilities {
};
}
static Future<Box<SPLToken>> _openSolTokensBoxFor(WalletInfo wallet) async {
final boxName = '${wallet.name.replaceAll(' ', '_')}_${SPLToken.boxName}';
if (CakeHive.isBoxOpen(boxName)) {
return CakeHive.box<SPLToken>(boxName);
}
return CakeHive.openBox<SPLToken>(boxName);
}
static Future<Box<TronToken>> _openTronTokensBoxFor(WalletInfo walletInfo) async {
final boxName = '${walletInfo.name.replaceAll(' ', '_')}_${TronToken.boxName}';
if (CakeHive.isBoxOpen(boxName)) {
return CakeHive.box<TronToken>(boxName);
}
return CakeHive.openBox<TronToken>(boxName);
}
static Erc20Token? findErc20Token(CryptoCurrency currency, WalletBase wallet) {
if (currency is Erc20Token) return currency;
@@ -341,54 +276,6 @@ class TokenUtilities {
}
}
// Handle Solana network
else if (network == WalletType.solana) {
final userSolTokens = await loadAllUniqueSolTokens();
for (final token in userSolTokens) {
final mintAddress = token.mintAddress.toLowerCase();
if (addedAddresses.add(mintAddress)) {
allTokens.add(token);
}
}
for (final currency in CryptoCurrency.all) {
if (currency.tag?.toLowerCase() == 'sol') {
if (currency is SPLToken) {
final mintAddress = currency.mintAddress.toLowerCase();
if (addedAddresses.add(mintAddress)) {
allTokens.add(currency);
}
} else if (!allTokens.any((t) => _matchesCurrency(t, currency))) {
allTokens.add(currency);
}
}
}
}
// Handle Tron network
else if (network == WalletType.tron) {
final userTronTokens = await loadAllUniqueTronTokens();
for (final token in userTronTokens) {
final contractAddress = token.contractAddress.toLowerCase();
if (addedAddresses.add(contractAddress)) {
allTokens.add(token);
}
}
for (final currency in CryptoCurrency.all) {
if (currency.tag?.toLowerCase() == 'trx') {
if (currency is TronToken) {
final contractAddress = currency.contractAddress.toLowerCase();
if (addedAddresses.add(contractAddress)) {
allTokens.add(currency);
}
} else if (!allTokens.any((t) => _matchesCurrency(t, currency))) {
allTokens.add(currency);
}
}
}
}
return allTokens;
}
@@ -411,14 +298,6 @@ class TokenUtilities {
}).toList();
}
if (walletType == WalletType.solana) {
return await loadAllUniqueSolTokens();
}
if (walletType == WalletType.tron) {
return await loadAllUniqueTronTokens();
}
return [];
}
}

View File

@@ -56,9 +56,6 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.tron:
case WalletType.zcash:
return true;
case WalletType.bitcoin:
@@ -72,9 +69,6 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
case WalletType.monero:
case WalletType.wownero:
case WalletType.none:
case WalletType.haven:
case WalletType.zano:
case WalletType.decred:
return false;
}
}
@@ -100,13 +94,9 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
WalletType.base,
WalletType.arbitrum,
WalletType.bsc,
WalletType.tron,
WalletType.solana,
WalletType.monero,
WalletType.wownero,
WalletType.zano,
WalletType.dogecoin,
WalletType.zcash,
].contains(type);
@computed

View File

@@ -118,8 +118,6 @@ abstract class CakePayBuyCardViewModelBase with Store {
];
case WalletType.monero:
return [CakePayPaymentMethod.XMR];
case WalletType.zcash:
return [CakePayPaymentMethod.ZEC];
default:
return const [];
}
@@ -148,10 +146,9 @@ abstract class CakePayBuyCardViewModelBase with Store {
WalletType.bitcoin,
WalletType.monero,
WalletType.litecoin,
WalletType.zcash,
].contains(walletType)) {
sendViewModel.state =
FailureState('Unsupported wallet type, please use Bitcoin, Monero, Litecoin or Zcash.');
FailureState('Unsupported wallet type, please use Bitcoin, Monero, or Litecoin.');
}
try {
order = await _cakePayService.createOrder(

View File

@@ -37,7 +37,7 @@ abstract class ContactListViewModelBase with Store {
for (final info in walletInfos) {
final addressInfos = await info.getAddressInfos();
final addresses = await info.getAddresses();
if ([WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type) &&
if ([WalletType.monero, WalletType.wownero].contains(info.type) &&
addressInfos.isNotEmpty) {
for (var key in addressInfos.keys) {
final value = addressInfos[key];
@@ -55,7 +55,7 @@ abstract class ContactListViewModelBase with Store {
}
}
} else if (addresses.isNotEmpty == true && addresses.length > 1) {
if ([WalletType.monero, WalletType.wownero, WalletType.haven, WalletType.decred]
if ([WalletType.monero, WalletType.wownero]
.contains(info.type)) {
final address = info.address;
final name = _createName(info.name, "", key: 0);
@@ -89,7 +89,7 @@ abstract class ContactListViewModelBase with Store {
walletContacts.add(WalletContact(
info.address,
_createName(info.name, "",
key: [WalletType.monero, WalletType.wownero, WalletType.haven].contains(info.type)
key: [WalletType.monero, WalletType.wownero].contains(info.type)
? 0
: null),
getCryptoCurrencyForWalletListItem(

View File

@@ -7,9 +7,6 @@ import 'package:hash_wallet/entities/sort_balance_types.dart';
import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:cw_core/crypto_amount_format.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_core/wallet_base.dart';
@@ -122,9 +119,7 @@ abstract class BalanceViewModelBase with Store {
bool get isFiatDisabled => settingsStore.fiatApiMode == FiatApiMode.disabled;
@computed
bool get isHomeScreenSettingsEnabled =>
isEVMCompatibleChain(wallet.type) ||
[WalletType.solana, WalletType.tron, WalletType.zano].contains(wallet.type);
bool get isHomeScreenSettingsEnabled => isEVMCompatibleChain(wallet.type);
@computed
bool get isEVMCompatible => isEVMCompatibleChain(wallet.type);
@@ -151,12 +146,7 @@ abstract class BalanceViewModelBase with Store {
final typeFormatted = walletTypeToString(wallet.type);
switch (wallet.type) {
case WalletType.haven:
return '$typeFormatted Assets';
default:
return typeFormatted;
}
return typeFormatted;
}
@computed
@@ -184,14 +174,11 @@ abstract class BalanceViewModelBase with Store {
@computed
String get additionalBalanceLabel {
switch (wallet.type) {
case WalletType.haven:
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.tron:
return S.current.xmr_full_balance;
case WalletType.nano:
case WalletType.banano:
@@ -346,9 +333,6 @@ abstract class BalanceViewModelBase with Store {
bool _hasAdditionalBalanceForWalletType(WalletType type) => [
WalletType.monero,
WalletType.wownero,
WalletType.zano,
WalletType.decred,
WalletType.zcash
].contains(type);
String _getFormattedCryptoAmount(CryptoCurrency cryptoCurrency, BigInt? amount) {
@@ -383,7 +367,7 @@ abstract class BalanceViewModelBase with Store {
if (a.asset == wallet.currency) return -1;
}
final isTokenWallet = isEVMCompatibleChain(wallet.type) || wallet.type == WalletType.solana;
final isTokenWallet = isEVMCompatibleChain(wallet.type);
if (isTokenWallet) {
final aIsToken = a.asset is Erc20Token || a.asset is SPLToken;
@@ -434,22 +418,10 @@ abstract class BalanceViewModelBase with Store {
}
String? getTokenAddressBasedOnWallet(CryptoCurrency asset) {
if (wallet.type == WalletType.tron) {
return tron!.getTokenAddress(asset);
}
if (wallet.type == WalletType.solana) {
return solana!.getTokenAddress(asset);
}
if (isEVMCompatibleChain(wallet.type) && asset is Erc20Token) {
return evm!.getTokenAddress(asset);
}
if (wallet.type == WalletType.zano) {
return zano!.getZanoAssetAddress(asset);
}
return null;
}
@@ -532,13 +504,6 @@ abstract class BalanceViewModelBase with Store {
}
String _formatterAsset(CryptoCurrency asset) {
final assetString = asset.toString();
if (wallet.type == WalletType.haven &&
asset != CryptoCurrency.xhv &&
assetString[0].toUpperCase() == 'X') {
return assetString.replaceFirst('X', 'x');
}
return appStore.amountParsingProxy.getCryptoSymbol(asset);
}
}

View File

@@ -23,7 +23,6 @@ import 'package:hash_wallet/src/widgets/alert_with_one_action.dart';
import 'package:hash_wallet/store/dashboard/order_filter_store.dart';
import 'package:hash_wallet/utils/device_info.dart';
import 'package:hash_wallet/utils/show_pop_up.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:hash_wallet/utils/tor.dart';
@@ -208,8 +207,7 @@ abstract class DashboardViewModelBase with Store {
cardDesigns = ObservableList<CardDesign>(),
cardOrder = ObservableMap<int, int>(),
wallet = appStore.wallet! {
showDecredInfoCard = wallet.type == WalletType.decred &&
(sharedPreferences.getBool(PreferencesKey.showDecredInfoCard) ?? true);
showDecredInfoCard = false;
name = wallet.name;
type = wallet.type;
@@ -306,8 +304,7 @@ abstract class DashboardViewModelBase with Store {
_onWalletChange(wallet);
_checkMweb();
loadCardDesigns();
showDecredInfoCard = wallet?.type == WalletType.decred &&
sharedPreferences.getBool(PreferencesKey.showDecredInfoCard) != false;
showDecredInfoCard = false;
tradeMonitor.stopTradeMonitoring();
tradeMonitor.monitorActiveTrades(wallet!.id);
@@ -320,14 +317,12 @@ abstract class DashboardViewModelBase with Store {
return 0;
}
int confirmations = 1;
if (![WalletType.solana, WalletType.tron].contains(wallet.type)) {
try {
confirmations =
appStore.wallet!.transactionHistory.transactions.values.first.confirmations +
appStore.wallet!.transactionHistory.transactions.values.last.confirmations +
1;
} catch (_) {}
}
try {
confirmations =
appStore.wallet!.transactionHistory.transactions.values.first.confirmations +
appStore.wallet!.transactionHistory.transactions.values.last.confirmations +
1;
} catch (_) {}
return length * confirmations;
}, _transactionDisposerCallback, delay: 300);
@@ -376,9 +371,6 @@ abstract class DashboardViewModelBase with Store {
if ([
WalletType.monero,
WalletType.wownero,
WalletType.decred,
WalletType.zcash,
WalletType.zano
].contains(wallet.type)) {
return true;
}
@@ -782,11 +774,7 @@ abstract class DashboardViewModelBase with Store {
}
@computed
bool get showZcashMissingFundsCard {
if (wallet.type != WalletType.zcash) return false;
if (!settingsStore.showZcashMissingFundsCard) return false;
return zcash!.showMissingFundsCard(wallet);
}
bool get showZcashMissingFundsCard => false;
@computed
bool get hasSilentPayments =>
@@ -1064,11 +1052,6 @@ abstract class DashboardViewModelBase with Store {
bitcoin!.setMwebEnabled(wallet, false);
}
@action
Future<void> rescanInternalChangeZcash() async {
await zcash!.rescanInternalChange(wallet);
}
@action
void dismissZcash() {
settingsStore.showZcashMissingFundsCard = false;
@@ -1171,17 +1154,11 @@ abstract class DashboardViewModelBase with Store {
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.nano:
case WalletType.banano:
case WalletType.tron:
case WalletType.wownero:
case WalletType.decred:
case WalletType.dogecoin:
return true;
case WalletType.zano:
case WalletType.haven:
case WalletType.zcash:
case WalletType.none:
return false;
}
@@ -1288,14 +1265,12 @@ abstract class DashboardViewModelBase with Store {
return 0;
}
int confirmations = 1;
if (![WalletType.solana, WalletType.tron].contains(wallet.type)) {
try {
confirmations =
appStore.wallet!.transactionHistory.transactions.values.first.confirmations +
appStore.wallet!.transactionHistory.transactions.values.last.confirmations +
1;
} catch (_) {}
}
try {
confirmations =
appStore.wallet!.transactionHistory.transactions.values.first.confirmations +
appStore.wallet!.transactionHistory.transactions.values.last.confirmations +
1;
} catch (_) {}
return length * confirmations;
}, _transactionDisposerCallback, delay: 300);
}
@@ -1413,14 +1388,6 @@ abstract class DashboardViewModelBase with Store {
@action
void setSyncAll(bool value) => settingsStore.currentSyncAll = value;
Future<List<String>> checkForHavenWallets() async {
final walletInfos = await WalletInfo.getAll();
return walletInfos
.where((element) => element.type == WalletType.haven)
.map((e) => e.name)
.toList();
}
Future<List<String>> checkAffectedWallets() async {
try {
// await load file

View File

@@ -6,13 +6,10 @@ import 'package:hash_wallet/entities/erc20_token_info_moralis.dart';
import 'package:hash_wallet/entities/sort_balance_types.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/store/settings_store.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/utils/token_utilities.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:hash_wallet/view_model/dashboard/balance_view_model.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart';
import 'package:cw_core/utils/homoglyph_normalizer.dart';
@@ -112,24 +109,6 @@ abstract class HomeSettingsViewModelBase with Store {
await evm!.addErc20Token(_balanceViewModel.wallet, evmToken);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
final splToken = token.copyWith(enabled: true);
await solana!.addSPLToken(
_balanceViewModel.wallet,
splToken,
contractAddress,
);
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
final tronToken = token.copyWith(enabled: true);
await tron!.addTronToken(_balanceViewModel.wallet, tronToken, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
await zano!.addZanoAssetById(_balanceViewModel.wallet, contractAddress);
}
_updateTokensList();
_updateFiatPrices(token);
} catch (e) {
@@ -145,18 +124,6 @@ abstract class HomeSettingsViewModelBase with Store {
return evm!.isTokenAlreadyAdded(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
return solana!.isTokenAlreadyAdded(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
return tron!.isTokenAlreadyAdded(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
return zano!.isTokenAlreadyAdded(_balanceViewModel.wallet, contractAddress);
}
return false;
}
@@ -168,16 +135,6 @@ abstract class HomeSettingsViewModelBase with Store {
await evm!.deleteErc20Token(_balanceViewModel.wallet, token as Erc20Token);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
await solana!.deleteSPLToken(_balanceViewModel.wallet, token);
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
await tron!.deleteTronToken(_balanceViewModel.wallet, token);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
await zano!.deleteZanoAsset(_balanceViewModel.wallet, token);
}
_updateTokensList();
} finally {
isDeletingToken = false;
@@ -223,25 +180,15 @@ abstract class HomeSettingsViewModelBase with Store {
case WalletType.bsc:
defaultTokenAddresses = evm!.getDefaultTokenContractAddresses(_balanceViewModel.wallet);
break;
case WalletType.solana:
defaultTokenAddresses = solana!.getDefaultTokenContractAddresses();
break;
case WalletType.tron:
defaultTokenAddresses = tron!.getDefaultTokenContractAddresses();
break;
case WalletType.zano:
case WalletType.banano:
case WalletType.monero:
case WalletType.none:
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.haven:
case WalletType.nano:
case WalletType.wownero:
case WalletType.bitcoinCash:
case WalletType.decred:
case WalletType.dogecoin:
case WalletType.zcash:
return false;
}
@@ -264,25 +211,15 @@ abstract class HomeSettingsViewModelBase with Store {
case WalletType.bsc:
defaultTokenSymbols = evm!.getDefaultTokenSymbols(_balanceViewModel.wallet);
break;
case WalletType.solana:
defaultTokenSymbols = solana!.getDefaultTokenSymbols();
break;
case WalletType.tron:
defaultTokenSymbols = tron!.getDefaultTokenSymbols();
break;
case WalletType.zano:
case WalletType.banano:
case WalletType.monero:
case WalletType.none:
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.haven:
case WalletType.nano:
case WalletType.wownero:
case WalletType.bitcoinCash:
case WalletType.decred:
case WalletType.dogecoin:
case WalletType.zcash:
return false;
}
@@ -393,18 +330,6 @@ abstract class HomeSettingsViewModelBase with Store {
return await evm!.getErc20Token(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
return await solana!.getSPLToken(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
return await tron!.getTronToken(_balanceViewModel.wallet, contractAddress);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
return await zano!.getZanoAsset(_balanceViewModel.wallet, contractAddress);
}
return null;
}
@@ -429,20 +354,6 @@ abstract class HomeSettingsViewModelBase with Store {
if (!value) evm!.removeTokenTransactionsInHistory(_balanceViewModel.wallet, token);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
final address = solana!.getTokenAddress(token);
solana!.addSPLToken(_balanceViewModel.wallet, token, address);
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
final address = tron!.getTokenAddress(token);
tron!.addTronToken(_balanceViewModel.wallet, token, address);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
await zano!.changeZanoAssetAvailability(_balanceViewModel.wallet, token);
}
_refreshTokensList();
}
@@ -473,30 +384,6 @@ abstract class HomeSettingsViewModelBase with Store {
.toList()
..sort(_sortFunc));
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
tokens.addAll(solana!
.getSPLTokenCurrencies(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
..sort(_sortFunc));
}
if (_balanceViewModel.wallet.type == WalletType.tron) {
tokens.addAll(tron!
.getTronTokenCurrencies(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
..sort(_sortFunc));
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
tokens.addAll(zano!
.getZanoAssets(_balanceViewModel.wallet)
.where((element) => _matchesSearchText(element))
.toList()
..sort(_sortFunc));
}
}
@@ -564,23 +451,10 @@ abstract class HomeSettingsViewModelBase with Store {
}
String? getTokenAddressBasedOnWallet(CryptoCurrency asset) {
if (_balanceViewModel.wallet.type == WalletType.tron) {
return tron!.getTokenAddress(asset);
}
if (_balanceViewModel.wallet.type == WalletType.solana) {
return solana!.getTokenAddress(asset);
}
if (isEVMCompatibleChain(_balanceViewModel.wallet.type)) {
return evm!.getTokenAddress(asset);
}
if (_balanceViewModel.wallet.type == WalletType.zano) {
return zano!.getZanoAssetAddress(asset);
}
// We return null if it's neither Tron, EVM or Solana wallet (which is actually impossible because we only display home settings for either of these four wallets).
return null;
}
}

View File

@@ -65,25 +65,17 @@ abstract class NFTViewModelBase with Store {
// and used within the wallet
// the [excludeSpam] field is a boolean that determines if spam nfts be excluded from the response.
Uri uri;
if (wallet.type == WalletType.solana) {
uri = Uri.https(
'solana-gateway.moralis.io',
'/account/$chainName/$walletAddress/nft',
);
} else {
uri = Uri.https(
'deep-index.moralis.io',
'/api/v2.2/$walletAddress/nft',
{
"chain": chainName,
"format": "decimal",
"media_items": "false",
"exclude_spam": "true",
"normalizeMetadata": "true",
},
);
}
Uri uri = Uri.https(
'deep-index.moralis.io',
'/api/v2.2/$walletAddress/nft',
{
"chain": chainName,
"format": "decimal",
"media_items": "false",
"exclude_spam": "true",
"normalizeMetadata": "true",
},
);
try {
if (isLoading) return;
@@ -100,27 +92,11 @@ abstract class NFTViewModelBase with Store {
final decodedResponse = jsonDecode(response.body);
if (wallet.type == WalletType.solana) {
final results = await Future.wait(
(decodedResponse as List<dynamic>).map(
(x) {
final data = x as Map<String, dynamic>;
final mint = data['mint'] as String? ?? '';
return getSolanaNFTDetails(mint, chainName);
},
).toList(),
);
final result = WalletNFTsResponseModel.fromJson(decodedResponse as Map<String, dynamic>).result ?? [];
solanaNftAssetModels.clear();
nftAssetByWalletModels.clear();
solanaNftAssetModels.addAll(results);
} else {
final result = WalletNFTsResponseModel.fromJson(decodedResponse as Map<String, dynamic>).result ?? [];
nftAssetByWalletModels.clear();
nftAssetByWalletModels.addAll(result);
}
nftAssetByWalletModels.addAll(result);
} catch (e) {
log(e.toString());
bottomSheetService.queueBottomSheet(
@@ -170,35 +146,29 @@ abstract class NFTViewModelBase with Store {
try {
isImportNFTLoading = true;
if (appStore.wallet!.type == WalletType.solana) {
final result = await getSolanaNFTDetails(tokenAddress, chainName);
final uri = Uri.https(
'deep-index.moralis.io',
'/api/v2.2/nft/$tokenAddress/$tokenId',
{
"chain": chainName,
"format": "decimal",
"media_items": "false",
"normalizeMetadata": "true",
},
);
final response = await ProxyWrapper().get(
clearnetUri: uri,
headers: {
"Accept": "application/json",
"X-API-Key": secrets.moralisApiKey,
},
);
solanaNftAssetModels.add(result);
} else {
final uri = Uri.https(
'deep-index.moralis.io',
'/api/v2.2/nft/$tokenAddress/$tokenId',
{
"chain": chainName,
"format": "decimal",
"media_items": "false",
"normalizeMetadata": "true",
},
);
final response = await ProxyWrapper().get(
clearnetUri: uri,
headers: {
"Accept": "application/json",
"X-API-Key": secrets.moralisApiKey,
},
);
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
final decodedResponse = jsonDecode(response.body) as Map<String, dynamic>;
final nftAsset = NFTAssetModel.fromJson(decodedResponse);
final nftAsset = NFTAssetModel.fromJson(decodedResponse);
nftAssetByWalletModels.add(nftAsset);
}
nftAssetByWalletModels.add(nftAsset);
} catch (e) {
bottomSheetService.queueBottomSheet(
isModalDismissible: true,

View File

@@ -1,5 +1,4 @@
import 'package:hash_wallet/bitcoin/bitcoin.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/receive_page_option.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart';
@@ -14,11 +13,7 @@ abstract class ReceiveOptionViewModelBase with Store {
: selectedReceiveOption = initialPageOption ??
([WalletType.bitcoin, WalletType.litecoin].contains(_wallet.type)
? bitcoin!.getSelectedAddressType(_wallet)
: (_wallet.type == WalletType.decred && _wallet.isTestnet)
? ReceivePageOption.testnet
: _wallet.type == WalletType.zcash
? zcash!.getSelectedAddressType(_wallet)
: ReceivePageOption.mainnet);
: ReceivePageOption.mainnet);
final WalletBase _wallet;

View File

@@ -25,7 +25,6 @@ abstract class SignViewModelBase with Store {
WalletType.bitcoinCash,
WalletType.litecoin,
WalletType.dogecoin,
WalletType.haven,
].contains(wallet.type);
@action

View File

@@ -1,16 +1,11 @@
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/entities/balance_display_mode.dart';
import 'package:hash_wallet/entities/fiat_currency.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/nano/nano.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/crypto_amount_format.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/transaction_direction.dart';
@@ -44,10 +39,7 @@ class TransactionListItem extends ActionListItem with Keyable {
@override
dynamic get keyIndex => transaction.id;
bool get hasTokens =>
isEVMCompatibleChain(balanceViewModel.wallet.type) ||
balanceViewModel.wallet.type == WalletType.solana ||
balanceViewModel.wallet.type == WalletType.tron;
bool get hasTokens => isEVMCompatibleChain(balanceViewModel.wallet.type);
String get formattedCryptoAmount {
if (displayMode == BalanceDisplayMode.hiddenBalance) return '---';
@@ -87,8 +79,6 @@ class TransactionListItem extends ActionListItem with Keyable {
int get neededConfirmations {
switch (balanceViewModel.wallet.type) {
case WalletType.monero:
case WalletType.haven:
case WalletType.zano:
return 10;
case WalletType.wownero:
return 3;
@@ -106,8 +96,6 @@ class TransactionListItem extends ActionListItem with Keyable {
String get formattedPendingStatus {
switch (balanceViewModel.wallet.type) {
case WalletType.monero:
case WalletType.haven:
case WalletType.zano:
if (transaction.confirmations >= 0 && transaction.confirmations < 10) {
return ' (${transaction.confirmations}/10)';
}
@@ -147,10 +135,8 @@ class TransactionListItem extends ActionListItem with Keyable {
String get formattedStatus {
if ([
WalletType.monero,
WalletType.haven,
WalletType.wownero,
WalletType.litecoin,
WalletType.zano,
].contains(balanceViewModel.wallet.type)) {
return formattedPendingStatus;
}
@@ -171,16 +157,6 @@ class TransactionListItem extends ActionListItem with Keyable {
final asset = evm!.assetOfTransaction(balanceViewModel.wallet, transaction);
return asset;
}
if (balanceViewModel.wallet.type == WalletType.solana) {
final asset = solana!.assetOfTransaction(balanceViewModel.wallet, transaction);
return asset;
}
if (balanceViewModel.wallet.type == WalletType.tron) {
final asset = tron!.assetOfTransaction(balanceViewModel.wallet, transaction);
return asset;
}
} catch (e) {
return null;
}
@@ -232,52 +208,8 @@ class TransactionListItem extends ActionListItem with Keyable {
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
break;
case WalletType.solana:
final asset = solana!.assetOfTransaction(balanceViewModel.wallet, transaction);
final price = balanceViewModel.fiatConversionStore.prices[asset];
amount = calculateFiatAmountRaw(
cryptoAmount: solana!.getTransactionAmountRaw(transaction),
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
break;
case WalletType.tron:
final asset = tron!.assetOfTransaction(balanceViewModel.wallet, transaction);
final price = balanceViewModel.fiatConversionStore.prices[asset];
final cryptoAmount = tron!.getTransactionAmountRaw(transaction);
amount = calculateFiatAmountRaw(
cryptoAmount: cryptoAmount,
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
break;
case WalletType.zano:
final asset = zano!.assetOfTransaction(balanceViewModel.wallet, transaction);
if (asset == null) {
amount = "0.00";
break;
}
final price = balanceViewModel.fiatConversionStore.prices[asset];
amount = calculateFiatAmountRaw(
cryptoAmount: zano!.formatterIntAmountToDouble(
amount: transaction.amount, currency: asset, forFee: false),
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
break;
case WalletType.decred:
amount = calculateFiatAmountRaw(
cryptoAmount: decred!.formatterDecredAmountToDouble(amount: transaction.amount),
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
break;
case WalletType.zcash:
amount = calculateFiatAmountRaw(
cryptoAmount:
zcash!.formatterZcashAmountToDouble(amount: BigInt.from(transaction.amount)),
price: price,
).withLocalSeperator(_appStore.settingsStore.languageCode);
case WalletType.none:
case WalletType.banano:
case WalletType.haven:
break;
}

View File

@@ -8,7 +8,6 @@ import 'package:hash_wallet/exchange/provider/chainflip_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/changenow_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/exolix_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/jupiter_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/near_Intents_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/swapsxyz_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/swaptrade_exchange_provider.dart';
@@ -87,9 +86,6 @@ abstract class ExchangeTradeViewModelBase with Store {
case ExchangeProviderDescription.swapsXyz:
_provider = SwapsXyzExchangeProvider();
break;
case ExchangeProviderDescription.jupiter:
_provider = JupiterExchangeProvider();
break;
case ExchangeProviderDescription.nearIntents:
_provider = NearIntentsExchangeProvider();
break;
@@ -121,20 +117,13 @@ abstract class ExchangeTradeViewModelBase with Store {
bool isSwapsXYZCanSendFromExternal;
/// Providers that should hide the "send from external" button
static const List<Type> _providersThatHideExternalSend = [
JupiterExchangeProvider,
];
/// Returns true if the current provider should hide the external send button
bool get shouldHideExternalSendButton {
if (_provider == null) return false;
if (!isSwapsXYZCanSendFromExternal) return true;
return _providersThatHideExternalSend.any(
(providerType) => _provider.runtimeType == providerType,
);
return false;
}
String get extraInfo => trade.extraId != null && trade.extraId!.isNotEmpty
@@ -439,10 +428,6 @@ abstract class ExchangeTradeViewModelBase with Store {
return ArbitrumURI(amount: amount, address: inputAddress);
case WalletType.bsc:
return BSCURI(amount: amount, address: inputAddress);
case WalletType.solana:
return SolanaURI(amount: amount, address: inputAddress);
case WalletType.tron:
return TronURI(amount: amount, address: inputAddress);
case WalletType.monero:
return MoneroURI(address: inputAddress, amount: amount);
case WalletType.wownero:
@@ -453,15 +438,8 @@ abstract class ExchangeTradeViewModelBase with Store {
return LitecoinURI(amount: amount, address: inputAddress);
case WalletType.nano:
return NanoURI(amount: amount, address: inputAddress);
case WalletType.zano:
return ZanoURI(amount: amount, address: inputAddress);
case WalletType.decred:
return DecredURI(amount: amount, address: inputAddress);
case WalletType.zcash:
return ZcashURI(amount: amount, address: inputAddress);
case WalletType.banano:
case WalletType.none:
case WalletType.haven:
return null;
}
}

View File

@@ -24,7 +24,6 @@ import 'package:hash_wallet/exchange/exchange_trade_state.dart';
import 'package:hash_wallet/exchange/limits.dart';
import 'package:hash_wallet/exchange/limits_state.dart';
import 'package:hash_wallet/exchange/provider/chainflip_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/jupiter_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/letsexchange_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/changenow_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/exchange_provider.dart';
@@ -302,7 +301,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
].contains(wallet.type);
bool get hideAddressAfterExchange =>
[WalletType.monero, WalletType.wownero, WalletType.zcash].contains(wallet.type);
[WalletType.monero, WalletType.wownero].contains(wallet.type);
bool _useTorOnly;
final ExchangeTemplateStore _exchangeTemplateStore;
@@ -1451,10 +1450,6 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
depositCurrency = CryptoCurrency.doge;
receiveCurrency = CryptoCurrency.xmr;
break;
case WalletType.haven:
depositCurrency = CryptoCurrency.xhv;
receiveCurrency = CryptoCurrency.btc;
break;
case WalletType.ethereum:
depositCurrency = CryptoCurrency.eth;
receiveCurrency = CryptoCurrency.xmr;
@@ -1483,30 +1478,10 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
depositCurrency = CryptoCurrency.bnb;
receiveCurrency = CryptoCurrency.xmr;
break;
case WalletType.solana:
depositCurrency = CryptoCurrency.sol;
receiveCurrency = CryptoCurrency.xmr;
break;
case WalletType.tron:
depositCurrency = CryptoCurrency.trx;
receiveCurrency = CryptoCurrency.xmr;
break;
case WalletType.wownero:
depositCurrency = CryptoCurrency.wow;
receiveCurrency = CryptoCurrency.xmr;
break;
case WalletType.zano:
depositCurrency = CryptoCurrency.zano;
receiveCurrency = CryptoCurrency.xmr;
break;
case WalletType.decred:
depositCurrency = CryptoCurrency.dcr;
receiveCurrency = CryptoCurrency.xmr;
break;
case WalletType.zcash:
depositCurrency = CryptoCurrency.zec;
receiveCurrency = CryptoCurrency.xmr;
break;
case WalletType.none:
break;
}

View File

@@ -111,14 +111,11 @@ abstract class NodeCreateOrEditViewModelBase with Store {
String socksProxyAddress;
@computed
bool get isReady =>
(address.isNotEmpty) ||
walletType == WalletType.decred; // Allow an empty address.
bool get isReady => address.isNotEmpty;
bool get hasAuthCredentials =>
walletType == WalletType.monero ||
walletType == WalletType.wownero ||
walletType == WalletType.haven;
walletType == WalletType.wownero;
bool get hasPathSupport {
switch (walletType) {
@@ -127,22 +124,16 @@ abstract class NodeCreateOrEditViewModelBase with Store {
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.banano:
case WalletType.nano:
case WalletType.tron:
return true;
case WalletType.none:
case WalletType.monero:
case WalletType.wownero:
case WalletType.haven:
case WalletType.litecoin:
case WalletType.bitcoinCash:
case WalletType.bitcoin:
case WalletType.dogecoin:
case WalletType.zano:
case WalletType.decred:
case WalletType.zcash:
return false;
}
}

View File

@@ -82,24 +82,6 @@ abstract class PaymentViewModelBase with Store {
return PaymentFlowResult.currentWalletCompatible();
}
if (detectedWalletType == WalletType.solana) {
final compatibleWallets = await getWalletsByType(WalletType.solana);
return PaymentFlowResult.solanaTokenSelection(
detectionResult,
compatibleWallets: compatibleWallets,
wallet: compatibleWallets.isNotEmpty ? compatibleWallets.first : null,
);
}
if (detectedWalletType == WalletType.tron) {
final compatibleWallets = await getWalletsByType(WalletType.tron);
return PaymentFlowResult.tronTokenSelection(
detectionResult,
compatibleWallets: compatibleWallets,
wallet: compatibleWallets.isNotEmpty ? compatibleWallets.first : null,
);
}
if (isEVMCompatibleChain(detectedWalletType!)) {
return PaymentFlowResult.evmNetworkSelection(detectionResult);
}
@@ -186,34 +168,6 @@ class PaymentFlowResult {
);
}
/// Solana address detected - needs token selection
factory PaymentFlowResult.solanaTokenSelection(
AddressDetectionResult addressDetectionResult, {
List<WalletInfo>? compatibleWallets,
WalletInfo? wallet,
}) =>
PaymentFlowResult._(
type: PaymentFlowType.solanaTokenSelection,
addressDetectionResult: addressDetectionResult,
walletType: WalletType.solana,
wallets: compatibleWallets ?? [],
wallet: wallet,
);
/// Tron address detected - needs token selection
factory PaymentFlowResult.tronTokenSelection(
AddressDetectionResult addressDetectionResult, {
List<WalletInfo>? compatibleWallets,
WalletInfo? wallet,
}) =>
PaymentFlowResult._(
type: PaymentFlowType.tronTokenSelection,
addressDetectionResult: addressDetectionResult,
walletType: WalletType.tron,
wallets: compatibleWallets ?? [],
wallet: wallet,
);
/// Current wallet is compatible
factory PaymentFlowResult.currentWalletCompatible() =>
PaymentFlowResult._(type: PaymentFlowType.currentWalletCompatible);
@@ -292,9 +246,7 @@ class PaymentFlowResult {
PaymentFlowResult._(type: PaymentFlowType.incompatible, message: message);
CryptoCurrency? get detectedCurrency {
if (type == PaymentFlowType.evmNetworkSelection ||
type == PaymentFlowType.solanaTokenSelection ||
type == PaymentFlowType.tronTokenSelection) {
if (type == PaymentFlowType.evmNetworkSelection) {
return addressDetectionResult?.detectedCurrency;
}
if (walletType != null) {
@@ -314,8 +266,6 @@ enum PaymentFlowType {
multipleWallets,
noWallets,
evmNetworkSelection,
solanaTokenSelection,
tronTokenSelection,
error,
incompatible,
}

View File

@@ -39,25 +39,12 @@ class WalletRestoreFromQRCode {
'bitcoincash': WalletType.bitcoinCash,
'bitcoincash-wallet': WalletType.bitcoinCash,
'bitcoincash_wallet': WalletType.bitcoinCash,
'solana-wallet': WalletType.solana,
'tron': WalletType.tron,
'tron-wallet': WalletType.tron,
'tron_wallet': WalletType.tron,
'wownero': WalletType.wownero,
'wownero-wallet': WalletType.wownero,
'wownero_wallet': WalletType.wownero,
'zano': WalletType.zano,
'zano-wallet': WalletType.zano,
'zano_wallet': WalletType.zano,
'decred': WalletType.decred,
'decred-wallet': WalletType.decred,
'decred_wallet': WalletType.decred,
'dogecoin': WalletType.dogecoin,
'dogecoin-wallet': WalletType.dogecoin,
'dogecoin_wallet': WalletType.dogecoin,
'zcash': WalletType.zcash,
'zcash-wallet': WalletType.zcash,
'zcash_wallet': WalletType.zcash,
};
static WalletType? _extractWalletType(String code) {
@@ -234,22 +221,6 @@ class WalletRestoreFromQRCode {
return WalletRestoreMode.seed;
}
if (type == WalletType.solana && credentials.containsKey('private_key')) {
final privateKey = credentials['private_key'] as String;
if (privateKey.isEmpty) {
throw Exception('Unexpected restore mode: private_key');
}
return WalletRestoreMode.keys;
}
if (type == WalletType.tron && credentials.containsKey('private_key')) {
final privateKey = credentials['private_key'] as String;
if (privateKey.isEmpty) {
throw Exception('Unexpected restore mode: private_key');
}
return WalletRestoreMode.keys;
}
if (type == WalletType.monero) {
final codeParsed = json.decode(credentials['raw_qr'].toString());
if (codeParsed["version"] != 0)

View File

@@ -1,12 +1,10 @@
import 'package:hash_wallet/bitcoin_cash/bitcoin_cash.dart';
import 'package:hash_wallet/core/amount_parsing_proxy.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/dogecoin/dogecoin.dart';
import 'package:hash_wallet/entities/priority_for_wallet_type.dart';
import 'package:hash_wallet/core/wallet_change_listener_view_model.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/view_model/dashboard/balance_view_model.dart';
import 'package:cw_core/crypto_currency.dart';
@@ -85,8 +83,6 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
switch (wallet.type) {
case WalletType.monero:
case WalletType.wownero:
case WalletType.haven:
case WalletType.zano:
return transactionPriority == monero!.getMoneroTransactionPrioritySlow();
case WalletType.bitcoin:
return transactionPriority == bitcoin!.getBitcoinTransactionPrioritySlow();
@@ -99,17 +95,12 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
return transactionPriority == evm!.getEVMTransactionPrioritySlow();
case WalletType.bitcoinCash:
return transactionPriority == bitcoinCash!.getBitcoinCashTransactionPrioritySlow();
case WalletType.decred:
return transactionPriority == decred!.getDecredTransactionPrioritySlow();
case WalletType.dogecoin:
return transactionPriority == dogecoin!.getDogeCoinTransactionPrioritySlow();
case WalletType.none:
case WalletType.nano:
case WalletType.banano:
case WalletType.solana:
case WalletType.tron:
case WalletType.arbitrum:
case WalletType.zcash:
return false;
}
}
@@ -126,8 +117,6 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
bool get hasFeesPriority =>
wallet.type != WalletType.nano &&
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
@@ -186,14 +175,9 @@ abstract class FeesViewModelBase extends WalletChangeListenerViewModel with Stor
void setDefaultTransactionPriority() {
switch (wallet.type) {
case WalletType.monero:
case WalletType.haven:
case WalletType.wownero:
case WalletType.zano:
_settingsStore.setPriority(wallet.type, monero!.getMoneroTransactionPriorityAutomatic());
break;
case WalletType.zcash:
_settingsStore.setPriority(wallet.type, zcash!.getZcashTransactionPriorityAutomatic());
break;
case WalletType.bitcoin:
_settingsStore.setPriority(wallet.type, bitcoin!.getBitcoinTransactionPriorityMedium());
break;

View File

@@ -1,6 +1,5 @@
import 'dart:math' show min;
import 'package:hash_wallet/bitcoin/bitcoin.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/di.dart';
import 'package:hash_wallet/entities/calculate_fiat_amount.dart';
import 'package:hash_wallet/entities/calculate_fiat_amount_raw.dart';
@@ -11,15 +10,11 @@ import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/src/screens/send/widgets/extract_address_from_parsed.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:hash_wallet/store/settings_store.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/balance.dart';
import 'package:cw_core/crypto_amount_format.dart';
import 'package:cw_core/crypto_currency.dart';
@@ -133,9 +128,6 @@ abstract class OutputBase with Store {
case WalletType.dogecoin:
_amount = cryptoCurrencyHandler().parseAmount(_cryptoAmount).toInt();
break;
case WalletType.decred:
_amount = decred!.formatterStringDoubleToDecredAmount(_cryptoAmount);
break;
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.base:
@@ -146,19 +138,9 @@ abstract class OutputBase with Store {
case WalletType.wownero:
_amount = wownero!.formatterWowneroParseAmount(amount: _cryptoAmount);
break;
case WalletType.zano:
_amount = zano!
.formatterParseAmount(amount: _cryptoAmount, currency: cryptoCurrencyHandler());
break;
case WalletType.zcash:
_amount = zcash!.formatterZcashParseAmount(_cryptoAmount);
break;
case WalletType.none:
case WalletType.haven:
case WalletType.nano:
case WalletType.banano:
case WalletType.solana:
case WalletType.tron:
break;
}
@@ -198,7 +180,6 @@ abstract class OutputBase with Store {
case WalletType.litecoin:
case WalletType.bitcoinCash:
case WalletType.dogecoin:
case WalletType.decred:
estimatedFee = walletTypeToCryptoCurrency(_wallet.type).formatAmount(BigInt.from(fee));
break;
case WalletType.bitcoin:
@@ -215,26 +196,6 @@ abstract class OutputBase with Store {
estimatedFee = _appStore.amountParsingProxy.getDisplayCryptoString(fee, cryptoCurrencyHandler());
break;
case WalletType.solana:
estimatedFee = solana!.getEstimateFees(_wallet).toString();
break;
case WalletType.zano:
estimatedFee = zano!
.formatterIntAmountToDouble(
amount: fee, currency: cryptoCurrencyHandler(), forFee: true)
.toString();
break;
case WalletType.tron:
if (cryptoCurrencyHandler() == CryptoCurrency.trx) {
estimatedFee = tron!.getTronNativeEstimatedFee(_wallet).toString();
} else {
estimatedFee = tron!.getTronTRC20EstimatedFee(_wallet).toString();
}
break;
case WalletType.zcash:
estimatedFee = zcash!.formatterZcashAmountToDouble(amount: BigInt.from(fee)).toString();
break;
/// EVMs
case WalletType.ethereum:
@@ -256,7 +217,6 @@ abstract class OutputBase with Store {
/// end EVMs
case WalletType.haven:
case WalletType.nano:
case WalletType.banano:
case WalletType.none:
@@ -274,8 +234,7 @@ abstract class OutputBase with Store {
final _ = _wallet.syncStatus;
try {
final currency = (isEVMCompatibleChain(_wallet.type) ||
[WalletType.solana, WalletType.tron].contains(_wallet.type))
final currency = isEVMCompatibleChain(_wallet.type)
? _wallet.currency
: cryptoCurrencyHandler();

View File

@@ -55,11 +55,7 @@ abstract class SendTemplateViewModelBase with Store {
TemplateValidator get templateValidator => TemplateValidator();
bool get hasMultiRecipient =>
_wallet.type != WalletType.haven &&
_wallet.type != WalletType.solana &&
_wallet.type != WalletType.tron &&
!isEVMCompatibleChain(_wallet.type);
bool get hasMultiRecipient => !isEVMCompatibleChain(_wallet.type);
@computed
CryptoCurrency get cryptoCurrency => _wallet.currency;
@@ -106,8 +102,5 @@ abstract class SendTemplateViewModelBase with Store {
@computed
List<CryptoCurrency> get walletCurrencies => _wallet.balance.keys.toList();
bool get hasMultipleTokens =>
isEVMCompatibleChain(_wallet.type) ||
_wallet.type == WalletType.solana ||
_wallet.type == WalletType.tron;
bool get hasMultipleTokens => isEVMCompatibleChain(_wallet.type);
}

View File

@@ -10,7 +10,6 @@ import 'package:hash_wallet/core/open_crypto_pay/models.dart';
import 'package:hash_wallet/core/open_crypto_pay/open_cryptopay_service.dart';
import 'package:hash_wallet/core/validator.dart';
import 'package:hash_wallet/core/wallet_change_listener_view_model.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/entities/calculate_fiat_amount.dart';
import 'package:hash_wallet/entities/contact.dart';
import 'package:hash_wallet/entities/contact_record.dart';
@@ -24,13 +23,10 @@ import 'package:hash_wallet/entities/wallet_contact.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/exchange/exchange_provider_description.dart';
import 'package:hash_wallet/exchange/provider/exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/jupiter_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/near_Intents_exchange_provider.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/exchange/provider/swapsxyz_exchange_provider.dart';
import 'package:hash_wallet/exchange/provider/thorchain_exchange.provider.dart';
import 'package:hash_wallet/exchange/trade.dart';
import 'package:hash_wallet/exchange/trade_state.dart';
import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/nano/nano.dart';
@@ -39,7 +35,6 @@ import 'package:hash_wallet/routes.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:hash_wallet/store/settings_store.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/utils/payment_request.dart';
import 'package:hash_wallet/view_model/contact_list/contact_list_view_model.dart';
import 'package:hash_wallet/view_model/dashboard/balance_view_model.dart';
@@ -50,8 +45,6 @@ import 'package:hash_wallet/view_model/send/send_template_view_model.dart';
import 'package:hash_wallet/view_model/send/send_view_model_state.dart';
import 'package:hash_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/currency_for_wallet_type.dart';
import 'package:cw_core/erc20_token.dart';
@@ -80,8 +73,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
currencies = wallet.balance.keys.toList();
selectedCryptoCurrency =
coinTypeToSpendFrom == UnspentCoinType.lightning ? CryptoCurrency.btcln : wallet.currency;
hasMultipleTokens = isEVMWallet ||
[WalletType.solana, WalletType.tron, WalletType.zano].contains(wallet.type);
hasMultipleTokens = isEVMWallet;
for (final output in outputs) {
output.updateWallet(wallet);
@@ -112,8 +104,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
selectedCryptoCurrency = coinTypeToSpendFrom == UnspentCoinType.lightning
? CryptoCurrency.btcln
: _appStore.wallet!.currency,
hasMultipleTokens = isEVMCompatibleChain(_appStore.wallet!.type) ||
[WalletType.solana, WalletType.tron, WalletType.zano].contains(_appStore.wallet!.type),
hasMultipleTokens = isEVMCompatibleChain(_appStore.wallet!.type),
selectedChainId = _appStore.wallet!.chainId,
outputs = ObservableList<Output>(),
fiatFromSettings = _appStore.settingsStore.fiatCurrency,
@@ -189,8 +180,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
bool get isBatchSending => outputs.length > 1;
bool get shouldDisplaySendALL {
if (walletType == WalletType.solana) return false;
// if (walletType == WalletType.ethereum && selectedCryptoCurrency == CryptoCurrency.eth)
// return false;
@@ -257,8 +246,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.tron:
case WalletType.solana:
case WalletType.bitcoin:
return wallet.currency;
default:
@@ -335,7 +322,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
@computed
Future<String> get sendingBalance async {
// only for electrum, monero, wownero, decred wallets atm:
// only for electrum, monero, wownero wallets atm:
switch (wallet.type) {
case WalletType.bitcoin:
if (coinTypeToSpendFrom == UnspentCoinType.lightning) return balance;
@@ -347,7 +334,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
case WalletType.dogecoin:
case WalletType.monero:
case WalletType.wownero:
case WalletType.decred:
final sendingBalance =
await unspentCoinsListViewModel.getSendingBalance(coinTypeToSpendFrom);
return walletTypeToCryptoCurrency(walletType).formatAmount(BigInt.from(sendingBalance));
@@ -394,7 +380,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
WalletType.litecoin,
WalletType.monero,
WalletType.wownero,
WalletType.decred,
WalletType.bitcoinCash,
WalletType.dogecoin
].contains(wallet.type) &&
@@ -808,38 +793,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
}
// END Swaps.xyz path
// Jupiter (Solana) swap path
if (walletType == WalletType.solana && trade != null && provider is JupiterExchangeProvider) {
final swapTransactionBase64 = trade.routerData;
final requestId = trade.routerValue;
if (swapTransactionBase64?.isNotEmpty == true &&
requestId?.isNotEmpty == true &&
solana != null) {
try {
final actualFee = trade.fee ?? 0.0005;
// Fallback to estimate if not available
final fee = actualFee > 0 ? actualFee : 0.0005;
final amount = double.tryParse(trade.amount) ?? 0.0;
pendingTransaction = await solana!.signAndPrepareJupiterSwapTransaction(
wallet,
swapTransactionBase64!,
requestId!,
trade.payoutAddress ?? '',
amount,
fee,
);
state = ExecutedSuccessfullyState();
return pendingTransaction;
} catch (e, s) {
printV('Jupiter swap error: $e\n$s');
throw Exception('Failed to process Jupiter swap: $e');
}
}
}
// Regular flow
@@ -990,78 +943,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
}
}
await _updateSolanaTrade(signature: pendingTransaction!.id, isSuccess: true);
if (walletType == WalletType.solana) {
Future.delayed(Duration(seconds: 1), () async {
try {
await solana!.pollForTransaction(
wallet,
pendingTransaction!.id,
initialDelay: const Duration(seconds: 1),
maxRetries: 5,
);
} catch (e) {
printV('Failed to poll for transaction: $e');
}
});
// Update balances for currencies involved in swap
if (_currentTrade != null) {
Future.delayed(Duration(seconds: 2), () async {
try {
final tokenMints = <String>[];
// Extract from currency mint (skip native SOL)
if (_currentTrade!.from != null && _currentTrade!.from != CryptoCurrency.sol) {
try {
final fromMint = solana!.getTokenAddress(_currentTrade!.from!);
tokenMints.add(fromMint);
} catch (e) {
printV('Error getting from currency mint: $e');
}
}
// Extract to currency mint (skip native SOL)
if (_currentTrade!.to != null && _currentTrade!.to != CryptoCurrency.sol) {
try {
final toMint = solana!.getTokenAddress(_currentTrade!.to!);
tokenMints.add(toMint);
} catch (e) {
printV('Error getting to currency mint: $e');
}
}
if (tokenMints.isNotEmpty) {
solana!.updateTokenBalances(
wallet,
tokenMints: tokenMints,
);
// Retry after a bit more time to ensure balance is updated
Future.delayed(Duration(seconds: 2), () async {
try {
await solana!.updateTokenBalances(
wallet,
tokenMints: tokenMints,
);
} catch (e) {
printV('Error retrying balance update: $e');
}
});
}
} catch (e) {
printV('Failed to update balances after send: $e');
} finally {
_currentTrade = null;
_currentProvider = null;
}
});
}
}
// Immediate transaction update for EVM chains, Tron, and Nano
if (isEVMWallet || [WalletType.bitcoin, WalletType.solana, WalletType.tron, WalletType.nano].contains(walletType)) {
// Immediate transaction update for EVM chains and Nano
if (isEVMWallet || [WalletType.bitcoin, WalletType.nano].contains(walletType)) {
Future.delayed(Duration(seconds: 4), () async {
try {
await Future.wait([
@@ -1081,27 +964,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
await sharedPreferences.setString(PreferencesKey.backgroundSyncLastTrigger(wallet.name),
DateTime.now().add(Duration(minutes: 1)).toIso8601String());
} catch (e) {
if (e is JupiterSwapFailedException) {
await _updateSolanaTrade(signature: e.signature, isSuccess: false);
}
state = FailureState(translateErrorMessage(e, wallet.type, wallet.currency));
await _updateSolanaTrade(signature: '', isSuccess: false);
}
}
/// Update Jupiter trade with relevant details after transaction is committed
Future<void> _updateSolanaTrade({required String signature, required bool isSuccess}) async {
if (_currentTrade == null ||
_currentProvider?.title != 'Jupiter' ||
walletType != WalletType.solana) return;
_currentTrade!.txId = signature;
_currentTrade!.stateRaw = isSuccess ? TradeState.completed.raw : TradeState.failed.raw;
await _currentTrade!.save();
}
@action
Future<void> updateWalletBalance() async => await wallet.updateBalance();
@@ -1147,10 +1013,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
![
WalletType.nano,
WalletType.banano,
WalletType.solana,
WalletType.tron,
WalletType.arbitrum,
WalletType.zcash,
].contains(wallet.type)) {
throw Exception('Priority is null for wallet type: ${wallet.type}');
}
@@ -1198,23 +1061,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
);
case WalletType.nano:
return nano!.createNanoTransactionCredentials(outputs);
case WalletType.solana:
return solana!
.createSolanaTransactionCredentials(outputs, currency: selectedCryptoCurrency);
case WalletType.tron:
return tron!.createTronTransactionCredentials(outputs, currency: selectedCryptoCurrency);
case WalletType.zano:
return zano!.createZanoTransactionCredentials(
outputs: outputs, priority: priority!, currency: selectedCryptoCurrency);
case WalletType.decred:
this.coinTypeToSpendFrom = UnspentCoinType.any;
return decred!.createDecredTransactionCredentials(outputs, priority!);
case WalletType.zcash:
return zcash!.createZcashTransactionCredentials(
outputs,
currency: selectedCryptoCurrency,
// priority: priority,
);
default:
throw Exception('Unexpected wallet type: ${wallet.type} for send');
}
@@ -1242,11 +1088,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
}
@computed
bool get hasMemos => [WalletType.zcash].contains(wallet.type);
bool get hasMemos => false;
final Map<WalletType, int> _maxMemoLengths = {
WalletType.zcash: 512,
};
final Map<WalletType, int> _maxMemoLengths = {};
@computed
int get maxMemoLength => _maxMemoLengths[wallet.type] ?? 9999999;
@@ -1366,77 +1210,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
) {
String errorMessage = error.toString();
if (walletType == WalletType.solana) {
if (errorMessage.contains('insufficient lamports')) {
double solValueNeeded = 0.0;
// Regular expression to match the number after "need". This shows the exact lamports the user needs to perform the transaction.
RegExp regExp = RegExp(r'need (\d+)');
// Find the match
Match? match = regExp.firstMatch(errorMessage);
if (match != null) {
String neededAmount = match.group(1)!;
final lamportsNeeded = int.tryParse(neededAmount);
// 5000 lamport used here is the constant for sending a transaction on solana
int lamportsPerSol = 1000000000;
solValueNeeded =
lamportsNeeded != null ? ((lamportsNeeded + 5000) / lamportsPerSol) : 0.0;
return S.current.insufficient_lamports(solValueNeeded.toString());
} else {
return S.current.insufficient_lamport_for_tx;
}
}
if (error is SignNativeTokenTransactionRentException) {
return S.current.solana_sign_native_transaction_rent_exception;
}
if (error is CreateAssociatedTokenAccountException) {
return "${S.current.solana_create_associated_token_account_exception} ${S.current.added_message_for_ata_error}";
}
if (error is SignSPLTokenTransactionRentException) {
return S.current.solana_sign_spl_token_transaction_rent_exception;
}
if (error is NoAssociatedTokenAccountException) {
return S.current.solana_no_associated_token_account_exception;
}
if (errorMessage.contains('found no record of a prior credit')) {
return S.current.insufficient_funds_for_tx;
}
if (errorMessage.contains('insufficient funds for rent') &&
errorMessage.contains('Transaction simulation failed') &&
errorMessage.contains('account_index')) {
final accountIndexMatch = RegExp(r'account_index: (\d+)').firstMatch(errorMessage);
if (accountIndexMatch != null) {
return int.parse(accountIndexMatch.group(1)!) == 0
? S.current.insufficientFundsForRentError
: S.current.insufficientFundsForRentErrorReceiver;
}
}
if (errorMessage.contains('invalid account data')) {
return S.current.solana_invalid_data_message;
}
if (errorMessage.contains('Blockhash not found') ||
errorMessage.contains('BlockhashNotFound') ||
errorMessage.contains('BlockhashMNotFound')) {
return 'Transaction failed because its recent blockhash expired. '
'Please retry your send; if this keeps happening, try again in '
'a few seconds or switch to a different Solana node.';
}
return errorMessage;
}
if (isEVMWallet || walletType == WalletType.haven) {
if (isEVMWallet) {
if (errorMessage.contains('gas required exceeds allowance')) {
return S.current.gas_exceeds_allowance;
}
@@ -1478,16 +1252,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return errorMessage;
}
if (walletType == WalletType.tron) {
if (errorMessage.contains('balance is not sufficient')) {
return S.current.do_not_have_enough_gas_asset(currency.toString());
}
if (errorMessage.contains('Transaction expired')) {
return S.current.tx_retry_message;
}
}
if (error is TransactionWrongBalanceException) {
if (error.amount != null)
return S.current

View File

@@ -8,7 +8,6 @@ import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/src/widgets/alert_with_one_action.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/store/settings_store.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/utils/show_pop_up.dart';
import 'package:hash_wallet/utils/tor.dart';
import 'package:cw_core/balance.dart';
@@ -96,9 +95,6 @@ abstract class ConnectionSyncViewModelBase with Store {
@computed
bool get useBscScan => _settingsStore.useBscScan;
@computed
bool get useTronGrid => _settingsStore.useTronGrid;
@computed
bool get canUseEtherscan => _wallet.chainId == 1;
@@ -114,9 +110,6 @@ abstract class ConnectionSyncViewModelBase with Store {
@computed
bool get canUseBscScan => _wallet.chainId == 56;
@computed
bool get canUseTronGrid => _wallet.type == WalletType.tron;
@action
void setLookupsTwitter(bool value) => _settingsStore.lookupsTwitter = value;
@@ -175,12 +168,6 @@ abstract class ConnectionSyncViewModelBase with Store {
evm!.updateScanProviderUsageState(_wallet, value);
}
@action
void setUseTronGrid(bool value) {
_settingsStore.useTronGrid = value;
tron!.updateTronGridUsageState(_wallet, value);
}
@action
void setUseArbiScan(bool value) {
_settingsStore.useArbiScan = value;

View File

@@ -123,7 +123,7 @@ abstract class DisplaySettingsViewModelBase with Store {
bool get showDisplayAmountsInSatoshiSetting => _appStore.wallet?.type == WalletType.bitcoin;
@computed
bool get showZcashCardSetting => _appStore.wallet?.type == WalletType.zcash;
bool get showZcashCardSetting => false;
@action
void setDisplayAmountsInSatoshi(BitcoinAmountDisplayMode value) => _settingsStore.displayAmountsInSatoshi = value;

View File

@@ -76,7 +76,6 @@ abstract class OtherSettingsViewModelBase with Store {
WalletType.litecoin,
WalletType.bitcoinCash,
WalletType.dogecoin,
WalletType.decred
].contains(_wallet.type);
@computed
@@ -99,8 +98,6 @@ abstract class OtherSettingsViewModelBase with Store {
@computed
bool get displayTransactionPriority => !(changeRepresentativeEnabled ||
[
WalletType.solana,
WalletType.tron,
WalletType.arbitrum,
].contains(_wallet.type));

View File

@@ -45,7 +45,6 @@ abstract class PrivacySettingsViewModelBase with Store {
WalletType.litecoin,
WalletType.bitcoinCash,
WalletType.dogecoin,
WalletType.decred
].contains(_wallet.type);
@computed
@@ -55,7 +54,6 @@ abstract class PrivacySettingsViewModelBase with Store {
WalletType.litecoin,
WalletType.monero,
WalletType.wownero,
WalletType.decred,
WalletType.bitcoinCash,
WalletType.dogecoin
].contains(_wallet.type);

View File

@@ -1,11 +1,8 @@
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/src/screens/transaction_details/address_list_item.dart';
import 'package:hash_wallet/src/screens/transaction_details/confirmations_list_item.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/core/address_validator.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:cw_core/crypto_amount_format.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/currency_for_wallet_type.dart';
@@ -71,8 +68,7 @@ class TxDetailRowDefinition {
keyString: "standard_list_item_transaction_details_height_key",
title: S.current.transaction_details_height,
valueGetter: (vm) => vm.transactionInfo.height?.toString() ?? "",
applicable: (vm) => !([WalletType.solana, WalletType.tron].contains(vm.wallet.type) &&
!isLightning(vm.transactionInfo))),
applicable: (vm) => !isLightning(vm.transactionInfo)),
TxDetailRowDefinition(
@@ -89,7 +85,7 @@ class TxDetailRowDefinition {
title: S.current.confirmations,
valueGetter: (vm) => "${vm.transactionInfo.confirmations}/${vm.neededConfirmations}",
applicable: (vm) =>
[...electrumWalletTypes, ...evmWalletTypes, WalletType.zcash, WalletType.monero]
[...electrumWalletTypes, ...evmWalletTypes, WalletType.monero]
.contains(vm.wallet.type) &&
!isLightning(vm.transactionInfo),
listItemBuilder: ConfirmationsListItem.new),
@@ -113,8 +109,6 @@ class TxDetailRowDefinition {
ret = (bitcoin!.getTransactionAddresses(vm.wallet, vm.transactionInfo) ?? [])
.firstOrNull ??
"";
case WalletType.tron:
ret = tron!.getTronBase58Address(vm.transactionInfo.to!, vm.wallet);
default:
break;
}
@@ -127,7 +121,7 @@ class TxDetailRowDefinition {
applicable: (vm) =>
vm.showRecipientAddress &&
(vm.transactionInfo.to != null ||
[WalletType.monero, WalletType.tron].contains(vm.wallet.type) ||
[WalletType.monero].contains(vm.wallet.type) ||
vm.wallet.type == WalletType.bitcoin &&
vm.transactionInfo.direction == TransactionDirection.incoming),
listItemBuilder: AddressListItem.new),
@@ -136,14 +130,7 @@ class TxDetailRowDefinition {
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_source_address_key",
title: S.current.transaction_details_source_address,
valueGetter: (vm) {
switch (vm.wallet.type) {
case WalletType.tron:
return tron!.getTronBase58Address(vm.transactionInfo.from!, vm.wallet);
default:
return vm.transactionInfo.from!;
}
},
valueGetter: (vm) => vm.transactionInfo.from!,
applicable: (vm) => vm.transactionInfo.from != null,
listItemBuilder: AddressListItem.new),
@@ -181,30 +168,6 @@ class TxDetailRowDefinition {
applicable: (vm) => vm.wallet.type == WalletType.nano),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_memo_key",
title: S.current.memo,
valueGetter: (vm) => vm.transactionInfo.additionalInfo['memo'] as String,
applicable: (vm) =>
vm.wallet.type == WalletType.zcash &&
vm.transactionInfo.additionalInfo["memo"] != null),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_asset_id_key",
title: "Asset ID",
valueGetter: (vm) =>
vm.transactionInfo.additionalInfo["assetId"] as String? ?? "Unknown asset id",
applicable: (vm) => vm.wallet.type == WalletType.zano),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_comment_key",
title: S.current.transaction_details_title,
valueGetter: (vm) => vm.transactionInfo.additionalInfo['comment'] as String? ?? "",
applicable: (vm) => vm.wallet.type == WalletType.zano),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_id_key",
title: S.current.transaction_details_transaction_id,
@@ -304,12 +267,7 @@ abstract class TransactionDetailsViewModelBase with Store {
return evm!.assetOfTransaction(wallet, transactionInfo);
}
return switch (wallet.type) {
WalletType.solana => solana!.assetOfTransaction(wallet, transactionInfo),
WalletType.tron => tron!.assetOfTransaction(wallet, transactionInfo),
WalletType.zano => zano!.assetOfTransaction(wallet, transactionInfo) ?? CryptoCurrency.zano,
_ => walletTypeToCryptoCurrency(wallet.type)
};
return walletTypeToCryptoCurrency(wallet.type);
}
@@ -317,8 +275,6 @@ abstract class TransactionDetailsViewModelBase with Store {
String get formattedPendingStatus {
switch (wallet.type) {
case WalletType.monero:
case WalletType.haven:
case WalletType.zano:
if (transactionInfo.confirmations >= 0 && transactionInfo.confirmations < 10) {
return ' (${transactionInfo.confirmations}/10)';
}
@@ -358,10 +314,8 @@ abstract class TransactionDetailsViewModelBase with Store {
String get formattedStatus {
if ([
WalletType.monero,
WalletType.haven,
WalletType.wownero,
WalletType.litecoin,
WalletType.zano,
].contains(wallet.type)) {
return formattedPendingStatus;
}
@@ -372,8 +326,6 @@ abstract class TransactionDetailsViewModelBase with Store {
int get neededConfirmations {
switch (wallet.type) {
case WalletType.monero:
case WalletType.haven:
case WalletType.zano:
return 10;
case WalletType.wownero:
return 3;
@@ -423,8 +375,6 @@ abstract class TransactionDetailsViewModelBase with Store {
: 'https://blockchair.com/litecoin/transaction/${txId}';
case WalletType.bitcoinCash:
return 'https://blockchair.com/bitcoin-cash/transaction/${txId}';
case WalletType.haven:
return 'https://explorer.havenprotocol.org/search?value=${txId}';
case WalletType.ethereum:
return 'https://etherscan.io/tx/${txId}';
case WalletType.base:
@@ -439,20 +389,10 @@ abstract class TransactionDetailsViewModelBase with Store {
return 'https://nanexplorer.com/nano/block/${txId}';
case WalletType.banano:
return 'https://nanexplorer.com/banano/block/${txId}';
case WalletType.solana:
return 'https://solscan.io/tx/${txId}';
case WalletType.tron:
return 'https://tronscan.org/#/transaction/${txId}';
case WalletType.wownero:
return 'https://explore.wownero.com/tx/${txId}';
case WalletType.zano:
return 'https://explorer.zano.org/transaction/${txId}';
case WalletType.decred:
return 'https://${wallet.isTestnet ? "testnet" : "dcrdata"}.decred.org/tx/${txId.split(':')[0]}';
case WalletType.dogecoin:
return 'https://blockchair.com/dogecoin/transaction/${txId}';
case WalletType.zcash:
return 'https://blockchair.com/zcash/transaction/${txId}';
case WalletType.none:
return '';
}

View File

@@ -5,7 +5,6 @@ import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:hash_wallet/utils/exception_handler.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/view_model/unspent_coins/unspent_coins_item.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:cw_core/balance.dart';
@@ -152,9 +151,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(wallet.type)) {
await bitcoin!.updateUnspents(wallet);
}
if (wallet.type == WalletType.decred) {
decred!.updateUnspents(wallet);
}
_updateUnspentCoinsInfo();
}
@@ -169,8 +165,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
case WalletType.bitcoinCash:
case WalletType.dogecoin:
return bitcoin!.getUnspents(wallet, coinTypeToSpendFrom: coinTypeToSpendFrom);
case WalletType.decred:
return decred!.getUnspents(wallet);
default:
return List.empty();
}
@@ -187,8 +181,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
case WalletType.bitcoinCash:
case WalletType.dogecoin:
return bitcoin!.getUnspents(wallet, coinTypeToSpendFrom: overrideCoinTypeToSpendFrom);
case WalletType.decred:
return decred!.getUnspents(wallet);
default:
return List.empty();
}

View File

@@ -4,7 +4,6 @@ import 'package:mobx/mobx.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:hash_wallet/bitcoin/bitcoin.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:cw_core/wallet_type.dart';
part 'wallet_address_edit_or_create_view_model.g.dart';
@@ -78,11 +77,6 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
await wallet.save();
}
if (wallet.type == WalletType.decred) {
await decred!.generateNewAddress(wallet, label);
await wallet.save();
}
if (wallet.type == WalletType.monero) {
await monero!
.getSubaddressList(wallet)
@@ -115,12 +109,6 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
if (isElectrum) await bitcoin!.updateAddress(wallet, _item!.address, label);
if (wallet.type == WalletType.decred) {
await decred!.updateAddress(wallet, _item!.address, label);
await wallet.save();
return;
}
final index = _item?.id;
if (index != null) {
if (wallet.type == WalletType.monero) {

View File

@@ -4,7 +4,6 @@ import 'dart:developer' as dev;
import 'package:hash_wallet/bitcoin/bitcoin.dart';
import 'package:hash_wallet/core/fiat_conversion_service.dart';
import 'package:hash_wallet/core/wallet_change_listener_view_model.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/entities/auto_generate_subaddress_status.dart';
import 'package:hash_wallet/entities/fiat_api_mode.dart';
import 'package:hash_wallet/entities/fiat_currency.dart';
@@ -13,11 +12,9 @@ import 'package:hash_wallet/generated/i18n.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/reactions/wallet_utils.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:hash_wallet/store/yat/yat_store.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/utils/list_item.dart';
import 'package:hash_wallet/utils/qr_util.dart';
import 'package:hash_wallet/view_model/wallet_address_list/wallet_account_list_header.dart';
@@ -26,8 +23,6 @@ import 'package:hash_wallet/view_model/wallet_address_list/wallet_address_list_h
import 'package:hash_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
import 'package:hash_wallet/view_model/wallet_address_list/wallet_address_util.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/currency.dart';
import 'package:cw_core/currency_for_wallet_type.dart';
@@ -62,7 +57,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
_init();
selectedCurrency = wallet.currency;
hasAccounts = [WalletType.monero, WalletType.wownero, WalletType.haven].contains(wallet.type);
hasAccounts = [WalletType.monero, WalletType.wownero].contains(wallet.type);
}
final FiatConversionStore fiatConversionStore;
@@ -318,12 +313,6 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
}
if (wallet.type == WalletType.solana) {
final primaryAddress = solana!.getAddress(wallet);
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
}
if (wallet.type == WalletType.nano) {
addressList.add(WalletAddressListItem(
isPrimary: true,
@@ -332,28 +321,6 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
));
}
if (wallet.type == WalletType.tron) {
final primaryAddress = tron!.getAddress(wallet);
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
}
if (wallet.type == WalletType.decred) {
final addrInfos = decred!.getAddressInfos(wallet);
addrInfos.forEach((info) {
addressList.add(
new WalletAddressListItem(isPrimary: false, address: info.address, name: info.label));
});
}
if (wallet.type == WalletType.zcash) {
final addrInfos = zcash!.getAddressInfos(wallet);
addrInfos.forEach((info) {
addressList.add(
new WalletAddressListItem(isPrimary: false, address: info.address, name: info.label));
});
}
for (var i = 0; i < addressList.length; i++) {
if (!(addressList[i] is WalletAddressListItem)) continue;
final item = addressList[i] as WalletAddressListItem;
@@ -367,12 +334,6 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
.contains((addressList[i] as WalletAddressListItem).address);
}
if (wallet.type == WalletType.zano) {
final primaryAddress = zano!.getAddress(wallet);
addressList.add(WalletAddressListItem(isPrimary: true, name: null, address: primaryAddress));
}
if (searchText.isNotEmpty) {
return ObservableList.of(addressList.where((item) {
if (item is WalletAddressListItem) {
@@ -445,17 +406,14 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
bool get hasAddressList => [
WalletType.monero,
WalletType.wownero,
WalletType.haven,
WalletType.bitcoinCash,
WalletType.bitcoin,
WalletType.litecoin,
WalletType.decred,
WalletType.dogecoin,
WalletType.zcash
].contains(wallet.type) && !isLightning && isZCashTransparent;
].contains(wallet.type) && !isLightning;
@computed
bool get hasAddressRotation => hasAddressList && wallet.type != WalletType.zcash;
bool get hasAddressRotation => hasAddressList;
@computed
bool get isElectrumWallet => [
@@ -513,25 +471,6 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
}
switch (wallet.type) {
case WalletType.solana:
return [
'assets/images/sol_icon.svg',
'assets/images/usdc_icon.svg',
'assets/images/usdt_wallet_icon.svg',
'assets/images/more_tokens.svg',
];
case WalletType.tron:
return [
'assets/images/trx_icon.svg',
'assets/images/usdc_icon.svg',
'assets/images/usdt_wallet_icon.svg',
'assets/images/more_tokens.svg',
];
case WalletType.zano:
return [
'assets/images/zano_icon.svg',
'assets/images/more_tokens.svg',
];
default:
return [];
}
@@ -559,15 +498,6 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
@computed
bool get isLightning => wallet.type == WalletType.bitcoin && (wallet.walletAddresses.getPaymentUri(_amount) is LightningPaymentRequest);
@computed
bool get isZCashTransparent {
if(wallet.type != WalletType.zcash) {
return true;
}
receivePageOption;
return wallet.type == WalletType.zcash && zcash!.hasSelectedTransparentAddress(wallet);
}
@observable
String receivePageOption;
@@ -609,9 +539,6 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
if ([WalletType.bitcoin, WalletType.litecoin].contains(wallet.type)) {
await bitcoin!.setAddressType(wallet, option);
}
if (wallet.type == WalletType.zcash) {
await zcash!.setAddressType(wallet, option);
}
}
void _init() {
@@ -624,7 +551,6 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
if ([
WalletType.monero,
WalletType.wownero,
WalletType.haven,
].contains(wallet.type)) {
_baseItems.add(WalletAccountListHeader());
}

View File

@@ -1,5 +1,4 @@
import 'package:hash_wallet/bitcoin/bitcoin.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:cw_core/wallet_base.dart';
@@ -16,11 +15,6 @@ Future<void> createNewAddress(WalletBase wallet, String label) async {
await wallet.save();
}
if (wallet.type == WalletType.decred) {
await decred!.generateNewAddress(wallet, label);
await wallet.save();
}
if (wallet.type == WalletType.monero) {
await monero!
.getSubaddressList(wallet)

View File

@@ -118,7 +118,7 @@ abstract class WalletCreationVMBase with Store {
path: path,
dirPath: dirPath,
address: '',
showIntroCakePayCard: (!await walletCreationService.typeExists(type)) && type != WalletType.haven,
showIntroCakePayCard: !await walletCreationService.typeExists(type),
derivationInfoId: diId,
hardwareWalletType: credentials.hardwareWalletType,
);

View File

@@ -4,8 +4,6 @@ import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/src/screens/transaction_details/standart_list_item.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/wallet_base.dart';
@@ -14,7 +12,6 @@ import 'package:cw_core/wallet_type.dart';
import 'package:cw_monero/monero_wallet.dart';
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:polyseed/polyseed.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
@@ -38,7 +35,6 @@ abstract class WalletKeysViewModelBase with Store {
});
if (_wallet.type == WalletType.monero ||
_wallet.type == WalletType.haven ||
_wallet.type == WalletType.wownero) {
final accountTransactions = _getWalletTransactions(_wallet);
if (accountTransactions.isNotEmpty) {
@@ -85,7 +81,7 @@ abstract class WalletKeysViewModelBase with Store {
bool get isBitcoin => _wallet.type == WalletType.bitcoin;
// this is incomplete, needs legacy seed toggle for XMR
bool get shouldShowHeightBox => [WalletType.bitcoin, WalletType.zcash].contains(_wallet.type);
bool get shouldShowHeightBox => [WalletType.bitcoin].contains(_wallet.type);
final ObservableList<StandartListItem> items;
@observable
@@ -160,19 +156,11 @@ abstract class WalletKeysViewModelBase with Store {
case WalletType.wownero:
keys = wownero!.getKeys(_wallet);
break;
case WalletType.zano:
keys = zano!.getKeys(_wallet);
break;
case WalletType.zcash:
keys = zcash!.getKeys(_wallet);
break;
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.solana:
case WalletType.tron:
items.addAll([
if (_wallet.privateKey != null)
StandartListItem(
@@ -200,12 +188,6 @@ abstract class WalletKeysViewModelBase with Store {
),
]);
break;
case WalletType.decred:
final pubkey = decred!.pubkey(_appStore.wallet!);
items.addAll([
StandartListItem(title: S.current.view_key_public, value: pubkey),
]);
break;
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.bitcoinCash:
@@ -228,7 +210,6 @@ abstract class WalletKeysViewModelBase with Store {
]);
break;
case WalletType.none:
case WalletType.haven:
break;
}
@@ -297,8 +278,6 @@ abstract class WalletKeysViewModelBase with Store {
return 'bitcoin-wallet';
case WalletType.litecoin:
return 'litecoin-wallet';
case WalletType.haven:
return 'haven-wallet';
case WalletType.ethereum:
return 'ethereum-wallet';
case WalletType.bitcoinCash:
@@ -315,20 +294,10 @@ abstract class WalletKeysViewModelBase with Store {
return 'arbitrum-wallet';
case WalletType.bsc:
return 'bsc-wallet';
case WalletType.solana:
return 'solana-wallet';
case WalletType.tron:
return 'tron-wallet';
case WalletType.wownero:
return 'wownero-wallet';
case WalletType.zano:
return 'zano-wallet';
case WalletType.decred:
return 'decred-wallet';
case WalletType.dogecoin:
return 'dogecoin-wallet';
case WalletType.zcash:
return 'zcash-wallet';
case WalletType.none:
throw Exception('Unexpected wallet type: ${_wallet.type.toString()} for wallet keys');
}
@@ -341,9 +310,6 @@ abstract class WalletKeysViewModelBase with Store {
if (_wallet.type == WalletType.wownero) {
return wownero!.getRestoreHeight(_wallet)?.toString();
}
if (_wallet.type == WalletType.zcash) {
return zcash!.getKeys(_wallet)["restoreHeight"]?.toString();
}
if (_restoreHeightByTransactions != 0)
return getRoundedRestoreHeight(_restoreHeightByTransactions);
if (_restoreHeight != 0) return _restoreHeight.toString();

View File

@@ -75,9 +75,6 @@ abstract class WalletListViewModelBase with Store {
@action
Future<void> loadWallet(WalletListItem walletItem) async {
if (walletItem.type == WalletType.haven) {
return;
}
// bool switchingToSameWalletType = walletItem.type == _appStore.wallet?.type;
// await _appStore.wallet?.close(shouldCleanup: !switchingToSameWalletType);
final wallet = await _walletLoadingService.load(walletItem.type, walletItem.name);

View File

@@ -1,12 +1,8 @@
import 'package:hash_wallet/core/new_wallet_arguments.dart';
import 'package:hash_wallet/dogecoin/dogecoin.dart';
import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/bitcoin_cash/bitcoin_cash.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:mobx/mobx.dart';
import 'package:hash_wallet/bitcoin/bitcoin.dart';
import 'package:hash_wallet/core/wallet_creation_service.dart';
@@ -16,7 +12,6 @@ import 'package:hash_wallet/nano/nano.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/view_model/seed_settings_view_model.dart';
import 'package:hash_wallet/view_model/wallet_creation_vm.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_type.dart';
@@ -44,7 +39,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
String selectedMnemonicLanguage;
bool get hasLanguageSelector =>
[WalletType.monero, WalletType.haven, WalletType.wownero].contains(type);
[WalletType.monero, WalletType.wownero].contains(type);
bool get showLanguageSelector => newWalletArguments?.mnemonic == null && hasLanguageSelector;
@@ -112,20 +107,6 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
passphrase: passphrase,
);
case WalletType.solana:
return solana!.createSolanaNewWalletCredentials(
name: name,
password: walletPassword,
mnemonic: newWalletArguments!.mnemonic,
passphrase: passphrase,
);
case WalletType.tron:
return tron!.createTronNewWalletCredentials(
name: name,
password: walletPassword,
mnemonic: newWalletArguments!.mnemonic,
passphrase: passphrase,
);
case WalletType.wownero:
return wownero!.createWowneroNewWalletCredentials(
name: name,
@@ -134,23 +115,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
password: walletPassword,
passphrase: passphrase,
);
case WalletType.zano:
return zano!.createZanoNewWalletCredentials(
name: name,
password: walletPassword,
passphrase: passphrase,
);
case WalletType.zcash:
return zcash!.createZcashNewWalletCredentials(
name: name,
password: walletPassword,
mnemonic: newWalletArguments!.mnemonic,
passphrase: passphrase,
);
case WalletType.decred:
return decred!.createDecredNewWalletCredentials(name: name);
case WalletType.none:
case WalletType.haven:
throw Exception('Unexpected type: ${type.toString()}');
}
}

View File

@@ -8,18 +8,13 @@ import 'package:hash_wallet/evm/evm.dart';
import 'package:hash_wallet/monero/monero.dart';
import 'package:hash_wallet/nano/nano.dart';
import 'package:hash_wallet/reactions/wallet_connect.dart';
import 'package:hash_wallet/solana/solana.dart';
import 'package:hash_wallet/store/app_store.dart';
import 'package:hash_wallet/tron/tron.dart';
import 'package:hash_wallet/decred/decred.dart';
import 'package:hash_wallet/utils/feature_flag.dart';
import 'package:hash_wallet/view_model/restore/restore_mode.dart';
import 'package:hash_wallet/view_model/restore/restore_wallet.dart';
import 'package:hash_wallet/view_model/seed_settings_view_model.dart';
import 'package:hash_wallet/view_model/wallet_creation_vm.dart';
import 'package:hash_wallet/wownero/wownero.dart';
import 'package:hash_wallet/zano/zano.dart';
import 'package:hash_wallet/zcash/zcash.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
@@ -45,23 +40,17 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
break;
case WalletType.nano:
case WalletType.banano:
case WalletType.solana:
case WalletType.tron:
case WalletType.wownero:
case WalletType.haven:
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.base:
case WalletType.arbitrum:
case WalletType.bsc:
case WalletType.decred:
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.zcash:
availableModes = [WalletRestoreMode.seed, WalletRestoreMode.keys];
break;
case WalletType.bitcoinCash:
case WalletType.zano:
case WalletType.dogecoin:
availableModes = [WalletRestoreMode.seed];
break;
@@ -77,14 +66,13 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
}
static const moneroSeedMnemonicLength = 25;
static const decredSeedMnemonicLength = 15;
late List<WalletRestoreMode> availableModes;
late final bool hasSeedLanguageSelector =
[WalletType.monero, WalletType.haven, WalletType.wownero].contains(type);
[WalletType.monero, WalletType.wownero].contains(type);
late final bool hasBlockchainHeightSelector =
[WalletType.monero, WalletType.haven, WalletType.wownero, WalletType.zcash].contains(type);
[WalletType.monero, WalletType.wownero].contains(type);
late final bool hasRestoreFromPrivateKey = [
WalletType.ethereum,
@@ -94,13 +82,10 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
WalletType.bsc,
WalletType.nano,
WalletType.banano,
WalletType.solana,
WalletType.tron,
WalletType.zcash,
].contains(type);
late final bool onlyViewKeyRestore =
[if (FeatureFlag.hasBitcoinViewOnly) WalletType.bitcoin, WalletType.decred].contains(type);
[if (FeatureFlag.hasBitcoinViewOnly) WalletType.bitcoin].contains(type);
final RestoredWallet? restoredWallet;
final HardwareWalletType? hardwareWalletType;
@@ -177,20 +162,6 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
password: password,
passphrase: passphrase,
);
case WalletType.solana:
return solana!.createSolanaRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.tron:
return tron!.createTronRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.wownero:
return wownero!.createWowneroRestoreWalletFromSeedCredentials(
name: name,
@@ -199,30 +170,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
passphrase: passphrase ?? '',
height: height,
);
case WalletType.zano:
return zano!.createZanoRestoreWalletFromSeedCredentials(
name: name,
password: password,
height: height,
passphrase: passphrase ?? '',
mnemonic: seed,
);
case WalletType.decred:
return decred!.createDecredRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
);
case WalletType.zcash:
return zcash!.createZcashRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
height: height,
);
case WalletType.none:
case WalletType.haven:
break;
}
}
@@ -282,18 +230,6 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
password: password,
privateKey: options['private_key'] as String,
);
case WalletType.solana:
return solana!.createSolanaRestoreWalletFromPrivateKey(
name: name,
password: password,
privateKey: options['private_key'] as String,
);
case WalletType.tron:
return tron!.createTronRestoreWalletFromPrivateKey(
name: name,
password: password,
privateKey: options['private_key'] as String,
);
case WalletType.wownero:
return wownero!.createWowneroRestoreWalletFromKeysCredentials(
name: name,
@@ -304,19 +240,6 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
password: password,
language: 'English',
);
case WalletType.decred:
return decred!.createDecredRestoreWalletFromPubkeyCredentials(
name: name,
password: password,
pubkey: viewKey!,
);
case WalletType.zcash:
return zcash!.createZcashRestoreWalletFromPrivateKey(
name: name,
privateKey: options['private_key'] as String,
password: password,
height: height
);
default:
break;
}

View File

@@ -369,26 +369,4 @@ class CWWownero extends Wownero {
Map<String, List<int>> debugCallLength() {
return wownero_wallet_api.debugCallLength();
}
@override
Future<void> backupSeeds(Box<HavenSeedStore> havenSeedStore) async {
final wallets = await WalletInfo.selectList('type = ?', [WalletType.wownero.index]);
final unspentCoinsInfo = await CakeHive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
for (final w in wallets) {
final walletService = WowneroWalletService(unspentCoinsInfo);
final flutterSecureStorage = secureStorageShared;
final keyService = KeyService(flutterSecureStorage);
final password = await keyService.getWalletPassword(walletName: w.name);
String seed = "unknown";
try {
final wallet = await walletService.openWallet(w.name, password);
seed = wallet.seed;
wallet.close();
} catch (e) {
seed += "\n$e";
}
await havenSeedStore.add(HavenSeedStore(id: w.id, seed: seed));
}
await havenSeedStore.flush();
}
}

View File

@@ -1,145 +0,0 @@
part of 'zano.dart';
class CWZano extends Zano {
List<ZanoAsset> getZanoAssets(WalletBase wallet) => (wallet as ZanoWallet).zanoAssets.values.toList();
@override
Future<CryptoCurrency> addZanoAssetById(WalletBase wallet, String assetId) async => await (wallet as ZanoWallet).addZanoAssetById(assetId);
@override
Future<void> changeZanoAssetAvailability(WalletBase wallet, CryptoCurrency token) async => await (wallet as ZanoWallet).changeZanoAssetAvailability(token as ZanoAsset);
@override
Future<void> deleteZanoAsset(WalletBase wallet, CryptoCurrency token) async => await (wallet as ZanoWallet).deleteZanoAsset(token as ZanoAsset);
@override
Future<ZanoAsset?> getZanoAsset(WalletBase wallet, String assetId) async {
final zanoWallet = wallet as ZanoWallet;
return await zanoWallet.getZanoAsset(assetId);
}
// @override
// TransactionHistoryBase getTransactionHistory(Object wallet) {
// final zanoWallet = wallet as ZanoWallet;
// return zanoWallet.transactionHistory;
// }
@override
TransactionPriority getDefaultTransactionPriority() {
return MoneroTransactionPriority.automatic;
}
@override
TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
return MoneroTransactionPriority.deserialize(raw: raw);
}
@override
List<TransactionPriority> getTransactionPriorities() {
return MoneroTransactionPriority.all;
}
@override
List<String> getWordList(String language) {
assert(language.toLowerCase() == LanguageList.english.toLowerCase());
return EnglishMnemonics.words;
}
@override
WalletCredentials createZanoRestoreWalletFromSeedCredentials(
{required String name, required String password, required int height, required String passphrase, required String mnemonic}) {
return ZanoRestoreWalletFromSeedCredentials(name: name, password: password, passphrase: passphrase, height: height, mnemonic: mnemonic);
}
@override
WalletCredentials createZanoNewWalletCredentials({required String name, required String? password, required String? passphrase}) {
return ZanoNewWalletCredentials(name: name, password: password, passphrase: passphrase);
}
@override
Map<String, String> getKeys(Object wallet) {
final zanoWallet = wallet as ZanoWallet;
final keys = zanoWallet.keys;
return <String, String>{
'privateSpendKey': keys.privateSpendKey,
'privateViewKey': keys.privateViewKey,
'publicSpendKey': keys.publicSpendKey,
'publicViewKey': keys.publicViewKey
};
}
@override
Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency}) {
return ZanoTransactionCredentials(
outputs: outputs
.map((out) => OutputInfo(
fiatAmount: out.fiatAmount,
cryptoAmount: out.cryptoAmount,
address: out.address,
note: out.note,
sendAll: out.sendAll,
extractedAddress: out.extractedAddress,
isParsedAddress: out.isParsedAddress,
formattedCryptoAmount: out.formattedCryptoAmount))
.toList(),
priority: priority as MoneroTransactionPriority,
currency: currency,
);
}
@override
double formatterIntAmountToDouble({required int amount, required CryptoCurrency currency, required bool forFee}) {
// fee always counted in zano with default decimal points
if (forFee) return ZanoFormatter.intAmountToDouble(amount);
if (currency is ZanoAsset) return ZanoFormatter.intAmountToDouble(amount, currency.decimalPoint);
return ZanoFormatter.intAmountToDouble(amount);
}
@override
int formatterParseAmount({required String amount, required CryptoCurrency currency}) {
if (currency is ZanoAsset) return ZanoFormatter.parseAmount(amount, currency.decimalPoint);
return ZanoFormatter.parseAmount(amount);
}
// @override
// int getTransactionInfoAccountId(TransactionInfo tx) {
// final zanoTransactionInfo = tx as ZanoTransactionInfo;
// return zanoTransactionInfo.accountIndex;
// }
@override
WalletService createZanoWalletService() {
return ZanoWalletService();
}
@override
CryptoCurrency? assetOfTransaction(WalletBase wallet, TransactionInfo transaction) {
transaction as ZanoTransactionInfo;
if (transaction.tokenSymbol == CryptoCurrency.zano.title) {
return CryptoCurrency.zano;
}
wallet as ZanoWallet;
final asset = wallet.zanoAssets.values.firstWhereOrNull((element) => element?.ticker == transaction.tokenSymbol);
return asset;
}
String getZanoAssetAddress(CryptoCurrency asset) => (asset as ZanoAsset).assetId;
@override
String getAddress(WalletBase wallet) => (wallet as ZanoWallet).walletAddresses.address;
@override
bool validateAddress(String address) => ZanoUtils.validateAddress(address);
@override
Map<String, List<int>> debugCallLength() {
return api.debugCallLength();
}
@override
bool isTokenAlreadyAdded(WalletBase wallet, String contractAddress) {
final zanoWallet = wallet as ZanoWallet;
return zanoWallet.zanoAssets.values.any((element) => element?.assetId == contractAddress);
}
}

File diff suppressed because it is too large Load Diff