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

94 files changed, -5926 net lines. No stubs, no generators, no dead enum
values, no orphan switch branches. Removed for principled reasons (we
do not ship these chains) and to make the codebase smaller and friendlier
to contribute to.

What's gone:
- lib/{solana,tron,zano,decred,zcash,haven}/ directories
- lib/exchange/provider/jupiter_exchange_provider.dart (Solana-only)
- lib/entities/haven_seed_store.dart
- WalletType.{solana,tron,zano,decred,zcash,haven} enum values
  (HiveField IDs are pinned: Wownero stays at 12, all surviving types
  keep their IDs, so existing user-saved wallets deserialize unchanged)
- All ~70 lib/ files that imported the removed chain stubs or branched
  on the removed WalletType values
- backupSeeds(Box<HavenSeedStore>) abstract method + Wownero implementation
- Jupiter exchange branches in send/exchange view models
- TronGrid usage settings, Zano alias lookups, Zcash transparent address
  handling, Decred default-spv-nodes branches, Haven seed migration

What stays (intentional):
- CryptoCurrency.{xhv,sol,trx,dcr,zano,zec} enum entries in cw_core —
  they're still used as exchange/swap currency identifiers in
  address_validator.dart and elsewhere. The wallet types are gone but
  the *currencies* are still tradeable through Trocador.
- cw_core/spl_token.dart and cw_core/tron_token.dart Hive adapters in
  main.dart — the tokens still register as Hive types for backwards-
  compat with any old box data.
- lib/buy/{moonpay,robinhood,onramper,dfx,kryptonim,meld}/ provider
  source files (just stripped of solana/tron/etc references; providers
  themselves remain dormant per provider_types.dart).

Pinned-ID note: WalletType enum now has gaps in @HiveField IDs (4, 10,
11, 13, 14, 18 removed). This is deliberate — re-using a freed ID later
would mis-deserialize old hive boxes. Don't renumber.

Bundled config / CI hasn't changed; configure.dart was already free of
these chains in commit 4eb7db0b7.
This commit is contained in:
jwinterm
2026-05-17 12:30:25 -04:00
parent ac7830e181
commit b57ab7cc06
94 changed files with 228 additions and 6154 deletions
-12
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');
-52
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/
+1 -4
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 => [
+1 -4
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;
+5 -84
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;
}
-8
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}");
@@ -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");
}
}
+1 -10
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:
-1
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,
-16
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 [];
}
}
-6
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;
}
}
-113
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;
}
}
+1 -20
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');
}
+2 -218
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');
}
}
-2
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:
-19
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;
}
-31
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 +
+2 -4
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);
}
}
@@ -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 [];
}
}
@@ -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.');
}
}
-79
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();
}
}
-25
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,
-10
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));
}
}
});
}
-17
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:
@@ -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;
-3
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());
-12
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:
+1 -17
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) {
-17
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);
}
-9
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:
-412
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 (_) {}
}
}
@@ -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;
}
@@ -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();
},
@@ -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));
}
}
});
@@ -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);
}
}
@@ -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(
@@ -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);
},
),
);
},
);
}
@@ -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()}');
}
@@ -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() {
@@ -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(
@@ -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
+1 -4
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(
@@ -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>(),
+43 -71
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(),
@@ -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,
@@ -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,
@@ -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;
@@ -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:
@@ -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",
@@ -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 '';
}
@@ -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
@@ -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");
}
@@ -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);
-169
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:
-156
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);
}
}
-1
View File
@@ -157,7 +157,6 @@ class AddressFormatter {
switch (walletType) {
case WalletType.monero:
case WalletType.wownero:
case WalletType.zano:
return 6;
default:
return 4;
-17
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';
}
+4 -125
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 [];
}
}
@@ -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
@@ -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(
@@ -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(
@@ -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);
}
}
@@ -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
@@ -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;
}
}
+34 -64
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,
@@ -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;
@@ -25,7 +25,6 @@ abstract class SignViewModelBase with Store {
WalletType.bitcoinCash,
WalletType.litecoin,
WalletType.dogecoin,
WalletType.haven,
].contains(wallet.type);
@action
@@ -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;
}
@@ -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;
}
}
@@ -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;
}
@@ -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;
}
}
+1 -51
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,
}
@@ -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)
-16
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;
+1 -42
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();
@@ -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);
}
+8 -244
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
@@ -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;
@@ -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;
@@ -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));
@@ -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);
@@ -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 '';
}
@@ -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();
}
@@ -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) {
@@ -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());
}
@@ -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)
+1 -1
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,
);
+1 -35
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();
@@ -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);
+1 -36
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()}');
}
}
+3 -80
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;
}
-22
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();
}
}
-145
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