diff --git a/lib/db/db_version_migration.dart b/lib/db/db_version_migration.dart
index eb75bf5b1..3cc9b9c3c 100644
--- a/lib/db/db_version_migration.dart
+++ b/lib/db/db_version_migration.dart
@@ -26,13 +26,14 @@ import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/services/mixins/wallet_db.dart';
 import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/services/wallets_service.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:tuple/tuple.dart';
@@ -59,14 +60,16 @@ class DbVersionMigrator with WalletDB {
         ElectrumXClient? client;
         int? latestSetId;
 
+        final firo = Firo(CryptoCurrencyNetwork.main);
         // only instantiate client if there are firo wallets
-        if (walletInfoList.values.any((element) => element.coin == Coin.firo)) {
+        if (walletInfoList.values
+            .any((element) => element.coinIdentifier == firo.identifier)) {
           await Hive.openBox<NodeModel>(DB.boxNameNodeModels);
           await Hive.openBox<NodeModel>(DB.boxNamePrimaryNodes);
-          final node = nodeService.getPrimaryNodeFor(coin: Coin.firo) ??
-              DefaultNodes.firo;
-          List<ElectrumXNode> failovers = nodeService
-              .failoverNodesFor(coin: Coin.firo)
+          final node =
+              nodeService.getPrimaryNodeFor(currency: firo) ?? firo.defaultNode;
+          final List<ElectrumXNode> failovers = nodeService
+              .failoverNodesFor(currency: firo)
               .map(
                 (e) => ElectrumXNode(
                   address: e.host,
@@ -80,11 +83,12 @@ class DbVersionMigrator with WalletDB {
 
           client = ElectrumXClient.from(
             node: ElectrumXNode(
-                address: node.host,
-                port: node.port,
-                name: node.name,
-                id: node.id,
-                useSSL: node.useSSL),
+              address: node.host,
+              port: node.port,
+              name: node.name,
+              id: node.id,
+              useSSL: node.useSSL,
+            ),
             prefs: prefs,
             failovers: failovers,
             cryptoCurrency: Firo(CryptoCurrencyNetwork.main),
@@ -96,26 +100,29 @@ class DbVersionMigrator with WalletDB {
             // default to 2 for now
             latestSetId = 2;
             Logging.instance.log(
-                "Failed to fetch latest coin id during firo db migrate: $e \nUsing a default value of 2",
-                level: LogLevel.Warning);
+              "Failed to fetch latest coin id during firo db migrate: $e \nUsing a default value of 2",
+              level: LogLevel.Warning,
+            );
           }
         }
 
         for (final walletInfo in walletInfoList.values) {
           // migrate each firo wallet's lelantus coins
-          if (walletInfo.coin == Coin.firo) {
+          if (walletInfo.coinIdentifier == firo.identifier) {
             await Hive.openBox<dynamic>(walletInfo.walletId);
             final _lelantusCoins = DB.instance.get<dynamic>(
-                boxName: walletInfo.walletId, key: '_lelantus_coins') as List?;
+              boxName: walletInfo.walletId,
+              key: '_lelantus_coins',
+            ) as List?;
             final List<Map<dynamic, LelantusCoin>> lelantusCoins = [];
-            for (var lCoin in _lelantusCoins ?? []) {
+            for (final lCoin in _lelantusCoins ?? []) {
               lelantusCoins
                   .add({lCoin.keys.first: lCoin.values.first as LelantusCoin});
             }
 
-            List<Map<dynamic, LelantusCoin>> coins = [];
+            final List<Map<dynamic, LelantusCoin>> coins = [];
             for (final element in lelantusCoins) {
-              LelantusCoin coin = element.values.first;
+              final LelantusCoin coin = element.values.first;
               int anonSetId = coin.anonymitySetId;
               if (coin.anonymitySetId == 1 &&
                   (coin.publicCoin == '' ||
@@ -123,21 +130,31 @@ class DbVersionMigrator with WalletDB {
                 anonSetId = latestSetId!;
               }
               coins.add({
-                element.keys.first: LelantusCoin(coin.index, coin.value,
-                    coin.publicCoin, coin.txId, anonSetId, coin.isUsed)
+                element.keys.first: LelantusCoin(
+                  coin.index,
+                  coin.value,
+                  coin.publicCoin,
+                  coin.txId,
+                  anonSetId,
+                  coin.isUsed,
+                ),
               });
             }
             Logger.print("newcoins $coins", normalLength: false);
             await DB.instance.put<dynamic>(
-                boxName: walletInfo.walletId,
-                key: '_lelantus_coins',
-                value: coins);
+              boxName: walletInfo.walletId,
+              key: '_lelantus_coins',
+              value: coins,
+            );
           }
         }
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 1);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 1,
+        );
 
         // try to continue migrating
         return await migrate(1, secureStore: secureStore);
@@ -161,7 +178,10 @@ class DbVersionMigrator with WalletDB {
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 2);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 2,
+        );
 
         // try to continue migrating
         return await migrate(2, secureStore: secureStore);
@@ -176,16 +196,26 @@ class DbVersionMigrator with WalletDB {
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 3);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 3,
+        );
         return await migrate(3, secureStore: secureStore);
 
       case 3:
         // clear possible broken firo cache
-        await DB.instance.clearSharedTransactionCache(coin: Coin.firo);
+        await DB.instance.clearSharedTransactionCache(
+          currency: Firo(
+            CryptoCurrencyNetwork.test,
+          ),
+        );
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 4);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 4,
+        );
 
         // try to continue migrating
         return await migrate(4, secureStore: secureStore);
@@ -196,7 +226,10 @@ class DbVersionMigrator with WalletDB {
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 5);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 5,
+        );
 
         // try to continue migrating
         return await migrate(5, secureStore: secureStore);
@@ -212,11 +245,17 @@ class DbVersionMigrator with WalletDB {
                 "light";
 
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNamePrefs, key: "theme", value: themeName);
+          boxName: DB.boxNamePrefs,
+          key: "theme",
+          value: themeName,
+        );
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 6);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 6,
+        );
 
         // try to continue migrating
         return await migrate(6, secureStore: secureStore);
@@ -287,7 +326,10 @@ class DbVersionMigrator with WalletDB {
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 7);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 7,
+        );
 
         // try to continue migrating
         return await migrate(7, secureStore: secureStore);
@@ -298,7 +340,10 @@ class DbVersionMigrator with WalletDB {
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 8);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 8,
+        );
 
         // try to continue migrating
         return await migrate(8, secureStore: secureStore);
@@ -311,8 +356,10 @@ class DbVersionMigrator with WalletDB {
         await MainDB.instance.initMainDB();
         for (final walletId in walletInfoList.keys) {
           final info = walletInfoList[walletId]!;
-          if (info.coin == Coin.bitcoincash ||
-              info.coin == Coin.bitcoincashTestnet) {
+          if (info.coinIdentifier ==
+                  Bitcoincash(CryptoCurrencyNetwork.main).identifier ||
+              info.coinIdentifier ==
+                  Bitcoincash(CryptoCurrencyNetwork.test).identifier) {
             final ids = await MainDB.instance
                 .getAddresses(walletId)
                 .filter()
@@ -328,7 +375,10 @@ class DbVersionMigrator with WalletDB {
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 9);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 9,
+        );
 
         // try to continue migrating
         return await migrate(9, secureStore: secureStore);
@@ -339,7 +389,10 @@ class DbVersionMigrator with WalletDB {
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 10);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 10,
+        );
 
         // try to continue migrating
         return await migrate(10, secureStore: secureStore);
@@ -350,7 +403,10 @@ class DbVersionMigrator with WalletDB {
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 11);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 11,
+        );
 
         // try to continue migrating
         return await migrate(11, secureStore: secureStore);
@@ -361,7 +417,10 @@ class DbVersionMigrator with WalletDB {
 
         // update version
         await DB.instance.put<dynamic>(
-            boxName: DB.boxNameDBInfo, key: "hive_data_version", value: 12);
+          boxName: DB.boxNameDBInfo,
+          key: "hive_data_version",
+          value: 12,
+        );
 
         // try to continue migrating
         return await migrate(12, secureStore: secureStore);
@@ -392,7 +451,8 @@ class DbVersionMigrator with WalletDB {
 
       // we need to manually migrate epic cash transactions as they are not
       // stored on the epic cash blockchain
-      if (info.coin == Coin.epicCash) {
+      final epic = Epiccash(CryptoCurrencyNetwork.main);
+      if (info.coinIdentifier == epic.identifier) {
         final txnData = walletBox.get("latest_tx_model") as TransactionData?;
 
         // we ever only used index 0 in the past
@@ -404,7 +464,7 @@ class DbVersionMigrator with WalletDB {
           final txns = txnData.getAllTransactions();
 
           for (final tx in txns.values) {
-            bool isIncoming = tx.txType == "Received";
+            final bool isIncoming = tx.txType == "Received";
 
             final iTx = isar_models.Transaction(
               walletId: walletId,
@@ -417,7 +477,7 @@ class DbVersionMigrator with WalletDB {
               amount: tx.amount,
               amountString: Amount(
                 rawValue: BigInt.from(tx.amount),
-                fractionDigits: info.coin.decimals,
+                fractionDigits: epic.fractionDigits,
               ).toJsonString(),
               fee: tx.fees,
               height: tx.height,
@@ -470,12 +530,14 @@ class DbVersionMigrator with WalletDB {
       if ((await secureStore.read(key: '${walletId}_mnemonicPassphrase')) ==
           null) {
         await secureStore.write(
-            key: '${walletId}_mnemonicPassphrase', value: "");
+          key: '${walletId}_mnemonicPassphrase',
+          value: "",
+        );
       }
 
       // doing this for epic cash will delete transaction history as it is not
       // stored on the epic cash blockchain
-      if (info.coin != Coin.epicCash) {
+      if (info.coinIdentifier != epic.identifier) {
         // set flag to initiate full rescan on opening wallet
         await DB.instance.put<dynamic>(
           boxName: DB.boxNameDBInfo,
@@ -498,6 +560,8 @@ class DbVersionMigrator with WalletDB {
 
       final count = await MainDB.instance.getTransactions(walletId).count();
 
+      final crypto = SupportedCoins.getCryptoCurrencyFor(info.coinIdentifier);
+
       for (var i = 0; i < count; i += 50) {
         final txns = await MainDB.instance
             .getTransactions(walletId)
@@ -512,7 +576,7 @@ class DbVersionMigrator with WalletDB {
                 tx
                   ..amountString = Amount(
                     rawValue: BigInt.from(tx.amount),
-                    fractionDigits: info.coin.decimals,
+                    fractionDigits: crypto.fractionDigits,
                   ).toJsonString(),
                 tx.address.value,
               ),
@@ -531,11 +595,13 @@ class DbVersionMigrator with WalletDB {
 
     final keys = List<String>.from(addressBookBox.keys);
     final contacts = keys
-        .map((id) => Contact.fromJson(
-              Map<String, dynamic>.from(
-                addressBookBox.get(id) as Map,
-              ),
-            ))
+        .map(
+          (id) => Contact.fromJson(
+            Map<String, dynamic>.from(
+              addressBookBox.get(id) as Map,
+            ),
+          ),
+        )
         .toList(growable: false);
 
     final List<isar_contact.ContactEntry> newContacts = [];
@@ -547,7 +613,7 @@ class DbVersionMigrator with WalletDB {
       for (final entry in contact.addresses) {
         newContactAddressEntries.add(
           isar_contact.ContactAddressEntry()
-            ..coinName = entry.coin.name
+            ..coinName = entry.coin.identifier
             ..address = entry.address
             ..label = entry.label
             ..other = entry.other,
@@ -580,11 +646,13 @@ class DbVersionMigrator with WalletDB {
     await prefs.init();
     await MainDB.instance.initMainDB();
 
+    final firo = Firo(CryptoCurrencyNetwork.main);
+
     for (final walletId in walletInfoList.keys) {
       final info = walletInfoList[walletId]!;
       assert(info.walletId == walletId);
 
-      if (info.coin == Coin.firo &&
+      if (info.coinIdentifier == firo.identifier &&
           MainDB.instance.isar.lelantusCoins
                   .where()
                   .walletIdEqualTo(walletId)
diff --git a/lib/db/hive/db.dart b/lib/db/hive/db.dart
index 6f4ebd3c3..f63c00e94 100644
--- a/lib/db/hive/db.dart
+++ b/lib/db/hive/db.dart
@@ -18,8 +18,10 @@ import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/models/notification_model.dart';
 import 'package:stackwallet/models/trade_wallet_lookup.dart';
 import 'package:stackwallet/services/wallets_service.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class DB {
   // legacy (required for migrations)
@@ -48,17 +50,18 @@ class DB {
   static const String boxNamePrefs = "prefs";
   static const String boxNameOneTimeDialogsShown = "oneTimeDialogsShown";
 
-  String _boxNameTxCache({required Coin coin}) => "${coin.name}_txCache";
+  String _boxNameTxCache({required CryptoCurrency currency}) =>
+      "${currency.identifier}_txCache";
 
   // firo only
-  String _boxNameSetCache({required Coin coin}) =>
-      "${coin.name}_anonymitySetCache";
-  String _boxNameSetSparkCache({required Coin coin}) =>
-      "${coin.name}_anonymitySetSparkCache";
-  String _boxNameUsedSerialsCache({required Coin coin}) =>
-      "${coin.name}_usedSerialsCache";
-  String _boxNameSparkUsedCoinsTagsCache({required Coin coin}) =>
-      "${coin.name}_sparkUsedCoinsTagsCache";
+  String _boxNameSetCache({required CryptoCurrency currency}) =>
+      "${currency.identifier}_anonymitySetCache";
+  String _boxNameSetSparkCache({required CryptoCurrency currency}) =>
+      "${currency.identifier}_anonymitySetSparkCache";
+  String _boxNameUsedSerialsCache({required CryptoCurrency currency}) =>
+      "${currency.identifier}_usedSerialsCache";
+  String _boxNameSparkUsedCoinsTagsCache({required CryptoCurrency currency}) =>
+      "${currency.identifier}_sparkUsedCoinsTagsCache";
 
   Box<NodeModel>? _boxNodeModels;
   Box<NodeModel>? _boxPrimaryNodes;
@@ -77,11 +80,11 @@ class DB {
 
   final Map<String, Box<dynamic>> _walletBoxes = {};
 
-  final Map<Coin, Box<dynamic>> _txCacheBoxes = {};
-  final Map<Coin, Box<dynamic>> _setCacheBoxes = {};
-  final Map<Coin, Box<dynamic>> _setSparkCacheBoxes = {};
-  final Map<Coin, Box<dynamic>> _usedSerialsCacheBoxes = {};
-  final Map<Coin, Box<dynamic>> _getSparkUsedCoinsTagsCacheBoxes = {};
+  final Map<String, Box<dynamic>> _txCacheBoxes = {};
+  final Map<String, Box<dynamic>> _setCacheBoxes = {};
+  final Map<String, Box<dynamic>> _setSparkCacheBoxes = {};
+  final Map<String, Box<dynamic>> _usedSerialsCacheBoxes = {};
+  final Map<String, Box<dynamic>> _getSparkUsedCoinsTagsCacheBoxes = {};
 
   // exposed for monero
   Box<xmr.WalletInfo> get moneroWalletInfoBox => _walletInfoSource!;
@@ -97,7 +100,8 @@ class DB {
     // TODO: make sure this works properly
     if (Isolate.current.debugName != "main") {
       throw Exception(
-          "DB.instance should not be accessed outside the main isolate!");
+        "DB.instance should not be accessed outside the main isolate!",
+      );
     }
 
     return _instance;
@@ -160,17 +164,22 @@ class DB {
     names.removeWhere((name, dyn) {
       final jsonObject = Map<String, dynamic>.from(dyn as Map);
       try {
-        Coin.values.byName(jsonObject["coin"] as String);
+        SupportedCoins.getCryptoCurrencyFor(jsonObject["coin"] as String);
         return false;
       } catch (e, s) {
         Logging.instance.log(
-            "Error, ${jsonObject["coin"]} does not exist, $name wallet cannot be loaded",
-            level: LogLevel.Error);
+          "Error, ${jsonObject["coin"]} does not exist, $name wallet cannot be loaded",
+          level: LogLevel.Error,
+        );
         return true;
       }
     });
-    final mapped = Map<String, dynamic>.from(names).map((name, dyn) => MapEntry(
-        name, WalletInfo.fromJson(Map<String, dynamic>.from(dyn as Map))));
+    final mapped = Map<String, dynamic>.from(names).map(
+      (name, dyn) => MapEntry(
+        name,
+        WalletInfo.fromJson(Map<String, dynamic>.from(dyn as Map)),
+      ),
+    );
 
     for (final entry in mapped.entries) {
       if (Hive.isBoxOpen(entry.value.walletId)) {
@@ -183,70 +192,90 @@ class DB {
     }
   }
 
-  Future<Box<dynamic>> getTxCacheBox({required Coin coin}) async {
-    if (_txCacheBoxes[coin]?.isOpen != true) {
-      _txCacheBoxes.remove(coin);
+  Future<Box<dynamic>> getTxCacheBox({required CryptoCurrency currency}) async {
+    if (_txCacheBoxes[currency.identifier]?.isOpen != true) {
+      _txCacheBoxes.remove(currency.identifier);
     }
-    return _txCacheBoxes[coin] ??=
-        await Hive.openBox<dynamic>(_boxNameTxCache(coin: coin));
+    return _txCacheBoxes[currency.identifier] ??=
+        await Hive.openBox<dynamic>(_boxNameTxCache(currency: currency));
   }
 
-  Future<void> closeTxCacheBox({required Coin coin}) async {
-    await _txCacheBoxes[coin]?.close();
+  Future<void> closeTxCacheBox({required CryptoCurrency currency}) async {
+    await _txCacheBoxes[currency.identifier]?.close();
   }
 
-  Future<Box<dynamic>> getAnonymitySetCacheBox({required Coin coin}) async {
-    if (_setCacheBoxes[coin]?.isOpen != true) {
-      _setCacheBoxes.remove(coin);
+  Future<Box<dynamic>> getAnonymitySetCacheBox({
+    required CryptoCurrency currency,
+  }) async {
+    if (_setCacheBoxes[currency.identifier]?.isOpen != true) {
+      _setCacheBoxes.remove(currency.identifier);
     }
-    return _setCacheBoxes[coin] ??=
-        await Hive.openBox<dynamic>(_boxNameSetCache(coin: coin));
+    return _setCacheBoxes[currency.identifier] ??=
+        await Hive.openBox<dynamic>(_boxNameSetCache(currency: currency));
   }
 
-  Future<Box<dynamic>> getSparkAnonymitySetCacheBox(
-      {required Coin coin}) async {
-    if (_setSparkCacheBoxes[coin]?.isOpen != true) {
-      _setSparkCacheBoxes.remove(coin);
+  Future<Box<dynamic>> getSparkAnonymitySetCacheBox({
+    required CryptoCurrency currency,
+  }) async {
+    if (_setSparkCacheBoxes[currency.identifier]?.isOpen != true) {
+      _setSparkCacheBoxes.remove(currency.identifier);
     }
-    return _setSparkCacheBoxes[coin] ??=
-        await Hive.openBox<dynamic>(_boxNameSetSparkCache(coin: coin));
+    return _setSparkCacheBoxes[currency.identifier] ??=
+        await Hive.openBox<dynamic>(_boxNameSetSparkCache(currency: currency));
   }
 
-  Future<void> closeAnonymitySetCacheBox({required Coin coin}) async {
-    await _setCacheBoxes[coin]?.close();
+  Future<void> closeAnonymitySetCacheBox({
+    required CryptoCurrency currency,
+  }) async {
+    await _setCacheBoxes[currency.identifier]?.close();
   }
 
-  Future<Box<dynamic>> getUsedSerialsCacheBox({required Coin coin}) async {
-    if (_usedSerialsCacheBoxes[coin]?.isOpen != true) {
-      _usedSerialsCacheBoxes.remove(coin);
+  Future<Box<dynamic>> getUsedSerialsCacheBox({
+    required CryptoCurrency currency,
+  }) async {
+    if (_usedSerialsCacheBoxes[currency.identifier]?.isOpen != true) {
+      _usedSerialsCacheBoxes.remove(currency.identifier);
     }
-    return _usedSerialsCacheBoxes[coin] ??=
-        await Hive.openBox<dynamic>(_boxNameUsedSerialsCache(coin: coin));
-  }
-
-  Future<Box<dynamic>> getSparkUsedCoinsTagsCacheBox(
-      {required Coin coin}) async {
-    if (_getSparkUsedCoinsTagsCacheBoxes[coin]?.isOpen != true) {
-      _getSparkUsedCoinsTagsCacheBoxes.remove(coin);
-    }
-    return _getSparkUsedCoinsTagsCacheBoxes[coin] ??=
+    return _usedSerialsCacheBoxes[currency.identifier] ??=
         await Hive.openBox<dynamic>(
-            _boxNameSparkUsedCoinsTagsCache(coin: coin));
+      _boxNameUsedSerialsCache(currency: currency),
+    );
   }
 
-  Future<void> closeUsedSerialsCacheBox({required Coin coin}) async {
-    await _usedSerialsCacheBoxes[coin]?.close();
+  Future<Box<dynamic>> getSparkUsedCoinsTagsCacheBox({
+    required CryptoCurrency currency,
+  }) async {
+    if (_getSparkUsedCoinsTagsCacheBoxes[currency.identifier]?.isOpen != true) {
+      _getSparkUsedCoinsTagsCacheBoxes.remove(currency.identifier);
+    }
+    return _getSparkUsedCoinsTagsCacheBoxes[currency.identifier] ??=
+        await Hive.openBox<dynamic>(
+      _boxNameSparkUsedCoinsTagsCache(currency: currency),
+    );
+  }
+
+  Future<void> closeUsedSerialsCacheBox({
+    required CryptoCurrency currency,
+  }) async {
+    await _usedSerialsCacheBoxes[currency.identifier]?.close();
   }
 
   /// Clear all cached transactions for the specified coin
-  Future<void> clearSharedTransactionCache({required Coin coin}) async {
-    await deleteAll<dynamic>(boxName: _boxNameTxCache(coin: coin));
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
-      await deleteAll<dynamic>(boxName: _boxNameSetCache(coin: coin));
-      await deleteAll<dynamic>(boxName: _boxNameSetSparkCache(coin: coin));
-      await deleteAll<dynamic>(boxName: _boxNameUsedSerialsCache(coin: coin));
+  Future<void> clearSharedTransactionCache({
+    required CryptoCurrency currency,
+  }) async {
+    await deleteAll<dynamic>(boxName: _boxNameTxCache(currency: currency));
+    if (currency is Firo) {
+      await deleteAll<dynamic>(boxName: _boxNameSetCache(currency: currency));
       await deleteAll<dynamic>(
-          boxName: _boxNameSparkUsedCoinsTagsCache(coin: coin));
+        boxName: _boxNameSetSparkCache(currency: currency),
+      );
+      await deleteAll<dynamic>(
+        boxName: _boxNameUsedSerialsCache(currency: currency),
+      );
+      await deleteAll<dynamic>(
+        boxName: _boxNameSparkUsedCoinsTagsCache(currency: currency),
+      );
     }
   }
 
@@ -284,23 +313,28 @@ class DB {
 
   // writes
 
-  Future<void> put<T>(
-          {required String boxName,
-          required dynamic key,
-          required T value}) async =>
+  Future<void> put<T>({
+    required String boxName,
+    required dynamic key,
+    required T value,
+  }) async =>
       await mutex
           .protect(() async => await Hive.box<T>(boxName).put(key, value));
 
   Future<void> add<T>({required String boxName, required T value}) async =>
       await mutex.protect(() async => await Hive.box<T>(boxName).add(value));
 
-  Future<void> addAll<T>(
-          {required String boxName, required Iterable<T> values}) async =>
+  Future<void> addAll<T>({
+    required String boxName,
+    required Iterable<T> values,
+  }) async =>
       await mutex
           .protect(() async => await Hive.box<T>(boxName).addAll(values));
 
-  Future<void> delete<T>(
-          {required dynamic key, required String boxName}) async =>
+  Future<void> delete<T>({
+    required dynamic key,
+    required String boxName,
+  }) async =>
       await mutex.protect(() async => await Hive.box<T>(boxName).delete(key));
 
   Future<void> deleteAll<T>({required String boxName}) async {
diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart
index ac5a544f4..62673b004 100644
--- a/lib/db/isar/main_db.dart
+++ b/lib/db/isar/main_db.dart
@@ -19,8 +19,8 @@ import 'package:stackwallet/models/isar/models/isar_models.dart';
 import 'package:stackwallet/models/isar/ordinal.dart';
 import 'package:stackwallet/models/isar/stack_theme.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/stack_file_system.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/models/frost_wallet_info.dart';
 import 'package:stackwallet/wallets/isar/models/spark_coin.dart';
 import 'package:stackwallet/wallets/isar/models/token_wallet_info.dart';
@@ -149,15 +149,17 @@ class MainDB {
   }
 
   // tx block explorers
-  TransactionBlockExplorer? getTransactionBlockExplorer({required Coin coin}) {
+  TransactionBlockExplorer? getTransactionBlockExplorer(
+      {required CryptoCurrency cryptoCurrency}) {
     return isar.transactionBlockExplorers
         .where()
-        .tickerEqualTo(coin.ticker)
+        .tickerEqualTo(cryptoCurrency.ticker)
         .findFirstSync();
   }
 
   Future<int> putTransactionBlockExplorer(
-      TransactionBlockExplorer explorer) async {
+    TransactionBlockExplorer explorer,
+  ) async {
     try {
       return await isar.writeTxn(() async {
         return await isar.transactionBlockExplorers.put(explorer);
@@ -169,7 +171,8 @@ class MainDB {
 
   // addresses
   QueryBuilder<Address, Address, QAfterWhereClause> getAddresses(
-          String walletId) =>
+    String walletId,
+  ) =>
       isar.addresses.where().walletIdEqualTo(walletId);
 
   Future<int> putAddress(Address address) async {
@@ -194,7 +197,7 @@ class MainDB {
 
   Future<List<int>> updateOrPutAddresses(List<Address> addresses) async {
     try {
-      List<int> ids = [];
+      final List<int> ids = [];
       await isar.writeTxn(() async {
         for (final address in addresses) {
           final storedAddress = await isar.addresses
@@ -239,13 +242,16 @@ class MainDB {
       });
     } catch (e) {
       throw MainDBException(
-          "failed updateAddress: from=$oldAddress to=$newAddress", e);
+        "failed updateAddress: from=$oldAddress to=$newAddress",
+        e,
+      );
     }
   }
 
   // transactions
   QueryBuilder<Transaction, Transaction, QAfterWhereClause> getTransactions(
-          String walletId) =>
+    String walletId,
+  ) =>
       isar.transactions.where().walletIdEqualTo(walletId);
 
   Future<int> putTransaction(Transaction transaction) async {
@@ -284,7 +290,9 @@ class MainDB {
       isar.utxos.where().walletIdEqualTo(walletId);
 
   QueryBuilder<UTXO, UTXO, QAfterFilterCondition> getUTXOsByAddress(
-          String walletId, String address) =>
+    String walletId,
+    String address,
+  ) =>
       isar.utxos
           .where()
           .walletIdEqualTo(walletId)
@@ -357,7 +365,9 @@ class MainDB {
       });
 
   Future<TransactionNote?> getTransactionNote(
-      String walletId, String txid) async {
+    String walletId,
+    String txid,
+  ) async {
     return isar.transactionNotes.getByTxidWalletId(
       txid,
       walletId,
@@ -374,7 +384,8 @@ class MainDB {
 
   // address labels
   QueryBuilder<AddressLabel, AddressLabel, QAfterWhereClause> getAddressLabels(
-          String walletId) =>
+    String walletId,
+  ) =>
       isar.addressLabels.where().walletIdEqualTo(walletId);
 
   Future<int> putAddressLabel(AddressLabel addressLabel) =>
@@ -392,7 +403,9 @@ class MainDB {
       });
 
   Future<AddressLabel?> getAddressLabel(
-      String walletId, String addressString) async {
+    String walletId,
+    String addressString,
+  ) async {
     return isar.addressLabels.getByAddressStringWalletId(
       addressString,
       walletId,
@@ -573,7 +586,7 @@ class MainDB {
     List<TransactionV2> transactions,
   ) async {
     try {
-      List<int> ids = [];
+      final List<int> ids = [];
       await isar.writeTxn(() async {
         for (final tx in transactions) {
           final storedTx = await isar.transactionV2s
@@ -595,7 +608,9 @@ class MainDB {
       return ids;
     } catch (e) {
       throw MainDBException(
-          "failed updateOrPutTransactionV2s: $transactions", e);
+        "failed updateOrPutTransactionV2s: $transactions",
+        e,
+      );
     }
   }
 
diff --git a/lib/db/migrate_wallets_to_isar.dart b/lib/db/migrate_wallets_to_isar.dart
index ab263a1c2..72a9b501f 100644
--- a/lib/db/migrate_wallets_to_isar.dart
+++ b/lib/db/migrate_wallets_to_isar.dart
@@ -6,8 +6,13 @@ import 'package:stackwallet/db/hive/db.dart';
 import 'package:stackwallet/db/isar/main_db.dart';
 import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart';
 import 'package:stackwallet/models/isar/models/isar_models.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/models/token_wallet_info.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info_meta.dart';
@@ -37,13 +42,13 @@ Future<void> migrateWalletsToIsar({
   //
   final List<
       ({
-        Coin coin,
+        String coinIdentifier,
         String name,
         String walletId,
       })> oldInfo = Map<String, dynamic>.from(names).values.map((e) {
     final map = e as Map;
     return (
-      coin: Coin.values.byName(map["coin"] as String),
+      coinIdentifier: map["coin"] as String,
       walletId: map["id"] as String,
       name: map["name"] as String,
     );
@@ -93,16 +98,16 @@ Future<void> migrateWalletsToIsar({
     }
 
     // reset stellar + tezos address type
-    if (old.coin == Coin.stellar ||
-        old.coin == Coin.stellarTestnet ||
-        old.coin == Coin.tezos) {
+    if (old.coinIdentifier == Stellar(CryptoCurrencyNetwork.main).identifier ||
+        old.coinIdentifier == Stellar(CryptoCurrencyNetwork.test).identifier ||
+        old.coinIdentifier == Tezos(CryptoCurrencyNetwork.main).identifier) {
       await MainDB.instance.deleteWalletBlockchainData(old.walletId);
     }
 
     //
     // Set other data values
     //
-    Map<String, dynamic> otherData = {};
+    final Map<String, dynamic> otherData = {};
 
     final List<String>? tokenContractAddresses = walletBox.get(
       "ethTokenContracts",
@@ -129,7 +134,7 @@ Future<void> migrateWalletsToIsar({
     }
 
     // epiccash specifics
-    if (old.coin == Coin.epicCash) {
+    if (old.coinIdentifier == Epiccash(CryptoCurrencyNetwork.main)) {
       final epicWalletInfo = ExtraEpiccashWalletInfo.fromMap({
         "receivingIndex": walletBox.get("receivingIndex") as int? ?? 0,
         "changeIndex": walletBox.get("changeIndex") as int? ?? 0,
@@ -142,7 +147,9 @@ Future<void> migrateWalletsToIsar({
       otherData[WalletInfoKeys.epiccashData] = jsonEncode(
         epicWalletInfo.toMap(),
       );
-    } else if (old.coin == Coin.firo || old.coin == Coin.firoTestNet) {
+    } else if (old.coinIdentifier ==
+            Firo(CryptoCurrencyNetwork.main).identifier ||
+        old.coinIdentifier == Firo(CryptoCurrencyNetwork.test).identifier) {
       otherData[WalletInfoKeys.lelantusCoinIsarRescanRequired] = walletBox
               .get(WalletInfoKeys.lelantusCoinIsarRescanRequired) as bool? ??
           true;
@@ -161,10 +168,11 @@ Future<void> migrateWalletsToIsar({
     );
 
     final info = WalletInfo(
-      coinName: old.coin.name,
+      coinName: old.coinIdentifier,
       walletId: old.walletId,
       name: old.name,
-      mainAddressType: old.coin.primaryAddressType,
+      mainAddressType: SupportedCoins.getCryptoCurrencyFor(old.coinIdentifier)
+          .primaryAddressType,
       favouriteOrderIndex: favourites.indexOf(old.walletId),
       cachedChainHeight: walletBox.get(
             DBKeys.storedChainHeight,
diff --git a/lib/db/queries/queries.dart b/lib/db/queries/queries.dart
index 7e14de0e6..d2b49cea8 100644
--- a/lib/db/queries/queries.dart
+++ b/lib/db/queries/queries.dart
@@ -42,7 +42,7 @@ extension MainDBQueries on MainDB {
     required CCFilter filter,
     required CCSortDescriptor sort,
     required String searchTerm,
-    required Coin coin,
+    required CryptoCurrency cryptoCurrency,
   }) {
     var preSort = getUTXOs(walletId).filter().group((q) {
       final qq = q.group(
@@ -79,7 +79,7 @@ extension MainDBQueries on MainDB {
             qq = qq.or().valueEqualTo(
                   Amount.fromDecimal(
                     maybeDecimal,
-                    fractionDigits: coin.decimals,
+                    fractionDigits: cryptoCurrency.fractionDigits,
                   ).raw.toInt(),
                 );
           }
@@ -114,7 +114,7 @@ extension MainDBQueries on MainDB {
     required CCFilter filter,
     required CCSortDescriptor sort,
     required String searchTerm,
-    required Coin coin,
+    required CryptoCurrency cryptoCurrency,
   }) {
     var preSort = getUTXOs(walletId).filter().group((q) {
       final qq = q.group(
@@ -151,7 +151,7 @@ extension MainDBQueries on MainDB {
             qq = qq.or().valueEqualTo(
                   Amount.fromDecimal(
                     maybeDecimal,
-                    fractionDigits: coin.decimals,
+                    fractionDigits: cryptoCurrency.fractionDigits,
                   ).raw.toInt(),
                 );
           }
diff --git a/lib/dto/ethereum/eth_token_tx_extra_dto.dart b/lib/dto/ethereum/eth_token_tx_extra_dto.dart
index aab41bb76..377b0ad60 100644
--- a/lib/dto/ethereum/eth_token_tx_extra_dto.dart
+++ b/lib/dto/ethereum/eth_token_tx_extra_dto.dart
@@ -11,7 +11,8 @@
 import 'dart:convert';
 
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class EthTokenTxExtraDTO {
   EthTokenTxExtraDTO({
@@ -42,7 +43,7 @@ class EthTokenTxExtraDTO {
         to: map['to'] as String,
         value: Amount(
           rawValue: BigInt.parse(map['value'] as String),
-          fractionDigits: Coin.ethereum.decimals,
+          fractionDigits: Ethereum(CryptoCurrencyNetwork.main).fractionDigits,
         ),
         gas: _amountFromJsonNum(map['gas']),
         gasPrice: _amountFromJsonNum(map['gasPrice']),
@@ -70,7 +71,7 @@ class EthTokenTxExtraDTO {
   static Amount _amountFromJsonNum(dynamic json) {
     return Amount(
       rawValue: BigInt.from(json as num),
-      fractionDigits: Coin.ethereum.decimals,
+      fractionDigits: Ethereum(CryptoCurrencyNetwork.main).fractionDigits,
     );
   }
 
diff --git a/lib/dto/ethereum/eth_tx_dto.dart b/lib/dto/ethereum/eth_tx_dto.dart
index e0708646d..669583170 100644
--- a/lib/dto/ethereum/eth_tx_dto.dart
+++ b/lib/dto/ethereum/eth_tx_dto.dart
@@ -11,7 +11,8 @@
 import 'dart:convert';
 
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class EthTxDTO {
   EthTxDTO({
@@ -75,7 +76,7 @@ class EthTxDTO {
     }
     return Amount(
       rawValue: BigInt.parse(json.toString()),
-      fractionDigits: Coin.ethereum.decimals,
+      fractionDigits: Ethereum(CryptoCurrencyNetwork.main).fractionDigits,
     );
   }
 
diff --git a/lib/electrumx_rpc/cached_electrumx_client.dart b/lib/electrumx_rpc/cached_electrumx_client.dart
index 559526f17..10bd0aceb 100644
--- a/lib/electrumx_rpc/cached_electrumx_client.dart
+++ b/lib/electrumx_rpc/cached_electrumx_client.dart
@@ -13,8 +13,8 @@ import 'dart:math';
 
 import 'package:stackwallet/db/hive/db.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx_client.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:string_validator/string_validator.dart';
 
 class CachedElectrumXClient {
@@ -34,10 +34,11 @@ class CachedElectrumXClient {
   Future<Map<String, dynamic>> getAnonymitySet({
     required String groupId,
     String blockhash = "",
-    required Coin coin,
+    required CryptoCurrency cryptoCurrency,
   }) async {
     try {
-      final box = await DB.instance.getAnonymitySetCacheBox(coin: coin);
+      final box =
+          await DB.instance.getAnonymitySetCacheBox(currency: cryptoCurrency);
       final cachedSet = box.get(groupId) as Map?;
 
       Map<String, dynamic> set;
@@ -68,30 +69,38 @@ class CachedElectrumXClient {
             ? base64ToReverseHex(newSet["blockHash"] as String)
             : newSet["blockHash"];
         for (int i = (newSet["coins"] as List).length - 1; i >= 0; i--) {
-          dynamic newCoin = newSet["coins"][i];
-          List<dynamic> translatedCoin = [];
-          translatedCoin.add(!isHexadecimal(newCoin[0] as String)
-              ? base64ToHex(newCoin[0] as String)
-              : newCoin[0]);
-          translatedCoin.add(!isHexadecimal(newCoin[1] as String)
-              ? base64ToReverseHex(newCoin[1] as String)
-              : newCoin[1]);
+          final dynamic newCoin = newSet["coins"][i];
+          final List<dynamic> translatedCoin = [];
+          translatedCoin.add(
+            !isHexadecimal(newCoin[0] as String)
+                ? base64ToHex(newCoin[0] as String)
+                : newCoin[0],
+          );
+          translatedCoin.add(
+            !isHexadecimal(newCoin[1] as String)
+                ? base64ToReverseHex(newCoin[1] as String)
+                : newCoin[1],
+          );
           try {
-            translatedCoin.add(!isHexadecimal(newCoin[2] as String)
-                ? base64ToHex(newCoin[2] as String)
-                : newCoin[2]);
+            translatedCoin.add(
+              !isHexadecimal(newCoin[2] as String)
+                  ? base64ToHex(newCoin[2] as String)
+                  : newCoin[2],
+            );
           } catch (e) {
             translatedCoin.add(newCoin[2]);
           }
-          translatedCoin.add(!isHexadecimal(newCoin[3] as String)
-              ? base64ToReverseHex(newCoin[3] as String)
-              : newCoin[3]);
+          translatedCoin.add(
+            !isHexadecimal(newCoin[3] as String)
+                ? base64ToReverseHex(newCoin[3] as String)
+                : newCoin[3],
+          );
           set["coins"].insert(0, translatedCoin);
         }
         // save set to db
         await box.put(groupId, set);
         Logging.instance.log(
-          "Updated current anonymity set for ${coin.name} with group ID $groupId",
+          "Updated current anonymity set for ${cryptoCurrency.identifier} with group ID $groupId",
           level: LogLevel.Info,
         );
       }
@@ -99,8 +108,9 @@ class CachedElectrumXClient {
       return set;
     } catch (e, s) {
       Logging.instance.log(
-          "Failed to process CachedElectrumX.getAnonymitySet(): $e\n$s",
-          level: LogLevel.Error);
+        "Failed to process CachedElectrumX.getAnonymitySet(): $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
   }
@@ -108,11 +118,13 @@ class CachedElectrumXClient {
   Future<Map<String, dynamic>> getSparkAnonymitySet({
     required String groupId,
     String blockhash = "",
-    required Coin coin,
+    required CryptoCurrency cryptoCurrency,
     required bool useOnlyCacheIfNotEmpty,
   }) async {
     try {
-      final box = await DB.instance.getSparkAnonymitySetCacheBox(coin: coin);
+      final box = await DB.instance.getSparkAnonymitySetCacheBox(
+        currency: cryptoCurrency,
+      );
       final cachedSet = box.get(groupId) as Map?;
 
       Map<String, dynamic> set;
@@ -152,7 +164,7 @@ class CachedElectrumXClient {
         // save set to db
         await box.put(groupId, set);
         Logging.instance.log(
-          "Updated current anonymity set for ${coin.name} with group ID $groupId",
+          "Updated current anonymity set for ${cryptoCurrency.identifier} with group ID $groupId",
           level: LogLevel.Info,
         );
       }
@@ -160,8 +172,9 @@ class CachedElectrumXClient {
       return set;
     } catch (e, s) {
       Logging.instance.log(
-          "Failed to process CachedElectrumX.getSparkAnonymitySet(): $e\n$s",
-          level: LogLevel.Error);
+        "Failed to process CachedElectrumX.getSparkAnonymitySet(): $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
   }
@@ -182,11 +195,11 @@ class CachedElectrumXClient {
   /// ElectrumX api only called if the tx does not exist in local db
   Future<Map<String, dynamic>> getTransaction({
     required String txHash,
-    required Coin coin,
+    required CryptoCurrency cryptoCurrency,
     bool verbose = true,
   }) async {
     try {
-      final box = await DB.instance.getTxCacheBox(coin: coin);
+      final box = await DB.instance.getTxCacheBox(currency: cryptoCurrency);
 
       final cachedTx = box.get(txHash) as Map?;
       if (cachedTx == null) {
@@ -213,22 +226,24 @@ class CachedElectrumXClient {
       }
     } catch (e, s) {
       Logging.instance.log(
-          "Failed to process CachedElectrumX.getTransaction(): $e\n$s",
-          level: LogLevel.Error);
+        "Failed to process CachedElectrumX.getTransaction(): $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
   }
 
   Future<List<String>> getUsedCoinSerials({
-    required Coin coin,
+    required CryptoCurrency cryptoCurrency,
     int startNumber = 0,
   }) async {
     try {
-      final box = await DB.instance.getUsedSerialsCacheBox(coin: coin);
+      final box =
+          await DB.instance.getUsedSerialsCacheBox(currency: cryptoCurrency);
 
       final _list = box.get("serials") as List?;
 
-      Set<String> cachedSerials =
+      final Set<String> cachedSerials =
           _list == null ? {} : List<String>.from(_list).toSet();
 
       startNumber = max(
@@ -269,14 +284,16 @@ class CachedElectrumXClient {
   }
 
   Future<Set<String>> getSparkUsedCoinsTags({
-    required Coin coin,
+    required CryptoCurrency cryptoCurrency,
   }) async {
     try {
-      final box = await DB.instance.getSparkUsedCoinsTagsCacheBox(coin: coin);
+      final box = await DB.instance.getSparkUsedCoinsTagsCacheBox(
+        currency: cryptoCurrency,
+      );
 
       final _list = box.get("tags") as List?;
 
-      Set<String> cachedTags =
+      final Set<String> cachedTags =
           _list == null ? {} : List<String>.from(_list).toSet();
 
       final startNumber = max(
@@ -314,8 +331,9 @@ class CachedElectrumXClient {
   }
 
   /// Clear all cached transactions for the specified coin
-  Future<void> clearSharedTransactionCache({required Coin coin}) async {
-    await DB.instance.clearSharedTransactionCache(coin: coin);
-    await DB.instance.closeAnonymitySetCacheBox(coin: coin);
+  Future<void> clearSharedTransactionCache(
+      {required CryptoCurrency cryptoCurrency}) async {
+    await DB.instance.clearSharedTransactionCache(currency: cryptoCurrency);
+    await DB.instance.closeAnonymitySetCacheBox(currency: cryptoCurrency);
   }
 }
diff --git a/lib/models/add_wallet_list_entity/add_wallet_list_entity.dart b/lib/models/add_wallet_list_entity/add_wallet_list_entity.dart
index f59725f6b..b9fcdf1a0 100644
--- a/lib/models/add_wallet_list_entity/add_wallet_list_entity.dart
+++ b/lib/models/add_wallet_list_entity/add_wallet_list_entity.dart
@@ -9,10 +9,10 @@
  */
 
 import 'package:equatable/equatable.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 abstract class AddWalletListEntity extends Equatable {
-  Coin get coin;
+  CryptoCurrency get cryptoCurrency;
   String get name;
   String get ticker;
 }
diff --git a/lib/models/add_wallet_list_entity/sub_classes/coin_entity.dart b/lib/models/add_wallet_list_entity/sub_classes/coin_entity.dart
index 10e78688f..99fd2754c 100644
--- a/lib/models/add_wallet_list_entity/sub_classes/coin_entity.dart
+++ b/lib/models/add_wallet_list_entity/sub_classes/coin_entity.dart
@@ -9,22 +9,22 @@
  */
 
 import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class CoinEntity extends AddWalletListEntity {
   CoinEntity(this._coin);
 
-  final Coin _coin;
+  final CryptoCurrency _coin;
 
   @override
-  Coin get coin => _coin;
+  CryptoCurrency get cryptoCurrency => _coin;
 
   @override
-  String get name => coin.prettyName;
+  String get name => cryptoCurrency.prettyName;
 
   @override
-  String get ticker => coin.ticker;
+  String get ticker => cryptoCurrency.ticker;
 
   @override
-  List<Object?> get props => [coin, name, ticker];
+  List<Object?> get props => [cryptoCurrency.identifier, name, ticker];
 }
diff --git a/lib/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart b/lib/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart
index 000bc810f..4bea313d0 100644
--- a/lib/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart
+++ b/lib/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart
@@ -10,15 +10,17 @@
 
 import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart';
 import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class EthTokenEntity extends AddWalletListEntity {
   EthTokenEntity(this.token);
 
   final EthContract token;
 
+  // TODO: check other networks in future and handle differently?
   @override
-  Coin get coin => Coin.ethereum;
+  CryptoCurrency get cryptoCurrency => Ethereum(CryptoCurrencyNetwork.main);
 
   @override
   String get name => token.name;
@@ -27,5 +29,6 @@ class EthTokenEntity extends AddWalletListEntity {
   String get ticker => token.symbol;
 
   @override
-  List<Object?> get props => [coin, name, ticker, token.address];
+  List<Object?> get props =>
+      [cryptoCurrency.identifier, name, ticker, token.address];
 }
diff --git a/lib/models/address_book_filter.dart b/lib/models/address_book_filter.dart
index 578ffc8c9..daddba49e 100644
--- a/lib/models/address_book_filter.dart
+++ b/lib/models/address_book_filter.dart
@@ -9,46 +9,46 @@
  */
 
 import 'package:flutter/material.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class AddressBookFilter extends ChangeNotifier {
-  AddressBookFilter(Set<Coin> coins) {
+  AddressBookFilter(Set<CryptoCurrency> coins) {
     _coins = coins;
   }
 
-  Set<Coin> _coins = {};
+  Set<CryptoCurrency> _coins = {};
 
-  Set<Coin> get coins => _coins;
+  Set<CryptoCurrency> get coins => _coins;
 
-  set coins(Set<Coin> coins) {
+  set coins(Set<CryptoCurrency> coins) {
     _coins = coins;
     notifyListeners();
   }
 
-  void add(Coin coin, bool shouldNotifyListeners) {
+  void add(CryptoCurrency coin, bool shouldNotifyListeners) {
     _coins.add(coin);
     if (shouldNotifyListeners) {
       notifyListeners();
     }
   }
 
-  void addAll(Iterable<Coin> coins, bool shouldNotifyListeners) {
+  void addAll(Iterable<CryptoCurrency> coins, bool shouldNotifyListeners) {
     _coins.addAll(coins);
     if (shouldNotifyListeners) {
       notifyListeners();
     }
   }
 
-  void remove(Coin coin, bool shouldNotifyListeners) {
-    _coins.removeWhere((e) => e.name == coin.name);
+  void remove(CryptoCurrency coin, bool shouldNotifyListeners) {
+    _coins.removeWhere((e) => e.identifier == coin.identifier);
     if (shouldNotifyListeners) {
       notifyListeners();
     }
   }
 
-  void removeMany(Set<Coin> coins, bool shouldNotifyListeners) {
+  void removeMany(Set<CryptoCurrency> coins, bool shouldNotifyListeners) {
     for (final coin in coins) {
-      _coins.removeWhere((e) => e.name == coin.name);
+      _coins.removeWhere((e) => e.identifier == coin.identifier);
     }
     if (shouldNotifyListeners) {
       notifyListeners();
diff --git a/lib/models/balance.dart b/lib/models/balance.dart
index 9f4b36a1c..be2c80859 100644
--- a/lib/models/balance.dart
+++ b/lib/models/balance.dart
@@ -11,7 +11,7 @@
 import 'dart:convert';
 
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class Balance {
   final Amount total;
@@ -26,10 +26,10 @@ class Balance {
     required this.pendingSpendable,
   });
 
-  factory Balance.zeroForCoin({required Coin coin}) {
+  factory Balance.zeroFor({required CryptoCurrency currency}) {
     final amount = Amount(
       rawValue: BigInt.zero,
-      fractionDigits: coin.decimals,
+      fractionDigits: currency.fractionDigits,
     );
 
     return Balance(
diff --git a/lib/models/contact_address_entry.dart b/lib/models/contact_address_entry.dart
index 6f1ad1d54..f57ed6d4b 100644
--- a/lib/models/contact_address_entry.dart
+++ b/lib/models/contact_address_entry.dart
@@ -10,11 +10,12 @@
 
 import 'dart:convert';
 
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 @Deprecated("Use lib/models/isar/models/contact_entry.dart instead")
 class ContactAddressEntry {
-  final Coin coin;
+  final CryptoCurrency coin;
   final String address;
   final String label;
   final String? other;
@@ -27,7 +28,7 @@ class ContactAddressEntry {
   });
 
   ContactAddressEntry copyWith({
-    Coin? coin,
+    CryptoCurrency? coin,
     String? address,
     String? label,
     String? other,
@@ -42,7 +43,7 @@ class ContactAddressEntry {
 
   factory ContactAddressEntry.fromJson(Map<String, dynamic> jsonObject) {
     return ContactAddressEntry(
-      coin: Coin.values.byName(jsonObject["coin"] as String),
+      coin: SupportedCoins.getCryptoCurrencyFor(jsonObject["coin"] as String),
       address: jsonObject["address"] as String,
       label: jsonObject["label"] as String,
       other: jsonObject["other"] as String?,
@@ -53,7 +54,7 @@ class ContactAddressEntry {
     return {
       "label": label,
       "address": address,
-      "coin": coin.name,
+      "coin": coin.identifier,
       "other": other ?? "",
     };
   }
diff --git a/lib/models/contact_address_entry_data.dart b/lib/models/contact_address_entry_data.dart
index d7fb17684..545f40bac 100644
--- a/lib/models/contact_address_entry_data.dart
+++ b/lib/models/contact_address_entry_data.dart
@@ -10,8 +10,7 @@
 
 import 'package:flutter/cupertino.dart';
 import 'package:stackwallet/models/isar/models/contact_entry.dart';
-import 'package:stackwallet/utilities/address_utils.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class AddressEntryData extends ChangeNotifier {
   late int id;
@@ -20,7 +19,7 @@ class AddressEntryData extends ChangeNotifier {
 
   String? _addressLabel;
   String? _address;
-  Coin? _coin;
+  CryptoCurrency? _coin;
 
   String? get addressLabel => _addressLabel;
 
@@ -36,9 +35,9 @@ class AddressEntryData extends ChangeNotifier {
     notifyListeners();
   }
 
-  Coin? get coin => _coin;
+  CryptoCurrency? get coin => _coin;
 
-  set coin(Coin? coin) {
+  set coin(CryptoCurrency? coin) {
     _coin = coin;
     notifyListeners();
   }
@@ -73,12 +72,12 @@ class AddressEntryData extends ChangeNotifier {
     if (_address == null) {
       return false;
     }
-    return AddressUtils.validateAddress(_address!, _coin!);
+    return _coin!.validateAddress(_address!);
   }
 
   ContactAddressEntry buildAddressEntry() {
     return ContactAddressEntry()
-      ..coinName = coin!.name
+      ..coinName = coin!.identifier
       ..address = address!
       ..other = null
       ..label = addressLabel!;
@@ -86,6 +85,6 @@ class AddressEntryData extends ChangeNotifier {
 
   @override
   String toString() {
-    return "AddressEntryData: { addressLabel: $addressLabel, address: $address, coin: ${coin?.name} }";
+    return "AddressEntryData: { addressLabel: $addressLabel, address: $address, coin: ${coin?.identifier} }";
   }
 }
diff --git a/lib/models/isar/exchange_cache/currency.dart b/lib/models/isar/exchange_cache/currency.dart
index 5a3915e08..0233cbe98 100644
--- a/lib/models/isar/exchange_cache/currency.dart
+++ b/lib/models/isar/exchange_cache/currency.dart
@@ -10,7 +10,7 @@
 
 import 'package:isar/isar.dart';
 import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
 
 part 'currency.g.dart';
 
@@ -161,7 +161,7 @@ class Currency {
 
   static bool checkIsStackCoin(String ticker) {
     try {
-      coinFromTickerCaseInsensitive(ticker);
+      SupportedCoins.getCryptoCurrencyForTicker(ticker);
       return true;
     } catch (_) {
       return false;
diff --git a/lib/models/isar/models/block_explorer.dart b/lib/models/isar/models/block_explorer.dart
index 05d832580..411ad4ec3 100644
--- a/lib/models/isar/models/block_explorer.dart
+++ b/lib/models/isar/models/block_explorer.dart
@@ -9,7 +9,8 @@
  */
 
 import 'package:isar/isar.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 part 'block_explorer.g.dart';
 
@@ -28,9 +29,9 @@ class TransactionBlockExplorer {
   late final String url;
 
   @ignore
-  Coin? get coin {
+  CryptoCurrency? get coin {
     try {
-      return coinFromTickerCaseInsensitive(ticker);
+      return SupportedCoins.getCryptoCurrencyForTicker(ticker);
     } catch (_) {
       return null;
     }
diff --git a/lib/models/isar/models/contact_entry.dart b/lib/models/isar/models/contact_entry.dart
index 6289e8d18..b3a0fe809 100644
--- a/lib/models/isar/models/contact_entry.dart
+++ b/lib/models/isar/models/contact_entry.dart
@@ -9,7 +9,8 @@
  */
 
 import 'package:isar/isar.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 part 'contact_entry.g.dart';
 
@@ -36,7 +37,7 @@ class ContactEntry {
   @ignore
   List<ContactAddressEntry> get addressesSorted {
     final List<ContactAddressEntry> sorted = [];
-    for (final coin in Coin.values) {
+    for (final coin in SupportedCoins.cryptocurrencies) {
       final slice = addresses.where((e) => e.coin == coin).toList();
       if (slice.isNotEmpty) {
         slice.sort(
@@ -56,13 +57,13 @@ class ContactEntry {
     List<ContactAddressEntry>? addresses,
     bool? isFavorite,
   }) {
-    List<ContactAddressEntry> _addresses = [];
+    final List<ContactAddressEntry> _addresses = [];
     if (addresses == null) {
-      for (var e in this.addresses) {
+      for (final e in this.addresses) {
         _addresses.add(e.copyWith());
       }
     } else {
-      for (var e in addresses) {
+      for (final e in addresses) {
         _addresses.add(e.copyWith());
       }
     }
@@ -101,18 +102,18 @@ class ContactAddressEntry {
   late final String? other;
 
   @ignore
-  Coin get coin => Coin.values.byName(coinName);
+  CryptoCurrency get coin => SupportedCoins.getCryptoCurrencyFor(coinName);
 
   ContactAddressEntry();
 
   ContactAddressEntry copyWith({
-    Coin? coin,
+    CryptoCurrency? coin,
     String? address,
     String? label,
     String? other,
   }) {
     return ContactAddressEntry()
-      ..coinName = coin?.name ?? coinName
+      ..coinName = coin?.identifier ?? coinName
       ..address = address ?? this.address
       ..label = label ?? this.label
       ..other = other ?? this.other;
@@ -122,7 +123,7 @@ class ContactAddressEntry {
     return {
       "label": label,
       "address": address,
-      "coin": coin.name,
+      "coin": coin.identifier,
       "other": other ?? "",
     };
   }
diff --git a/lib/models/isar/stack_theme.dart b/lib/models/isar/stack_theme.dart
index 09f42b1b6..b33ca274d 100644
--- a/lib/models/isar/stack_theme.dart
+++ b/lib/models/isar/stack_theme.dart
@@ -13,7 +13,7 @@ import 'dart:io';
 
 import 'package:flutter/material.dart';
 import 'package:isar/isar.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/extensions/impl/box_shadow.dart';
 import 'package:stackwallet/utilities/extensions/impl/gradient.dart';
 import 'package:stackwallet/utilities/extensions/impl/string.dart';
@@ -1482,10 +1482,10 @@ class StackTheme {
   // ==== coinColors =====================================================
 
   @ignore
-  Map<Coin, Color> get coinColors =>
+  Map<String, Color> get coinColors =>
       _coinColors ??= parseCoinColors(coinColorsJsonString);
   @ignore
-  Map<Coin, Color>? _coinColors;
+  Map<String, Color>? _coinColors;
   late final String coinColorsJsonString;
 
   // ==== assets =====================================================
@@ -1851,20 +1851,21 @@ class StackTheme {
   }
 
   /// parse coin colors json and fetch color or use default
-  static Map<Coin, Color> parseCoinColors(String jsonString) {
+  static Map<String, Color> parseCoinColors(String jsonString) {
     final json = jsonDecode(jsonString) as Map;
     final map = Map<String, dynamic>.from(json);
 
-    final Map<Coin, Color> result = {};
+    final Map<String, Color> result = {};
 
-    for (final coin in Coin.values.map((e) => e.mainNetVersion)) {
-      if (map[coin.name] is String) {
-        result[coin] = Color(
-          (map[coin.name] as String).toBigIntFromHex.toInt(),
+    for (final mainNetId
+        in SupportedCoins.cryptocurrencies.map((e) => e.mainNetId)) {
+      if (map[mainNetId] is String) {
+        result[mainNetId] = Color(
+          (map[mainNetId] as String).toBigIntFromHex.toInt(),
         );
       } else {
         Logging.instance.log(
-          "Color not found in theme for $coin",
+          "Color not found in theme for $mainNetId",
           level: LogLevel.Error,
         );
       }
@@ -2080,31 +2081,31 @@ class ThemeAssetsV2 implements IThemeAssets {
   late final String coinPlaceholder;
 
   @ignore
-  Map<Coin, String> get coinIcons => _coinIcons ??= parseCoinAssetsString(
+  Map<String, String> get coinIcons => _coinIcons ??= parseCoinAssetsString(
         coinIconsString,
         placeHolder: coinPlaceholder,
       );
   @ignore
-  Map<Coin, String>? _coinIcons;
+  Map<String, String>? _coinIcons;
   late final String coinIconsString;
 
   @ignore
-  Map<Coin, String> get coinImages => _coinImages ??= parseCoinAssetsString(
+  Map<String, String> get coinImages => _coinImages ??= parseCoinAssetsString(
         coinImagesString,
         placeHolder: coinPlaceholder,
       );
   @ignore
-  Map<Coin, String>? _coinImages;
+  Map<String, String>? _coinImages;
   late final String coinImagesString;
 
   @ignore
-  Map<Coin, String> get coinSecondaryImages =>
+  Map<String, String> get coinSecondaryImages =>
       _coinSecondaryImages ??= parseCoinAssetsString(
         coinSecondaryImagesString,
         placeHolder: coinPlaceholder,
       );
   @ignore
-  Map<Coin, String>? _coinSecondaryImages;
+  Map<String, String>? _coinSecondaryImages;
   late final String coinSecondaryImagesString;
 
   ThemeAssetsV2();
@@ -2166,17 +2167,17 @@ class ThemeAssetsV2 implements IThemeAssets {
     return jsonEncode(map);
   }
 
-  static Map<Coin, String> parseCoinAssetsString(
+  static Map<String, String> parseCoinAssetsString(
     String jsonString, {
     required String placeHolder,
   }) {
     final json = jsonDecode(jsonString) as Map;
     final map = Map<String, dynamic>.from(json);
 
-    final Map<Coin, String> result = {};
+    final Map<String, String> result = {};
 
-    for (final coin in Coin.values) {
-      result[coin] = map[coin.name] as String? ?? placeHolder;
+    for (final coin in SupportedCoins.cryptocurrencies) {
+      result[coin.mainNetId] = map[coin.mainNetId] as String? ?? placeHolder;
     }
 
     return result;
@@ -2350,35 +2351,35 @@ class ThemeAssetsV3 implements IThemeAssets {
   late final String? dummy3;
 
   @ignore
-  Map<Coin, String> get coinIcons => _coinIcons ??= parseCoinAssetsString(
+  Map<String, String> get coinIcons => _coinIcons ??= parseCoinAssetsString(
         coinIconsString,
         placeHolder: coinPlaceholder,
       );
   @ignore
-  Map<Coin, String>? _coinIcons;
+  Map<String, String>? _coinIcons;
   late final String coinIconsString;
 
   @ignore
-  Map<Coin, String> get coinImages => _coinImages ??= parseCoinAssetsString(
+  Map<String, String> get coinImages => _coinImages ??= parseCoinAssetsString(
         coinImagesString,
         placeHolder: coinPlaceholder,
       );
   @ignore
-  Map<Coin, String>? _coinImages;
+  Map<String, String>? _coinImages;
   late final String coinImagesString;
 
   @ignore
-  Map<Coin, String> get coinSecondaryImages =>
+  Map<String, String> get coinSecondaryImages =>
       _coinSecondaryImages ??= parseCoinAssetsString(
         coinSecondaryImagesString,
         placeHolder: coinPlaceholder,
       );
   @ignore
-  Map<Coin, String>? _coinSecondaryImages;
+  Map<String, String>? _coinSecondaryImages;
   late final String coinSecondaryImagesString;
 
   @ignore
-  Map<Coin, String>? get coinCardImages =>
+  Map<String, String>? get coinCardImages =>
       _coinCardImages ??= coinCardImagesString == null
           ? null
           : parseCoinAssetsString(
@@ -2386,11 +2387,11 @@ class ThemeAssetsV3 implements IThemeAssets {
               placeHolder: coinPlaceholder,
             );
   @ignore
-  Map<Coin, String>? _coinCardImages;
+  Map<String, String>? _coinCardImages;
   late final String? coinCardImagesString;
 
   @ignore
-  Map<Coin, String>? get coinCardFavoritesImages =>
+  Map<String, String>? get coinCardFavoritesImages =>
       _coinCardFavoritesImages ??= coinCardFavoritesImagesString == null
           ? null
           : parseCoinAssetsString(
@@ -2398,7 +2399,7 @@ class ThemeAssetsV3 implements IThemeAssets {
               placeHolder: coinPlaceholder,
             );
   @ignore
-  Map<Coin, String>? _coinCardFavoritesImages;
+  Map<String, String>? _coinCardFavoritesImages;
   @Name("otherStringParam1")
   late final String? coinCardFavoritesImagesString;
 
@@ -2501,19 +2502,18 @@ class ThemeAssetsV3 implements IThemeAssets {
     return jsonEncode(map);
   }
 
-  static Map<Coin, String> parseCoinAssetsString(
+  static Map<String, String> parseCoinAssetsString(
     String jsonString, {
     required String placeHolder,
   }) {
     final json = jsonDecode(jsonString) as Map;
     final map = Map<String, dynamic>.from(json);
 
-    final Map<Coin, String> result = {};
+    final Map<String, String> result = {};
 
-    for (final coin in Coin.values) {
-      result[coin] = map[coin.name] as String? ?? placeHolder;
-
-      result[coin] = prependIfNeeded(result[coin]!);
+    for (final coin in SupportedCoins.cryptocurrencies) {
+      result[coin.mainNetId] = map[coin.mainNetId] as String? ?? placeHolder;
+      result[coin.mainNetId] = prependIfNeeded(result[coin.mainNetId]!);
     }
 
     return result;
diff --git a/lib/models/paymint/transactions_model.dart b/lib/models/paymint/transactions_model.dart
index db2dd2eee..c00f31565 100644
--- a/lib/models/paymint/transactions_model.dart
+++ b/lib/models/paymint/transactions_model.dart
@@ -11,8 +11,6 @@
 import 'package:dart_numerics/dart_numerics.dart';
 import 'package:decimal/decimal.dart';
 import 'package:hive/hive.dart';
-import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 part '../type_adaptors/transactions_model.g.dart';
 
@@ -236,19 +234,11 @@ class Transaction {
       timestamp: json['timestamp'] as int? ??
           (DateTime.now().millisecondsSinceEpoch ~/ 1000),
       txType: json['txType'] as String,
-      amount: (Decimal.parse(json["amount"].toString()) *
-              Decimal.fromInt(Constants.satsPerCoin(Coin
-                  .firo).toInt())) // dirty hack but we need 8 decimal places here to keep consistent data structure
-          .toBigInt()
-          .toInt(),
+      amount: _parse(json["amount"].toString()),
       aliens: [],
       worthNow: json['worthNow'] as String,
       worthAtBlockTimestamp: json['worthAtBlockTimestamp'] as String? ?? "0",
-      fees: (Decimal.parse(json["fees"].toString()) *
-              Decimal.fromInt(Constants.satsPerCoin(Coin
-                  .firo).toInt())) // dirty hack but we need 8 decimal places here to keep consistent data structure
-          .toBigInt()
-          .toInt(),
+      fees: _parse(json["fees"].toString()),
       inputSize: json['inputSize'] as int? ?? 0,
       outputSize: json['outputSize'] as int? ?? 0,
       inputs: [],
@@ -411,12 +401,7 @@ class Output {
         scriptpubkeyAsm: json['scriptPubKey']['asm'] as String?,
         scriptpubkeyType: json['scriptPubKey']['type'] as String?,
         scriptpubkeyAddress: address,
-        value: (Decimal.parse(
-                    (json["value"] ?? 0).toString()) *
-                Decimal.fromInt(Constants.satsPerCoin(Coin
-                    .firo).toInt())) // dirty hack but we need 8 decimal places here to keep consistent data structure
-            .toBigInt()
-            .toInt(),
+        value: _parse((json["value"] ?? 0).toString()),
       );
     } catch (s, e) {
       return Output(
@@ -425,11 +410,11 @@ class Output {
           scriptpubkeyAsm: "",
           scriptpubkeyType: "",
           scriptpubkeyAddress: "",
-          value: (Decimal.parse(0.toString()) *
-                  Decimal.fromInt(Constants.satsPerCoin(Coin
-                      .firo).toInt())) // dirty hack but we need 8 decimal places here to keep consistent data structure
-              .toBigInt()
-              .toInt());
+          value: _parse(0.toString()));
     }
   }
 }
+
+int _parse(String value) {
+  return (Decimal.parse(value) * Decimal.fromInt(8)).toBigInt().toInt();
+}
diff --git a/lib/models/wallet_restore_state.dart b/lib/models/wallet_restore_state.dart
index 37598651d..e325cad4d 100644
--- a/lib/models/wallet_restore_state.dart
+++ b/lib/models/wallet_restore_state.dart
@@ -9,14 +9,14 @@
  */
 
 import 'package:flutter/material.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/stack_restoring_status.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/wallet/wallet.dart';
 
 class WalletRestoreState extends ChangeNotifier {
   final String walletId;
   final String walletName;
-  final Coin coin;
+  final CryptoCurrency coin;
   late StackRestoringStatus _restoringStatus;
   Wallet? wallet;
   String? address;
diff --git a/lib/notifications/notification_card.dart b/lib/notifications/notification_card.dart
index ada6400f6..1135a478c 100644
--- a/lib/notifications/notification_card.dart
+++ b/lib/notifications/notification_card.dart
@@ -15,10 +15,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/isar/stack_theme.dart';
 import 'package:stackwallet/models/notification_model.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/themes/theme_providers.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
@@ -44,7 +44,8 @@ class NotificationCard extends ConsumerWidget {
 
   String coinIconPath(IThemeAssets assets, WidgetRef ref) {
     try {
-      final coin = coinFromPrettyName(notification.coinName);
+      final coin =
+          SupportedCoins.getCryptoCurrencyByPrettyName(notification.coinName);
       return ref.read(coinIconProvider(coin));
     } catch (_) {
       return notification.iconAssetName;
diff --git a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
index 34048fcbb..267358b54 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart
@@ -28,13 +28,17 @@ import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/e
 import 'package:stackwallet/pages/add_wallet_views/add_wallet_view/sub_widgets/next_button.dart';
 import 'package:stackwallet/pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/default_eth_tokens.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin_frost.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
@@ -61,10 +65,14 @@ class _AddWalletViewState extends ConsumerState<AddWalletView> {
 
   String _searchTerm = "";
 
-  final List<Coin> _coinsTestnet = [
-    ...Coin.values.where((e) => e.isTestNet),
+  final _coinsTestnet = [
+    ...SupportedCoins.cryptocurrencies
+        .where((e) => e.network == CryptoCurrencyNetwork.test),
+  ];
+  final _coins = [
+    ...SupportedCoins.cryptocurrencies
+        .where((e) => e.network == CryptoCurrencyNetwork.main),
   ];
-  final List<Coin> _coins = [...Coin.values.where((e) => !e.isTestNet)];
   final List<AddWalletListEntity> coinEntities = [];
   final List<EthTokenEntity> tokenEntities = [];
 
@@ -81,7 +89,7 @@ class _AddWalletViewState extends ConsumerState<AddWalletView> {
         (e) =>
             e.ticker.toLowerCase().contains(lowercaseTerm) ||
             e.name.toLowerCase().contains(lowercaseTerm) ||
-            e.coin.name.toLowerCase().contains(lowercaseTerm) ||
+            e.cryptoCurrency.identifier.toLowerCase().contains(lowercaseTerm) ||
             (e is EthTokenEntity &&
                 e.token.address.toLowerCase().contains(lowercaseTerm)),
       );
@@ -129,15 +137,13 @@ class _AddWalletViewState extends ConsumerState<AddWalletView> {
     _searchFocusNode = FocusNode();
     // _coinsTestnet.remove(Coin.firoTestNet);
     if (Platform.isWindows) {
-      _coins.remove(Coin.monero);
-      _coins.remove(Coin.wownero);
+      _coins.removeWhere((e) => e is Monero || e is Wownero);
     } else if (Platform.isLinux) {
-      _coins.remove(Coin.wownero);
+      _coins.removeWhere((e) => e is Wownero);
     }
 
     if (Util.isDesktop && !kDebugMode) {
-      _coins.remove(Coin.bitcoinFrost);
-      _coins.remove(Coin.bitcoinFrostTestNet);
+      _coins.removeWhere((e) => e is BitcoinFrost);
     }
 
     coinEntities.addAll(_coins.map((e) => CoinEntity(e)));
diff --git a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/coin_select_item.dart b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/coin_select_item.dart
index 410ebc7bd..18527b059 100644
--- a/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/coin_select_item.dart
+++ b/lib/pages/add_wallet_views/add_wallet_view/sub_widgets/coin_select_item.dart
@@ -29,9 +29,9 @@ import 'package:stackwallet/utilities/util.dart';
 
 class CoinSelectItem extends ConsumerWidget {
   const CoinSelectItem({
-    Key? key,
+    super.key,
     required this.entity,
-  }) : super(key: key);
+  });
 
   final AddWalletListEntity entity;
 
@@ -90,7 +90,7 @@ class CoinSelectItem extends ConsumerWidget {
                     )
                   : SvgPicture.file(
                       File(
-                        ref.watch(coinIconProvider(entity.coin)),
+                        ref.watch(coinIconProvider(entity.cryptoCurrency)),
                       ),
                       width: 26,
                       height: 26,
diff --git a/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart b/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart
index ef4d55319..49531bf9c 100644
--- a/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart
@@ -24,9 +24,9 @@ import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
 
 class CreateOrRestoreWalletView extends StatelessWidget {
   const CreateOrRestoreWalletView({
-    Key? key,
+    super.key,
     required this.entity,
-  }) : super(key: key);
+  });
 
   static const routeName = "/createOrRestoreWallet";
 
@@ -57,7 +57,7 @@ class CreateOrRestoreWalletView extends StatelessWidget {
                     flex: 10,
                   ),*/
                   CreateRestoreWalletTitle(
-                    coin: entity.coin,
+                    coin: entity.cryptoCurrency,
                     isDesktop: isDesktop,
                   ),
                   const SizedBox(
@@ -73,7 +73,7 @@ class CreateOrRestoreWalletView extends StatelessWidget {
                     height: 32,
                   ),
                   CoinImage(
-                    coin: entity.coin,
+                    coin: entity.cryptoCurrency,
                     width: isDesktop
                         ? 324
                         : MediaQuery.of(context).size.width / 1.6,
@@ -85,7 +85,7 @@ class CreateOrRestoreWalletView extends StatelessWidget {
                     height: 32,
                   ),
                   CreateWalletButtonGroup(
-                    coin: entity.coin,
+                    coin: entity.cryptoCurrency,
                     isDesktop: isDesktop,
                   ),
                   /*const Spacer(
@@ -129,7 +129,7 @@ class CreateOrRestoreWalletView extends StatelessWidget {
                                 flex: 2,
                               ),
                               CoinImage(
-                                coin: entity.coin,
+                                coin: entity.cryptoCurrency,
                                 width: isDesktop
                                     ? 324
                                     : MediaQuery.of(context).size.width / 1.6,
@@ -141,7 +141,7 @@ class CreateOrRestoreWalletView extends StatelessWidget {
                                 flex: 2,
                               ),
                               CreateRestoreWalletTitle(
-                                coin: entity.coin,
+                                coin: entity.cryptoCurrency,
                                 isDesktop: isDesktop,
                               ),
                               const SizedBox(
@@ -154,7 +154,7 @@ class CreateOrRestoreWalletView extends StatelessWidget {
                                 flex: 5,
                               ),
                               CreateWalletButtonGroup(
-                                coin: entity.coin,
+                                coin: entity.cryptoCurrency,
                                 isDesktop: isDesktop,
                               ),
                             ],
diff --git a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart
index 0d13044be..f13aee957 100644
--- a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart
+++ b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/coin_image.dart
@@ -14,18 +14,18 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/themes/coin_image_provider.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class CoinImage extends ConsumerWidget {
   const CoinImage({
-    Key? key,
+    super.key,
     required this.coin,
     this.width,
     this.height,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final double? width;
   final double? height;
 
diff --git a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_or_restore_wallet_title.dart b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_or_restore_wallet_title.dart
index ae7e917c8..319d8daf7 100644
--- a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_or_restore_wallet_title.dart
+++ b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_or_restore_wallet_title.dart
@@ -9,17 +9,17 @@
  */
 
 import 'package:flutter/material.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class CreateRestoreWalletTitle extends StatelessWidget {
   const CreateRestoreWalletTitle({
-    Key? key,
+    super.key,
     required this.coin,
     required this.isDesktop,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final bool isDesktop;
 
   @override
diff --git a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_wallet_button_group.dart b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_wallet_button_group.dart
index 36c914fd8..2120f6c4d 100644
--- a/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_wallet_button_group.dart
+++ b/lib/pages/add_wallet_views/create_or_restore_wallet_view/sub_widgets/create_wallet_button_group.dart
@@ -14,18 +14,19 @@ import 'package:flutter/material.dart';
 import 'package:stackwallet/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:tuple/tuple.dart';
 
 class CreateWalletButtonGroup extends StatelessWidget {
   const CreateWalletButtonGroup({
-    Key? key,
+    super.key,
     required this.coin,
     required this.isDesktop,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final bool isDesktop;
 
   @override
@@ -34,7 +35,7 @@ class CreateWalletButtonGroup extends StatelessWidget {
       crossAxisAlignment:
           isDesktop ? CrossAxisAlignment.center : CrossAxisAlignment.stretch,
       children: [
-        if (Platform.isAndroid || coin != Coin.wownero)
+        if (Platform.isAndroid || coin is! Wownero)
           ConstrainedBox(
             constraints: BoxConstraints(
               minHeight: isDesktop ? 70 : 0,
@@ -61,7 +62,7 @@ class CreateWalletButtonGroup extends StatelessWidget {
               ),
             ),
           ),
-        if (Platform.isAndroid || coin != Coin.wownero)
+        if (Platform.isAndroid || coin is! Wownero)
           SizedBox(
             height: isDesktop ? 16 : 12,
           ),
diff --git a/lib/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_5.dart b/lib/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_5.dart
index 586a1c189..d64c163e3 100644
--- a/lib/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_5.dart
+++ b/lib/pages/add_wallet_views/frost_ms/new/steps/frost_create_step_5.dart
@@ -143,7 +143,7 @@ class _FrostCreateStep5State extends ConsumerState<FrostCreateStep5> {
                 final data = ref.read(pFrostScaffoldArgs)!;
 
                 final info = WalletInfo.createNew(
-                  coin: data.info.frostCurrency.coin,
+                  coin: data.info.frostCurrency,
                   name: data.info.walletName,
                 );
 
diff --git a/lib/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1c.dart b/lib/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1c.dart
index 2bbfef1de..25267beed 100644
--- a/lib/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1c.dart
+++ b/lib/pages/add_wallet_views/frost_ms/reshare/frost_reshare_step_1c.dart
@@ -49,7 +49,7 @@ class _FrostReshareStep1cState extends ConsumerState<FrostReshareStep1c> {
 
     final info = WalletInfo.createNew(
       name: data.info.walletName,
-      coin: data.info.frostCurrency.coin,
+      coin: data.info.frostCurrency,
     );
 
     final wallet = IncompleteFrostWallet();
diff --git a/lib/pages/add_wallet_views/frost_ms/restore/restore_frost_ms_wallet_view.dart b/lib/pages/add_wallet_views/frost_ms/restore/restore_frost_ms_wallet_view.dart
index 03a7ee8bf..138dd09da 100644
--- a/lib/pages/add_wallet_views/frost_ms/restore/restore_frost_ms_wallet_view.dart
+++ b/lib/pages/add_wallet_views/frost_ms/restore/restore_frost_ms_wallet_view.dart
@@ -75,7 +75,7 @@ class _RestoreFrostMsWalletViewState
     final myName = participants[myNameIndex];
 
     final info = WalletInfo.createNew(
-      coin: widget.frostCurrency.coin,
+      coin: widget.frostCurrency,
       name: widget.walletName,
     );
 
diff --git a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
index 3cfeb6bbd..c0e94fdd1 100644
--- a/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
+++ b/lib/pages/add_wallet_views/name_your_wallet_view/name_your_wallet_view.dart
@@ -26,12 +26,11 @@ import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_co
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/name_generator.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin_frost.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/frost_currency.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -48,15 +47,15 @@ import 'package:tuple/tuple.dart';
 
 class NameYourWalletView extends ConsumerStatefulWidget {
   const NameYourWalletView({
-    Key? key,
+    super.key,
     required this.addWalletType,
     required this.coin,
-  }) : super(key: key);
+  });
 
   static const routeName = "/nameYourWallet";
 
   final AddWalletType addWalletType;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<NameYourWalletView> createState() => _NameYourWalletViewState();
@@ -64,7 +63,7 @@ class NameYourWalletView extends ConsumerStatefulWidget {
 
 class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
   late final AddWalletType addWalletType;
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   late TextEditingController textEditingController;
   late FocusNode textFieldFocusNode;
@@ -96,7 +95,7 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
 
       if (mounted) {
         ref.read(mnemonicWordCountStateProvider.state).state =
-            Constants.possibleLengthsForCoin(coin).last;
+            coin.possibleMnemonicLengths.last;
         ref.read(pNewWalletOptions.notifier).state = null;
 
         switch (widget.addWalletType) {
@@ -244,7 +243,7 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
             height: isDesktop ? 0 : 16,
           ),
           Text(
-            "Name your ${coin.prettyName} ${coin.isFrost ? "multisig " : ""}wallet",
+            "Name your ${coin.prettyName} ${coin is FrostCurrency ? "multisig " : ""}wallet",
             textAlign: TextAlign.center,
             style: isDesktop
                 ? STextStyles.desktopH2(context)
@@ -254,7 +253,7 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
             height: isDesktop ? 16 : 8,
           ),
           Text(
-            "Enter a label for your wallet (e.g. ${coin.isFrost ? "Multisig" : "Savings"})",
+            "Enter a label for your wallet (e.g. ${coin is FrostCurrency ? "Multisig" : "Savings"})",
             textAlign: TextAlign.center,
             style: isDesktop
                 ? STextStyles.desktopSubtitleH2(context)
@@ -383,7 +382,7 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
             const SizedBox(
               height: 32,
             ),
-          if (widget.coin.isFrost)
+          if (widget.coin is FrostCurrency)
             if (widget.addWalletType == AddWalletType.Restore)
               PrimaryButton(
                 label: "Next",
@@ -395,15 +394,13 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
                     RestoreFrostMsWalletView.routeName,
                     arguments: (
                       walletName: name,
-                      // TODO: [prio=med] this will cause issues if frost is ever applied to other coins
-                      frostCurrency: coin.isTestNet
-                          ? BitcoinFrost(CryptoCurrencyNetwork.test)
-                          : BitcoinFrost(CryptoCurrencyNetwork.main),
+                      frostCurrency: coin,
                     ),
                   );
                 },
               ),
-          if (widget.coin.isFrost && widget.addWalletType == AddWalletType.New)
+          if (widget.coin is FrostCurrency &&
+              widget.addWalletType == AddWalletType.New)
             Column(
               children: [
                 PrimaryButton(
@@ -416,10 +413,7 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
                       CreateNewFrostMsWalletView.routeName,
                       arguments: (
                         walletName: name,
-                        // TODO: [prio=med] this will cause issues if frost is ever applied to other coins
-                        frostCurrency: coin.isTestNet
-                            ? BitcoinFrost(CryptoCurrencyNetwork.test)
-                            : BitcoinFrost(CryptoCurrencyNetwork.main),
+                        frostCurrency: coin,
                       ),
                     );
                   },
@@ -437,10 +431,7 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
                       SelectNewFrostImportTypeView.routeName,
                       arguments: (
                         walletName: name,
-                        // TODO: [prio=med] this will cause issues if frost is ever applied to other coins
-                        frostCurrency: coin.isTestNet
-                            ? BitcoinFrost(CryptoCurrencyNetwork.test)
-                            : BitcoinFrost(CryptoCurrencyNetwork.main),
+                        frostCurrency: coin,
                       ),
                     );
                   },
@@ -480,7 +471,7 @@ class _NameYourWalletViewState extends ConsumerState<NameYourWalletView> {
                 // ),
               ],
             ),
-          if (!widget.coin.isFrost)
+          if (widget.coin is! FrostCurrency)
             ConstrainedBox(
               constraints: BoxConstraints(
                 minWidth: isDesktop ? 480 : 0,
diff --git a/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart b/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart
index f6d3075b2..a8e9c3a8a 100644
--- a/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart
+++ b/lib/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart
@@ -11,9 +11,9 @@ import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_co
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -26,7 +26,8 @@ import 'package:tuple/tuple.dart';
 
 final pNewWalletOptions =
     StateProvider<({String mnemonicPassphrase, int mnemonicWordsCount})?>(
-        (ref) => null);
+  (ref) => null,
+);
 
 enum NewWalletOptions {
   Default,
@@ -35,15 +36,15 @@ enum NewWalletOptions {
 
 class NewWalletOptionsView extends ConsumerStatefulWidget {
   const NewWalletOptionsView({
-    Key? key,
+    super.key,
     required this.walletName,
     required this.coin,
-  }) : super(key: key);
+  });
 
   static const routeName = "/newWalletOptionsView";
 
   final String walletName;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<NewWalletOptionsView> createState() =>
@@ -74,7 +75,7 @@ class _NewWalletOptionsViewState extends ConsumerState<NewWalletOptionsView> {
 
   @override
   Widget build(BuildContext context) {
-    final lengths = Constants.possibleLengthsForCoin(widget.coin).toList();
+    final lengths = widget.coin.possibleMnemonicLengths;
     return ConditionalParent(
       condition: Util.isDesktop,
       builder: (child) => DesktopScaffold(
@@ -339,7 +340,8 @@ class _NewWalletOptionsViewState extends ConsumerState<NewWalletOptionsView> {
                                 ),
                                 GestureDetector(
                                   key: const Key(
-                                      "mnemonicPassphraseFieldShowPasswordButtonKey"),
+                                    "mnemonicPassphraseFieldShowPasswordButtonKey",
+                                  ),
                                   onTap: () async {
                                     setState(() {
                                       hidePassword = !hidePassword;
diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart
index 8e3f8750f..e6f620a02 100644
--- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart
+++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart
@@ -25,13 +25,14 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/transaction_notification_tracker.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/wallets/wallet/wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
@@ -45,14 +46,14 @@ import 'package:tuple/tuple.dart';
 
 class NewWalletRecoveryPhraseWarningView extends ConsumerStatefulWidget {
   const NewWalletRecoveryPhraseWarningView({
-    Key? key,
+    super.key,
     required this.coin,
     required this.walletName,
-  }) : super(key: key);
+  });
 
   static const routeName = "/newWalletRecoveryPhraseWarning";
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final String walletName;
 
   @override
@@ -62,7 +63,7 @@ class NewWalletRecoveryPhraseWarningView extends ConsumerStatefulWidget {
 
 class _NewWalletRecoveryPhraseWarningViewState
     extends ConsumerState<NewWalletRecoveryPhraseWarningView> {
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final String walletName;
   late final bool isDesktop;
 
@@ -79,8 +80,8 @@ class _NewWalletRecoveryPhraseWarningViewState
     debugPrint("BUILD: $runtimeType");
     final options = ref.read(pNewWalletOptions.state).state;
 
-    final seedCount = options?.mnemonicWordsCount ??
-        Constants.defaultSeedPhraseLengthFor(coin: coin);
+    final seedCount =
+        options?.mnemonicWordsCount ?? coin.defaultSeedPhraseLength;
 
     return MasterScaffold(
       isDesktop: isDesktop,
@@ -118,7 +119,7 @@ class _NewWalletRecoveryPhraseWarningViewState
                       );
                     },
                   ),
-                )
+                ),
               ],
             ),
       body: SingleChildScrollView(
@@ -180,7 +181,8 @@ class _NewWalletRecoveryPhraseWarningViewState
                               "access to your wallet.",
                               style: isDesktop
                                   ? STextStyles.desktopTextMediumRegular(
-                                      context)
+                                      context,
+                                    )
                                   : STextStyles.subtitle(context).copyWith(
                                       fontSize: 12,
                                     ),
@@ -359,13 +361,14 @@ class _NewWalletRecoveryPhraseWarningViewState
                                           child: Text(
                                             "Do not show them to anyone.",
                                             style: STextStyles.navBarTitle(
-                                                context),
+                                              context,
+                                            ),
                                           ),
                                         ),
                                       ],
                                     ),
                                   ],
-                                )
+                                ),
                               ],
                             ),
                     ),
@@ -410,12 +413,14 @@ class _NewWalletRecoveryPhraseWarningViewState
                                               MaterialTapTargetSize.shrinkWrap,
                                           value: ref
                                               .watch(
-                                                  checkBoxStateProvider.state)
+                                                checkBoxStateProvider.state,
+                                              )
                                               .state,
                                           onChanged: (newValue) {
                                             ref
                                                 .read(
-                                                    checkBoxStateProvider.state)
+                                                  checkBoxStateProvider.state,
+                                                )
                                                 .state = newValue!;
                                           },
                                         ),
@@ -428,7 +433,8 @@ class _NewWalletRecoveryPhraseWarningViewState
                                           "I understand that Stack Wallet does not keep and cannot restore my recovery phrase, and If I lose my recovery phrase, I will not be able to access my funds.",
                                           style: isDesktop
                                               ? STextStyles.desktopTextMedium(
-                                                  context)
+                                                  context,
+                                                )
                                               : STextStyles.baseXS(context)
                                                   .copyWith(
                                                   height: 1.3,
@@ -452,21 +458,23 @@ class _NewWalletRecoveryPhraseWarningViewState
                                           .state
                                       ? () async {
                                           try {
-                                            unawaited(showDialog<dynamic>(
-                                              context: context,
-                                              barrierDismissible: false,
-                                              useSafeArea: true,
-                                              builder: (ctx) {
-                                                return const Center(
-                                                  child: LoadingIndicator(
-                                                    width: 50,
-                                                    height: 50,
-                                                  ),
-                                                );
-                                              },
-                                            ));
+                                            unawaited(
+                                              showDialog<dynamic>(
+                                                context: context,
+                                                barrierDismissible: false,
+                                                useSafeArea: true,
+                                                builder: (ctx) {
+                                                  return const Center(
+                                                    child: LoadingIndicator(
+                                                      width: 50,
+                                                      height: 50,
+                                                    ),
+                                                  );
+                                                },
+                                              ),
+                                            );
                                             String? otherDataJsonString;
-                                            if (widget.coin == Coin.tezos) {
+                                            if (widget.coin is Tezos) {
                                               otherDataJsonString = jsonEncode({
                                                 WalletInfoKeys
                                                         .tezosDerivationPath:
@@ -474,7 +482,7 @@ class _NewWalletRecoveryPhraseWarningViewState
                                                         .value,
                                               });
                                               //  }//todo: probably not needed (broken anyways)
-                                              // else if (widget.coin == Coin.epicCash) {
+                                              // else if (widget.coin is Epiccash) {
                                               //    final int secondsSinceEpoch =
                                               //        DateTime.now().millisecondsSinceEpoch ~/ 1000;
                                               //    const int epicCashFirstBlock = 1565370278;
@@ -504,8 +512,7 @@ class _NewWalletRecoveryPhraseWarningViewState
                                               //        ),
                                               //      },
                                               //    );
-                                            } else if (widget.coin ==
-                                                Coin.firo) {
+                                            } else if (widget.coin is Firo) {
                                               otherDataJsonString = jsonEncode(
                                                 {
                                                   WalletInfoKeys
@@ -524,15 +531,18 @@ class _NewWalletRecoveryPhraseWarningViewState
 
                                             var node = ref
                                                 .read(
-                                                    nodeServiceChangeNotifierProvider)
-                                                .getPrimaryNodeFor(coin: coin);
+                                                  nodeServiceChangeNotifierProvider,
+                                                )
+                                                .getPrimaryNodeFor(
+                                                  currency: coin,
+                                                );
 
                                             if (node == null) {
-                                              node =
-                                                  DefaultNodes.getNodeFor(coin);
+                                              node = coin.defaultNode;
                                               await ref
                                                   .read(
-                                                      nodeServiceChangeNotifierProvider)
+                                                    nodeServiceChangeNotifierProvider,
+                                                  )
                                                   .setPrimaryNodeFor(
                                                     coin: coin,
                                                     node: node,
@@ -549,34 +559,35 @@ class _NewWalletRecoveryPhraseWarningViewState
                                             String? mnemonic;
                                             String? privateKey;
 
-                                            wordCount = Constants
-                                                .defaultSeedPhraseLengthFor(
-                                              coin: info.coin,
-                                            );
+                                            wordCount = info
+                                                .coin.defaultSeedPhraseLength;
 
-                                            if (coin == Coin.monero ||
-                                                coin == Coin.wownero) {
+                                            if (coin is Monero ||
+                                                coin is Wownero) {
                                               // currently a special case due to the
                                               // xmr/wow libraries handling their
                                               // own mnemonic generation
                                             } else if (wordCount > 0) {
                                               if (ref
-                                                      .read(pNewWalletOptions
-                                                          .state)
+                                                      .read(
+                                                        pNewWalletOptions.state,
+                                                      )
                                                       .state !=
                                                   null) {
                                                 if (coin
                                                     .hasMnemonicPassphraseSupport) {
                                                   mnemonicPassphrase = ref
-                                                      .read(pNewWalletOptions
-                                                          .state)
+                                                      .read(
+                                                        pNewWalletOptions.state,
+                                                      )
                                                       .state!
                                                       .mnemonicPassphrase;
                                                 } else {}
 
                                                 wordCount = ref
                                                     .read(
-                                                        pNewWalletOptions.state)
+                                                      pNewWalletOptions.state,
+                                                    )
                                                     .state!
                                                     .mnemonicWordsCount;
                                               } else {
@@ -587,7 +598,8 @@ class _NewWalletRecoveryPhraseWarningViewState
                                                   24 < wordCount ||
                                                   wordCount % 3 != 0) {
                                                 throw Exception(
-                                                    "Invalid word count");
+                                                  "Invalid word count",
+                                                );
                                               }
 
                                               final strength =
@@ -604,9 +616,11 @@ class _NewWalletRecoveryPhraseWarningViewState
                                               secureStorageInterface:
                                                   ref.read(secureStoreProvider),
                                               nodeService: ref.read(
-                                                  nodeServiceChangeNotifierProvider),
+                                                nodeServiceChangeNotifierProvider,
+                                              ),
                                               prefs: ref.read(
-                                                  prefsChangeNotifierProvider),
+                                                prefsChangeNotifierProvider,
+                                              ),
                                               mnemonicPassphrase:
                                                   mnemonicPassphrase,
                                               mnemonic: mnemonic,
@@ -616,31 +630,36 @@ class _NewWalletRecoveryPhraseWarningViewState
                                             await wallet.init();
 
                                             // pop progress dialog
-                                            if (mounted) {
+                                            if (context.mounted) {
                                               Navigator.pop(context);
                                             }
                                             // set checkbox back to unchecked to annoy users to agree again :P
                                             ref
                                                 .read(
-                                                    checkBoxStateProvider.state)
+                                                  checkBoxStateProvider.state,
+                                                )
                                                 .state = false;
 
-                                            if (mounted) {
-                                              unawaited(Navigator.of(context)
-                                                  .pushNamed(
-                                                NewWalletRecoveryPhraseView
-                                                    .routeName,
-                                                arguments: Tuple2(
-                                                  wallet,
-                                                  await (wallet
-                                                          as MnemonicInterface)
-                                                      .getMnemonicAsWords(),
+                                            if (context.mounted) {
+                                              final nav = Navigator.of(context);
+                                              unawaited(
+                                                nav.pushNamed(
+                                                  NewWalletRecoveryPhraseView
+                                                      .routeName,
+                                                  arguments: Tuple2(
+                                                    wallet,
+                                                    await (wallet
+                                                            as MnemonicInterface)
+                                                        .getMnemonicAsWords(),
+                                                  ),
                                                 ),
-                                              ));
+                                              );
                                             }
                                           } catch (e, s) {
-                                            Logging.instance.log("$e\n$s",
-                                                level: LogLevel.Fatal);
+                                            Logging.instance.log(
+                                              "$e\n$s",
+                                              level: LogLevel.Fatal,
+                                            );
                                             // TODO: handle gracefully
                                             // any network/socket exception here will break new wallet creation
                                             rethrow;
@@ -656,18 +675,22 @@ class _NewWalletRecoveryPhraseWarningViewState
                                       : Theme.of(context)
                                           .extension<StackColors>()!
                                           .getPrimaryDisabledButtonStyle(
-                                              context),
+                                            context,
+                                          ),
                                   child: Text(
                                     "View recovery phrase",
                                     style: isDesktop
                                         ? ref
                                                 .read(
-                                                    checkBoxStateProvider.state)
+                                                  checkBoxStateProvider.state,
+                                                )
                                                 .state
                                             ? STextStyles.desktopButtonEnabled(
-                                                context)
+                                                context,
+                                              )
                                             : STextStyles.desktopButtonDisabled(
-                                                context)
+                                                context,
+                                              )
                                         : STextStyles.button(context),
                                   ),
                                 ),
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
index 3c7bdfd9e..642833523 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_options_view/restore_options_view.dart
@@ -24,10 +24,13 @@ import 'package:stackwallet/providers/ui/verify_recovery_phrase/mnemonic_word_co
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/date_picker/date_picker.dart';
@@ -48,7 +51,7 @@ class RestoreOptionsView extends ConsumerStatefulWidget {
   static const routeName = "/restoreOptions";
 
   final String walletName;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<RestoreOptionsView> createState() => _RestoreOptionsViewState();
@@ -56,7 +59,7 @@ class RestoreOptionsView extends ConsumerStatefulWidget {
 
 class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
   late final String walletName;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final bool isDesktop;
 
   late TextEditingController _dateController;
@@ -69,8 +72,7 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
   bool hidePassword = true;
   bool _expandedAdavnced = false;
 
-  bool get supportsMnemonicPassphrase =>
-      !(coin == Coin.monero || coin == Coin.wownero || coin == Coin.epicCash);
+  bool get supportsMnemonicPassphrase => coin.hasMnemonicPassphraseSupport;
 
   @override
   void initState() {
@@ -153,7 +155,7 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
       ),
       builder: (_) {
         return MnemonicWordCountSelectSheet(
-          lengthOptions: Constants.possibleLengthsForCoin(coin),
+          lengthOptions: coin.possibleMnemonicLengths,
         );
       },
     );
@@ -161,9 +163,9 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
 
   @override
   Widget build(BuildContext context) {
-    debugPrint("BUILD: $runtimeType with ${coin.name} $walletName");
+    debugPrint("BUILD: $runtimeType with ${coin.identifier} $walletName");
 
-    final lengths = Constants.possibleLengthsForCoin(coin).toList();
+    final lengths = coin.possibleMnemonicLengths;
 
     return MasterScaffold(
       isDesktop: isDesktop,
@@ -217,9 +219,9 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
               SizedBox(
                 height: isDesktop ? 40 : 24,
               ),
-              if (coin == Coin.monero ||
-                  coin == Coin.epicCash ||
-                  (coin == Coin.wownero &&
+              if (coin is Monero ||
+                  coin is Epiccash ||
+                  (coin is Wownero &&
                       ref.watch(mnemonicWordCountStateProvider.state).state ==
                           25))
                 Text(
@@ -233,17 +235,17 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
                       : STextStyles.smallMed12(context),
                   textAlign: TextAlign.left,
                 ),
-              if (coin == Coin.monero ||
-                  coin == Coin.epicCash ||
-                  (coin == Coin.wownero &&
+              if (coin is Monero ||
+                  coin is Epiccash ||
+                  (coin is Wownero &&
                       ref.watch(mnemonicWordCountStateProvider.state).state ==
                           25))
                 SizedBox(
                   height: isDesktop ? 16 : 8,
                 ),
-              if (coin == Coin.monero ||
-                  coin == Coin.epicCash ||
-                  (coin == Coin.wownero &&
+              if (coin is Monero ||
+                  coin is Epiccash ||
+                  (coin is Wownero &&
                       ref.watch(mnemonicWordCountStateProvider.state).state ==
                           25))
                 if (!isDesktop)
@@ -251,9 +253,9 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
                     onTap: chooseDate,
                     controller: _dateController,
                   ),
-              if (coin == Coin.monero ||
-                  coin == Coin.epicCash ||
-                  (coin == Coin.wownero &&
+              if (coin is Monero ||
+                  coin is Epiccash ||
+                  (coin is Wownero &&
                       ref.watch(mnemonicWordCountStateProvider.state).state ==
                           25))
                 if (isDesktop)
@@ -262,17 +264,17 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
                     onTap: chooseDesktopDate,
                     controller: _dateController,
                   ),
-              if (coin == Coin.monero ||
-                  coin == Coin.epicCash ||
-                  (coin == Coin.wownero &&
+              if (coin is Monero ||
+                  coin is Epiccash ||
+                  (coin is Wownero &&
                       ref.watch(mnemonicWordCountStateProvider.state).state ==
                           25))
                 const SizedBox(
                   height: 8,
                 ),
-              if (coin == Coin.monero ||
-                  coin == Coin.epicCash ||
-                  (coin == Coin.wownero &&
+              if (coin is Monero ||
+                  coin is Epiccash ||
+                  (coin is Wownero &&
                       ref.watch(mnemonicWordCountStateProvider.state).state ==
                           25))
                 RoundedWhiteContainer(
@@ -291,9 +293,9 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
                     ),
                   ),
                 ),
-              if (coin == Coin.monero ||
-                  coin == Coin.epicCash ||
-                  (coin == Coin.wownero &&
+              if (coin is Monero ||
+                  coin is Epiccash ||
+                  (coin is Wownero &&
                       ref.watch(mnemonicWordCountStateProvider.state).state ==
                           25))
                 SizedBox(
diff --git a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
index 14174b22b..1b07eb565 100644
--- a/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
+++ b/lib/pages/add_wallet_views/restore_wallet_view/restore_wallet_view.dart
@@ -18,8 +18,8 @@ import 'package:bip39/bip39.dart' as bip39;
 import 'package:bip39/src/wordlists/english.dart' as bip39wordlist;
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
-import 'package:flutter_libmonero/monero/monero.dart';
-import 'package:flutter_libmonero/wownero/wownero.dart';
+import 'package:flutter_libmonero/monero/monero.dart' as libxmr;
+import 'package:flutter_libmonero/wownero/wownero.dart' as libwow;
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
@@ -44,12 +44,16 @@ import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/custom_text_selection_controls.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/form_input_status_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart';
 import 'package:stackwallet/wallets/wallet/impl/monero_wallet.dart';
@@ -69,7 +73,7 @@ import 'package:wakelock/wakelock.dart';
 
 class RestoreWalletView extends ConsumerStatefulWidget {
   const RestoreWalletView({
-    Key? key,
+    super.key,
     required this.walletName,
     required this.coin,
     required this.seedWordsLength,
@@ -77,12 +81,12 @@ class RestoreWalletView extends ConsumerStatefulWidget {
     required this.restoreFromDate,
     this.barcodeScanner = const BarcodeScannerWrapper(),
     this.clipboard = const ClipboardWrapper(),
-  }) : super(key: key);
+  });
 
   static const routeName = "/restoreWallet";
 
   final String walletName;
-  final Coin coin;
+  final CryptoCurrency coin;
   final String mnemonicPassphrase;
   final int seedWordsLength;
   final DateTime restoreFromDate;
@@ -166,7 +170,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
 
   @override
   void dispose() {
-    for (var element in _controllers) {
+    for (final element in _controllers) {
       element.dispose();
     }
 
@@ -176,13 +180,15 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
   // TODO: check for wownero wordlist?
   bool _isValidMnemonicWord(String word) {
     // TODO: get the actual language
-    if (widget.coin == Coin.monero) {
-      var moneroWordList = monero.getMoneroWordList("English");
+    if (widget.coin is Monero) {
+      final moneroWordList = libxmr.monero.getMoneroWordList("English");
       return moneroWordList.contains(word);
     }
-    if (widget.coin == Coin.wownero) {
-      var wowneroWordList = wownero.getWowneroWordList("English",
-          seedWordsLength: widget.seedWordsLength);
+    if (widget.coin is Wownero) {
+      final wowneroWordList = libwow.wownero.getWowneroWordList(
+        "English",
+        seedWordsLength: widget.seedWordsLength,
+      );
       return wowneroWordList.contains(word);
     }
     return _wordListHashSet.contains(word);
@@ -201,7 +207,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
   Future<void> attemptRestore() async {
     if (_formKey.currentState!.validate()) {
       String mnemonic = "";
-      for (var element in _controllers) {
+      for (final element in _controllers) {
         mnemonic += " ${element.text.trim().toLowerCase()}";
       }
       mnemonic = mnemonic.trim();
@@ -209,24 +215,25 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
       int height = 0;
       String? otherDataJsonString;
 
-      if (widget.coin == Coin.monero) {
-        height = monero.getHeigthByDate(date: widget.restoreFromDate);
-      } else if (widget.coin == Coin.wownero) {
-        height = wownero.getHeightByDate(date: widget.restoreFromDate);
+      if (widget.coin is Monero) {
+        height = libxmr.monero.getHeigthByDate(date: widget.restoreFromDate);
+      } else if (widget.coin is Wownero) {
+        height = libwow.wownero.getHeightByDate(date: widget.restoreFromDate);
       }
       // todo: wait until this implemented
-      // else if (widget.coin == Coin.wownero) {
+      // else if (widget.coin is Wownero) {
       //   height = wownero.getHeightByDate(date: widget.restoreFromDate);
       // }
 
       // TODO: make more robust estimate of date maybe using https://explorer.epic.tech/api-index
-      if (widget.coin == Coin.epicCash) {
-        int secondsSinceEpoch =
+      if (widget.coin is Epiccash) {
+        final int secondsSinceEpoch =
             widget.restoreFromDate.millisecondsSinceEpoch ~/ 1000;
         const int epicCashFirstBlock = 1565370278;
         const double overestimateSecondsPerBlock = 61;
-        int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock;
-        int approximateHeight = chosenSeconds ~/ overestimateSecondsPerBlock;
+        final int chosenSeconds = secondsSinceEpoch - epicCashFirstBlock;
+        final int approximateHeight =
+            chosenSeconds ~/ overestimateSecondsPerBlock;
         //todo: check if print needed
         // debugPrint(
         //     "approximate height: $approximateHeight chosen_seconds: $chosenSeconds");
@@ -250,7 +257,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
             ),
           },
         );
-      } else if (widget.coin == Coin.firo) {
+      } else if (widget.coin is Firo) {
         otherDataJsonString = jsonEncode(
           {
             WalletInfoKeys.lelantusCoinIsarRescanRequired: false,
@@ -260,12 +267,14 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
 
       // TODO: do actual check to make sure it is a valid mnemonic for monero
       if (bip39.validateMnemonic(mnemonic) == false &&
-          !(widget.coin == Coin.monero || widget.coin == Coin.wownero)) {
-        unawaited(showFloatingFlushBar(
-          type: FlushBarType.warning,
-          message: "Invalid seed phrase!",
-          context: context,
-        ));
+          !(widget.coin is Monero || widget.coin is Wownero)) {
+        unawaited(
+          showFloatingFlushBar(
+            type: FlushBarType.warning,
+            message: "Invalid seed phrase!",
+            context: context,
+          ),
+        );
       } else {
         if (!Platform.isLinux) await Wakelock.enable();
 
@@ -278,30 +287,35 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
 
         bool isRestoring = true;
         // show restoring in progress
-        unawaited(showDialog<dynamic>(
-          context: context,
-          useSafeArea: false,
-          barrierDismissible: false,
-          builder: (context) {
-            return RestoringDialog(
-              onCancel: () async {
-                isRestoring = false;
 
-                await ref.read(pWallets).deleteWallet(
-                      info,
-                      ref.read(secureStoreProvider),
-                    );
+        if (mounted) {
+          unawaited(
+            showDialog<dynamic>(
+              context: context,
+              useSafeArea: false,
+              barrierDismissible: false,
+              builder: (context) {
+                return RestoringDialog(
+                  onCancel: () async {
+                    isRestoring = false;
+
+                    await ref.read(pWallets).deleteWallet(
+                          info,
+                          ref.read(secureStoreProvider),
+                        );
+                  },
+                );
               },
-            );
-          },
-        ));
+            ),
+          );
+        }
 
         var node = ref
             .read(nodeServiceChangeNotifierProvider)
-            .getPrimaryNodeFor(coin: widget.coin);
+            .getPrimaryNodeFor(currency: widget.coin);
 
         if (node == null) {
-          node = DefaultNodes.getNodeFor(widget.coin);
+          node = widget.coin.defaultNode;
           await ref.read(nodeServiceChangeNotifierProvider).setPrimaryNodeFor(
                 coin: widget.coin,
                 node: node,
@@ -324,15 +338,15 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
 
           // TODO: extract interface with isRestore param
           switch (wallet.runtimeType) {
-            case EpiccashWallet:
+            case const (EpiccashWallet):
               await (wallet as EpiccashWallet).init(isRestore: true);
               break;
 
-            case MoneroWallet:
+            case const (MoneroWallet):
               await (wallet as MoneroWallet).init(isRestore: true);
               break;
 
-            case WowneroWallet:
+            case const (WowneroWallet):
               await (wallet as WowneroWallet).init(isRestore: true);
               break;
 
@@ -355,12 +369,11 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
             if (isCreateSpecialEthWallet) {
               ref.read(createSpecialEthWalletRoutingFlag.notifier).state =
                   false;
-              ref
-                      .read(newEthWalletTriggerTempUntilHiveCompletelyDeleted.state)
-                      .state =
+              ref.read(newEthWalletTriggerTempUntilHiveCompletelyDeleted.state).state =
                   !ref
-                      .read(newEthWalletTriggerTempUntilHiveCompletelyDeleted
-                          .state)
+                      .read(
+                        newEthWalletTriggerTempUntilHiveCompletelyDeleted.state,
+                      )
                       .state;
             }
 
@@ -385,7 +398,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                       (route) => false,
                     ),
                   );
-                  if (info.coin == Coin.ethereum) {
+                  if (info.coin is Ethereum) {
                     unawaited(
                       Navigator.of(context).pushNamed(
                         EditWalletTokensView.routeName,
@@ -451,7 +464,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
   }
 
   InputDecoration _getInputDecorationFor(
-      FormInputStatus status, String prefix) {
+    FormInputStatus status,
+    String prefix,
+  ) {
     Color color;
     Color prefixColor;
     Color borderColor;
@@ -656,9 +671,10 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                   if (FocusScope.of(context).hasFocus) {
                     FocusScope.of(context).unfocus();
                     await Future<void>.delayed(
-                        const Duration(milliseconds: 50));
+                      const Duration(milliseconds: 50),
+                    );
                   }
-                  if (mounted) {
+                  if (context.mounted) {
                     Navigator.of(context).pop();
                   }
                 },
@@ -788,8 +804,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                 "Paste",
                                 style: STextStyles
                                     .desktopButtonSmallSecondaryEnabled(
-                                        context),
-                              )
+                                  context,
+                                ),
+                              ),
                             ],
                           ),
                         ),
@@ -836,12 +853,14 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                                   textCapitalization:
                                                       TextCapitalization.none,
                                                   key: Key(
-                                                      "restoreMnemonicFormField_$i"),
+                                                    "restoreMnemonicFormField_$i",
+                                                  ),
                                                   decoration:
                                                       _getInputDecorationFor(
-                                                          _inputStatuses[
-                                                              i * 4 + j - 1],
-                                                          "${i * 4 + j}"),
+                                                    _inputStatuses[
+                                                        i * 4 + j - 1],
+                                                    "${i * 4 + j}",
+                                                  ),
                                                   autovalidateMode:
                                                       AutovalidateMode
                                                           .onUserInteraction,
@@ -861,9 +880,10 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                                       formInputStatus =
                                                           FormInputStatus.empty;
                                                     } else if (_isValidMnemonicWord(
-                                                        value
-                                                            .trim()
-                                                            .toLowerCase())) {
+                                                      value
+                                                          .trim()
+                                                          .toLowerCase(),
+                                                    )) {
                                                       formInputStatus =
                                                           FormInputStatus.valid;
                                                     } else {
@@ -921,17 +941,18 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                                             TextAlign.left,
                                                         style:
                                                             STextStyles.label(
-                                                                    context)
-                                                                .copyWith(
+                                                          context,
+                                                        ).copyWith(
                                                           color: Theme.of(
-                                                                  context)
+                                                            context,
+                                                          )
                                                               .extension<
                                                                   StackColors>()!
                                                               .textError,
                                                         ),
                                                       ),
                                                     ),
-                                                  )
+                                                  ),
                                               ],
                                             ),
                                           ),
@@ -945,7 +966,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                         for (int i = rows * cols;
                                             i < _seedWordCount - remainder;
                                             i++) ...[
-                                          TableViewCell(
+                                          const TableViewCell(
                                             flex: 1,
                                             child: Column(
                                                 // ... (existing code for input field)
@@ -965,11 +986,13 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                                   textCapitalization:
                                                       TextCapitalization.none,
                                                   key: Key(
-                                                      "restoreMnemonicFormField_$i"),
+                                                    "restoreMnemonicFormField_$i",
+                                                  ),
                                                   decoration:
                                                       _getInputDecorationFor(
-                                                          _inputStatuses[i],
-                                                          "${i + 1}"),
+                                                    _inputStatuses[i],
+                                                    "${i + 1}",
+                                                  ),
                                                   autovalidateMode:
                                                       AutovalidateMode
                                                           .onUserInteraction,
@@ -984,9 +1007,10 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                                       formInputStatus =
                                                           FormInputStatus.empty;
                                                     } else if (_isValidMnemonicWord(
-                                                        value
-                                                            .trim()
-                                                            .toLowerCase())) {
+                                                      value
+                                                          .trim()
+                                                          .toLowerCase(),
+                                                    )) {
                                                       formInputStatus =
                                                           FormInputStatus.valid;
                                                     } else {
@@ -1029,17 +1053,18 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                                             TextAlign.left,
                                                         style:
                                                             STextStyles.label(
-                                                                    context)
-                                                                .copyWith(
+                                                          context,
+                                                        ).copyWith(
                                                           color: Theme.of(
-                                                                  context)
+                                                            context,
+                                                          )
                                                               .extension<
                                                                   StackColors>()!
                                                               .textError,
                                                         ),
                                                       ),
                                                     ),
-                                                  )
+                                                  ),
                                               ],
                                             ),
                                           ),
@@ -1095,7 +1120,9 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                     textCapitalization: TextCapitalization.none,
                                     key: Key("restoreMnemonicFormField_$i"),
                                     decoration: _getInputDecorationFor(
-                                        _inputStatuses[i - 1], "$i"),
+                                      _inputStatuses[i - 1],
+                                      "$i",
+                                    ),
                                     autovalidateMode:
                                         AutovalidateMode.onUserInteraction,
                                     selectionControls:
@@ -1107,7 +1134,8 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                       if (value.isEmpty) {
                                         formInputStatus = FormInputStatus.empty;
                                       } else if (_isValidMnemonicWord(
-                                          value.trim().toLowerCase())) {
+                                        value.trim().toLowerCase(),
+                                      )) {
                                         formInputStatus = FormInputStatus.valid;
                                       } else {
                                         formInputStatus =
@@ -1155,7 +1183,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
                                         ),
                                       ),
                                     ),
-                                  )
+                                  ),
                               ],
                             ),
                           Padding(
diff --git a/lib/pages/add_wallet_views/select_wallet_for_token_view.dart b/lib/pages/add_wallet_views/select_wallet_for_token_view.dart
index d0f466a0c..ecffeaaaf 100644
--- a/lib/pages/add_wallet_views/select_wallet_for_token_view.dart
+++ b/lib/pages/add_wallet_views/select_wallet_for_token_view.dart
@@ -70,7 +70,7 @@ class _SelectWalletForTokenViewState
     ref.read(createSpecialEthWalletRoutingFlag.notifier).state = true;
     Navigator.of(context).pushNamed(
       CreateOrRestoreWalletView.routeName,
-      arguments: CoinEntity(widget.entity.coin),
+      arguments: CoinEntity(widget.entity.cryptoCurrency),
     );
   }
 
@@ -78,7 +78,7 @@ class _SelectWalletForTokenViewState
   Widget build(BuildContext context) {
     final ethWalletInfos = ref
         .watch(pAllWalletsInfo)
-        .where((e) => e.coin == widget.entity.coin)
+        .where((e) => e.coin == widget.entity.cryptoCurrency)
         .toList();
 
     final _hasEthWallets = ethWalletInfos.isNotEmpty;
diff --git a/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart b/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart
index 90163db3f..3443c2084 100644
--- a/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart
+++ b/lib/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart
@@ -30,9 +30,9 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -44,10 +44,10 @@ final createSpecialEthWalletRoutingFlag = StateProvider((ref) => false);
 
 class VerifyRecoveryPhraseView extends ConsumerStatefulWidget {
   const VerifyRecoveryPhraseView({
-    Key? key,
+    super.key,
     required this.wallet,
     required this.mnemonic,
-  }) : super(key: key);
+  });
 
   static const routeName = "/verifyRecoveryPhrase";
 
@@ -154,7 +154,7 @@ class _VerifyRecoveryPhraseViewState
                 DesktopHomeView.routeName,
               ),
             );
-            if (widget.wallet.info.coin == Coin.ethereum) {
+            if (widget.wallet.info.coin is Ethereum) {
               unawaited(
                 Navigator.of(context).pushNamed(
                   EditWalletTokensView.routeName,
@@ -177,7 +177,7 @@ class _VerifyRecoveryPhraseViewState
                 (route) => false,
               ),
             );
-            if (widget.wallet.info.coin == Coin.ethereum) {
+            if (widget.wallet.info.coin is Ethereum) {
               unawaited(
                 Navigator.of(context).pushNamed(
                   EditWalletTokensView.routeName,
@@ -198,12 +198,14 @@ class _VerifyRecoveryPhraseViewState
         );
       }
     } else {
-      unawaited(showFloatingFlushBar(
-        type: FlushBarType.warning,
-        message: "Incorrect. Please try again.",
-        iconAsset: Assets.svg.circleX,
-        context: context,
-      ));
+      unawaited(
+        showFloatingFlushBar(
+          type: FlushBarType.warning,
+          message: "Incorrect. Please try again.",
+          iconAsset: Assets.svg.circleX,
+          context: context,
+        ),
+      );
 
       final int next = Random().nextInt(_mnemonic.length);
       ref
@@ -221,7 +223,10 @@ class _VerifyRecoveryPhraseViewState
   }
 
   Tuple2<List<String>, String> randomize(
-      List<String> mnemonic, int chosenIndex, int wordsToShow) {
+    List<String> mnemonic,
+    int chosenIndex,
+    int wordsToShow,
+  ) {
     final List<String> remaining = [];
     final String chosenWord = mnemonic[chosenIndex];
 
@@ -354,7 +359,8 @@ class _VerifyRecoveryPhraseViewState
                         .extension<StackColors>()!
                         .textFieldDefaultBG,
                     borderRadius: BorderRadius.circular(
-                        Constants.size.circularBorderRadius),
+                      Constants.size.circularBorderRadius,
+                    ),
                   ),
                   child: Padding(
                     padding: const EdgeInsets.symmetric(
@@ -391,11 +397,13 @@ class _VerifyRecoveryPhraseViewState
                         builder: (_, ref, __) {
                           final selectedWord = ref
                               .watch(
-                                  verifyMnemonicSelectedWordStateProvider.state)
+                                verifyMnemonicSelectedWordStateProvider.state,
+                              )
                               .state;
                           final correctWord = ref
                               .watch(
-                                  verifyMnemonicCorrectWordStateProvider.state)
+                                verifyMnemonicCorrectWordStateProvider.state,
+                              )
                               .state;
 
                           return ConstrainedBox(
@@ -406,7 +414,8 @@ class _VerifyRecoveryPhraseViewState
                               onPressed: selectedWord.isNotEmpty
                                   ? () async {
                                       await _continue(
-                                          correctWord == selectedWord);
+                                        correctWord == selectedWord,
+                                      );
                                     }
                                   : null,
                               style: selectedWord.isNotEmpty
@@ -421,9 +430,11 @@ class _VerifyRecoveryPhraseViewState
                                       "Verify",
                                       style: selectedWord.isNotEmpty
                                           ? STextStyles.desktopButtonEnabled(
-                                              context)
+                                              context,
+                                            )
                                           : STextStyles.desktopButtonDisabled(
-                                              context),
+                                              context,
+                                            ),
                                     )
                                   : Text(
                                       "Continue",
diff --git a/lib/pages/address_book_views/address_book_view.dart b/lib/pages/address_book_views/address_book_view.dart
index 61d6233bd..3f47a8cd7 100644
--- a/lib/pages/address_book_views/address_book_view.dart
+++ b/lib/pages/address_book_views/address_book_view.dart
@@ -20,12 +20,14 @@ import 'package:stackwallet/providers/db/main_db_provider.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/ui/address_book_providers/address_book_filter_provider.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart';
 import 'package:stackwallet/widgets/address_book_card.dart';
 import 'package:stackwallet/widgets/background.dart';
@@ -45,7 +47,7 @@ class AddressBookView extends ConsumerStatefulWidget {
 
   static const String routeName = "/addressBook";
 
-  final Coin? coin;
+  final CryptoCurrency? coin;
   final String? filterTerm;
 
   @override
@@ -65,8 +67,10 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
     ref.refresh(addressBookFilterProvider);
 
     if (widget.coin == null) {
-      final List<Coin> coins = Coin.values.toList();
-      coins.remove(Coin.firoTestNet);
+      final coins = [...SupportedCoins.cryptocurrencies];
+      coins.removeWhere(
+        (e) => e is Firo && e.network == CryptoCurrencyNetwork.test,
+      );
 
       final bool showTestNet =
           ref.read(prefsChangeNotifierProvider).showTestNetCoins;
@@ -74,9 +78,10 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
       if (showTestNet) {
         ref.read(addressBookFilterProvider).addAll(coins, false);
       } else {
-        ref
-            .read(addressBookFilterProvider)
-            .addAll(coins.where((e) => !e.isTestNet), false);
+        ref.read(addressBookFilterProvider).addAll(
+              coins.where((e) => e.network != CryptoCurrencyNetwork.test),
+              false,
+            );
       }
     } else {
       ref.read(addressBookFilterProvider).add(widget.coin!, false);
@@ -101,7 +106,7 @@ class _AddressBookViewState extends ConsumerState<AddressBookView> {
 
         addresses.add(
           ContactAddressEntry()
-            ..coinName = wallet.info.coin.name
+            ..coinName = wallet.info.coin.identifier
             ..address = addressString
             ..label = "Current Receiving"
             ..other = wallet.info.name,
diff --git a/lib/pages/address_book_views/subviews/address_book_filter_view.dart b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
index 64eb97552..d973555af 100644
--- a/lib/pages/address_book_views/subviews/address_book_filter_view.dart
+++ b/lib/pages/address_book_views/subviews/address_book_filter_view.dart
@@ -12,10 +12,12 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/providers/ui/address_book_providers/address_book_filter_provider.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -25,7 +27,7 @@ import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class AddressBookFilterView extends ConsumerStatefulWidget {
-  const AddressBookFilterView({Key? key}) : super(key: key);
+  const AddressBookFilterView({super.key});
 
   static const String routeName = "/addressBookFilter";
 
@@ -35,19 +37,23 @@ class AddressBookFilterView extends ConsumerStatefulWidget {
 }
 
 class _AddressBookFilterViewState extends ConsumerState<AddressBookFilterView> {
-  late final List<Coin> _coins;
+  late final List<CryptoCurrency> _coins;
 
   @override
   void initState() {
-    List<Coin> coins = [...Coin.values];
-    coins.remove(Coin.firoTestNet);
+    final coins = [...SupportedCoins.cryptocurrencies];
+    coins.removeWhere(
+      (e) => e is Firo && e.network == CryptoCurrencyNetwork.test,
+    );
 
-    bool showTestNet = ref.read(prefsChangeNotifierProvider).showTestNetCoins;
+    final showTestNet = ref.read(prefsChangeNotifierProvider).showTestNetCoins;
 
     if (showTestNet) {
       _coins = coins.toList(growable: false);
     } else {
-      _coins = coins.where((e) => !e.isTestNet).toList(growable: false);
+      _coins = coins
+          .where((e) => e.network != CryptoCurrencyNetwork.test)
+          .toList(growable: false);
     }
     super.initState();
   }
diff --git a/lib/pages/address_book_views/subviews/coin_select_sheet.dart b/lib/pages/address_book_views/subviews/coin_select_sheet.dart
index 922502abd..fe8b91af5 100644
--- a/lib/pages/address_book_views/subviews/coin_select_sheet.dart
+++ b/lib/pages/address_book_views/subviews/coin_select_sheet.dart
@@ -14,20 +14,24 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_image_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class CoinSelectSheet extends StatelessWidget {
-  const CoinSelectSheet({Key? key}) : super(key: key);
+  const CoinSelectSheet({super.key});
 
   @override
   Widget build(BuildContext context) {
     final maxHeight = MediaQuery.of(context).size.height * 0.60;
-    var coins_ = [...Coin.values];
-    coins_.remove(Coin.firoTestNet);
+    final coins_ = [...SupportedCoins.cryptocurrencies];
+    coins_.removeWhere(
+      (e) => e is Firo && e.network == CryptoCurrencyNetwork.test,
+    );
     return Container(
       decoration: BoxDecoration(
         color: Theme.of(context).extension<StackColors>()!.popupBG,
@@ -85,7 +89,11 @@ class CoinSelectSheet extends StatelessWidget {
                       shrinkWrap: true,
                       itemCount: showTestNet
                           ? coins_.length
-                          : coins_.where((e) => !e.isTestNet).length,
+                          : coins_
+                              .where(
+                                (e) => e.network != CryptoCurrencyNetwork.test,
+                              )
+                              .length,
                       itemBuilder: (builderContext, index) {
                         final coin = coins_[index];
                         return Padding(
diff --git a/lib/pages/address_book_views/subviews/contact_details_view.dart b/lib/pages/address_book_views/subviews/contact_details_view.dart
index 419081f2b..d01cd2335 100644
--- a/lib/pages/address_book_views/subviews/contact_details_view.dart
+++ b/lib/pages/address_book_views/subviews/contact_details_view.dart
@@ -27,7 +27,6 @@ import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -41,10 +40,10 @@ import 'package:tuple/tuple.dart';
 
 class ContactDetailsView extends ConsumerStatefulWidget {
   const ContactDetailsView({
-    Key? key,
+    super.key,
     required this.contactId,
     this.clipboard = const ClipboardWrapper(),
-  }) : super(key: key);
+  });
 
   static const String routeName = "/contactDetails";
 
@@ -79,7 +78,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
         .sortByTimestampDesc()
         .findAll();
 
-    List<Tuple2<String, Transaction>> result = [];
+    final List<Tuple2<String, Transaction>> result = [];
 
     for (final tx in transactions) {
       result.add(Tuple2(tx.walletId, tx));
@@ -151,7 +150,7 @@ class _ContactDetailsViewState extends ConsumerState<ContactDetailsView> {
                     height: 20,
                   ),
                   onPressed: () {
-                    bool isFavorite = _contact.isFavorite;
+                    final bool isFavorite = _contact.isFavorite;
 
                     ref.read(addressBookServiceProvider).editContact(
                         _contact.copyWith(isFavorite: !isFavorite));
diff --git a/lib/pages/address_book_views/subviews/contact_popup.dart b/lib/pages/address_book_views/subviews/contact_popup.dart
index ae31f8c09..a22b205aa 100644
--- a/lib/pages/address_book_views/subviews/contact_popup.dart
+++ b/lib/pages/address_book_views/subviews/contact_popup.dart
@@ -27,7 +27,6 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
@@ -56,8 +55,8 @@ class ContactPopUp extends ConsumerWidget {
 
     final active = ref.read(currentWalletIdProvider);
 
-    bool hasActiveWallet = active != null;
-    bool isExchangeFlow =
+    final bool hasActiveWallet = active != null;
+    final bool isExchangeFlow =
         ref.watch(exchangeFlowIsActiveStateProvider.state).state;
 
     final addresses = contact.addressesSorted.where((e) {
diff --git a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
index 7381de7cc..00a735c93 100644
--- a/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
+++ b/lib/pages/address_book_views/subviews/new_contact_address_entry_form.dart
@@ -19,6 +19,7 @@ import 'package:stackwallet/pages/address_book_views/subviews/coin_select_sheet.
 import 'package:stackwallet/providers/providers.dart';
 // import 'package:stackwallet/providers/global/should_show_lockscreen_on_resume_state_provider.dart';
 import 'package:stackwallet/providers/ui/address_book_providers/address_entry_data_provider.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/address_utils.dart';
@@ -26,10 +27,11 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
@@ -62,7 +64,7 @@ class _NewContactAddressEntryFormState
   late final FocusNode addressLabelFocusNode;
   late final FocusNode addressFocusNode;
 
-  List<Coin> coins = [];
+  List<CryptoCurrency> coins = [];
 
   @override
   void initState() {
@@ -72,7 +74,7 @@ class _NewContactAddressEntryFormState
       ..text = ref.read(addressEntryDataProvider(widget.id)).address ?? "";
     addressLabelFocusNode = FocusNode();
     addressFocusNode = FocusNode();
-    coins = [...Coin.values];
+    coins = [...SupportedCoins.cryptocurrencies];
     super.initState();
   }
 
@@ -88,15 +90,20 @@ class _NewContactAddressEntryFormState
   @override
   Widget build(BuildContext context) {
     final isDesktop = Util.isDesktop;
-    bool showTestNet = ref.watch(
-      prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
-    );
     if (isDesktop) {
-      coins = [...Coin.values];
+      coins = [...SupportedCoins.cryptocurrencies];
+      coins.removeWhere(
+        (e) => e is Firo && e.network == CryptoCurrencyNetwork.test,
+      );
 
-      coins.remove(Coin.firoTestNet);
+      final showTestNet =
+          ref.read(prefsChangeNotifierProvider).showTestNetCoins;
       if (showTestNet) {
-        coins = coins.where((e) => !e.isTestNet).toList();
+        coins = coins.toList();
+      } else {
+        coins = coins
+            .where((e) => e.network != CryptoCurrencyNetwork.test)
+            .toList();
       }
     }
 
@@ -104,7 +111,7 @@ class _NewContactAddressEntryFormState
       children: [
         if (isDesktop)
           DropdownButtonHideUnderline(
-            child: DropdownButton2<Coin>(
+            child: DropdownButton2<CryptoCurrency>(
               hint: Text(
                 "Select cryptocurrency",
                 style: STextStyles.fieldLabel(context),
@@ -128,10 +135,12 @@ class _NewContactAddressEntryFormState
                 ),
               ),
               isExpanded: true,
-              value: ref.watch(addressEntryDataProvider(widget.id)
-                  .select((value) => value.coin)),
+              value: ref.watch(
+                addressEntryDataProvider(widget.id)
+                    .select((value) => value.coin),
+              ),
               onChanged: (value) {
-                if (value is Coin) {
+                if (value is CryptoCurrency) {
                   ref.read(addressEntryDataProvider(widget.id)).coin = value;
                 }
               },
@@ -145,7 +154,7 @@ class _NewContactAddressEntryFormState
               ),
               items: [
                 ...coins.map(
-                  (coin) => DropdownMenuItem<Coin>(
+                  (coin) => DropdownMenuItem<CryptoCurrency>(
                     value: coin,
                     child: Padding(
                       padding: const EdgeInsets.symmetric(vertical: 4),
@@ -205,7 +214,7 @@ class _NewContactAddressEntryFormState
                         context: context,
                         builder: (_) => const CoinSelectSheet(),
                       ).then((value) {
-                        if (value is Coin) {
+                        if (value is CryptoCurrency) {
                           ref.read(addressEntryDataProvider(widget.id)).coin =
                               value;
                         }
@@ -214,8 +223,10 @@ class _NewContactAddressEntryFormState
                     child: Row(
                       mainAxisAlignment: MainAxisAlignment.spaceBetween,
                       children: [
-                        ref.watch(addressEntryDataProvider(widget.id)
-                                    .select((value) => value.coin)) ==
+                        ref.watch(
+                                  addressEntryDataProvider(widget.id)
+                                      .select((value) => value.coin),
+                                ) ==
                                 null
                             ? Text(
                                 "Select cryptocurrency",
@@ -245,8 +256,9 @@ class _NewContactAddressEntryFormState
                                   Text(
                                     ref
                                         .watch(
-                                            addressEntryDataProvider(widget.id)
-                                                .select((value) => value.coin))!
+                                          addressEntryDataProvider(widget.id)
+                                              .select((value) => value.coin),
+                                        )!
                                         .prettyName,
                                     style: STextStyles.itemSubtitle12(context),
                                   ),
@@ -335,8 +347,10 @@ class _NewContactAddressEntryFormState
               suffixIcon: UnconstrainedBox(
                 child: Row(
                   children: [
-                    if (ref.watch(addressEntryDataProvider(widget.id)
-                            .select((value) => value.address)) !=
+                    if (ref.watch(
+                          addressEntryDataProvider(widget.id)
+                              .select((value) => value.address),
+                        ) !=
                         null)
                       TextFieldIconButton(
                         key: const Key("addAddressBookClearAddressButtonKey"),
@@ -348,8 +362,10 @@ class _NewContactAddressEntryFormState
                         },
                         child: const XIcon(),
                       ),
-                    if (ref.watch(addressEntryDataProvider(widget.id)
-                            .select((value) => value.address)) ==
+                    if (ref.watch(
+                          addressEntryDataProvider(widget.id)
+                              .select((value) => value.address),
+                        ) ==
                         null)
                       TextFieldIconButton(
                         key: const Key("addAddressPasteAddressButtonKey"),
@@ -372,8 +388,10 @@ class _NewContactAddressEntryFormState
                         child: const ClipboardIcon(),
                       ),
                     if (!Util.isDesktop &&
-                        ref.watch(addressEntryDataProvider(widget.id)
-                                .select((value) => value.address)) ==
+                        ref.watch(
+                              addressEntryDataProvider(widget.id)
+                                  .select((value) => value.address),
+                            ) ==
                             null)
                       TextFieldIconButton(
                         key: const Key("addAddressBookEntryScanQrButtonKey"),
@@ -419,11 +437,12 @@ class _NewContactAddressEntryFormState
                                     .read(addressEntryDataProvider(widget.id))
                                     .coin !=
                                 null) {
-                              if (AddressUtils.validateAddress(
-                                  qrResult.rawContent,
-                                  ref
-                                      .read(addressEntryDataProvider(widget.id))
-                                      .coin!)) {
+                              if (ref
+                                  .read(addressEntryDataProvider(widget.id))
+                                  .coin!
+                                  .validateAddress(
+                                    qrResult.rawContent,
+                                  )) {
                                 addressController.text = qrResult.rawContent;
                                 ref
                                     .read(addressEntryDataProvider(widget.id))
@@ -436,8 +455,9 @@ class _NewContactAddressEntryFormState
                             //         .state)
                             //     .state = true;
                             Logging.instance.log(
-                                "Failed to get camera permissions to scan address qr code: $e\n$s",
-                                level: LogLevel.Warning);
+                              "Failed to get camera permissions to scan address qr code: $e\n$s",
+                              level: LogLevel.Warning,
+                            );
                           }
                         },
                         child: const QrCodeIcon(),
@@ -466,8 +486,10 @@ class _NewContactAddressEntryFormState
             },
           ),
         ),
-        if (!ref.watch(addressEntryDataProvider(widget.id)
-                .select((value) => value.isValidAddress)) &&
+        if (!ref.watch(
+              addressEntryDataProvider(widget.id)
+                  .select((value) => value.isValidAddress),
+            ) &&
             addressController.text.isNotEmpty)
           Row(
             children: [
diff --git a/lib/pages/buy_view/buy_form.dart b/lib/pages/buy_view/buy_form.dart
index d986a1e3c..67021d8f8 100644
--- a/lib/pages/buy_view/buy_form.dart
+++ b/lib/pages/buy_view/buy_form.dart
@@ -30,16 +30,17 @@ import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/buy/buy_response.dart';
 import 'package:stackwallet/services/buy/simplex/simplex_api.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/address_utils.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/custom_loading_overlay.dart';
@@ -58,14 +59,14 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
 class BuyForm extends ConsumerStatefulWidget {
   const BuyForm({
-    Key? key,
+    super.key,
     this.coin,
     this.tokenContract,
     this.clipboard = const ClipboardWrapper(),
     this.scanner = const BarcodeScannerWrapper(),
-  }) : super(key: key);
+  });
 
-  final Coin? coin;
+  final CryptoCurrency? coin;
 
   final ClipboardInterface clipboard;
   final BarcodeScannerInterface scanner;
@@ -76,7 +77,7 @@ class BuyForm extends ConsumerStatefulWidget {
 }
 
 class _BuyFormState extends ConsumerState<BuyForm> {
-  late final Coin? coin;
+  late final CryptoCurrency? coin;
 
   late final ClipboardInterface clipboard;
   late final BarcodeScannerInterface scanner;
@@ -249,7 +250,8 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                   ],
                 ),
               );
-            })
+            },
+          )
         : await Navigator.of(context).push(
             MaterialPageRoute<dynamic>(
               builder: (_) => CryptoSelectionView(
@@ -386,7 +388,8 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                   ],
                 ),
               );
-            })
+            },
+          )
         : await Navigator.of(context).push(
             MaterialPageRoute<dynamic>(
               builder: (_) => FiatSelectionView(
@@ -410,7 +413,7 @@ class _BuyFormState extends ConsumerState<BuyForm> {
     if (ticker == null) return false;
 
     try {
-      coinFromTickerCaseInsensitive(ticker);
+      SupportedCoins.getCryptoCurrencyForTicker(ticker);
       return true;
     } on ArgumentError catch (_) {
       return false;
@@ -501,7 +504,7 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                             ),
                           ),
                         ],
-                      )
+                      ),
                     ],
                   ),
                 ),
@@ -517,9 +520,10 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                   child: Text(
                     "Ok",
                     style: STextStyles.button(context).copyWith(
-                        color: Theme.of(context)
-                            .extension<StackColors>()!
-                            .accentColorDark),
+                      color: Theme.of(context)
+                          .extension<StackColors>()!
+                          .accentColorDark,
+                    ),
                   ),
                   onPressed: () {
                     Navigator.of(context).pop();
@@ -589,7 +593,7 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                           ),
                         ),
                       ],
-                    )
+                    ),
                   ],
                 ),
               ),
@@ -606,9 +610,10 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                 child: Text(
                   "Ok",
                   style: STextStyles.button(context).copyWith(
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .accentColorDark),
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .accentColorDark,
+                  ),
                 ),
                 onPressed: () {
                   Navigator.of(context).pop();
@@ -701,7 +706,8 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                   ],
                 ),
               );
-            })
+            },
+          )
         : await Navigator.of(context).push(
             MaterialPageRoute<dynamic>(
               builder: (_) => BuyQuotePreviewView(
@@ -742,7 +748,7 @@ class _BuyFormState extends ConsumerState<BuyForm> {
         Fiat.fromJson({'ticker': 'USD', 'name': 'United States Dollar'});
     selectedCrypto = Crypto.fromJson({
       'ticker': widget.coin?.ticker ?? 'BTC',
-      'name': widget.coin?.prettyName ?? 'Bitcoin'
+      'name': widget.coin?.prettyName ?? 'Bitcoin',
     });
 
     // THIS IS BAD. No way to be certain the simplex ticker points to the same
@@ -907,7 +913,9 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                       children: <Widget>[
                         Container(
                           padding: const EdgeInsets.symmetric(
-                              vertical: 3, horizontal: 6),
+                            vertical: 3,
+                            horizontal: 6,
+                          ),
                           decoration: BoxDecoration(
                             color: Theme.of(context)
                                 .extension<StackColors>()!
@@ -916,12 +924,14 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                           ),
                           child: Text(
                             format.simpleCurrencySymbol(
-                                selectedFiat?.ticker ?? "ERR".toUpperCase()),
+                              selectedFiat?.ticker ?? "ERR".toUpperCase(),
+                            ),
                             textAlign: TextAlign.center,
                             style: STextStyles.smallMed12(context).copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .accentColorDark),
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorDark,
+                            ),
                           ),
                         ),
                         const SizedBox(
@@ -976,7 +986,7 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                     });
                     validateAmount();
                   },
-                )
+                ),
               ],
             ),
             SizedBox(
@@ -1026,47 +1036,53 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                   fit: BoxFit.scaleDown,
                   child: Padding(
                     padding: const EdgeInsets.all(12),
-                    child: Row(children: [
-                      const SizedBox(width: 2),
-                      buyWithFiat
-                          ? Container(
-                              padding: const EdgeInsets.symmetric(
-                                  vertical: 3, horizontal: 6),
-                              decoration: BoxDecoration(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .currencyListItemBG,
-                                borderRadius: BorderRadius.circular(4),
-                              ),
-                              child: Text(
-                                format.simpleCurrencySymbol(
-                                    selectedFiat?.ticker.toUpperCase() ??
-                                        "ERR"),
-                                textAlign: TextAlign.center,
-                                style: STextStyles.smallMed12(context).copyWith(
+                    child: Row(
+                      children: [
+                        const SizedBox(width: 2),
+                        buyWithFiat
+                            ? Container(
+                                padding: const EdgeInsets.symmetric(
+                                  vertical: 3,
+                                  horizontal: 6,
+                                ),
+                                decoration: BoxDecoration(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .currencyListItemBG,
+                                  borderRadius: BorderRadius.circular(4),
+                                ),
+                                child: Text(
+                                  format.simpleCurrencySymbol(
+                                    selectedFiat?.ticker.toUpperCase() ?? "ERR",
+                                  ),
+                                  textAlign: TextAlign.center,
+                                  style:
+                                      STextStyles.smallMed12(context).copyWith(
                                     color: Theme.of(context)
                                         .extension<StackColors>()!
-                                        .accentColorDark),
+                                        .accentColorDark,
+                                  ),
+                                ),
+                              )
+                            : CoinIconForTicker(
+                                ticker: selectedCrypto?.ticker ?? "BTC",
+                                size: 20,
                               ),
-                            )
-                          : CoinIconForTicker(
-                              ticker: selectedCrypto?.ticker ?? "BTC",
-                              size: 20,
-                            ),
-                      SizedBox(
-                          width: buyWithFiat
-                              ? 8
-                              : 10), // maybe make isDesktop-aware?
-                      Text(
-                        buyWithFiat
-                            ? selectedFiat?.ticker ?? "ERR"
-                            : selectedCrypto?.ticker ?? "ERR",
-                        style: STextStyles.smallMed14(context).copyWith(
+                        SizedBox(
+                          width: buyWithFiat ? 8 : 10,
+                        ), // maybe make isDesktop-aware?
+                        Text(
+                          buyWithFiat
+                              ? selectedFiat?.ticker ?? "ERR"
+                              : selectedCrypto?.ticker ?? "ERR",
+                          style: STextStyles.smallMed14(context).copyWith(
                             color: Theme.of(context)
                                 .extension<StackColors>()!
-                                .accentColorDark),
-                      ),
-                    ]),
+                                .accentColorDark,
+                          ),
+                        ),
+                      ],
+                    ),
                   ),
                 ),
                 suffixIcon: Padding(
@@ -1078,7 +1094,8 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                         _buyAmountController.text.isNotEmpty
                             ? TextFieldIconButton(
                                 key: const Key(
-                                    "buyViewClearAmountFieldButtonKey"),
+                                  "buyViewClearAmountFieldButtonKey",
+                                ),
                                 onTap: () {
                                   // if (_BuyFormState.buyWithFiat) {
                                   //   _buyAmountController.text = _BuyFormState
@@ -1099,7 +1116,8 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                               )
                             : TextFieldIconButton(
                                 key: const Key(
-                                    "buyViewPasteAddressFieldButtonKey"),
+                                  "buyViewPasteAddressFieldButtonKey",
+                                ),
                                 onTap: () async {
                                   final ClipboardData? data = await clipboard
                                       .getData(Clipboard.kTextPlain);
@@ -1150,7 +1168,7 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                     text: "Choose from Stack",
                     onTap: () {
                       try {
-                        final coin = coinFromTickerCaseInsensitive(
+                        final coin = SupportedCoins.getCryptoCurrencyForTicker(
                           selectedCrypto!.ticker,
                         );
                         Navigator.of(context)
@@ -1236,7 +1254,8 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                           _addressToggleFlag
                               ? TextFieldIconButton(
                                   key: const Key(
-                                      "buyViewClearAddressFieldButtonKey"),
+                                    "buyViewClearAddressFieldButtonKey",
+                                  ),
                                   onTap: () {
                                     _receiveAddressController.text = "";
                                     _address = "";
@@ -1248,7 +1267,8 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                                 )
                               : TextFieldIconButton(
                                   key: const Key(
-                                      "buyViewPasteAddressFieldButtonKey"),
+                                    "buyViewPasteAddressFieldButtonKey",
+                                  ),
                                   onTap: () async {
                                     final ClipboardData? data = await clipboard
                                         .getData(Clipboard.kTextPlain);
@@ -1257,7 +1277,9 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                                       String content = data.text!.trim();
                                       if (content.contains("\n")) {
                                         content = content.substring(
-                                            0, content.indexOf("\n"));
+                                          0,
+                                          content.indexOf("\n"),
+                                        );
                                       }
 
                                       _receiveAddressController.text = content;
@@ -1300,7 +1322,8 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                                               child: Text(
                                                 "Address book",
                                                 style: STextStyles.desktopH3(
-                                                    context),
+                                                  context,
+                                                ),
                                               ),
                                             ),
                                             const DesktopDialogCloseButton(),
@@ -1308,9 +1331,15 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                                         ),
                                         Expanded(
                                           child: AddressBookAddressChooser(
-                                            coin: coinFromTickerCaseInsensitive(
-                                                selectedCrypto!.ticker
-                                                    .toString()),
+                                            coin: SupportedCoins
+                                                .cryptocurrencies
+                                                .firstWhere(
+                                              (e) =>
+                                                  e.ticker.toLowerCase() ==
+                                                  selectedCrypto!.ticker
+                                                      .toString()
+                                                      .toLowerCase(),
+                                            ),
                                           ),
                                         ),
                                       ],
@@ -1352,21 +1381,25 @@ class _BuyFormState extends ConsumerState<BuyForm> {
                                   if (FocusScope.of(context).hasFocus) {
                                     FocusScope.of(context).unfocus();
                                     await Future<void>.delayed(
-                                        const Duration(milliseconds: 75));
+                                      const Duration(milliseconds: 75),
+                                    );
                                   }
 
                                   final qrResult = await scanner.scan();
 
                                   Logging.instance.log(
-                                      "qrResult content: ${qrResult.rawContent}",
-                                      level: LogLevel.Info);
+                                    "qrResult content: ${qrResult.rawContent}",
+                                    level: LogLevel.Info,
+                                  );
 
                                   final results = AddressUtils.parseUri(
-                                      qrResult.rawContent);
+                                    qrResult.rawContent,
+                                  );
 
                                   Logging.instance.log(
-                                      "qrResult parsed: $results",
-                                      level: LogLevel.Info);
+                                    "qrResult parsed: $results",
+                                    level: LogLevel.Info,
+                                  );
 
                                   if (results.isNotEmpty) {
                                     // auto fill address
diff --git a/lib/pages/buy_view/buy_in_wallet_view.dart b/lib/pages/buy_view/buy_in_wallet_view.dart
index b0183eb79..18f4d643a 100644
--- a/lib/pages/buy_view/buy_in_wallet_view.dart
+++ b/lib/pages/buy_view/buy_in_wallet_view.dart
@@ -12,21 +12,21 @@ import 'package:flutter/material.dart';
 import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
 import 'package:stackwallet/pages/buy_view/buy_view.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 
 class BuyInWalletView extends StatefulWidget {
   const BuyInWalletView({
-    Key? key,
+    super.key,
     required this.coin,
     this.contract,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/stackBuyInWalletView";
 
-  final Coin? coin;
+  final CryptoCurrency? coin;
   final EthContract? contract;
 
   @override
@@ -34,7 +34,7 @@ class BuyInWalletView extends StatefulWidget {
 }
 
 class _BuyInWalletViewState extends State<BuyInWalletView> {
-  late final Coin? coin;
+  late final CryptoCurrency? coin;
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/pages/buy_view/buy_view.dart b/lib/pages/buy_view/buy_view.dart
index e87fa3398..5bfed3475 100644
--- a/lib/pages/buy_view/buy_view.dart
+++ b/lib/pages/buy_view/buy_view.dart
@@ -15,18 +15,18 @@ import 'package:stackwallet/pages/buy_view/buy_form.dart';
 import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart';
 import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 import 'package:stackwallet/widgets/tor_subscription.dart';
 
 class BuyView extends ConsumerStatefulWidget {
   const BuyView({
-    Key? key,
+    super.key,
     this.coin,
     this.tokenContract,
-  }) : super(key: key);
+  });
 
-  final Coin? coin;
+  final CryptoCurrency? coin;
   final EthContract? tokenContract;
 
   static const String routeName = "/stackBuyView";
@@ -36,7 +36,7 @@ class BuyView extends ConsumerStatefulWidget {
 }
 
 class _BuyViewState extends ConsumerState<BuyView> {
-  Coin? coin;
+  CryptoCurrency? coin;
   EthContract? tokenContract;
 
   late bool torEnabled;
diff --git a/lib/pages/buy_view/sub_widgets/crypto_selection_view.dart b/lib/pages/buy_view/sub_widgets/crypto_selection_view.dart
index b7ae75de0..bf101ec72 100644
--- a/lib/pages/buy_view/sub_widgets/crypto_selection_view.dart
+++ b/lib/pages/buy_view/sub_widgets/crypto_selection_view.dart
@@ -14,11 +14,11 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/buy/response_objects/crypto.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
@@ -53,9 +53,11 @@ class _CryptoSelectionViewState extends ConsumerState<CryptoSelectionView> {
   void filter(String text) {
     setState(() {
       _coins = [
-        ...coins.where((e) =>
-            e.name.toLowerCase().contains(text.toLowerCase()) ||
-            e.ticker.toLowerCase().contains(text.toLowerCase()))
+        ...coins.where(
+          (e) =>
+              e.name.toLowerCase().contains(text.toLowerCase()) ||
+              e.ticker.toLowerCase().contains(text.toLowerCase()),
+        ),
       ];
     });
   }
@@ -66,10 +68,12 @@ class _CryptoSelectionViewState extends ConsumerState<CryptoSelectionView> {
 
     coins = [...widget.coins];
     coins.sort(
-        (a, b) => a.ticker.toLowerCase().compareTo(b.ticker.toLowerCase()));
-    for (Coin coin in Coin.values.reversed) {
-      int index = coins.indexWhere((element) =>
-          element.ticker.toLowerCase() == coin.ticker.toLowerCase());
+      (a, b) => a.ticker.toLowerCase().compareTo(b.ticker.toLowerCase()),
+    );
+    for (final coin in SupportedCoins.cryptocurrencies.reversed) {
+      final index = coins.indexWhere(
+        (element) => element.ticker.toLowerCase() == coin.ticker.toLowerCase(),
+      );
       if (index > 0) {
         final currency = coins.removeAt(index);
         coins.insert(0, currency);
@@ -104,7 +108,8 @@ class _CryptoSelectionViewState extends ConsumerState<CryptoSelectionView> {
                   if (FocusScope.of(context).hasFocus) {
                     FocusScope.of(context).unfocus();
                     await Future<void>.delayed(
-                        const Duration(milliseconds: 50));
+                      const Duration(milliseconds: 50),
+                    );
                   }
                   if (mounted) {
                     Navigator.of(context).pop();
@@ -265,7 +270,7 @@ bool isStackCoin(String? ticker) {
   if (ticker == null) return false;
 
   try {
-    coinFromTickerCaseInsensitive(ticker);
+    SupportedCoins.getCryptoCurrencyForTicker(ticker);
     return true;
   } on ArgumentError catch (_) {
     return false;
@@ -289,10 +294,10 @@ bool isStackCoin(String? ticker) {
 /// caller must ensure [Coin] for ticker exists
 class CoinIconForTicker extends ConsumerWidget {
   const CoinIconForTicker({
-    Key? key,
+    super.key,
     required this.ticker,
     required this.size,
-  }) : super(key: key);
+  });
 
   final String ticker;
   final double size;
@@ -300,7 +305,7 @@ class CoinIconForTicker extends ConsumerWidget {
   @override
   Widget build(BuildContext context, WidgetRef ref) {
     try {
-      final coin = coinFromTickerCaseInsensitive(ticker);
+      final coin = SupportedCoins.getCryptoCurrencyForTicker(ticker);
       return SvgPicture.file(
         File(
           ref.watch(coinIconProvider(coin)),
@@ -321,7 +326,7 @@ class CoinIconForTicker extends ConsumerWidget {
 // }) {
 //   String? iconAsset = /*isStackCoin(ticker)
 //       ?*/
-//       Assets.svg.iconFor(coin: coinFromTickerCaseInsensitive(ticker));
+//       Assets.svg.iconFor(coin: SupportedCoins.getCryptoCurrencyForTicker(ticker));
 //   // : Assets.svg.buyIconFor(ticker);
 //   return (iconAsset != null)
 //       ? SvgPicture.asset(iconAsset, height: size, width: size)
diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart
index 5de0003d9..ff058859e 100644
--- a/lib/pages/cashfusion/cashfusion_view.dart
+++ b/lib/pages/cashfusion/cashfusion_view.dart
@@ -23,8 +23,8 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart';
 import 'package:stackwallet/widgets/background.dart';
@@ -56,7 +56,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> {
   late final FocusNode portFocusNode;
   late final TextEditingController fusionRoundController;
   late final FocusNode fusionRoundFocusNode;
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   bool _enableSSLCheckbox = false;
   bool _enableStartButton = false;
diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart
index 78bc9ccc7..40844cde7 100644
--- a/lib/pages/cashfusion/fusion_progress_view.dart
+++ b/lib/pages/cashfusion/fusion_progress_view.dart
@@ -17,10 +17,10 @@ import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provi
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart';
 import 'package:stackwallet/widgets/background.dart';
@@ -44,7 +44,7 @@ class FusionProgressView extends ConsumerStatefulWidget {
 }
 
 class _FusionProgressViewState extends ConsumerState<FusionProgressView> {
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   Future<bool> _requestAndProcessCancel() async {
     final shouldCancel = await showDialog<bool?>(
diff --git a/lib/pages/coin_control/coin_control_view.dart b/lib/pages/coin_control/coin_control_view.dart
index b57281dd7..b82b13914 100644
--- a/lib/pages/coin_control/coin_control_view.dart
+++ b/lib/pages/coin_control/coin_control_view.dart
@@ -24,7 +24,6 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
@@ -49,12 +48,12 @@ enum CoinControlViewType {
 
 class CoinControlView extends ConsumerStatefulWidget {
   const CoinControlView({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.type,
     this.requestedTotal,
     this.selectedUTXOs,
-  }) : super(key: key);
+  });
 
   static const routeName = "/coinControl";
 
@@ -128,7 +127,7 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
         filter: CCFilter.all,
         sort: _sort,
         searchTerm: "",
-        coin: coin,
+        cryptoCurrency: coin,
       );
     } else {
       _map = null;
@@ -141,7 +140,7 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
                 : CCFilter.available,
         sort: _sort,
         searchTerm: _isSearching ? searchController.text : "",
-        coin: coin,
+        cryptoCurrency: coin,
       );
     }
 
@@ -682,7 +681,7 @@ class _CoinControlViewState extends ConsumerState<CoinControlView> {
                                                       );
                                           final selectedSum =
                                               selectedSumInt.toAmountAsRaw(
-                                            fractionDigits: coin.decimals,
+                                            fractionDigits: coin.fractionDigits,
                                           );
                                           return Text(
                                             ref
diff --git a/lib/pages/coin_control/utxo_card.dart b/lib/pages/coin_control/utxo_card.dart
index 74c5d3b82..5688d2b2a 100644
--- a/lib/pages/coin_control/utxo_card.dart
+++ b/lib/pages/coin_control/utxo_card.dart
@@ -17,7 +17,6 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
@@ -26,14 +25,14 @@ import 'package:stackwallet/widgets/rounded_container.dart';
 
 class UtxoCard extends ConsumerStatefulWidget {
   const UtxoCard({
-    Key? key,
+    super.key,
     required this.utxo,
     required this.walletId,
     required this.onSelectedChanged,
     required this.initialSelectedState,
     required this.canSelect,
     this.onPressed,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final UTXO utxo;
@@ -138,7 +137,7 @@ class _UtxoCardState extends ConsumerState<UtxoCard> {
                         Text(
                           ref.watch(pAmountFormatter(coin)).format(
                                 utxo.value.toAmountAsRaw(
-                                  fractionDigits: coin.decimals,
+                                  fractionDigits: coin.fractionDigits,
                                 ),
                               ),
                           style: STextStyles.w600_14(context),
diff --git a/lib/pages/coin_control/utxo_details_view.dart b/lib/pages/coin_control/utxo_details_view.dart
index 7c32fee2f..ce6dce597 100644
--- a/lib/pages/coin_control/utxo_details_view.dart
+++ b/lib/pages/coin_control/utxo_details_view.dart
@@ -20,7 +20,6 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
@@ -37,10 +36,10 @@ import 'package:stackwallet/widgets/rounded_container.dart';
 
 class UtxoDetailsView extends ConsumerStatefulWidget {
   const UtxoDetailsView({
-    Key? key,
+    super.key,
     required this.utxoId,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   static const routeName = "/utxoDetails";
 
@@ -244,7 +243,7 @@ class _UtxoDetailsViewState extends ConsumerState<UtxoDetailsView> {
                           Text(
                             ref.watch(pAmountFormatter(coin)).format(
                                   utxo!.value.toAmountAsRaw(
-                                    fractionDigits: coin.decimals,
+                                    fractionDigits: coin.fractionDigits,
                                   ),
                                 ),
                             style: STextStyles.pageTitleH2(context),
diff --git a/lib/pages/exchange_view/choose_from_stack_view.dart b/lib/pages/exchange_view/choose_from_stack_view.dart
index 553c11628..d6aa4f837 100644
--- a/lib/pages/exchange_view/choose_from_stack_view.dart
+++ b/lib/pages/exchange_view/choose_from_stack_view.dart
@@ -13,8 +13,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -24,11 +24,11 @@ import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_
 
 class ChooseFromStackView extends ConsumerStatefulWidget {
   const ChooseFromStackView({
-    Key? key,
+    super.key,
     required this.coin,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   static const String routeName = "/chooseFromStack";
 
@@ -38,7 +38,7 @@ class ChooseFromStackView extends ConsumerStatefulWidget {
 }
 
 class _ChooseFromStackViewState extends ConsumerState<ChooseFromStackView> {
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   @override
   void initState() {
diff --git a/lib/pages/exchange_view/confirm_change_now_send.dart b/lib/pages/exchange_view/confirm_change_now_send.dart
index 85072c98c..5135d96ee 100644
--- a/lib/pages/exchange_view/confirm_change_now_send.dart
+++ b/lib/pages/exchange_view/confirm_change_now_send.dart
@@ -26,7 +26,6 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
@@ -47,14 +46,14 @@ import 'package:uuid/uuid.dart';
 
 class ConfirmChangeNowSendView extends ConsumerStatefulWidget {
   const ConfirmChangeNowSendView({
-    Key? key,
+    super.key,
     required this.txData,
     required this.walletId,
     this.routeOnSuccessName = WalletView.routeName,
     required this.trade,
     this.shouldSendPublicFiroFunds,
     this.fromDesktopStep4 = false,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/confirmChangeNowSend";
 
diff --git a/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart b/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart
index 3a23ea331..7698d875b 100644
--- a/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart
+++ b/lib/pages/exchange_view/exchange_coin_selection/exchange_currency_selection_view.dart
@@ -22,10 +22,10 @@ import 'package:stackwallet/services/exchange/exchange.dart';
 import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
 import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
 import 'package:stackwallet/services/exchange/trocador/trocador_exchange.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
@@ -143,7 +143,8 @@ class _ExchangeCurrencySelectionViewState
               onPressed: () async {
                 Navigator.of(context, rootNavigator: isDesktop).pop();
                 _currencies = await _showUpdatingCurrencies(
-                    whileFuture: _loadCurrencies());
+                  whileFuture: _loadCurrencies(),
+                );
                 setState(() {});
               },
             ),
@@ -164,15 +165,17 @@ class _ExchangeCurrencySelectionViewState
         .filter()
         .isFiatEqualTo(false)
         .and()
-        .group((q) => widget.isFixedRate
-            ? q
-                .rateTypeEqualTo(SupportedRateType.both)
-                .or()
-                .rateTypeEqualTo(SupportedRateType.fixed)
-            : q
-                .rateTypeEqualTo(SupportedRateType.both)
-                .or()
-                .rateTypeEqualTo(SupportedRateType.estimated))
+        .group(
+          (q) => widget.isFixedRate
+              ? q
+                  .rateTypeEqualTo(SupportedRateType.both)
+                  .or()
+                  .rateTypeEqualTo(SupportedRateType.fixed)
+              : q
+                  .rateTypeEqualTo(SupportedRateType.both)
+                  .or()
+                  .rateTypeEqualTo(SupportedRateType.estimated),
+        )
         .sortByIsStackCoin()
         .thenByName()
         .findAll();
@@ -180,9 +183,10 @@ class _ExchangeCurrencySelectionViewState
     // If using Tor, filter exchanges which do not support Tor.
     if (Prefs.instance.useTor) {
       if (Exchange.exchangeNamesWithTorSupport.isNotEmpty) {
-        currencies.removeWhere((element) => !Exchange
-            .exchangeNamesWithTorSupport
-            .contains(element.exchangeName));
+        currencies.removeWhere(
+          (element) => !Exchange.exchangeNamesWithTorSupport
+              .contains(element.exchangeName),
+        );
       }
     }
 
@@ -193,7 +197,8 @@ class _ExchangeCurrencySelectionViewState
     final List<Currency> distinctCurrencies = [];
     for (final currency in currencies) {
       if (!distinctCurrencies.any(
-          (e) => e.ticker.toLowerCase() == currency.ticker.toLowerCase())) {
+        (e) => e.ticker.toLowerCase() == currency.ticker.toLowerCase(),
+      )) {
         distinctCurrencies.add(currency);
       }
     }
@@ -207,23 +212,29 @@ class _ExchangeCurrencySelectionViewState
       }
 
       return _currencies
-          .where((e) =>
-              e.name.toLowerCase().contains(text.toLowerCase()) ||
-              e.ticker.toLowerCase().contains(text.toLowerCase()))
+          .where(
+            (e) =>
+                e.name.toLowerCase().contains(text.toLowerCase()) ||
+                e.ticker.toLowerCase().contains(text.toLowerCase()),
+          )
           .toList();
     } else {
       if (text.isEmpty) {
         return _currencies
-            .where((e) =>
-                e.ticker.toLowerCase() != widget.pairedTicker!.toLowerCase())
+            .where(
+              (e) =>
+                  e.ticker.toLowerCase() != widget.pairedTicker!.toLowerCase(),
+            )
             .toList();
       }
 
       return _currencies
-          .where((e) =>
-              e.ticker.toLowerCase() != widget.pairedTicker!.toLowerCase() &&
-              (e.name.toLowerCase().contains(text.toLowerCase()) ||
-                  e.ticker.toLowerCase().contains(text.toLowerCase())))
+          .where(
+            (e) =>
+                e.ticker.toLowerCase() != widget.pairedTicker!.toLowerCase() &&
+                (e.name.toLowerCase().contains(text.toLowerCase()) ||
+                    e.ticker.toLowerCase().contains(text.toLowerCase())),
+          )
           .toList();
     }
   }
@@ -266,7 +277,8 @@ class _ExchangeCurrencySelectionViewState
                   if (FocusScope.of(context).hasFocus) {
                     FocusScope.of(context).unfocus();
                     await Future<void>.delayed(
-                        const Duration(milliseconds: 50));
+                      const Duration(milliseconds: 50),
+                    );
                   }
                   if (mounted) {
                     Navigator.of(context).pop();
@@ -353,18 +365,24 @@ class _ExchangeCurrencySelectionViewState
           Flexible(
             child: Builder(
               builder: (context) {
-                final coins = Coin.values.where((e) =>
-                    e.ticker.toLowerCase() !=
-                    widget.pairedTicker?.toLowerCase());
+                final coins = SupportedCoins.cryptocurrencies.where(
+                  (e) =>
+                      e.ticker.toLowerCase() !=
+                      widget.pairedTicker?.toLowerCase(),
+                );
 
                 final items = filter(_searchString);
 
                 final walletCoins = items
-                    .where((currency) => coins
-                        .where((coin) =>
-                            coin.ticker.toLowerCase() ==
-                            currency.ticker.toLowerCase())
-                        .isNotEmpty)
+                    .where(
+                      (currency) => coins
+                          .where(
+                            (coin) =>
+                                coin.ticker.toLowerCase() ==
+                                currency.ticker.toLowerCase(),
+                          )
+                          .isNotEmpty,
+                    )
                     .toList();
 
                 // sort alphabetically by name
@@ -402,7 +420,9 @@ class _ExchangeCurrencySelectionViewState
                                   height: 24,
                                   child: isStackCoin(items[index].ticker)
                                       ? CoinIconForTicker(
-                                          ticker: items[index].ticker, size: 24)
+                                          ticker: items[index].ticker,
+                                          size: 24,
+                                        )
                                       // ? getIconForTicker(
                                       //     items[index].ticker,
                                       //     size: 24,
diff --git a/lib/pages/exchange_view/exchange_form.dart b/lib/pages/exchange_view/exchange_form.dart
index a233a35c7..2dbd40094 100644
--- a/lib/pages/exchange_view/exchange_form.dart
+++ b/lib/pages/exchange_view/exchange_form.dart
@@ -40,10 +40,11 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount_unit.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_loading_overlay.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -59,14 +60,14 @@ import 'package:uuid/uuid.dart';
 
 class ExchangeForm extends ConsumerStatefulWidget {
   const ExchangeForm({
-    Key? key,
+    super.key,
     this.walletId,
     this.coin,
     this.contract,
-  }) : super(key: key);
+  });
 
   final String? walletId;
-  final Coin? coin;
+  final CryptoCurrency? coin;
   final EthContract? contract;
 
   @override
@@ -75,7 +76,7 @@ class ExchangeForm extends ConsumerStatefulWidget {
 
 class _ExchangeFormState extends ConsumerState<ExchangeForm> {
   late final String? walletId;
-  late final Coin? coin;
+  late final CryptoCurrency? coin;
   late final bool walletInitiated;
 
   List<Exchange> get usableExchanges {
@@ -172,7 +173,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
         .tryParse(
           value,
           locale: ref.read(localeServiceChangeNotifierProvider).locale,
-          coin: Coin.bitcoin, // dummy value (not used due to override)
+          coin: Bitcoin(CryptoCurrencyNetwork
+              .main), // dummy value (not used due to override)
           overrideWithDecimalPlacesFromString: true,
         )
         ?.decimal;
@@ -607,12 +609,12 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
     }
   }
 
-  bool isWalletCoin(Coin? coin, bool isSend) {
+  bool isWalletCoin(CryptoCurrency? coin, bool isSend) {
     if (coin == null) {
       return false;
     }
 
-    String? ticker = isSend
+    final String? ticker = isSend
         ? ref.read(efCurrencyPairProvider).send?.ticker
         : ref.read(efCurrencyPairProvider).receive?.ticker;
 
diff --git a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart
index 95734e94c..5f4ed4a6b 100644
--- a/lib/pages/exchange_view/exchange_step_views/step_2_view.dart
+++ b/lib/pages/exchange_view/exchange_step_views/step_2_view.dart
@@ -19,12 +19,12 @@ import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_3_view.
 import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/address_utils.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/background.dart';
@@ -72,7 +72,7 @@ class _Step2ViewState extends ConsumerState<Step2View> {
 
   bool isStackCoin(String ticker) {
     try {
-      coinFromTickerCaseInsensitive(ticker);
+      SupportedCoins.getCryptoCurrencyForTicker(ticker);
       return true;
     } on ArgumentError catch (_) {
       return false;
@@ -207,10 +207,13 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                   text: "Choose from Stack",
                                   onTap: () {
                                     try {
-                                      final coin =
-                                          coinFromTickerCaseInsensitive(
-                                        model.receiveTicker,
-                                      );
+                                      final coin = SupportedCoins
+                                          .cryptocurrencies
+                                          .firstWhere((e) =>
+                                              e.ticker.toLowerCase() ==
+                                              model.receiveTicker
+                                                  .toLowerCase());
+
                                       Navigator.of(context)
                                           .pushNamed(
                                         ChooseFromStackView.routeName,
@@ -480,10 +483,12 @@ class _Step2ViewState extends ConsumerState<Step2View> {
                                     text: "Choose from Stack",
                                     onTap: () {
                                       try {
-                                        final coin =
-                                            coinFromTickerCaseInsensitive(
-                                          model.sendTicker,
-                                        );
+                                        final coin = SupportedCoins
+                                            .cryptocurrencies
+                                            .firstWhere((e) =>
+                                                e.ticker.toLowerCase() ==
+                                                model.sendTicker.toLowerCase());
+
                                         Navigator.of(context)
                                             .pushNamed(
                                           ChooseFromStackView.routeName,
diff --git a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
index 496975116..ba9e37ad6 100644
--- a/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
+++ b/lib/pages/exchange_view/exchange_step_views/step_4_view.dart
@@ -26,15 +26,18 @@ import 'package:stackwallet/pages/send_view/sub_widgets/building_transaction_dia
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/route_generator.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
@@ -72,7 +75,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
 
   bool _isWalletCoinAndHasWallet(String ticker, WidgetRef ref) {
     try {
-      final coin = coinFromTickerCaseInsensitive(ticker);
+      final coin = SupportedCoins.getCryptoCurrencyForTicker(ticker);
       return ref
           .read(pWallets)
           .wallets
@@ -194,9 +197,9 @@ class _Step4ViewState extends ConsumerState<Step4View> {
     );
   }
 
-  Future<void> _confirmSend(Tuple2<String, Coin> tuple) async {
+  Future<void> _confirmSend(Tuple2<String, CryptoCurrency> tuple) async {
     final bool firoPublicSend;
-    if (tuple.item2 == Coin.firo) {
+    if (tuple.item2 is Firo) {
       final result = await _showSendFromFiroBalanceSelectSheet(tuple.item1);
       if (result == null) {
         return;
@@ -210,7 +213,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
     final wallet = ref.read(pWallets).getWallet(tuple.item1);
 
     final Amount amount = model.sendAmount.toAmount(
-      fractionDigits: wallet.info.coin.decimals,
+      fractionDigits: wallet.info.coin.fractionDigits,
     );
     final address = model.trade!.payInAddress;
 
@@ -258,8 +261,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
           ),
         );
       } else {
-        final memo = wallet.info.coin == Coin.stellar ||
-                wallet.info.coin == Coin.stellarTestnet
+        final memo = wallet.info.coin is Stellar
             ? model.trade!.payInExtraId.isNotEmpty
                 ? model.trade!.payInExtraId
                 : null
@@ -851,16 +853,23 @@ class _Step4ViewState extends ConsumerState<Step4View> {
                                                         .useMaterialPageRoute,
                                                 builder:
                                                     (BuildContext context) {
-                                                  final coin =
-                                                      coinFromTickerCaseInsensitive(
-                                                    model.trade!.payInCurrency,
+                                                  final coin = SupportedCoins
+                                                      .cryptocurrencies
+                                                      .firstWhere(
+                                                    (e) =>
+                                                        e.ticker
+                                                            .toLowerCase() ==
+                                                        model.trade!
+                                                            .payInCurrency
+                                                            .toLowerCase(),
                                                   );
+
                                                   return SendFromView(
                                                     coin: coin,
                                                     amount: model.sendAmount
                                                         .toAmount(
                                                       fractionDigits:
-                                                          coin.decimals,
+                                                          coin.fractionDigits,
                                                     ),
                                                     address: model
                                                         .trade!.payInAddress,
diff --git a/lib/pages/exchange_view/send_from_view.dart b/lib/pages/exchange_view/send_from_view.dart
index a97b94a28..b0dbd0252 100644
--- a/lib/pages/exchange_view/send_from_view.dart
+++ b/lib/pages/exchange_view/send_from_view.dart
@@ -23,14 +23,17 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
+import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
@@ -56,7 +59,7 @@ class SendFromView extends ConsumerStatefulWidget {
 
   static const String routeName = "/sendFrom";
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final Amount amount;
   final String address;
   final Trade trade;
@@ -68,7 +71,7 @@ class SendFromView extends ConsumerStatefulWidget {
 }
 
 class _SendFromViewState extends ConsumerState<SendFromView> {
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final Amount amount;
   late final String address;
   late final Trade trade;
@@ -279,7 +282,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
 
       // if not firo then do normal send
       if (shouldSendPublicFiroFunds == null) {
-        final memo = coin == Coin.stellar || coin == Coin.stellarTestnet
+        final memo = coin is Stellar
             ? trade.payInExtraId.isNotEmpty
                 ? trade.payInExtraId
                 : null
@@ -427,7 +430,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
 
     final coin = ref.watch(pWalletCoin(walletId));
 
-    final isFiro = coin == Coin.firoTestNet || coin == Coin.firo;
+    final isFiro = coin is Firo;
 
     return RoundedWhiteContainer(
       padding: const EdgeInsets.all(0),
@@ -602,10 +605,7 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
             children: [
               Container(
                 decoration: BoxDecoration(
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .colorForCoin(coin)
-                      .withOpacity(0.5),
+                  color: ref.watch(pCoinColor(coin)).withOpacity(0.5),
                   borderRadius: BorderRadius.circular(
                     Constants.size.circularBorderRadius,
                   ),
diff --git a/lib/pages/exchange_view/sub_widgets/exchange_provider_option.dart b/lib/pages/exchange_view/sub_widgets/exchange_provider_option.dart
index e891f148e..926fa5ddb 100644
--- a/lib/pages/exchange_view/sub_widgets/exchange_provider_option.dart
+++ b/lib/pages/exchange_view/sub_widgets/exchange_provider_option.dart
@@ -16,16 +16,18 @@ import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
 import 'package:stackwallet/providers/exchange/exchange_form_state_provider.dart';
 import 'package:stackwallet/providers/global/locale_provider.dart';
 import 'package:stackwallet/services/exchange/exchange.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/amount/amount_unit.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/animated_text.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/exchange/trocador/trocador_kyc_info_button.dart';
@@ -33,11 +35,11 @@ import 'package:stackwallet/widgets/exchange/trocador/trocador_rating_type_enum.
 
 class ExchangeOption extends ConsumerStatefulWidget {
   const ExchangeOption({
-    Key? key,
+    super.key,
     required this.exchange,
     required this.fixedRate,
     required this.reversed,
-  }) : super(key: key);
+  });
 
   final Exchange exchange;
   final bool fixedRate;
@@ -92,9 +94,9 @@ class _ExchangeOptionState extends ConsumerState<ExchangeOption> {
 
                         int decimals;
                         try {
-                          decimals = coinFromTickerCaseInsensitive(
-                                  receivingCurrency.ticker)
-                              .decimals;
+                          decimals = SupportedCoins.getCryptoCurrencyForTicker(
+                            receivingCurrency.ticker,
+                          ).fractionDigits;
                         } catch (_) {
                           decimals = 8; // some reasonable alternative
                         }
@@ -109,10 +111,11 @@ class _ExchangeOptionState extends ConsumerState<ExchangeOption> {
                               .toAmount(fractionDigits: decimals);
                         }
 
-                        Coin? coin;
+                        CryptoCurrency? coin;
                         try {
-                          coin = coinFromTickerCaseInsensitive(
-                              receivingCurrency.ticker);
+                          coin = SupportedCoins.getCryptoCurrencyForTicker(
+                            receivingCurrency.ticker,
+                          );
                         } catch (_) {
                           coin = null;
                         }
@@ -128,7 +131,8 @@ class _ExchangeOptionState extends ConsumerState<ExchangeOption> {
                               localeServiceChangeNotifierProvider
                                   .select((value) => value.locale),
                             ),
-                            coin: Coin.bitcoin, // some sane default
+                            coin: Bitcoin(CryptoCurrencyNetwork
+                                .main), // some sane default
                             maxDecimals: 8, // some sane default
                           );
                           rateString = "1 ${sendCurrency.ticker.toUpperCase()} "
diff --git a/lib/pages/exchange_view/trade_details_view.dart b/lib/pages/exchange_view/trade_details_view.dart
index ab3aa0b1f..33d516d8e 100644
--- a/lib/pages/exchange_view/trade_details_view.dart
+++ b/lib/pages/exchange_view/trade_details_view.dart
@@ -33,6 +33,7 @@ import 'package:stackwallet/services/exchange/exchange.dart';
 import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
 import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
 import 'package:stackwallet/services/exchange/trocador/trocador_exchange.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
@@ -40,10 +41,10 @@ import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -58,13 +59,13 @@ import 'package:url_launcher/url_launcher.dart';
 
 class TradeDetailsView extends ConsumerStatefulWidget {
   const TradeDetailsView({
-    Key? key,
+    super.key,
     required this.tradeId,
     required this.transactionIfSentFromStack,
     required this.walletId,
     required this.walletName,
     this.clipboard = const ClipboardWrapper(),
-  }) : super(key: key);
+  });
 
   static const String routeName = "/tradeDetails";
 
@@ -87,9 +88,9 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
   bool isStackCoin(String ticker) {
     try {
       try {
-        coinFromTickerCaseInsensitive(ticker);
+        SupportedCoins.getCryptoCurrencyForTicker(ticker);
       } catch (_) {}
-      coinFromPrettyName(ticker);
+      SupportedCoins.getCryptoCurrencyByPrettyName(ticker);
       return true;
     } on ArgumentError catch (_) {
       return false;
@@ -167,8 +168,11 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
     final bool sentFromStack =
         transactionIfSentFromStack != null && walletId != null;
 
-    final trade = ref.watch(tradesServiceProvider.select(
-        (value) => value.trades.firstWhere((e) => e.tradeId == tradeId)));
+    final trade = ref.watch(
+      tradesServiceProvider.select(
+        (value) => value.trades.firstWhere((e) => e.tradeId == tradeId),
+      ),
+    );
 
     final bool hasTx = sentFromStack ||
         !(trade.status == "New" ||
@@ -273,16 +277,19 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                       label: "Send from Stack",
                       buttonHeight: ButtonHeight.l,
                       onPressed: () {
-                        Coin coin;
+                        CryptoCurrency coin;
                         try {
-                          coin = coinFromTickerCaseInsensitive(
-                              trade.payInCurrency);
+                          coin = SupportedCoins.getCryptoCurrencyForTicker(
+                            trade.payInCurrency,
+                          );
                         } catch (_) {
-                          coin = coinFromPrettyName(trade.payInCurrency);
+                          coin = SupportedCoins.getCryptoCurrencyByPrettyName(
+                            trade.payInCurrency,
+                          );
                         }
                         final amount = Amount.fromDecimal(
                           sendAmount,
-                          fractionDigits: coin.decimals,
+                          fractionDigits: coin.fractionDigits,
                         );
                         final address = trade.payInAddress;
 
@@ -368,28 +375,34 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                           const SizedBox(
                             height: 4,
                           ),
-                          Builder(builder: (context) {
-                            String text;
-                            try {
-                              final coin = coinFromTickerCaseInsensitive(
-                                  trade.payInCurrency);
-                              final amount = sendAmount.toAmount(
-                                  fractionDigits: coin.decimals);
-                              text = ref
-                                  .watch(pAmountFormatter(coin))
-                                  .format(amount);
-                            } catch (_) {
-                              text = sendAmount.toStringAsFixed(
+                          Builder(
+                            builder: (context) {
+                              String text;
+                              try {
+                                final coin =
+                                    SupportedCoins.getCryptoCurrencyForTicker(
+                                  trade.payInCurrency,
+                                );
+                                final amount = sendAmount.toAmount(
+                                  fractionDigits: coin.fractionDigits,
+                                );
+                                text = ref
+                                    .watch(pAmountFormatter(coin))
+                                    .format(amount);
+                              } catch (_) {
+                                text = sendAmount.toStringAsFixed(
                                   trade.payInCurrency.toLowerCase() == "xmr"
                                       ? 12
-                                      : 8);
-                            }
+                                      : 8,
+                                );
+                              }
 
-                            return SelectableText(
-                              "-$text ${trade.payInCurrency.toUpperCase()}",
-                              style: STextStyles.itemSubtitle(context),
-                            );
-                          }),
+                              return SelectableText(
+                                "-$text ${trade.payInCurrency.toUpperCase()}",
+                                style: STextStyles.itemSubtitle(context),
+                              );
+                            },
+                          ),
                         ],
                       ),
                       if (!isDesktop)
@@ -464,7 +477,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                               ),
                             ),
                           ],
-                        )
+                        ),
                     ],
                   ),
                   const SizedBox(
@@ -512,7 +525,8 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                               Text(
                                 "Amount",
                                 style: STextStyles.desktopTextExtraExtraSmall(
-                                    context),
+                                  context,
+                                ),
                               ),
                               const SizedBox(
                                 height: 2,
@@ -520,8 +534,8 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                               Text(
                                 "${trade.payInAmount} ${trade.payInCurrency.toUpperCase()}",
                                 style: STextStyles.desktopTextExtraExtraSmall(
-                                        context)
-                                    .copyWith(
+                                  context,
+                                ).copyWith(
                                   color: Theme.of(context)
                                       .extension<StackColors>()!
                                       .textDark,
@@ -542,43 +556,44 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                   ),
                   child: RichText(
                     text: TextSpan(
-                        text:
-                            "You must send at least ${sendAmount.toStringAsFixed(
-                          trade.payInCurrency.toLowerCase() == "xmr" ? 12 : 8,
-                        )} ${trade.payInCurrency.toUpperCase()}. ",
-                        style: isDesktop
-                            ? STextStyles.desktopTextExtraExtraSmall(context)
-                                .copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .accentColorRed)
-                            : STextStyles.label(context).copyWith(
-                                color: Theme.of(context)
-                                    .extension<StackColors>()!
-                                    .warningForeground,
-                              ),
-                        children: [
-                          TextSpan(
-                            text:
-                                "If you send less than ${sendAmount.toStringAsFixed(
-                              trade.payInCurrency.toLowerCase() == "xmr"
-                                  ? 12
-                                  : 8,
-                            )} ${trade.payInCurrency.toUpperCase()}, your transaction may not be converted and it may not be refunded.",
-                            style: isDesktop
-                                ? STextStyles.desktopTextExtraExtraSmall(
-                                        context)
-                                    .copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorRed)
-                                : STextStyles.label(context).copyWith(
-                                    color: Theme.of(context)
-                                        .extension<StackColors>()!
-                                        .warningForeground,
-                                  ),
-                          ),
-                        ]),
+                      text:
+                          "You must send at least ${sendAmount.toStringAsFixed(
+                        trade.payInCurrency.toLowerCase() == "xmr" ? 12 : 8,
+                      )} ${trade.payInCurrency.toUpperCase()}. ",
+                      style: isDesktop
+                          ? STextStyles.desktopTextExtraExtraSmall(context)
+                              .copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .accentColorRed,
+                            )
+                          : STextStyles.label(context).copyWith(
+                              color: Theme.of(context)
+                                  .extension<StackColors>()!
+                                  .warningForeground,
+                            ),
+                      children: [
+                        TextSpan(
+                          text:
+                              "If you send less than ${sendAmount.toStringAsFixed(
+                            trade.payInCurrency.toLowerCase() == "xmr" ? 12 : 8,
+                          )} ${trade.payInCurrency.toUpperCase()}, your transaction may not be converted and it may not be refunded.",
+                          style: isDesktop
+                              ? STextStyles.desktopTextExtraExtraSmall(
+                                  context,
+                                ).copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .accentColorRed,
+                                )
+                              : STextStyles.label(context).copyWith(
+                                  color: Theme.of(context)
+                                      .extension<StackColors>()!
+                                      .warningForeground,
+                                ),
+                        ),
+                      ],
+                    ),
                   ),
                 ),
               ),
@@ -613,8 +628,10 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                     CustomTextButton(
                       text: "View transaction",
                       onTap: () {
-                        final Coin coin =
-                            coinFromTickerCaseInsensitive(trade.payInCurrency);
+                        final CryptoCurrency coin =
+                            SupportedCoins.getCryptoCurrencyForTicker(
+                          trade.payInCurrency,
+                        );
 
                         if (isDesktop) {
                           Navigator.of(context).push(
@@ -638,7 +655,10 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                           Navigator.of(context).pushNamed(
                             TransactionDetailsView.routeName,
                             arguments: Tuple3(
-                                transactionIfSentFromStack!, coin, walletId!),
+                              transactionIfSentFromStack!,
+                              coin,
+                              walletId!,
+                            ),
                           );
                         }
                       },
@@ -787,14 +807,15 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                                         width: width + 20,
                                         height: width + 20,
                                         child: QrImageView(
-                                            data: trade.payInAddress,
-                                            size: width,
-                                            backgroundColor: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .popupBG,
-                                            foregroundColor: Theme.of(context)
-                                                .extension<StackColors>()!
-                                                .accentColorDark),
+                                          data: trade.payInAddress,
+                                          size: width,
+                                          backgroundColor: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .popupBG,
+                                          foregroundColor: Theme.of(context)
+                                              .extension<StackColors>()!
+                                              .accentColorDark,
+                                        ),
                                       ),
                                     ),
                                   ),
@@ -812,14 +833,16 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                                         style: Theme.of(context)
                                             .extension<StackColors>()!
                                             .getSecondaryEnabledButtonStyle(
-                                                context),
+                                              context,
+                                            ),
                                         child: Text(
                                           "Cancel",
                                           style: STextStyles.button(context)
                                               .copyWith(
-                                                  color: Theme.of(context)
-                                                      .extension<StackColors>()!
-                                                      .accentColorDark),
+                                            color: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .accentColorDark,
+                                          ),
                                         ),
                                       ),
                                     ),
@@ -1005,8 +1028,10 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                     height: 4,
                   ),
                   SelectableText(
-                    ref.watch(tradeNoteServiceProvider
-                        .select((value) => value.getNote(tradeId: tradeId))),
+                    ref.watch(
+                      tradeNoteServiceProvider
+                          .select((value) => value.getNote(tradeId: tradeId)),
+                    ),
                     style: STextStyles.itemSubtitle12(context),
                   ),
                 ],
@@ -1132,7 +1157,8 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                       if (isDesktop)
                         SelectableText(
                           Format.extractDateFrom(
-                              trade.timestamp.millisecondsSinceEpoch ~/ 1000),
+                            trade.timestamp.millisecondsSinceEpoch ~/ 1000,
+                          ),
                           style: STextStyles.desktopTextExtraExtraSmall(context)
                               .copyWith(
                             color: Theme.of(context)
@@ -1145,13 +1171,15 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                   if (!isDesktop)
                     SelectableText(
                       Format.extractDateFrom(
-                          trade.timestamp.millisecondsSinceEpoch ~/ 1000),
+                        trade.timestamp.millisecondsSinceEpoch ~/ 1000,
+                      ),
                       style: STextStyles.itemSubtitle12(context),
                     ),
                   if (isDesktop)
                     IconCopyButton(
                       data: Format.extractDateFrom(
-                          trade.timestamp.millisecondsSinceEpoch ~/ 1000),
+                        trade.timestamp.millisecondsSinceEpoch ~/ 1000,
+                      ),
                     ),
                 ],
               ),
@@ -1265,7 +1293,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
                                 .infoItemIcons,
                             width: 12,
                           ),
-                        )
+                        ),
                       ],
                     ),
                 ],
@@ -1352,15 +1380,19 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
               SecondaryButton(
                 label: "Send from Stack",
                 onPressed: () {
-                  Coin coin;
+                  CryptoCurrency coin;
                   try {
-                    coin = coinFromTickerCaseInsensitive(trade.payInCurrency);
+                    coin = SupportedCoins.getCryptoCurrencyForTicker(
+                      trade.payInCurrency,
+                    );
                   } catch (_) {
-                    coin = coinFromPrettyName(trade.payInCurrency);
+                    coin = SupportedCoins.getCryptoCurrencyByPrettyName(
+                      trade.payInCurrency,
+                    );
                   }
                   final amount = Amount.fromDecimal(
                     sendAmount,
-                    fractionDigits: coin.decimals,
+                    fractionDigits: coin.fractionDigits,
                   );
                   final address = trade.payInAddress;
 
diff --git a/lib/pages/exchange_view/wallet_initiated_exchange_view.dart b/lib/pages/exchange_view/wallet_initiated_exchange_view.dart
index 3b6c41093..9804a46c2 100644
--- a/lib/pages/exchange_view/wallet_initiated_exchange_view.dart
+++ b/lib/pages/exchange_view/wallet_initiated_exchange_view.dart
@@ -19,8 +19,8 @@ import 'package:stackwallet/providers/exchange/exchange_form_state_provider.dart
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -28,16 +28,16 @@ import 'package:stackwallet/widgets/custom_loading_overlay.dart';
 
 class WalletInitiatedExchangeView extends ConsumerStatefulWidget {
   const WalletInitiatedExchangeView({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.coin,
     this.contract,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/walletInitiatedExchange";
 
   final String walletId;
-  final Coin coin;
+  final CryptoCurrency coin;
   final EthContract? contract;
 
   @override
@@ -48,7 +48,7 @@ class WalletInitiatedExchangeView extends ConsumerStatefulWidget {
 class _WalletInitiatedExchangeViewState
     extends ConsumerState<WalletInitiatedExchangeView> {
   late final String walletId;
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   bool _initialCachePopulationUnderway = false;
 
diff --git a/lib/pages/monkey/monkey_loaded_view.dart b/lib/pages/monkey/monkey_loaded_view.dart
index 60f66a0ed..11c277b53 100644
--- a/lib/pages/monkey/monkey_loaded_view.dart
+++ b/lib/pages/monkey/monkey_loaded_view.dart
@@ -13,7 +13,7 @@
 //
 // import 'package:stackwallet/themes/stack_colors.dart';
 // import 'package:stackwallet/utilities/assets.dart';
-// import 'package:stackwallet/utilities/enums/coin_enum.dart';
+//
 // import 'package:stackwallet/utilities/text_styles.dart';
 // import 'package:stackwallet/widgets/background.dart';
 // import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -163,7 +163,7 @@
 //
 //   @override
 //   Widget build(BuildContext context) {
-//     final Coin coin = ref.watch(managerProvider.select((value) => value.coin));
+//     final CryptoCurrency coin = ref.watch(managerProvider.select((value) => value.coin));
 //     final wallet =  ref.watch(walletsChangeNotifierProvider
 //         .select((value) => value.getWallet(widget.walletId)));
 //
diff --git a/lib/pages/ordinals/ordinal_details_view.dart b/lib/pages/ordinals/ordinal_details_view.dart
index 590bca266..995c8fbb7 100644
--- a/lib/pages/ordinals/ordinal_details_view.dart
+++ b/lib/pages/ordinals/ordinal_details_view.dart
@@ -19,7 +19,6 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
@@ -30,10 +29,10 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class OrdinalDetailsView extends ConsumerStatefulWidget {
   const OrdinalDetailsView({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.ordinal,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final Ordinal ordinal;
@@ -113,7 +112,7 @@ class _OrdinalDetailsViewState extends ConsumerState<OrdinalDetailsView> {
                         : ref.watch(pAmountFormatter(coin)).format(
                               Amount(
                                 rawValue: BigInt.from(utxo!.value),
-                                fractionDigits: coin.decimals,
+                                fractionDigits: coin.fractionDigits,
                               ),
                             ),
                   ),
diff --git a/lib/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart b/lib/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart
index ae5bfed00..6c53e5370 100644
--- a/lib/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart
+++ b/lib/pages/paynym/dialogs/confirm_paynym_connect_dialog.dart
@@ -15,9 +15,9 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
@@ -26,19 +26,19 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
 
 class ConfirmPaynymConnectDialog extends ConsumerWidget {
   const ConfirmPaynymConnectDialog({
-    Key? key,
+    super.key,
     required this.nymName,
     required this.locale,
     required this.onConfirmPressed,
     required this.amount,
     required this.coin,
-  }) : super(key: key);
+  });
 
   final String nymName;
   final String locale;
   final VoidCallback onConfirmPressed;
   final Amount amount;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   String get title => "Connect to $nymName";
 
diff --git a/lib/pages/paynym/dialogs/paynym_details_popup.dart b/lib/pages/paynym/dialogs/paynym_details_popup.dart
index f5f970d38..922b775c3 100644
--- a/lib/pages/paynym/dialogs/paynym_details_popup.dart
+++ b/lib/pages/paynym/dialogs/paynym_details_popup.dart
@@ -28,7 +28,6 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
@@ -44,10 +43,10 @@ import 'package:tuple/tuple.dart';
 
 class PaynymDetailsPopup extends ConsumerStatefulWidget {
   const PaynymDetailsPopup({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.accountLite,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final PaynymAccountLite accountLite;
diff --git a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart
index c09baca9d..48a8a3684 100644
--- a/lib/pages/paynym/subwidgets/desktop_paynym_details.dart
+++ b/lib/pages/paynym/subwidgets/desktop_paynym_details.dart
@@ -26,7 +26,7 @@ import 'package:stackwallet/providers/global/locale_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
diff --git a/lib/pages/pinpad_views/lock_screen_view.dart b/lib/pages/pinpad_views/lock_screen_view.dart
index e4ecb85a4..17d405206 100644
--- a/lib/pages/pinpad_views/lock_screen_view.dart
+++ b/lib/pages/pinpad_views/lock_screen_view.dart
@@ -23,7 +23,7 @@ import 'package:stackwallet/themes/stack_colors.dart';
 // import 'package:stackwallet/providers/global/should_show_lockscreen_on_resume_state_provider.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/biometrics.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
diff --git a/lib/pages/receive_view/addresses/address_card.dart b/lib/pages/receive_view/addresses/address_card.dart
index 51e1402a3..9489712a4 100644
--- a/lib/pages/receive_view/addresses/address_card.dart
+++ b/lib/pages/receive_view/addresses/address_card.dart
@@ -30,9 +30,9 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/address_utils.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/simple_edit_button.dart';
@@ -53,7 +53,7 @@ class AddressCard extends ConsumerStatefulWidget {
 
   final int addressId;
   final String walletId;
-  final Coin coin;
+  final CryptoCurrency coin;
   final ClipboardInterface clipboard;
   final VoidCallback? onPressed;
 
diff --git a/lib/pages/receive_view/addresses/address_details_view.dart b/lib/pages/receive_view/addresses/address_details_view.dart
index 6da7be3c9..341bc4e8a 100644
--- a/lib/pages/receive_view/addresses/address_details_view.dart
+++ b/lib/pages/receive_view/addresses/address_details_view.dart
@@ -23,7 +23,6 @@ import 'package:stackwallet/providers/db/main_db_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/address_utils.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
@@ -40,10 +39,10 @@ import 'package:stackwallet/widgets/transaction_card.dart';
 
 class AddressDetailsView extends ConsumerStatefulWidget {
   const AddressDetailsView({
-    Key? key,
+    super.key,
     required this.addressId,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/addressDetailsView";
 
@@ -398,7 +397,11 @@ class _AddressDetailsViewState extends ConsumerState<AddressDetailsView> {
                     height: 12,
                   ),
                 if (!isDesktop)
-                  coin == Coin.bitcoincash || coin == Coin.bitcoincashTestnet
+                  ref
+                              .watch(pWallets)
+                              .getWallet(widget.walletId)
+                              .isarTransactionVersion ==
+                          2
                       ? _AddressDetailsTxV2List(
                           walletId: widget.walletId,
                           address: address,
@@ -418,10 +421,10 @@ class _AddressDetailsViewState extends ConsumerState<AddressDetailsView> {
 
 class _AddressDetailsTxList extends StatelessWidget {
   const _AddressDetailsTxList({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.address,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final Address address;
diff --git a/lib/pages/receive_view/addresses/address_qr_popup.dart b/lib/pages/receive_view/addresses/address_qr_popup.dart
index 6e0c2e15b..c5ff43576 100644
--- a/lib/pages/receive_view/addresses/address_qr_popup.dart
+++ b/lib/pages/receive_view/addresses/address_qr_popup.dart
@@ -25,23 +25,23 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/address_utils.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
 class AddressQrPopup extends StatefulWidget {
   const AddressQrPopup({
-    Key? key,
+    super.key,
     required this.addressString,
     required this.coin,
     this.clipboard = const ClipboardWrapper(),
-  }) : super(key: key);
+  });
 
   final String addressString;
-  final Coin coin;
+  final CryptoCurrency coin;
   final ClipboardInterface clipboard;
 
   @override
@@ -54,12 +54,12 @@ class _AddressQrPopupState extends State<AddressQrPopup> {
 
   Future<void> _capturePng(bool shouldSaveInsteadOfShare) async {
     try {
-      RenderRepaintBoundary boundary =
+      final RenderRepaintBoundary boundary =
           _qrKey.currentContext?.findRenderObject() as RenderRepaintBoundary;
-      ui.Image image = await boundary.toImage();
-      ByteData? byteData =
+      final ui.Image image = await boundary.toImage();
+      final ByteData? byteData =
           await image.toByteData(format: ui.ImageByteFormat.png);
-      Uint8List pngBytes = byteData!.buffer.asUint8List();
+      final Uint8List pngBytes = byteData!.buffer.asUint8List();
 
       if (shouldSaveInsteadOfShare) {
         if (isDesktop) {
diff --git a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
index 4fd9d0cf1..6b9b228b6 100644
--- a/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
+++ b/lib/pages/receive_view/generate_receiving_uri_qr_code_view.dart
@@ -28,10 +28,12 @@ import 'package:stackwallet/utilities/address_utils.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ecash.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -45,15 +47,15 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
 class GenerateUriQrCodeView extends StatefulWidget {
   const GenerateUriQrCodeView({
-    Key? key,
+    super.key,
     required this.coin,
     required this.receivingAddress,
     this.clipboard = const ClipboardWrapper(),
-  }) : super(key: key);
+  });
 
   static const String routeName = "/generateUriQrCodeView";
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final String receivingAddress;
   final ClipboardInterface clipboard;
 
@@ -76,12 +78,12 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
 
   Future<void> _capturePng(bool shouldSaveInsteadOfShare) async {
     try {
-      RenderRepaintBoundary boundary =
+      final RenderRepaintBoundary boundary =
           _qrKey.currentContext?.findRenderObject() as RenderRepaintBoundary;
-      ui.Image image = await boundary.toImage();
-      ByteData? byteData =
+      final ui.Image image = await boundary.toImage();
+      final ByteData? byteData =
           await image.toByteData(format: ui.ImageByteFormat.png);
-      Uint8List pngBytes = byteData!.buffer.asUint8List();
+      final Uint8List pngBytes = byteData!.buffer.asUint8List();
 
       if (shouldSaveInsteadOfShare) {
         if (Util.isDesktop) {
@@ -149,7 +151,7 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
       return null;
     }
 
-    Map<String, String> queryParams = {};
+    final Map<String, String> queryParams = {};
 
     if (amountString.isNotEmpty) {
       queryParams["amount"] = amountString;
@@ -159,9 +161,7 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
     }
 
     String receivingAddress = widget.receivingAddress;
-    if ((widget.coin == Coin.bitcoincash ||
-            widget.coin == Coin.eCash ||
-            widget.coin == Coin.bitcoincashTestnet) &&
+    if ((widget.coin is Bitcoincash || widget.coin is Ecash) &&
         receivingAddress.contains(":")) {
       // remove cash addr prefix
       receivingAddress = receivingAddress.split(":").sublist(1).join();
@@ -256,9 +256,7 @@ class _GenerateUriQrCodeViewState extends State<GenerateUriQrCodeView> {
     isDesktop = Util.isDesktop;
 
     String receivingAddress = widget.receivingAddress;
-    if ((widget.coin == Coin.bitcoincash ||
-            widget.coin == Coin.eCash ||
-            widget.coin == Coin.bitcoincashTestnet) &&
+    if ((widget.coin is Bitcoincash || widget.coin is Ecash) &&
         receivingAddress.contains(":")) {
       // remove cash addr prefix
       receivingAddress = receivingAddress.split(":").sublist(1).join();
diff --git a/lib/pages/receive_view/receive_view.dart b/lib/pages/receive_view/receive_view.dart
index f96e83274..c2bc6f979 100644
--- a/lib/pages/receive_view/receive_view.dart
+++ b/lib/pages/receive_view/receive_view.dart
@@ -29,9 +29,9 @@ import 'package:stackwallet/utilities/address_utils.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/impl/bitcoin_wallet.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
@@ -66,7 +66,7 @@ class ReceiveView extends ConsumerStatefulWidget {
 }
 
 class _ReceiveViewState extends ConsumerState<ReceiveView> {
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final String walletId;
   late final ClipboardInterface clipboard;
   late final bool _supportsSpark;
diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index e9063d328..daedd54e6 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -32,9 +32,10 @@ import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
@@ -55,7 +56,7 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
 class ConfirmTransactionView extends ConsumerStatefulWidget {
   const ConfirmTransactionView({
-    Key? key,
+    super.key,
     required this.txData,
     required this.walletId,
     required this.onSuccess,
@@ -65,7 +66,7 @@ class ConfirmTransactionView extends ConsumerStatefulWidget {
     this.isPaynymNotificationTransaction = false,
     this.isTokenTx = false,
     this.onSuccessInsteadOfRouteOnSuccess,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/confirmTransactionView";
 
@@ -157,7 +158,7 @@ class _ConfirmTransactionViewState
               break;
           }
         } else {
-          if (coin == Coin.epicCash) {
+          if (coin is Epiccash) {
             txDataFuture = wallet.confirmSend(
               txData: widget.txData.copyWith(
                 noteOnChain: onChainNoteController.text,
@@ -276,7 +277,7 @@ class _ConfirmTransactionViewState
                           ),
                         ),
                       ],
-                    )
+                    ),
                   ],
                 ),
               ),
@@ -292,9 +293,10 @@ class _ConfirmTransactionViewState
                 child: Text(
                   "Ok",
                   style: STextStyles.button(context).copyWith(
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .accentColorDark),
+                    color: Theme.of(context)
+                        .extension<StackColors>()!
+                        .accentColorDark,
+                  ),
                 ),
                 onPressed: () {
                   Navigator.of(context).pop();
@@ -340,7 +342,8 @@ class _ConfirmTransactionViewState
     final String unit;
     if (widget.isTokenTx) {
       unit = ref.watch(
-          pCurrentTokenWallet.select((value) => value!.tokenContract.symbol));
+        pCurrentTokenWallet.select((value) => value!.tokenContract.symbol),
+      );
     } else {
       unit = coin.ticker;
     }
@@ -375,10 +378,12 @@ class _ConfirmTransactionViewState
           fee = widget.txData.fee;
           amountWithoutChange = (widget.txData.amountWithoutChange ??
                   Amount.zeroWith(
-                      fractionDigits: wallet.cryptoCurrency.fractionDigits)) +
+                    fractionDigits: wallet.cryptoCurrency.fractionDigits,
+                  )) +
               (widget.txData.amountSparkWithoutChange ??
                   Amount.zeroWith(
-                      fractionDigits: wallet.cryptoCurrency.fractionDigits));
+                    fractionDigits: wallet.cryptoCurrency.fractionDigits,
+                  ));
           break;
       }
     } else {
@@ -526,11 +531,11 @@ class _ConfirmTransactionViewState
                       ],
                     ),
                   ),
-                  if (coin != Coin.banano && coin != Coin.nano)
+                  if (coin is! NanoCurrency)
                     const SizedBox(
                       height: 12,
                     ),
-                  if (coin != Coin.banano && coin != Coin.nano)
+                  if (coin is! NanoCurrency)
                     RoundedWhiteContainer(
                       child: Row(
                         mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -570,13 +575,11 @@ class _ConfirmTransactionViewState
                         ],
                       ),
                     ),
-                  if (coin == Coin.epicCash &&
-                      widget.txData.noteOnChain!.isNotEmpty)
+                  if (coin is Epiccash && widget.txData.noteOnChain!.isNotEmpty)
                     const SizedBox(
                       height: 12,
                     ),
-                  if (coin == Coin.epicCash &&
-                      widget.txData.noteOnChain!.isNotEmpty)
+                  if (coin is Epiccash && widget.txData.noteOnChain!.isNotEmpty)
                     RoundedWhiteContainer(
                       child: Column(
                         crossAxisAlignment: CrossAxisAlignment.stretch,
@@ -605,7 +608,7 @@ class _ConfirmTransactionViewState
                         crossAxisAlignment: CrossAxisAlignment.stretch,
                         children: [
                           Text(
-                            (coin == Coin.epicCash) ? "Local Note" : "Note",
+                            (coin is Epiccash) ? "Local Note" : "Note",
                             style: STextStyles.smallMed12(context),
                           ),
                           const SizedBox(
@@ -688,7 +691,8 @@ class _ConfirmTransactionViewState
                             Text(
                               "Amount",
                               style: STextStyles.desktopTextExtraExtraSmall(
-                                  context),
+                                context,
+                              ),
                             ),
                             const SizedBox(
                               height: 2,
@@ -696,15 +700,18 @@ class _ConfirmTransactionViewState
                             Builder(
                               builder: (context) {
                                 final externalCalls = ref.watch(
-                                    prefsChangeNotifierProvider.select(
-                                        (value) => value.externalCalls));
+                                  prefsChangeNotifierProvider.select(
+                                    (value) => value.externalCalls,
+                                  ),
+                                );
                                 String fiatAmount = "N/A";
 
                                 if (externalCalls) {
                                   final price = widget.isTokenTx
                                       ? ref
                                           .read(
-                                              priceAnd24hChangeNotifierProvider)
+                                            priceAnd24hChangeNotifierProvider,
+                                          )
                                           .getTokenPrice(
                                             ref
                                                 .read(pCurrentTokenWallet)!
@@ -714,7 +721,8 @@ class _ConfirmTransactionViewState
                                           .item1
                                       : ref
                                           .read(
-                                              priceAnd24hChangeNotifierProvider)
+                                            priceAnd24hChangeNotifierProvider,
+                                          )
                                           .getPrice(coin)
                                           .item1;
                                   if (price > Decimal.zero) {
@@ -724,7 +732,8 @@ class _ConfirmTransactionViewState
                                             .fiatString(
                                               locale: ref
                                                   .read(
-                                                      localeServiceChangeNotifierProvider)
+                                                    localeServiceChangeNotifierProvider,
+                                                  )
                                                   .locale,
                                             );
                                   }
@@ -734,14 +743,15 @@ class _ConfirmTransactionViewState
                                   children: [
                                     SelectableText(
                                       ref.watch(pAmountFormatter(coin)).format(
-                                          amountWithoutChange,
-                                          ethContract: ref
-                                              .read(pCurrentTokenWallet)
-                                              ?.tokenContract),
+                                            amountWithoutChange,
+                                            ethContract: ref
+                                                .read(pCurrentTokenWallet)
+                                                ?.tokenContract,
+                                          ),
                                       style: STextStyles
-                                              .desktopTextExtraExtraSmall(
-                                                  context)
-                                          .copyWith(
+                                          .desktopTextExtraExtraSmall(
+                                        context,
+                                      ).copyWith(
                                         color: Theme.of(context)
                                             .extension<StackColors>()!
                                             .textDark,
@@ -752,16 +762,20 @@ class _ConfirmTransactionViewState
                                         " | ",
                                         style: STextStyles
                                             .desktopTextExtraExtraSmall(
-                                                context),
+                                          context,
+                                        ),
                                       ),
                                     if (externalCalls)
                                       SelectableText(
-                                        "~$fiatAmount ${ref.watch(prefsChangeNotifierProvider.select(
-                                          (value) => value.currency,
-                                        ))}",
+                                        "~$fiatAmount ${ref.watch(
+                                          prefsChangeNotifierProvider.select(
+                                            (value) => value.currency,
+                                          ),
+                                        )}",
                                         style: STextStyles
                                             .desktopTextExtraExtraSmall(
-                                                context),
+                                          context,
+                                        ),
                                       ),
                                   ],
                                 );
@@ -787,7 +801,8 @@ class _ConfirmTransactionViewState
                                   ? "PayNym recipient"
                                   : "Send to",
                               style: STextStyles.desktopTextExtraExtraSmall(
-                                  context),
+                                context,
+                              ),
                             ),
                             const SizedBox(
                               height: 2,
@@ -800,13 +815,13 @@ class _ConfirmTransactionViewState
                                       widget.txData.sparkRecipients!.first
                                           .address,
                               style: STextStyles.desktopTextExtraExtraSmall(
-                                      context)
-                                  .copyWith(
+                                context,
+                              ).copyWith(
                                 color: Theme.of(context)
                                     .extension<StackColors>()!
                                     .textDark,
                               ),
-                            )
+                            ),
                           ],
                         ),
                       ),
@@ -827,7 +842,8 @@ class _ConfirmTransactionViewState
                               Text(
                                 "Transaction fee",
                                 style: STextStyles.desktopTextExtraExtraSmall(
-                                    context),
+                                  context,
+                                ),
                               ),
                               const SizedBox(
                                 height: 2,
@@ -835,8 +851,8 @@ class _ConfirmTransactionViewState
                               SelectableText(
                                 ref.watch(pAmountFormatter(coin)).format(fee!),
                                 style: STextStyles.desktopTextExtraExtraSmall(
-                                        context)
-                                    .copyWith(
+                                  context,
+                                ).copyWith(
                                   color: Theme.of(context)
                                       .extension<StackColors>()!
                                       .textDark,
@@ -892,17 +908,17 @@ class _ConfirmTransactionViewState
                   mainAxisSize: MainAxisSize.min,
                   crossAxisAlignment: CrossAxisAlignment.start,
                   children: [
-                    if (coin == Coin.epicCash)
+                    if (coin is Epiccash)
                       Text(
                         "On chain Note (optional)",
                         style: STextStyles.smallMed12(context),
                         textAlign: TextAlign.left,
                       ),
-                    if (coin == Coin.epicCash)
+                    if (coin is Epiccash)
                       const SizedBox(
                         height: 8,
                       ),
-                    if (coin == Coin.epicCash)
+                    if (coin is Epiccash)
                       ClipRRect(
                         borderRadius: BorderRadius.circular(
                           Constants.size.circularBorderRadius,
@@ -942,12 +958,12 @@ class _ConfirmTransactionViewState
                           ),
                         ),
                       ),
-                    if (coin == Coin.epicCash)
+                    if (coin is Epiccash)
                       const SizedBox(
                         height: 12,
                       ),
                     SelectableText(
-                      (coin == Coin.epicCash)
+                      (coin is Epiccash)
                           ? "Local Note (optional)"
                           : "Note (optional)",
                       style:
@@ -1016,7 +1032,7 @@ class _ConfirmTransactionViewState
                     ),
                     const SizedBox(
                       height: 20,
-                    )
+                    ),
                   ],
                 ),
               ),
@@ -1221,11 +1237,12 @@ class _ConfirmTransactionViewState
                     } else {
                       unawaited(
                         showFloatingFlushBar(
-                            type: FlushBarType.warning,
-                            message: Util.isDesktop
-                                ? "Invalid passphrase"
-                                : "Invalid PIN",
-                            context: context),
+                          type: FlushBarType.warning,
+                          message: Util.isDesktop
+                              ? "Invalid passphrase"
+                              : "Invalid PIN",
+                          context: context,
+                        ),
                       );
                     }
                   }
diff --git a/lib/pages/send_view/frost_ms/frost_send_view.dart b/lib/pages/send_view/frost_ms/frost_send_view.dart
index ccaf5452e..8397a2449 100644
--- a/lib/pages/send_view/frost_ms/frost_send_view.dart
+++ b/lib/pages/send_view/frost_ms/frost_send_view.dart
@@ -25,10 +25,10 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/impl/bitcoin_frost_wallet.dart';
@@ -58,7 +58,7 @@ class FrostSendView extends ConsumerStatefulWidget {
   static const String routeName = "/frostSendView";
 
   final String walletId;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<FrostSendView> createState() => _FrostSendViewState();
@@ -69,7 +69,7 @@ class _FrostSendViewState extends ConsumerState<FrostSendView> {
   int _greatestWidgetIndex = 0;
 
   late final String walletId;
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   late TextEditingController noteController;
   late TextEditingController onChainNoteController;
diff --git a/lib/pages/send_view/frost_ms/recipient.dart b/lib/pages/send_view/frost_ms/recipient.dart
index 043f080f6..1f6c0514a 100644
--- a/lib/pages/send_view/frost_ms/recipient.dart
+++ b/lib/pages/send_view/frost_ms/recipient.dart
@@ -12,10 +12,10 @@ import 'package:stackwallet/utilities/amount/amount_unit.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
 import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
@@ -55,7 +55,7 @@ class Recipient extends ConsumerStatefulWidget {
 
   final int index;
   final int displayNumber;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   final VoidCallback? remove;
   final VoidCallback? onChanged;
@@ -324,7 +324,8 @@ class _RecipientState extends ConsumerState<Recipient> {
                                     final Amount amount =
                                         Decimal.parse(results["amount"]!)
                                             .toAmount(
-                                      fractionDigits: widget.coin.decimals,
+                                      fractionDigits:
+                                          widget.coin.fractionDigits,
                                     );
                                     amountController.text = ref
                                         .read(pAmountFormatter(widget.coin))
@@ -409,7 +410,7 @@ class _RecipientState extends ConsumerState<Recipient> {
             textAlign: TextAlign.right,
             inputFormatters: [
               AmountInputFormatter(
-                decimals: widget.coin.decimals,
+                decimals: widget.coin.fractionDigits,
                 unit: ref.watch(pAmountUnit(widget.coin)),
                 locale: locale,
               ),
diff --git a/lib/pages/send_view/frost_ms/send_steps/frost_send_step_4.dart b/lib/pages/send_view/frost_ms/send_steps/frost_send_step_4.dart
index 2267e7226..424229a2f 100644
--- a/lib/pages/send_view/frost_ms/send_steps/frost_send_step_4.dart
+++ b/lib/pages/send_view/frost_ms/send_steps/frost_send_step_4.dart
@@ -11,7 +11,6 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -93,7 +92,7 @@ class _FrostSendStep4State extends ConsumerState<FrostSendStep4> {
               height: 12,
             ),
           Text(
-            "Send ${cryptoCurrency.coin.ticker}",
+            "Send ${cryptoCurrency.ticker}",
             style: STextStyles.w600_20(context),
           ),
           const SizedBox(
@@ -103,7 +102,7 @@ class _FrostSendStep4State extends ConsumerState<FrostSendStep4> {
               ? _Recipient(
                   address: recipients[0].address,
                   amount: ref
-                      .watch(pAmountFormatter(cryptoCurrency.coin))
+                      .watch(pAmountFormatter(cryptoCurrency))
                       .format(recipients[0].amount),
                 )
               : Column(
@@ -143,7 +142,7 @@ class _FrostSendStep4State extends ConsumerState<FrostSendStep4> {
                           body: _Recipient(
                             address: recipients[i].address,
                             amount: ref
-                                .watch(pAmountFormatter(cryptoCurrency.coin))
+                                .watch(pAmountFormatter(cryptoCurrency))
                                 .format(recipients[i].amount),
                           ),
                         ),
@@ -156,7 +155,7 @@ class _FrostSendStep4State extends ConsumerState<FrostSendStep4> {
           DetailItem(
             title: "Transaction fee",
             detail: ref
-                .watch(pAmountFormatter(cryptoCurrency.coin))
+                .watch(pAmountFormatter(cryptoCurrency))
                 .format(ref.watch(pFrostTxData)!.fee!),
             horizontal: true,
           ),
@@ -165,7 +164,7 @@ class _FrostSendStep4State extends ConsumerState<FrostSendStep4> {
           ),
           DetailItem(
             title: "Total",
-            detail: ref.watch(pAmountFormatter(cryptoCurrency.coin)).format(
+            detail: ref.watch(pAmountFormatter(cryptoCurrency)).format(
                 ref.watch(pFrostTxData)!.fee! +
                     recipients.map((e) => e.amount).reduce((v, e) => v += e)),
             horizontal: true,
diff --git a/lib/pages/send_view/send_view.dart b/lib/pages/send_view/send_view.dart
index fc0b89dc3..803595178 100644
--- a/lib/pages/send_view/send_view.dart
+++ b/lib/pages/send_view/send_view.dart
@@ -43,13 +43,19 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
@@ -73,19 +79,19 @@ import 'package:tuple/tuple.dart';
 
 class SendView extends ConsumerStatefulWidget {
   const SendView({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.coin,
     this.autoFillData,
     this.clipboard = const ClipboardWrapper(),
     this.barcodeScanner = const BarcodeScannerWrapper(),
     this.accountLite,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/sendView";
 
   final String walletId;
-  final Coin coin;
+  final CryptoCurrency coin;
   final SendViewAutoFillData? autoFillData;
   final ClipboardInterface clipboard;
   final BarcodeScannerInterface barcodeScanner;
@@ -97,7 +103,7 @@ class SendView extends ConsumerStatefulWidget {
 
 class _SendViewState extends ConsumerState<SendView> {
   late final String walletId;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final ClipboardInterface clipboard;
   late final BarcodeScannerInterface scanner;
 
@@ -178,7 +184,7 @@ class _SendViewState extends ConsumerState<SendView> {
         // autofill amount field
         if (results["amount"] != null) {
           final Amount amount = Decimal.parse(results["amount"]!).toAmount(
-            fractionDigits: coin.decimals,
+            fractionDigits: coin.fractionDigits,
           );
           cryptoAmountController.text = ref.read(pAmountFormatter(coin)).format(
                 amount,
@@ -232,15 +238,15 @@ class _SendViewState extends ConsumerState<SendView> {
           ref.read(priceAnd24hChangeNotifierProvider).getPrice(coin).item1;
 
       if (_price == Decimal.zero) {
-        amount = 0.toAmountAsRaw(fractionDigits: coin.decimals);
+        amount = 0.toAmountAsRaw(fractionDigits: coin.fractionDigits);
       } else {
         amount = baseAmount <= Amount.zero
-            ? 0.toAmountAsRaw(fractionDigits: coin.decimals)
+            ? 0.toAmountAsRaw(fractionDigits: coin.fractionDigits)
             : (baseAmount.decimal / _price)
                 .toDecimal(
-                  scaleOnInfinitePrecision: coin.decimals,
+                  scaleOnInfinitePrecision: coin.fractionDigits,
                 )
-                .toAmount(fractionDigits: coin.decimals);
+                .toAmount(fractionDigits: coin.fractionDigits);
       }
       if (_cachedAmountToSend != null && _cachedAmountToSend == amount) {
         return;
@@ -258,7 +264,7 @@ class _SendViewState extends ConsumerState<SendView> {
       cryptoAmountController.text = amountString;
       _cryptoAmountChangeLock = false;
     } else {
-      amount = 0.toAmountAsRaw(fractionDigits: coin.decimals);
+      amount = 0.toAmountAsRaw(fractionDigits: coin.fractionDigits);
       _cryptoAmountChangeLock = true;
       cryptoAmountController.text = "";
       _cryptoAmountChangeLock = false;
@@ -309,11 +315,11 @@ class _SendViewState extends ConsumerState<SendView> {
 
       _cryptoAmountChangedFeeUpdateTimer?.cancel();
       _cryptoAmountChangedFeeUpdateTimer = Timer(updateFeesTimerDuration, () {
-        if (coin != Coin.epicCash && !_baseFocus.hasFocus) {
+        if (coin is! Epiccash && !_baseFocus.hasFocus) {
           setState(() {
             _calculateFeesFuture = calculateFees(
               amount == null
-                  ? 0.toAmountAsRaw(fractionDigits: coin.decimals)
+                  ? 0.toAmountAsRaw(fractionDigits: coin.fractionDigits)
                   : amount!,
             );
           });
@@ -330,11 +336,11 @@ class _SendViewState extends ConsumerState<SendView> {
   void _baseAmountChanged() {
     _baseAmountChangedFeeUpdateTimer?.cancel();
     _baseAmountChangedFeeUpdateTimer = Timer(updateFeesTimerDuration, () {
-      if (coin != Coin.epicCash && !_cryptoFocus.hasFocus) {
+      if (coin is! Epiccash && !_cryptoFocus.hasFocus) {
         setState(() {
           _calculateFeesFuture = calculateFees(
             ref.read(pSendAmount) == null
-                ? 0.toAmountAsRaw(fractionDigits: coin.decimals)
+                ? 0.toAmountAsRaw(fractionDigits: coin.fractionDigits)
                 : ref.read(pSendAmount)!,
           );
         });
@@ -356,8 +362,8 @@ class _SendViewState extends ConsumerState<SendView> {
 
     final value = fee.contains(",")
         ? Decimal.parse(fee.replaceFirst(",", "."))
-            .toAmount(fractionDigits: coin.decimals)
-        : Decimal.parse(fee).toAmount(fractionDigits: coin.decimals);
+            .toAmount(fractionDigits: coin.fractionDigits)
+        : Decimal.parse(fee).toAmount(fractionDigits: coin.fractionDigits);
 
     if (shouldSetState) {
       setState(() => _currentFee = value);
@@ -455,7 +461,7 @@ class _SendViewState extends ConsumerState<SendView> {
     }
 
     Amount fee;
-    if (coin == Coin.monero) {
+    if (coin is Monero) {
       MoneroTransactionPriority specialMoneroId;
       switch (ref.read(feeRateTypeStateProvider.state).state) {
         case FeeRateType.fast:
@@ -552,7 +558,7 @@ class _SendViewState extends ConsumerState<SendView> {
     final coinControlEnabled =
         ref.read(prefsChangeNotifierProvider).enableCoinControl;
 
-    if (coin != Coin.ethereum &&
+    if (coin is! Ethereum &&
             !(wallet is CoinControlInterface && coinControlEnabled) ||
         (wallet is CoinControlInterface &&
             coinControlEnabled &&
@@ -751,9 +757,7 @@ class _SendViewState extends ConsumerState<SendView> {
             break;
         }
       } else {
-        final memo = coin == Coin.stellar || coin == Coin.stellarTestnet
-            ? memoController.text
-            : null;
+        final memo = coin is Stellar ? memoController.text : null;
         txDataFuture = wallet.prepareSend(
           txData: TxData(
             recipients: [
@@ -878,16 +882,16 @@ class _SendViewState extends ConsumerState<SendView> {
   void initState() {
     coin = widget.coin;
     ref.refresh(feeSheetSessionCacheProvider);
-    _currentFee = 0.toAmountAsRaw(fractionDigits: coin.decimals);
+    _currentFee = 0.toAmountAsRaw(fractionDigits: coin.fractionDigits);
 
     _calculateFeesFuture =
-        calculateFees(0.toAmountAsRaw(fractionDigits: coin.decimals));
+        calculateFees(0.toAmountAsRaw(fractionDigits: coin.fractionDigits));
     _data = widget.autoFillData;
     walletId = widget.walletId;
     clipboard = widget.clipboard;
     scanner = widget.barcodeScanner;
-    isStellar = coin == Coin.stellar || coin == Coin.stellarTestnet;
-    isFiro = coin == Coin.firo || coin == Coin.firoTestNet;
+    isStellar = coin is Stellar;
+    isFiro = coin is Firo;
 
     sendToController = TextEditingController();
     cryptoAmountController = TextEditingController();
@@ -905,7 +909,7 @@ class _SendViewState extends ConsumerState<SendView> {
       if (_data!.amount != null) {
         final amount = Amount.fromDecimal(
           _data!.amount!,
-          fractionDigits: coin.decimals,
+          fractionDigits: coin.fractionDigits,
         );
 
         cryptoAmountController.text = ref.read(pAmountFormatter(coin)).format(
@@ -927,7 +931,7 @@ class _SendViewState extends ConsumerState<SendView> {
       noteController.text = "PayNym send";
     }
 
-    // if (coin != Coin.epicCash) {
+    // if (coin is! Epiccash) {
     // _cryptoFocus.addListener(() {
     //   if (!_cryptoFocus.hasFocus && !_baseFocus.hasFocus) {
     //     if (_amountToSend == null) {
@@ -1005,8 +1009,8 @@ class _SendViewState extends ConsumerState<SendView> {
       ref.listen(publicPrivateBalanceStateProvider, (previous, next) {
         if (ref.read(pSendAmount) == null) {
           setState(() {
-            _calculateFeesFuture =
-                calculateFees(0.toAmountAsRaw(fractionDigits: coin.decimals));
+            _calculateFeesFuture = calculateFees(
+                0.toAmountAsRaw(fractionDigits: coin.fractionDigits));
           });
         } else {
           setState(() {
@@ -1019,7 +1023,7 @@ class _SendViewState extends ConsumerState<SendView> {
     }
 
     // add listener for epic cash to strip http:// and https:// prefixes if the address also ocntains an @ symbol (indicating an epicbox address)
-    if (coin == Coin.epicCash) {
+    if (coin is Epiccash) {
       sendToController.addListener(() {
         _address = sendToController.text.trim();
 
@@ -1119,8 +1123,7 @@ class _SendViewState extends ConsumerState<SendView> {
                                           style: STextStyles.label(context)
                                               .copyWith(fontSize: 10),
                                         ),
-                                      if (coin != Coin.firo &&
-                                          coin != Coin.firoTestNet)
+                                      if (coin is! Firo)
                                         Text(
                                           "Available balance",
                                           style: STextStyles.label(context)
@@ -1233,7 +1236,7 @@ class _SendViewState extends ConsumerState<SendView> {
                                 style: STextStyles.smallMed12(context),
                                 textAlign: TextAlign.left,
                               ),
-                              // if (coin == Coin.monero)
+                              // if (coin is Monero)
                               //   CustomTextButton(
                               //     text: "Use OpenAlias",
                               //     onTap: () async {
@@ -1359,8 +1362,7 @@ class _SendViewState extends ConsumerState<SendView> {
                                                         );
                                                       }
 
-                                                      if (coin ==
-                                                          Coin.epicCash) {
+                                                      if (coin is Epiccash) {
                                                         // strip http:// and https:// if content contains @
                                                         content = formatAddress(
                                                           content,
@@ -1433,10 +1435,7 @@ class _SendViewState extends ConsumerState<SendView> {
                               ),
                               child: TextField(
                                 key: const Key("sendViewMemoFieldKey"),
-                                maxLength: (coin == Coin.firo ||
-                                        coin == Coin.firoTestNet)
-                                    ? 31
-                                    : null,
+                                maxLength: (coin is Firo) ? 31 : null,
                                 controller: memoController,
                                 readOnly: false,
                                 autocorrect: false,
@@ -1527,7 +1526,8 @@ class _SendViewState extends ConsumerState<SendView> {
                                       _data!.contactLabel == _address) {
                                     error = SparkInterface.validateSparkAddress(
                                       address: _data!.address,
-                                      isTestNet: coin.isTestNet,
+                                      isTestNet: coin.network ==
+                                          CryptoCurrencyNetwork.test,
                                     )
                                         ? "Unsupported"
                                         : null;
@@ -1733,7 +1733,7 @@ class _SendViewState extends ConsumerState<SendView> {
                                 style: STextStyles.smallMed12(context),
                                 textAlign: TextAlign.left,
                               ),
-                              if (coin != Coin.ethereum && coin != Coin.tezos)
+                              if (coin is! Ethereum && coin is! Tezos)
                                 CustomTextButton(
                                   text: "Send all ${coin.ticker}",
                                   onTap: () async {
@@ -1815,7 +1815,7 @@ class _SendViewState extends ConsumerState<SendView> {
                             textAlign: TextAlign.right,
                             inputFormatters: [
                               AmountInputFormatter(
-                                decimals: coin.decimals,
+                                decimals: coin.fractionDigits,
                                 unit: ref.watch(pAmountUnit(coin)),
                                 locale: locale,
                               ),
@@ -1825,7 +1825,7 @@ class _SendViewState extends ConsumerState<SendView> {
                               //         newValue) =>
                               //     // RegExp(r'^([0-9]*[,.]?[0-9]{0,8}|[,.][0-9]{0,8})$')
                               //     // RegExp(r'^\d{1,3}([,\.]\d+)?|[,\.\d]+$')
-                              //     getAmountRegex(locale, coin.decimals)
+                              //     getAmountRegex(locale, coin.fractionDigits)
                               //             .hasMatch(newValue.text)
                               //         ? newValue
                               //         : oldValue),
@@ -2001,17 +2001,17 @@ class _SendViewState extends ConsumerState<SendView> {
                           const SizedBox(
                             height: 12,
                           ),
-                          if (coin == Coin.epicCash)
+                          if (coin is Epiccash)
                             Text(
                               "On chain Note (optional)",
                               style: STextStyles.smallMed12(context),
                               textAlign: TextAlign.left,
                             ),
-                          if (coin == Coin.epicCash)
+                          if (coin is Epiccash)
                             const SizedBox(
                               height: 8,
                             ),
-                          if (coin == Coin.epicCash)
+                          if (coin is Epiccash)
                             ClipRRect(
                               borderRadius: BorderRadius.circular(
                                 Constants.size.circularBorderRadius,
@@ -2055,12 +2055,12 @@ class _SendViewState extends ConsumerState<SendView> {
                                 ),
                               ),
                             ),
-                          if (coin == Coin.epicCash)
+                          if (coin is Epiccash)
                             const SizedBox(
                               height: 12,
                             ),
                           Text(
-                            (coin == Coin.epicCash)
+                            (coin is Epiccash)
                                 ? "Local Note (optional)"
                                 : "Note (optional)",
                             style: STextStyles.smallMed12(context),
@@ -2111,26 +2111,23 @@ class _SendViewState extends ConsumerState<SendView> {
                           const SizedBox(
                             height: 12,
                           ),
-                          if (coin != Coin.epicCash &&
-                              coin != Coin.nano &&
-                              coin != Coin.banano &&
-                              coin != Coin.tezos)
+                          if (coin is! Epiccash &&
+                              coin is! NanoCurrency &&
+                              coin is! Tezos)
                             Text(
                               "Transaction fee (estimated)",
                               style: STextStyles.smallMed12(context),
                               textAlign: TextAlign.left,
                             ),
-                          if (coin != Coin.epicCash &&
-                              coin != Coin.nano &&
-                              coin != Coin.banano &&
-                              coin != Coin.tezos)
+                          if (coin is! Epiccash &&
+                              coin is! NanoCurrency &&
+                              coin is! Tezos)
                             const SizedBox(
                               height: 8,
                             ),
-                          if (coin != Coin.epicCash &&
-                              coin != Coin.nano &&
-                              coin != Coin.banano &&
-                              coin != Coin.tezos)
+                          if (coin is! Epiccash &&
+                              coin is! NanoCurrency &&
+                              coin is! Tezos)
                             Stack(
                               children: [
                                 TextField(
@@ -2187,7 +2184,8 @@ class _SendViewState extends ConsumerState<SendView> {
                                                             ?.decimal ??
                                                         Decimal.zero)
                                                     .toAmount(
-                                                  fractionDigits: coin.decimals,
+                                                  fractionDigits:
+                                                      coin.fractionDigits,
                                                 ),
                                                 updateChosen: (String fee) {
                                                   if (fee == "custom") {
diff --git a/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart b/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
index 8529925d6..112c33339 100644
--- a/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
+++ b/lib/pages/send_view/sub_widgets/building_transaction_dialog.dart
@@ -14,9 +14,9 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/themes/coin_image_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/animated_widgets/rotating_arrows.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
@@ -30,7 +30,7 @@ class BuildingTransactionDialog extends ConsumerStatefulWidget {
   });
 
   final VoidCallback onCancel;
-  final Coin coin;
+  final CryptoCurrency coin;
   final bool isSpark;
 
   @override
diff --git a/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart b/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart
index 0376e9e3d..42f8ea47e 100644
--- a/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart
+++ b/lib/pages/send_view/sub_widgets/sending_transaction_dialog.dart
@@ -13,23 +13,23 @@ import 'dart:io';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:lottie/lottie.dart';
-import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/themes/coin_image_provider.dart';
+import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/stack_dialog.dart';
 
 class SendingTransactionDialog extends ConsumerStatefulWidget {
   const SendingTransactionDialog({
-    Key? key,
+    super.key,
     required this.coin,
     required this.controller,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final ProgressAndSuccessController controller;
 
   @override
diff --git a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart
index 8572d5037..e177c0f37 100644
--- a/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart
+++ b/lib/pages/send_view/sub_widgets/transaction_fee_selection_sheet.dart
@@ -19,10 +19,14 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
@@ -44,12 +48,12 @@ class FeeSheetSessionCache extends ChangeNotifier {
 
 class TransactionFeeSelectionSheet extends ConsumerStatefulWidget {
   const TransactionFeeSelectionSheet({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.amount,
     required this.updateChosen,
     this.isToken = false,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final Amount amount;
@@ -79,7 +83,7 @@ class _TransactionFeeSelectionSheetState
     required Amount amount,
     required FeeRateType feeRateType,
     required int feeRate,
-    required Coin coin,
+    required CryptoCurrency coin,
   }) async {
     switch (feeRateType) {
       case FeeRateType.fast:
@@ -87,11 +91,13 @@ class _TransactionFeeSelectionSheetState
           if (widget.isToken == false) {
             final wallet = ref.read(pWallets).getWallet(walletId);
 
-            if (coin == Coin.monero || coin == Coin.wownero) {
+            if (coin is Monero || coin is Wownero) {
               final fee = await wallet.estimateFeeFor(
-                  amount, MoneroTransactionPriority.fast.raw!);
+                amount,
+                MoneroTransactionPriority.fast.raw!,
+              );
               ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
-            } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+            } else if (coin is Firo) {
               final Amount fee;
               switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
                 case FiroType.spark:
@@ -122,11 +128,13 @@ class _TransactionFeeSelectionSheetState
         if (ref.read(feeSheetSessionCacheProvider).average[amount] == null) {
           if (widget.isToken == false) {
             final wallet = ref.read(pWallets).getWallet(walletId);
-            if (coin == Coin.monero || coin == Coin.wownero) {
+            if (coin is Monero || coin is Wownero) {
               final fee = await wallet.estimateFeeFor(
-                  amount, MoneroTransactionPriority.regular.raw!);
+                amount,
+                MoneroTransactionPriority.regular.raw!,
+              );
               ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
-            } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+            } else if (coin is Firo) {
               final Amount fee;
               switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
                 case FiroType.spark:
@@ -156,11 +164,13 @@ class _TransactionFeeSelectionSheetState
         if (ref.read(feeSheetSessionCacheProvider).slow[amount] == null) {
           if (widget.isToken == false) {
             final wallet = ref.read(pWallets).getWallet(walletId);
-            if (coin == Coin.monero || coin == Coin.wownero) {
+            if (coin is Monero || coin is Wownero) {
               final fee = await wallet.estimateFeeFor(
-                  amount, MoneroTransactionPriority.slow.raw!);
+                amount,
+                MoneroTransactionPriority.slow.raw!,
+              );
               ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
-            } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+            } else if (coin is Firo) {
               final Amount fee;
               switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
                 case FiroType.spark:
@@ -192,10 +202,12 @@ class _TransactionFeeSelectionSheetState
   }
 
   String estimatedTimeToBeIncludedInNextBlock(
-      int targetBlockTime, int estimatedNumberOfBlocks) {
-    int time = targetBlockTime * estimatedNumberOfBlocks;
+    int targetBlockTime,
+    int estimatedNumberOfBlocks,
+  ) {
+    final int time = targetBlockTime * estimatedNumberOfBlocks;
 
-    int hours = (time / 3600).floor();
+    final int hours = (time / 3600).floor();
     if (hours > 1) {
       return "~$hours hours";
     } else if (hours == 1) {
@@ -295,7 +307,7 @@ class _TransactionFeeSelectionSheetState
                           ref.read(feeRateTypeStateProvider.state).state =
                               FeeRateType.fast;
                         }
-                        String? fee =
+                        final String? fee =
                             getAmount(FeeRateType.fast, wallet.info.coin);
                         if (fee != null) {
                           widget.updateChosen(fee);
@@ -364,8 +376,10 @@ class _TransactionFeeSelectionSheetState
                                             feeRate: feeObject!.fast,
                                             amount: amount,
                                           ),
-                                          builder: (_,
-                                              AsyncSnapshot<Amount> snapshot) {
+                                          builder: (
+                                            _,
+                                            AsyncSnapshot<Amount> snapshot,
+                                          ) {
                                             if (snapshot.connectionState ==
                                                     ConnectionState.done &&
                                                 snapshot.hasData) {
@@ -380,7 +394,8 @@ class _TransactionFeeSelectionSheetState
                                                           false,
                                                     )})",
                                                 style: STextStyles.itemSubtitle(
-                                                    context),
+                                                  context,
+                                                ),
                                                 textAlign: TextAlign.left,
                                               );
                                             } else {
@@ -388,7 +403,8 @@ class _TransactionFeeSelectionSheetState
                                                 stringsToLoopThrough:
                                                     stringsToLoopThrough,
                                                 style: STextStyles.itemSubtitle(
-                                                    context),
+                                                  context,
+                                                ),
                                               );
                                             }
                                           },
@@ -398,19 +414,16 @@ class _TransactionFeeSelectionSheetState
                                   const SizedBox(
                                     height: 2,
                                   ),
-                                  if (feeObject == null &&
-                                      coin != Coin.ethereum)
+                                  if (feeObject == null && coin is! Ethereum)
                                     AnimatedText(
                                       stringsToLoopThrough:
                                           stringsToLoopThrough,
                                       style: STextStyles.itemSubtitle(context),
                                     ),
-                                  if (feeObject != null &&
-                                      coin != Coin.ethereum)
+                                  if (feeObject != null && coin is! Ethereum)
                                     Text(
                                       estimatedTimeToBeIncludedInNextBlock(
-                                        Constants.targetBlockTimeInSeconds(
-                                            coin),
+                                        coin.targetBlockTimeSeconds,
                                         feeObject!.numberOfBlocksFast,
                                       ),
                                       style: STextStyles.itemSubtitle(context),
@@ -418,7 +431,7 @@ class _TransactionFeeSelectionSheetState
                                     ),
                                 ],
                               ),
-                            )
+                            ),
                           ],
                         ),
                       ),
@@ -434,7 +447,8 @@ class _TransactionFeeSelectionSheetState
                           ref.read(feeRateTypeStateProvider.state).state =
                               FeeRateType.average;
                         }
-                        String? fee = getAmount(FeeRateType.average, coin);
+                        final String? fee =
+                            getAmount(FeeRateType.average, coin);
                         if (fee != null) {
                           widget.updateChosen(fee);
                         }
@@ -500,8 +514,10 @@ class _TransactionFeeSelectionSheetState
                                             feeRate: feeObject!.medium,
                                             amount: amount,
                                           ),
-                                          builder: (_,
-                                              AsyncSnapshot<Amount> snapshot) {
+                                          builder: (
+                                            _,
+                                            AsyncSnapshot<Amount> snapshot,
+                                          ) {
                                             if (snapshot.connectionState ==
                                                     ConnectionState.done &&
                                                 snapshot.hasData) {
@@ -516,7 +532,8 @@ class _TransactionFeeSelectionSheetState
                                                           false,
                                                     )})",
                                                 style: STextStyles.itemSubtitle(
-                                                    context),
+                                                  context,
+                                                ),
                                                 textAlign: TextAlign.left,
                                               );
                                             } else {
@@ -524,7 +541,8 @@ class _TransactionFeeSelectionSheetState
                                                 stringsToLoopThrough:
                                                     stringsToLoopThrough,
                                                 style: STextStyles.itemSubtitle(
-                                                    context),
+                                                  context,
+                                                ),
                                               );
                                             }
                                           },
@@ -534,19 +552,16 @@ class _TransactionFeeSelectionSheetState
                                   const SizedBox(
                                     height: 2,
                                   ),
-                                  if (feeObject == null &&
-                                      coin != Coin.ethereum)
+                                  if (feeObject == null && coin is! Ethereum)
                                     AnimatedText(
                                       stringsToLoopThrough:
                                           stringsToLoopThrough,
                                       style: STextStyles.itemSubtitle(context),
                                     ),
-                                  if (feeObject != null &&
-                                      coin != Coin.ethereum)
+                                  if (feeObject != null && coin is! Ethereum)
                                     Text(
                                       estimatedTimeToBeIncludedInNextBlock(
-                                        Constants.targetBlockTimeInSeconds(
-                                            coin),
+                                        coin.targetBlockTimeSeconds,
                                         feeObject!.numberOfBlocksAverage,
                                       ),
                                       style: STextStyles.itemSubtitle(context),
@@ -570,7 +585,7 @@ class _TransactionFeeSelectionSheetState
                           ref.read(feeRateTypeStateProvider.state).state =
                               FeeRateType.slow;
                         }
-                        String? fee = getAmount(FeeRateType.slow, coin);
+                        final String? fee = getAmount(FeeRateType.slow, coin);
                         if (fee != null) {
                           widget.updateChosen(fee);
                         }
@@ -636,8 +651,10 @@ class _TransactionFeeSelectionSheetState
                                             feeRate: feeObject!.slow,
                                             amount: amount,
                                           ),
-                                          builder: (_,
-                                              AsyncSnapshot<Amount> snapshot) {
+                                          builder: (
+                                            _,
+                                            AsyncSnapshot<Amount> snapshot,
+                                          ) {
                                             if (snapshot.connectionState ==
                                                     ConnectionState.done &&
                                                 snapshot.hasData) {
@@ -652,7 +669,8 @@ class _TransactionFeeSelectionSheetState
                                                           false,
                                                     )})",
                                                 style: STextStyles.itemSubtitle(
-                                                    context),
+                                                  context,
+                                                ),
                                                 textAlign: TextAlign.left,
                                               );
                                             } else {
@@ -660,7 +678,8 @@ class _TransactionFeeSelectionSheetState
                                                 stringsToLoopThrough:
                                                     stringsToLoopThrough,
                                                 style: STextStyles.itemSubtitle(
-                                                    context),
+                                                  context,
+                                                ),
                                               );
                                             }
                                           },
@@ -670,19 +689,16 @@ class _TransactionFeeSelectionSheetState
                                   const SizedBox(
                                     height: 2,
                                   ),
-                                  if (feeObject == null &&
-                                      coin != Coin.ethereum)
+                                  if (feeObject == null && coin is! Ethereum)
                                     AnimatedText(
                                       stringsToLoopThrough:
                                           stringsToLoopThrough,
                                       style: STextStyles.itemSubtitle(context),
                                     ),
-                                  if (feeObject != null &&
-                                      coin != Coin.ethereum)
+                                  if (feeObject != null && coin is! Ethereum)
                                     Text(
                                       estimatedTimeToBeIncludedInNextBlock(
-                                        Constants.targetBlockTimeInSeconds(
-                                            coin),
+                                        coin.targetBlockTimeSeconds,
                                         feeObject!.numberOfBlocksSlow,
                                       ),
                                       style: STextStyles.itemSubtitle(context),
@@ -732,7 +748,8 @@ class _TransactionFeeSelectionSheetState
                                       onChanged: (x) {
                                         ref
                                             .read(
-                                                feeRateTypeStateProvider.state)
+                                              feeRateTypeStateProvider.state,
+                                            )
                                             .state = FeeRateType.custom;
                                         Navigator.of(context).pop();
                                       },
@@ -781,7 +798,7 @@ class _TransactionFeeSelectionSheetState
     );
   }
 
-  String? getAmount(FeeRateType feeRateType, Coin coin) {
+  String? getAmount(FeeRateType feeRateType, CryptoCurrency coin) {
     try {
       switch (feeRateType) {
         case FeeRateType.fast:
diff --git a/lib/pages/send_view/token_send_view.dart b/lib/pages/send_view/token_send_view.dart
index 028538d63..d537bc61a 100644
--- a/lib/pages/send_view/token_send_view.dart
+++ b/lib/pages/send_view/token_send_view.dart
@@ -34,12 +34,13 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/token_balance_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
@@ -70,7 +71,7 @@ class TokenSendView extends ConsumerStatefulWidget {
   static const String routeName = "/tokenSendView";
 
   final String walletId;
-  final Coin coin;
+  final CryptoCurrency coin;
   final EthContract tokenContract;
   final SendViewAutoFillData? autoFillData;
   final ClipboardInterface clipboard;
@@ -82,7 +83,7 @@ class TokenSendView extends ConsumerStatefulWidget {
 
 class _TokenSendViewState extends ConsumerState<TokenSendView> {
   late final String walletId;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final EthContract tokenContract;
   late final ClipboardInterface clipboard;
   late final BarcodeScannerInterface scanner;
@@ -317,7 +318,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
 
       _cryptoAmountChangedFeeUpdateTimer?.cancel();
       _cryptoAmountChangedFeeUpdateTimer = Timer(updateFeesTimerDuration, () {
-        if (coin != Coin.epicCash && !_baseFocus.hasFocus) {
+        if (coin is! Epiccash && !_baseFocus.hasFocus) {
           setState(() {
             _calculateFeesFuture = calculateFees();
           });
@@ -329,7 +330,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
   void _baseAmountChanged() {
     _baseAmountChangedFeeUpdateTimer?.cancel();
     _baseAmountChangedFeeUpdateTimer = Timer(updateFeesTimerDuration, () {
-      if (coin != Coin.epicCash && !_cryptoFocus.hasFocus) {
+      if (coin is! Epiccash && !_cryptoFocus.hasFocus) {
         setState(() {
           _calculateFeesFuture = calculateFees();
         });
@@ -1161,7 +1162,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
                           const SizedBox(
                             height: 12,
                           ),
-                          if (coin != Coin.epicCash)
+                          if (coin is! Epiccash)
                             Text(
                               "Transaction fee (estimated)",
                               style: STextStyles.smallMed12(context),
diff --git a/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/choose_unit_sheet.dart b/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/choose_unit_sheet.dart
index d5ef002b7..ebacd1c77 100644
--- a/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/choose_unit_sheet.dart
+++ b/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/choose_unit_sheet.dart
@@ -4,16 +4,16 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/amount/amount_unit.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class ChooseUnitSheet extends ConsumerStatefulWidget {
   const ChooseUnitSheet({
-    Key? key,
+    super.key,
     required this.coin,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<ChooseUnitSheet> createState() => _ChooseUnitSheetState();
diff --git a/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/edit_coin_units_view.dart b/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/edit_coin_units_view.dart
index bf06ebd2c..e68a96c69 100644
--- a/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/edit_coin_units_view.dart
+++ b/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/edit_coin_units_view.dart
@@ -9,9 +9,9 @@ import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/amount/amount_unit.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -25,11 +25,11 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
 class EditCoinUnitsView extends ConsumerStatefulWidget {
   const EditCoinUnitsView({
-    Key? key,
+    super.key,
     required this.coin,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   static const String routeName = "/editCoinUnitsView";
 
diff --git a/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/manage_coin_units_view.dart b/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/manage_coin_units_view.dart
index f562b911e..7ec0656c1 100644
--- a/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/manage_coin_units_view.dart
+++ b/lib/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/manage_coin_units_view.dart
@@ -5,12 +5,14 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/advanced_views/manage_coin_units/edit_coin_units_view.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -19,11 +21,11 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class ManageCoinUnitsView extends ConsumerWidget {
-  const ManageCoinUnitsView({Key? key}) : super(key: key);
+  const ManageCoinUnitsView({super.key});
 
   static const String routeName = "/manageCoinUnitsView";
 
-  void onEditPressed(Coin coin, BuildContext context) {
+  void onEditPressed(CryptoCurrency coin, BuildContext context) {
     if (Util.isDesktop) {
       showDialog<void>(
         context: context,
@@ -39,14 +41,17 @@ class ManageCoinUnitsView extends ConsumerWidget {
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    bool showTestNet = ref.watch(
+    final showTestNet = ref.watch(
       prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
     );
 
-    final _coins = Coin.values.where((e) => e != Coin.firoTestNet).toList();
+    final _coins = SupportedCoins.cryptocurrencies
+        .where((e) => e is! Firo && e.network != CryptoCurrencyNetwork.test)
+        .toList();
 
-    List<Coin> coins =
-        showTestNet ? _coins : _coins.where((e) => !e.isTestNet).toList();
+    final coins = showTestNet
+        ? _coins
+        : _coins.where((e) => e.network != CryptoCurrencyNetwork.test).toList();
 
     return ConditionalParent(
       condition: Util.isDesktop,
diff --git a/lib/pages/settings_views/global_settings_view/advanced_views/manage_explorer_view.dart b/lib/pages/settings_views/global_settings_view/advanced_views/manage_explorer_view.dart
index 9242731d1..5ebf47bd2 100644
--- a/lib/pages/settings_views/global_settings_view/advanced_views/manage_explorer_view.dart
+++ b/lib/pages/settings_views/global_settings_view/advanced_views/manage_explorer_view.dart
@@ -12,21 +12,21 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/block_explorers.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class ManageExplorerView extends ConsumerStatefulWidget {
   const ManageExplorerView({
-    Key? key,
+    super.key,
     required this.coin,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/manageExplorer";
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<ManageExplorerView> createState() => _ManageExplorerViewState();
diff --git a/lib/pages/settings_views/global_settings_view/hidden_settings.dart b/lib/pages/settings_views/global_settings_view/hidden_settings.dart
index 6ebafad4a..fa0db26b0 100644
--- a/lib/pages/settings_views/global_settings_view/hidden_settings.dart
+++ b/lib/pages/settings_views/global_settings_view/hidden_settings.dart
@@ -19,8 +19,9 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/dialogs/tor_warning_dialog.dart';
@@ -74,42 +75,46 @@ class HiddenSettings extends StatelessWidget {
                     child: Column(
                       crossAxisAlignment: CrossAxisAlignment.stretch,
                       children: [
-                        Consumer(builder: (_, ref, __) {
-                          return GestureDetector(
-                            onTap: () async {
-                              final notifs =
-                                  ref.read(notificationsProvider).notifications;
+                        Consumer(
+                          builder: (_, ref, __) {
+                            return GestureDetector(
+                              onTap: () async {
+                                final notifs = ref
+                                    .read(notificationsProvider)
+                                    .notifications;
 
-                              for (final n in notifs) {
+                                for (final n in notifs) {
+                                  await ref
+                                      .read(notificationsProvider)
+                                      .delete(n, false);
+                                }
                                 await ref
                                     .read(notificationsProvider)
-                                    .delete(n, false);
-                              }
-                              await ref
-                                  .read(notificationsProvider)
-                                  .delete(notifs[0], true);
+                                    .delete(notifs[0], true);
 
-                              if (context.mounted) {
-                                unawaited(
-                                  showFloatingFlushBar(
-                                    type: FlushBarType.success,
-                                    message: "Notification history deleted",
-                                    context: context,
-                                  ),
-                                );
-                              }
-                            },
-                            child: RoundedWhiteContainer(
-                              child: Text(
-                                "Delete notifications",
-                                style: STextStyles.button(context).copyWith(
+                                if (context.mounted) {
+                                  unawaited(
+                                    showFloatingFlushBar(
+                                      type: FlushBarType.success,
+                                      message: "Notification history deleted",
+                                      context: context,
+                                    ),
+                                  );
+                                }
+                              },
+                              child: RoundedWhiteContainer(
+                                child: Text(
+                                  "Delete notifications",
+                                  style: STextStyles.button(context).copyWith(
                                     color: Theme.of(context)
                                         .extension<StackColors>()!
-                                        .accentColorDark),
+                                        .accentColorDark,
+                                  ),
+                                ),
                               ),
-                            ),
-                          );
-                        }),
+                            );
+                          },
+                        ),
                         // const SizedBox(
                         //   height: 12,
                         // ),
@@ -141,34 +146,37 @@ class HiddenSettings extends StatelessWidget {
                         const SizedBox(
                           height: 12,
                         ),
-                        Consumer(builder: (_, ref, __) {
-                          return GestureDetector(
-                            onTap: () async {
-                              await ref
-                                  .read(debugServiceProvider)
-                                  .deleteAllLogs();
+                        Consumer(
+                          builder: (_, ref, __) {
+                            return GestureDetector(
+                              onTap: () async {
+                                await ref
+                                    .read(debugServiceProvider)
+                                    .deleteAllLogs();
 
-                              if (context.mounted) {
-                                unawaited(
-                                  showFloatingFlushBar(
-                                    type: FlushBarType.success,
-                                    message: "Debug Logs deleted",
-                                    context: context,
-                                  ),
-                                );
-                              }
-                            },
-                            child: RoundedWhiteContainer(
-                              child: Text(
-                                "Delete Debug Logs",
-                                style: STextStyles.button(context).copyWith(
+                                if (context.mounted) {
+                                  unawaited(
+                                    showFloatingFlushBar(
+                                      type: FlushBarType.success,
+                                      message: "Debug Logs deleted",
+                                      context: context,
+                                    ),
+                                  );
+                                }
+                              },
+                              child: RoundedWhiteContainer(
+                                child: Text(
+                                  "Delete Debug Logs",
+                                  style: STextStyles.button(context).copyWith(
                                     color: Theme.of(context)
                                         .extension<StackColors>()!
-                                        .accentColorDark),
+                                        .accentColorDark,
+                                  ),
+                                ),
                               ),
-                            ),
-                          );
-                        }),
+                            );
+                          },
+                        ),
                         const SizedBox(
                           height: 12,
                         ),
@@ -216,8 +224,10 @@ class HiddenSettings extends StatelessWidget {
                         // ),
                         Consumer(
                           builder: (_, ref, __) {
-                            if (ref.watch(prefsChangeNotifierProvider
-                                    .select((value) => value.familiarity)) <
+                            if (ref.watch(
+                                  prefsChangeNotifierProvider
+                                      .select((value) => value.familiarity),
+                                ) <
                                 6) {
                               return GestureDetector(
                                 onTap: () async {
@@ -236,9 +246,10 @@ class HiddenSettings extends StatelessWidget {
                                   child: Text(
                                     "Enable exchange",
                                     style: STextStyles.button(context).copyWith(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .accentColorDark),
+                                      color: Theme.of(context)
+                                          .extension<StackColors>()!
+                                          .accentColorDark,
+                                    ),
                                   ),
                                 ),
                               );
@@ -257,7 +268,7 @@ class HiddenSettings extends StatelessWidget {
                                 await showDialog<bool>(
                                   context: context,
                                   builder: (_) => TorWarningDialog(
-                                    coin: Coin.stellar,
+                                    coin: Stellar(CryptoCurrencyNetwork.main),
                                   ),
                                 );
                               },
@@ -265,9 +276,10 @@ class HiddenSettings extends StatelessWidget {
                                 child: Text(
                                   "Show Tor warning popup",
                                   style: STextStyles.button(context).copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .accentColorDark),
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark,
+                                  ),
                                 ),
                               ),
                             );
@@ -286,9 +298,10 @@ class HiddenSettings extends StatelessWidget {
                                 child: Text(
                                   "Do nothing",
                                   style: STextStyles.button(context).copyWith(
-                                      color: Theme.of(context)
-                                          .extension<StackColors>()!
-                                          .accentColorDark),
+                                    color: Theme.of(context)
+                                        .extension<StackColors>()!
+                                        .accentColorDark,
+                                  ),
                                 ),
                               ),
                             );
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
index 7a656c288..87a354191 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart
@@ -14,26 +14,23 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/flutter_svg.dart';
-import 'package:solana/solana.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
-import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/connection_check/electrum_connection_check.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
-import 'package:stackwallet/utilities/logger.dart';
-import 'package:stackwallet/utilities/test_epic_box_connection.dart';
-import 'package:stackwallet/utilities/test_eth_node_connection.dart';
-import 'package:stackwallet/utilities/test_monero_node_connection.dart';
-import 'package:stackwallet/utilities/test_stellar_node_connection.dart';
+import 'package:stackwallet/utilities/test_node_connection.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
-import 'package:stackwallet/wallets/api/tezos/tezos_rpc_api.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/cryptonote_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -51,17 +48,17 @@ enum AddEditNodeViewType { add, edit }
 
 class AddEditNodeView extends ConsumerStatefulWidget {
   const AddEditNodeView({
-    Key? key,
+    super.key,
     required this.viewType,
     required this.coin,
     required this.nodeId,
     required this.routeOnSuccessOrDelete,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/addEditNode";
 
   final AddEditNodeViewType viewType;
-  final Coin coin;
+  final CryptoCurrency coin;
   final String routeOnSuccessOrDelete;
   final String? nodeId;
 
@@ -71,192 +68,31 @@ class AddEditNodeView extends ConsumerStatefulWidget {
 
 class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
   late final AddEditNodeViewType viewType;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final String? nodeId;
   late final bool isDesktop;
 
   late bool saveEnabled;
   late bool testConnectionEnabled;
 
-  Future<bool> _xmrHelper(String url, int? port) async {
-    final uri = Uri.parse(url);
-
-    final String path = uri.path.isEmpty ? "/json_rpc" : uri.path;
-
-    final uriString = "${uri.scheme}://${uri.host}:${port ?? 0}$path";
-
-    ref.read(nodeFormDataProvider).useSSL = true;
-
-    final response = await testMoneroNodeConnection(
-      Uri.parse(uriString),
-      false,
-    );
-
-    if (response.cert != null) {
-      if (mounted) {
-        final shouldAllowBadCert = await showBadX509CertificateDialog(
-          response.cert!,
-          response.url!,
-          response.port!,
-          context,
-        );
-
-        if (shouldAllowBadCert) {
-          final response =
-              await testMoneroNodeConnection(Uri.parse(uriString), true);
-          ref.read(nodeFormDataProvider).host = url;
-          return response.success;
-        }
-      }
-    } else {
-      ref.read(nodeFormDataProvider).host = url;
-      return response.success;
+  void _onTestSuccess(NodeFormData data) {
+    if (coin is Epiccash) {
+      ref.read(nodeFormDataProvider).host = data.host;
+      ref.read(nodeFormDataProvider).port = data.port;
+      ref.read(nodeFormDataProvider).useSSL = data.useSSL;
+    } else if (coin is CryptonoteCurrency) {
+      ref.read(nodeFormDataProvider).host = data.host;
     }
-
-    return false;
-  }
-
-  Future<bool> _testConnection({bool showFlushBar = true}) async {
-    final formData = ref.read(nodeFormDataProvider);
-
-    bool testPassed = false;
-
-    switch (coin) {
-      case Coin.epicCash:
-        try {
-          final data = await testEpicNodeConnection(formData);
-
-          if (data != null) {
-            testPassed = true;
-            ref.read(nodeFormDataProvider).host = data.host;
-            ref.read(nodeFormDataProvider).port = data.port;
-            ref.read(nodeFormDataProvider).useSSL = data.useSSL;
-          }
-        } catch (e, s) {
-          Logging.instance.log("$e\n$s", level: LogLevel.Warning);
-        }
-        break;
-
-      case Coin.monero:
-      case Coin.wownero:
-        try {
-          final url = formData.host!;
-          final uri = Uri.tryParse(url);
-          if (uri != null) {
-            if (!uri.hasScheme) {
-              // try https first
-              testPassed = await _xmrHelper("https://$url", formData.port);
-
-              if (testPassed == false) {
-                // try http
-                testPassed = await _xmrHelper("http://$url", formData.port);
-              }
-            } else {
-              testPassed = await _xmrHelper(url, formData.port);
-            }
-          }
-        } catch (e, s) {
-          Logging.instance.log("$e\n$s", level: LogLevel.Warning);
-        }
-
-        break;
-
-      case Coin.bitcoin:
-      case Coin.bitcoincash:
-      case Coin.litecoin:
-      case Coin.dogecoin:
-      case Coin.eCash:
-      case Coin.firo:
-      case Coin.namecoin:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.bitcoinTestNet:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincashTestnet:
-      case Coin.firoTestNet:
-      case Coin.dogecoinTestNet:
-        try {
-          testPassed = await checkElectrumServer(
-            host: formData.host!,
-            port: formData.port!,
-            useSSL: formData.useSSL!,
-            overridePrefs: ref.read(prefsChangeNotifierProvider),
-            overrideTorService: ref.read(pTorService),
-          );
-        } catch (_) {
-          testPassed = false;
-        }
-
-        break;
-
-      case Coin.ethereum:
-        try {
-          testPassed = await testEthNodeConnection(formData.host!);
-        } catch (_) {
-          testPassed = false;
-        }
-        break;
-
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        try {
-          testPassed =
-              await testStellarNodeConnection(formData.host!, formData.port!);
-        } catch (_) {}
-        break;
-
-      case Coin.nano:
-      case Coin.banano:
-        throw UnimplementedError();
-      //TODO: check network/node
-      case Coin.tezos:
-        try {
-          testPassed = await TezosRpcAPI.testNetworkConnection(
-            nodeInfo: (host: formData.host!, port: formData.port!),
-          );
-        } catch (_) {}
-        break;
-
-      case Coin.solana:
-        try {
-          RpcClient rpcClient;
-          if (formData.host!.startsWith("http") ||
-              formData.host!.startsWith("https")) {
-            rpcClient = RpcClient("${formData.host}:${formData.port}");
-          } else {
-            rpcClient = RpcClient("http://${formData.host}:${formData.port}");
-          }
-          await rpcClient.getEpochInfo().then((value) => testPassed = true);
-        } catch (_) {
-          testPassed = false;
-        }
-        break;
-    }
-
-    if (showFlushBar && mounted) {
-      if (testPassed) {
-        unawaited(showFloatingFlushBar(
-          type: FlushBarType.success,
-          message: "Server ping success",
-          context: context,
-        ));
-      } else {
-        unawaited(showFloatingFlushBar(
-          type: FlushBarType.warning,
-          message: "Server unreachable",
-          context: context,
-        ));
-      }
-    }
-
-    return testPassed;
   }
 
   Future<void> attemptSave() async {
-    final canConnect = await _testConnection(showFlushBar: false);
+    final canConnect = await testNodeConnection(
+      context: context,
+      onSuccess: _onTestSuccess,
+      cryptoCurrency: coin,
+      nodeFormData: ref.read(nodeFormDataProvider),
+      ref: ref,
+    );
 
     bool? shouldSave;
 
@@ -387,7 +223,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
 
     // strip unused path
     String address = formData.host!;
-    if (coin == Coin.monero || coin == Coin.wownero) {
+    if (coin is Monero || coin is Wownero) {
       if (address.startsWith("http")) {
         final uri = Uri.parse(address);
         address = "${uri.scheme}://${uri.host}";
@@ -404,7 +240,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
           useSSL: formData.useSSL!,
           loginName: formData.login,
           enabled: true,
-          coinName: coin.name,
+          coinName: coin.identifier,
           isFailover: formData.isFailover!,
           trusted: formData.trusted!,
           isDown: false,
@@ -429,7 +265,7 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
           useSSL: formData.useSSL!,
           loginName: formData.login,
           enabled: true,
-          coinName: coin.name,
+          coinName: coin.identifier,
           isFailover: formData.isFailover!,
           trusted: formData.trusted!,
           isDown: false,
@@ -652,7 +488,32 @@ class _AddEditNodeViewState extends ConsumerState<AddEditNodeView> {
                     buttonHeight: isDesktop ? ButtonHeight.l : null,
                     onPressed: testConnectionEnabled
                         ? () async {
-                            await _testConnection();
+                            final testPassed = await testNodeConnection(
+                              context: context,
+                              onSuccess: _onTestSuccess,
+                              cryptoCurrency: coin,
+                              nodeFormData: ref.read(nodeFormDataProvider),
+                              ref: ref,
+                            );
+                            if (context.mounted) {
+                              if (testPassed) {
+                                unawaited(
+                                  showFloatingFlushBar(
+                                    type: FlushBarType.success,
+                                    message: "Server ping success",
+                                    context: context,
+                                  ),
+                                );
+                              } else {
+                                unawaited(
+                                  showFloatingFlushBar(
+                                    type: FlushBarType.warning,
+                                    message: "Server unreachable",
+                                    context: context,
+                                  ),
+                                );
+                              }
+                            }
                           }
                         : null,
                   ),
@@ -724,7 +585,7 @@ class NodeForm extends ConsumerStatefulWidget {
   final NodeModel? node;
   final SecureStorageInterface secureStore;
   final bool readOnly;
-  final Coin coin;
+  final CryptoCurrency coin;
   final void Function(bool canSave, bool canTestConnection)? onChanged;
 
   @override
@@ -754,39 +615,15 @@ class _NodeFormState extends ConsumerState<NodeForm> {
 
   void Function(bool canSave, bool canTestConnection)? onChanged;
 
-  bool _checkShouldEnableAuthFields(Coin coin) {
+  bool _checkShouldEnableAuthFields(CryptoCurrency coin) {
     // TODO: which coin servers can have username and password?
     switch (coin) {
-      case Coin.bitcoin:
-      case Coin.litecoin:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.namecoin:
-      case Coin.bitcoincash:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-      case Coin.tezos:
-      case Coin.bitcoinTestNet:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincashTestnet:
-      case Coin.firoTestNet:
-      case Coin.dogecoinTestNet:
-      case Coin.epicCash:
-      case Coin.nano:
-      case Coin.banano:
-      case Coin.eCash:
-      case Coin.solana:
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-        return false;
-
-      case Coin.ethereum:
-      case Coin.monero:
-      case Coin.wownero:
+      case Ethereum():
+      case CryptonoteCurrency():
         return true;
+
+      default:
+        return false;
     }
   }
 
@@ -862,7 +699,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
       _useSSL = node.useSSL;
       _isFailover = node.isFailover;
       _trusted = node.trusted ?? false;
-      if (widget.coin == Coin.epicCash) {
+      if (widget.coin is Epiccash) {
         enableSSLCheckbox = !node.host.startsWith("http");
       } else {
         enableSSLCheckbox = true;
@@ -961,9 +798,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
             focusNode: _hostFocusNode,
             style: STextStyles.field(context),
             decoration: standardInputDecoration(
-              (widget.coin != Coin.monero && widget.coin != Coin.wownero)
-                  ? "IP address"
-                  : "Url",
+              (widget.coin is! CryptonoteCurrency) ? "IP address" : "Url",
               _hostFocusNode,
               context,
             ).copyWith(
@@ -987,7 +822,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
                   : null,
             ),
             onChanged: (newValue) {
-              if (widget.coin == Coin.epicCash) {
+              if (widget.coin is Epiccash) {
                 if (newValue.startsWith("https://")) {
                   _useSSL = true;
                   enableSSLCheckbox = false;
@@ -1151,7 +986,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
           const SizedBox(
             height: 8,
           ),
-        if (widget.coin != Coin.monero && widget.coin != Coin.wownero)
+        if (widget.coin is! CryptonoteCurrency)
           Row(
             children: [
               GestureDetector(
@@ -1202,7 +1037,7 @@ class _NodeFormState extends ConsumerState<NodeForm> {
               ),
             ],
           ),
-        if (widget.coin == Coin.monero || widget.coin == Coin.wownero)
+        if (widget.coin is Monero || widget.coin is Wownero)
           Row(
             children: [
               GestureDetector(
@@ -1253,15 +1088,11 @@ class _NodeFormState extends ConsumerState<NodeForm> {
               ),
             ],
           ),
-        if (widget.coin != Coin.monero &&
-            widget.coin != Coin.wownero &&
-            widget.coin != Coin.epicCash)
+        if (widget.coin is! CryptonoteCurrency && widget.coin is! Epiccash)
           const SizedBox(
             height: 8,
           ),
-        if (widget.coin != Coin.monero &&
-            widget.coin != Coin.wownero &&
-            widget.coin != Coin.epicCash)
+        if (widget.coin is! CryptonoteCurrency && widget.coin is! Epiccash)
           Row(
             children: [
               GestureDetector(
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart
index 1bb393246..56b5538e5 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart
@@ -18,9 +18,9 @@ import 'package:stackwallet/pages/settings_views/sub_widgets/nodes_list.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
@@ -30,14 +30,14 @@ import 'package:tuple/tuple.dart';
 
 class CoinNodesView extends ConsumerStatefulWidget {
   const CoinNodesView({
-    Key? key,
+    super.key,
     required this.coin,
     this.rootNavigator = false,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/coinNodes";
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final bool rootNavigator;
 
   @override
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart
index c6e59c96c..74980942b 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/manage_nodes_view.dart
@@ -15,19 +15,21 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class ManageNodesView extends ConsumerStatefulWidget {
   const ManageNodesView({
-    Key? key,
-  }) : super(key: key);
+    super.key,
+  });
 
   static const String routeName = "/manageNodes";
 
@@ -36,12 +38,14 @@ class ManageNodesView extends ConsumerStatefulWidget {
 }
 
 class _ManageNodesViewState extends ConsumerState<ManageNodesView> {
-  List<Coin> _coins = [...Coin.values];
+  List<CryptoCurrency> _coins = [...SupportedCoins.cryptocurrencies];
 
   @override
   void initState() {
     _coins = _coins.toList();
-    _coins.remove(Coin.firoTestNet);
+    _coins.removeWhere(
+      (e) => e is Firo && e.network == CryptoCurrencyNetwork.test,
+    );
     super.initState();
   }
 
@@ -52,12 +56,13 @@ class _ManageNodesViewState extends ConsumerState<ManageNodesView> {
 
   @override
   Widget build(BuildContext context) {
-    bool showTestNet = ref.watch(
+    final showTestNet = ref.watch(
       prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
     );
 
-    List<Coin> coins =
-        showTestNet ? _coins : _coins.where((e) => !e.isTestNet).toList();
+    final coins = showTestNet
+        ? _coins
+        : _coins.where((e) => e.network != CryptoCurrencyNetwork.test).toList();
 
     return Background(
       child: Scaffold(
diff --git a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
index 1034d986c..8cb734e94 100644
--- a/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
+++ b/lib/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart
@@ -13,25 +13,17 @@ import 'dart:async';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:solana/solana.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart';
 import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
-import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/connection_check/electrum_connection_check.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
-import 'package:stackwallet/utilities/logger.dart';
-import 'package:stackwallet/utilities/test_epic_box_connection.dart';
-import 'package:stackwallet/utilities/test_eth_node_connection.dart';
-import 'package:stackwallet/utilities/test_monero_node_connection.dart';
-import 'package:stackwallet/utilities/test_stellar_node_connection.dart';
+import 'package:stackwallet/utilities/test_node_connection.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
-import 'package:stackwallet/wallets/api/tezos/tezos_rpc_api.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -43,15 +35,15 @@ import 'package:tuple/tuple.dart';
 
 class NodeDetailsView extends ConsumerStatefulWidget {
   const NodeDetailsView({
-    Key? key,
+    super.key,
     required this.coin,
     required this.nodeId,
     required this.popRouteName,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/nodeDetails";
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final String nodeId;
   final String popRouteName;
 
@@ -61,7 +53,7 @@ class NodeDetailsView extends ConsumerStatefulWidget {
 
 class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
   late final SecureStorageInterface secureStore;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final String nodeId;
   late final String popRouteName;
 
@@ -76,170 +68,19 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
     super.initState();
   }
 
-  Future<void> _testConnection(WidgetRef ref, BuildContext context) async {
-    final node =
-        ref.watch(nodeServiceChangeNotifierProvider).getNodeById(id: nodeId);
-
-    bool testPassed = false;
-
-    switch (coin) {
-      case Coin.epicCash:
-        try {
-          testPassed = await testEpicNodeConnection(
-                NodeFormData()
-                  ..host = node!.host
-                  ..useSSL = node.useSSL
-                  ..port = node.port,
-              ) !=
-              null;
-        } catch (e, s) {
-          Logging.instance.log("$e\n$s", level: LogLevel.Warning);
-          testPassed = false;
-        }
-        break;
-
-      case Coin.monero:
-      case Coin.wownero:
-        try {
-          final uri = Uri.parse(node!.host);
-          if (uri.scheme.startsWith("http")) {
-            final String path = uri.path.isEmpty ? "/json_rpc" : uri.path;
-
-            String uriString = "${uri.scheme}://${uri.host}:${node.port}$path";
-
-            final response = await testMoneroNodeConnection(
-              Uri.parse(uriString),
-              false,
-            );
-
-            if (response.cert != null) {
-              if (mounted) {
-                final shouldAllowBadCert = await showBadX509CertificateDialog(
-                  response.cert!,
-                  response.url!,
-                  response.port!,
-                  context,
-                );
-
-                if (shouldAllowBadCert) {
-                  final response = await testMoneroNodeConnection(
-                      Uri.parse(uriString), true);
-                  testPassed = response.success;
-                }
-              }
-            } else {
-              testPassed = response.success;
-            }
-          }
-        } catch (e, s) {
-          Logging.instance.log("$e\n$s", level: LogLevel.Warning);
-        }
-
-        break;
-
-      case Coin.bitcoin:
-      case Coin.litecoin:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-      case Coin.bitcoinTestNet:
-      case Coin.firoTestNet:
-      case Coin.dogecoinTestNet:
-      case Coin.bitcoincash:
-      case Coin.namecoin:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincashTestnet:
-      case Coin.eCash:
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-        try {
-          testPassed = await checkElectrumServer(
-            host: node!.host,
-            port: node.port,
-            useSSL: node.useSSL,
-            overridePrefs: ref.read(prefsChangeNotifierProvider),
-            overrideTorService: ref.read(pTorService),
-          );
-        } catch (_) {
-          testPassed = false;
-        }
-
-        break;
-
-      case Coin.ethereum:
-        try {
-          testPassed = await testEthNodeConnection(node!.host);
-        } catch (_) {
-          testPassed = false;
-        }
-        break;
-
-      case Coin.nano:
-      case Coin.banano:
-        // TODO: fix this lacking code
-        throw UnimplementedError();
-      //TODO: check network/node
-      case Coin.tezos:
-        try {
-          testPassed = await TezosRpcAPI.testNetworkConnection(
-            nodeInfo: (host: node!.host, port: node!.port),
-          );
-        } catch (_) {}
-        break;
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        try {
-          testPassed = await testStellarNodeConnection(node!.host, node.port);
-        } catch (_) {
-          testPassed = false;
-        }
-        break;
-
-      case Coin.solana:
-        try {
-          RpcClient rpcClient;
-          if (node!.host.startsWith("http") || node.host.startsWith("https")) {
-            rpcClient = RpcClient("${node.host}:${node.port}");
-          } else {
-            rpcClient = RpcClient("http://${node.host}:${node.port}");
-          }
-          await rpcClient.getEpochInfo().then((value) => testPassed = true);
-        } catch (_) {
-          testPassed = false;
-        }
-        break;
-    }
-
-    if (testPassed) {
-      unawaited(
-        showFloatingFlushBar(
-          type: FlushBarType.success,
-          message: "Server ping success",
-          context: context,
-        ),
-      );
-    } else {
-      unawaited(
-        showFloatingFlushBar(
-          type: FlushBarType.warning,
-          message: "Server unreachable",
-          context: context,
-        ),
-      );
-    }
-  }
-
   @override
   Widget build(BuildContext context) {
     final isDesktop = Util.isDesktop;
 
-    final node = ref.watch(nodeServiceChangeNotifierProvider
-        .select((value) => value.getNodeById(id: nodeId)));
+    final node = ref.watch(
+      nodeServiceChangeNotifierProvider
+          .select((value) => value.getNodeById(id: nodeId)),
+    );
 
-    final nodesForCoin = ref.watch(nodeServiceChangeNotifierProvider
-        .select((value) => value.getNodesFor(coin)));
+    final nodesForCoin = ref.watch(
+      nodeServiceChangeNotifierProvider
+          .select((value) => value.getNodesFor(coin)),
+    );
 
     final canDelete = nodesForCoin.length > 1;
 
@@ -256,7 +97,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
                   FocusScope.of(context).unfocus();
                   await Future<void>.delayed(const Duration(milliseconds: 75));
                 }
-                if (mounted) {
+                if (context.mounted) {
                   Navigator.of(context).pop();
                 }
               },
@@ -350,7 +191,7 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
                   Text(
                     "Node details",
                     style: STextStyles.desktopH3(context),
-                  )
+                  ),
                 ],
               ),
               Padding(
@@ -420,7 +261,52 @@ class _NodeDetailsViewState extends ConsumerState<NodeDetailsView> {
                     label: "Test connection",
                     buttonHeight: isDesktop ? ButtonHeight.l : null,
                     onPressed: () async {
-                      await _testConnection(ref, context);
+                      final node = ref
+                          .read(nodeServiceChangeNotifierProvider)
+                          .getNodeById(id: nodeId)!;
+
+                      final nodeFormData = NodeFormData()
+                        ..useSSL = node.useSSL
+                        ..trusted = node.trusted
+                        ..name = node.name
+                        ..host = node.host
+                        ..login = node.loginName
+                        ..port = node.port
+                        ..isFailover = node.isFailover;
+                      nodeFormData.password = await node.getPassword(
+                        ref.read(secureStoreProvider),
+                      );
+
+                      if (context.mounted) {
+                        final testPassed = await testNodeConnection(
+                          context: context,
+                          nodeFormData: nodeFormData,
+                          cryptoCurrency: coin,
+                          ref: ref,
+                        );
+
+                        if (testPassed) {
+                          if (context.mounted) {
+                            unawaited(
+                              showFloatingFlushBar(
+                                type: FlushBarType.success,
+                                message: "Server ping success",
+                                context: context,
+                              ),
+                            );
+                          }
+                        } else {
+                          if (context.mounted) {
+                            unawaited(
+                              showFloatingFlushBar(
+                                type: FlushBarType.warning,
+                                message: "Server unreachable",
+                                context: context,
+                              ),
+                            );
+                          }
+                        }
+                      }
                     },
                   ),
                 ),
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart
index f6491cf1d..6ece250f1 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/helpers/restore_create_backup.dart
@@ -33,9 +33,8 @@ import 'package:stackwallet/services/trade_notes_service.dart';
 import 'package:stackwallet/services/trade_sent_from_stack_service.dart';
 import 'package:stackwallet/services/trade_service.dart';
 import 'package:stackwallet/services/wallets.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/stack_restoring_status.dart';
 import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
@@ -43,6 +42,8 @@ import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/frost_currency.dart';
 import 'package:stackwallet/wallets/isar/models/frost_wallet_info.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/wallets/wallet/impl/bitcoin_frost_wallet.dart';
@@ -80,7 +81,9 @@ String getErrorMessageFromSWBException(Exception e) {
 
 String createAutoBackupFilename(String dirPath, DateTime date) {
   // this filename structure is important. DO NOT CHANGE
-  return "$dirPath/stackautobackup_${date.year}_${date.month}_${date.day}_${date.hour}_${date.minute}_${date.second}.swb";
+  return "$dirPath/stackautobackup_"
+      "${date.year}_${date.month}_${date.day}_${date.hour}"
+      "_${date.minute}_${date.second}.swb";
 }
 
 abstract class SWB {
@@ -95,8 +98,9 @@ abstract class SWB {
           .log("SWB cancel restore requested", level: LogLevel.Info);
     } else {
       Logging.instance.log(
-          "SWB cancel restore requested while a cancellation request is currently in progress",
-          level: LogLevel.Warning);
+        "SWB cancel restore requested while a cancellation request is currently in progress",
+        level: LogLevel.Warning,
+      );
     }
 
     // return completer that will complete on SWBRestoreCancelEventType.completed event
@@ -129,11 +133,11 @@ abstract class SWB {
     String plaintext,
   ) async {
     try {
-      File backupFile = File(fileToSave);
+      final File backupFile = File(fileToSave);
       if (!backupFile.existsSync()) {
-        String jsonBackup = plaintext;
-        Uint8List content = Uint8List.fromList(utf8.encode(jsonBackup));
-        Uint8List encryptedContent =
+        final String jsonBackup = plaintext;
+        final Uint8List content = Uint8List.fromList(utf8.encode(jsonBackup));
+        final Uint8List encryptedContent =
             await encryptWithPassphrase(passphrase, content);
         backupFile
             .writeAsStringSync(Format.uint8listToString(encryptedContent));
@@ -153,13 +157,15 @@ abstract class SWB {
     int adkVersion,
   ) async {
     try {
-      File backupFile = File(fileToSave);
+      final File backupFile = File(fileToSave);
       if (!backupFile.existsSync()) {
-        String jsonBackup = plaintext;
-        Uint8List content = Uint8List.fromList(utf8.encode(jsonBackup));
-        Uint8List encryptedContent = await encryptWithAdk(
-            Format.stringToUint8List(adk), content,
-            version: adkVersion);
+        final String jsonBackup = plaintext;
+        final Uint8List content = Uint8List.fromList(utf8.encode(jsonBackup));
+        final Uint8List encryptedContent = await encryptWithAdk(
+          Format.stringToUint8List(adk),
+          content,
+          version: adkVersion,
+        );
         backupFile
             .writeAsStringSync(Format.uint8listToString(encryptedContent));
       }
@@ -175,10 +181,10 @@ abstract class SWB {
     Tuple2<String, String> data,
   ) async {
     try {
-      String fileToRestore = data.item1;
-      String passphrase = data.item2;
-      File backupFile = File(fileToRestore);
-      String encryptedText = await backupFile.readAsString();
+      final String fileToRestore = data.item1;
+      final String passphrase = data.item2;
+      final File backupFile = File(fileToRestore);
+      final String encryptedText = await backupFile.readAsString();
       return await decryptStackWalletStringWithPassphrase(
         Tuple2(encryptedText, passphrase),
       );
@@ -192,15 +198,15 @@ abstract class SWB {
     Tuple2<String, String> data,
   ) async {
     try {
-      String encryptedText = data.item1;
-      String passphrase = data.item2;
+      final encryptedText = data.item1;
+      final passphrase = data.item2;
 
-      final Uint8List encryptedBytes = Format.stringToUint8List(encryptedText);
+      final encryptedBytes = Format.stringToUint8List(encryptedText);
 
-      Uint8List decryptedContent =
+      final decryptedContent =
           await decryptWithPassphrase(passphrase, encryptedBytes);
 
-      final String jsonBackup = utf8.decode(decryptedContent);
+      final jsonBackup = utf8.decode(decryptedContent);
       return jsonBackup;
     } catch (e, s) {
       Logging.instance.log("$e\n$s", level: LogLevel.Error);
@@ -215,24 +221,27 @@ abstract class SWB {
     Logging.instance
         .log("Starting createStackWalletJSON...", level: LogLevel.Info);
     final _wallets = Wallets.sharedInstance;
-    Map<String, dynamic> backupJson = {};
-    NodeService nodeService =
+    final Map<String, dynamic> backupJson = {};
+    final NodeService nodeService =
         NodeService(secureStorageInterface: secureStorage);
     final _secureStore = secureStorage;
 
-    Logging.instance.log("createStackWalletJSON awaiting DB.instance.mutex...",
-        level: LogLevel.Info);
+    Logging.instance.log(
+      "createStackWalletJSON awaiting DB.instance.mutex...",
+      level: LogLevel.Info,
+    );
     // prevent modification of data
     await DB.instance.mutex.protect(() async {
       Logging.instance.log(
-          "...createStackWalletJSON DB.instance.mutex acquired",
-          level: LogLevel.Info);
+        "...createStackWalletJSON DB.instance.mutex acquired",
+        level: LogLevel.Info,
+      );
       Logging.instance.log(
         "SWB backing up nodes",
         level: LogLevel.Warning,
       );
       try {
-        var primaryNodes = nodeService.primaryNodes.map((e) async {
+        final primaryNodes = nodeService.primaryNodes.map((e) async {
           final map = e.toMap();
           map["password"] = await e.getPassword(_secureStore);
           return map;
@@ -258,7 +267,7 @@ abstract class SWB {
         level: LogLevel.Warning,
       );
 
-      Map<String, dynamic> prefs = {};
+      final Map<String, dynamic> prefs = {};
       final _prefs = Prefs.instance;
       await _prefs.init();
       prefs['currency'] = _prefs.currency;
@@ -282,8 +291,8 @@ abstract class SWB {
         level: LogLevel.Warning,
       );
 
-      AddressBookService addressBookService = AddressBookService();
-      var addresses = addressBookService.contacts;
+      final AddressBookService addressBookService = AddressBookService();
+      final addresses = addressBookService.contacts;
       backupJson['addressBookEntries'] =
           addresses.map((e) => e.toMap()).toList();
 
@@ -292,9 +301,9 @@ abstract class SWB {
         level: LogLevel.Warning,
       );
 
-      List<dynamic> backupWallets = [];
-      for (var wallet in _wallets.wallets) {
-        Map<String, dynamic> backupWallet = {};
+      final List<dynamic> backupWallets = [];
+      for (final wallet in _wallets.wallets) {
+        final Map<String, dynamic> backupWallet = {};
         backupWallet['name'] = wallet.info.name;
         backupWallet['id'] = wallet.walletId;
         backupWallet['isFavorite'] = wallet.info.isFavourite;
@@ -307,10 +316,11 @@ abstract class SWB {
         } else if (wallet is PrivateKeyInterface) {
           backupWallet['privateKey'] = await wallet.getPrivateKey();
         } else if (wallet is BitcoinFrostWallet) {
-          String? keys = await wallet.getSerializedKeys();
-          String? config = await wallet.getMultisigConfig();
+          final String? keys = await wallet.getSerializedKeys();
+          final String? config = await wallet.getMultisigConfig();
           if (keys == null || config == null) {
-            String err = "${wallet.info.coin.name} wallet ${wallet.info.name} "
+            final String err =
+                "${wallet.info.coin.identifier} wallet ${wallet.info.name} "
                 "has null keys or config";
             Logging.instance.log(err, level: LogLevel.Fatal);
             throw Exception(err);
@@ -320,12 +330,12 @@ abstract class SWB {
           // TODO [prio=low]: solve case in which either keys or config is null.
 
           // Format keys & config as a JSON string and set otherDataJsonString.
-          Map<String, dynamic> frostData = {};
+          final Map<String, dynamic> frostData = {};
           frostData["keys"] = keys;
           frostData["config"] = config;
           backupWallet['frostWalletData'] = jsonEncode(frostData);
         }
-        backupWallet['coinName'] = wallet.info.coin.name;
+        backupWallet['coinName'] = wallet.info.coin.identifier;
         backupWallet['storedChainHeight'] = wallet.info.cachedChainHeight;
 
         // backupWallet['txidList'] = DB.instance.get<dynamic>(
@@ -377,8 +387,10 @@ abstract class SWB {
       final tradeNotes = tradeNotesService.all;
       backupJson["tradeNotes"] = tradeNotes;
     });
-    Logging.instance.log("createStackWalletJSON DB.instance.mutex released",
-        level: LogLevel.Info);
+    Logging.instance.log(
+      "createStackWalletJSON DB.instance.mutex released",
+      level: LogLevel.Info,
+    );
 
     // // back up notifications data
     // final notificationsService = NotificationsService();
@@ -411,9 +423,10 @@ abstract class SWB {
       }
     } else {
       if (walletbackup['mnemonic'] is List) {
-        List<String> mnemonicList = (walletbackup['mnemonic'] as List<dynamic>)
-            .map<String>((e) => e as String)
-            .toList();
+        final List<String> mnemonicList =
+            (walletbackup['mnemonic'] as List<dynamic>)
+                .map<String>((e) => e as String)
+                .toList();
         mnemonic = mnemonicList.join(" ").trim();
       } else {
         mnemonic = walletbackup['mnemonic'] as String;
@@ -432,7 +445,7 @@ abstract class SWB {
     try {
       String? serializedKeys;
       String? multisigConfig;
-      if (info.coin.isFrost) {
+      if (info.coin is FrostCurrency) {
         // Decode info.otherDataJsonString for Frost recovery info.
         final frostData = jsonDecode(walletbackup["frostWalletData"] as String);
         serializedKeys = frostData["keys"] as String;
@@ -544,8 +557,9 @@ abstract class SWB {
       await restoringFuture;
 
       Logging.instance.log(
-          "SWB restored: ${info.walletId} ${info.name} ${info.coin.prettyName}",
-          level: LogLevel.Info);
+        "SWB restored: ${info.walletId} ${info.name} ${info.coin.prettyName}",
+        level: LogLevel.Info,
+      );
 
       final currentAddress = await wallet.getCurrentReceivingAddress();
       uiState?.update(
@@ -576,15 +590,16 @@ abstract class SWB {
     Map<String, String> oldToNewWalletIdMap,
     SecureStorageInterface secureStorageInterface,
   ) async {
-    Map<String, dynamic> prefs = validJSON["prefs"] as Map<String, dynamic>;
-    List<dynamic>? addressBookEntries =
+    final Map<String, dynamic> prefs =
+        validJSON["prefs"] as Map<String, dynamic>;
+    final List<dynamic>? addressBookEntries =
         validJSON["addressBookEntries"] as List?;
-    List<dynamic>? primaryNodes = validJSON["primaryNodes"] as List?;
-    List<dynamic>? nodes = validJSON["nodes"] as List?;
-    List<dynamic>? trades = validJSON["tradeHistory"] as List?;
-    List<dynamic>? tradeTxidLookupData =
+    final List<dynamic>? primaryNodes = validJSON["primaryNodes"] as List?;
+    final List<dynamic>? nodes = validJSON["nodes"] as List?;
+    final List<dynamic>? trades = validJSON["tradeHistory"] as List?;
+    final List<dynamic>? tradeTxidLookupData =
         validJSON["tradeTxidLookupData"] as List?;
-    Map<String, dynamic>? tradeNotes =
+    final Map<String, dynamic>? tradeNotes =
         validJSON["tradeNotes"] as Map<String, dynamic>?;
 
     uiState?.preferences = StackRestoringStatus.restoring;
@@ -689,7 +704,7 @@ abstract class SWB {
       level: LogLevel.Warning,
     );
 
-    List<String> _currentWalletIds = await MainDB.instance.isar.walletInfo
+    final List<String> _currentWalletIds = await MainDB.instance.isar.walletInfo
         .where()
         .walletIdProperty()
         .findAll();
@@ -697,12 +712,12 @@ abstract class SWB {
     final preRestoreState =
         PreRestoreState(_currentWalletIds.toSet(), preRestoreJSON);
 
-    Map<String, String> oldToNewWalletIdMap = {};
+    final Map<String, String> oldToNewWalletIdMap = {};
 
-    Map<String, dynamic> validJSON =
+    final Map<String, dynamic> validJSON =
         json.decode(jsonBackup) as Map<String, dynamic>;
 
-    List<dynamic> wallets = validJSON["wallets"] as List;
+    final List<dynamic> wallets = validJSON["wallets"] as List;
 
     // check for duplicate walletIds and assign new ones if required
     for (final wallet in wallets) {
@@ -748,9 +763,9 @@ abstract class SWB {
 
     final List<Tuple2<dynamic, WalletInfo>> managers = [];
 
-    Map<String, WalletRestoreState> walletStates = {};
+    final Map<String, WalletRestoreState> walletStates = {};
 
-    for (var walletbackup in wallets) {
+    for (final walletbackup in wallets) {
       // check if cancel was requested and restore previous state
       if (_checkShouldCancel(
         preRestoreState,
@@ -759,8 +774,10 @@ abstract class SWB {
         return false;
       }
 
-      final coin = Coin.values
-          .firstWhere((element) => element.name == walletbackup['coinName']);
+      final coin = SupportedCoins.getCryptoCurrencyFor(
+        walletbackup['coinName'] as String,
+      );
+
       final walletName = walletbackup['name'] as String;
       final walletId = oldToNewWalletIdMap[walletbackup["id"] as String]!;
 
@@ -781,7 +798,7 @@ abstract class SWB {
         );
       }
 
-      if (coin == Coin.firo) {
+      if (coin is Firo) {
         otherData ??= {};
         // swb will do a restore so this flag should be set to false so another
         // rescan/restore isn't done when opening the wallet
@@ -789,7 +806,7 @@ abstract class SWB {
       }
 
       final info = WalletInfo(
-        coinName: coin.name,
+        coinName: coin.identifier,
         walletId: walletId,
         name: walletName,
         mainAddressType: coin.primaryAddressType,
@@ -798,10 +815,10 @@ abstract class SWB {
         cachedChainHeight: walletbackup['storedChainHeight'] as int? ?? 0,
       );
 
-      var node = nodeService.getPrimaryNodeFor(coin: coin);
+      var node = nodeService.getPrimaryNodeFor(currency: coin);
 
       if (node == null) {
-        node = DefaultNodes.getNodeFor(coin);
+        node = coin.defaultNode;
         await nodeService.setPrimaryNodeFor(coin: coin, node: node);
       }
 
@@ -845,7 +862,7 @@ abstract class SWB {
     // set the states so the ui can display each status as they update during restores
     uiState?.walletStates = walletStates;
 
-    List<Future<bool>> restoreStatuses = [];
+    final List<Future<bool>> restoreStatuses = [];
     // start restoring wallets
     for (final tuple in managers) {
       // check if cancel was requested and restore previous state
@@ -873,7 +890,7 @@ abstract class SWB {
       return false;
     }
 
-    for (Future<bool> status in restoreStatuses) {
+    for (final Future<bool> status in restoreStatuses) {
       // check if cancel was requested and restore previous state
       if (_checkShouldCancel(
         preRestoreState,
@@ -905,17 +922,18 @@ abstract class SWB {
     PreRestoreState revertToState,
     SecureStorageInterface secureStorageInterface,
   ) async {
-    Map<String, dynamic> prefs =
+    final Map<String, dynamic> prefs =
         revertToState.validJSON["prefs"] as Map<String, dynamic>;
-    List<dynamic>? addressBookEntries =
+    final List<dynamic>? addressBookEntries =
         revertToState.validJSON["addressBookEntries"] as List?;
-    List<dynamic>? primaryNodes =
+    final List<dynamic>? primaryNodes =
         revertToState.validJSON["primaryNodes"] as List?;
-    List<dynamic>? nodes = revertToState.validJSON["nodes"] as List?;
-    List<dynamic>? trades = revertToState.validJSON["tradeHistory"] as List?;
-    List<dynamic>? tradeTxidLookupData =
+    final List<dynamic>? nodes = revertToState.validJSON["nodes"] as List?;
+    final List<dynamic>? trades =
+        revertToState.validJSON["tradeHistory"] as List?;
+    final List<dynamic>? tradeTxidLookupData =
         revertToState.validJSON["tradeTxidLookupData"] as List?;
-    Map<String, dynamic>? tradeNotes =
+    final Map<String, dynamic>? tradeNotes =
         revertToState.validJSON["tradeNotes"] as Map<String, dynamic>?;
 
     // prefs
@@ -971,7 +989,7 @@ abstract class SWB {
     }
 
     // nodes
-    NodeService nodeService = NodeService(
+    final NodeService nodeService = NodeService(
       secureStorageInterface: secureStorageInterface,
     );
     final currentNodes = nodeService.nodes;
@@ -1015,10 +1033,12 @@ abstract class SWB {
 
     // primary nodes
     if (primaryNodes != null) {
-      for (var node in primaryNodes) {
+      for (final node in primaryNodes) {
         try {
           await nodeService.setPrimaryNodeFor(
-            coin: coinFromPrettyName(node['coinName'] as String),
+            coin: SupportedCoins.getCryptoCurrencyByPrettyName(
+              node['coinName'] as String,
+            ),
             node: nodeService.getNodeById(id: node['id'] as String)!,
           );
         } catch (e, s) {
@@ -1050,12 +1070,15 @@ abstract class SWB {
           // trade existed before attempted restore so we don't delete it, only
           // revert data to pre restore state
           await tradesService.edit(
-              trade: Trade.fromMap(tradeData as Map<String, dynamic>),
-              shouldNotifyListeners: true);
+            trade: Trade.fromMap(tradeData as Map<String, dynamic>),
+            shouldNotifyListeners: true,
+          );
         } else {
           // trade did not exist before so we delete it
           await tradesService.delete(
-              trade: tradeTx, shouldNotifyListeners: true);
+            trade: tradeTx,
+            shouldNotifyListeners: true,
+          );
         }
       }
     }
@@ -1093,7 +1116,7 @@ abstract class SWB {
     if (tradeTxidLookupData != null) {
       for (int i = 0; i < tradeTxidLookupData.length; i++) {
         final json = Map<String, dynamic>.from(tradeTxidLookupData[i] as Map);
-        TradeWalletLookup lookup = TradeWalletLookup.fromJson(json);
+        final TradeWalletLookup lookup = TradeWalletLookup.fromJson(json);
         await tradeTxidLookupDataService.save(tradeWalletLookup: lookup);
       }
     }
@@ -1137,8 +1160,9 @@ abstract class SWB {
     _prefs.isAutoBackupEnabled = prefs['isAutoBackupEnabled'] as bool;
     _prefs.autoBackupLocation = prefs['autoBackupLocation'] as String?;
     _prefs.backupFrequencyType = BackupFrequencyType.values.firstWhere(
-        (e) => e.name == (prefs['backupFrequencyType'] as String?),
-        orElse: () => BackupFrequencyType.everyAppStart);
+      (e) => e.name == (prefs['backupFrequencyType'] as String?),
+      orElse: () => BackupFrequencyType.everyAppStart,
+    );
     _prefs.lastAutoBackup =
         DateTime.tryParse(prefs['lastAutoBackup'] as String? ?? "");
   }
@@ -1146,10 +1170,10 @@ abstract class SWB {
   static Future<void> _restoreAddressBook(
     List<dynamic> addressBookEntries,
   ) async {
-    AddressBookService addressBookService = AddressBookService();
-    for (var contact in addressBookEntries) {
-      List<ContactAddressEntry> addresses = [];
-      for (var address in (contact['addresses'] as List<dynamic>)) {
+    final AddressBookService addressBookService = AddressBookService();
+    for (final contact in addressBookEntries) {
+      final List<ContactAddressEntry> addresses = [];
+      for (final address in (contact['addresses'] as List<dynamic>)) {
         addresses.add(
           ContactAddressEntry()
             ..coinName = address['coin'] as String
@@ -1175,11 +1199,11 @@ abstract class SWB {
     List<dynamic>? primaryNodes,
     SecureStorageInterface secureStorageInterface,
   ) async {
-    NodeService nodeService = NodeService(
+    final NodeService nodeService = NodeService(
       secureStorageInterface: secureStorageInterface,
     );
     if (nodes != null) {
-      for (var node in nodes) {
+      for (final node in nodes) {
         await nodeService.add(
           NodeModel(
             host: node['host'] as String,
@@ -1199,10 +1223,12 @@ abstract class SWB {
       }
     }
     if (primaryNodes != null) {
-      for (var node in primaryNodes) {
+      for (final node in primaryNodes) {
         try {
           await nodeService.setPrimaryNodeFor(
-            coin: coinFromPrettyName(node['coinName'] as String),
+            coin: SupportedCoins.getCryptoCurrencyByPrettyName(
+              node['coinName'] as String,
+            ),
             node: nodeService.getNodeById(id: node['id'] as String)!,
           );
         } catch (e, s) {
@@ -1272,16 +1298,18 @@ abstract class SWB {
       final json = Map<String, dynamic>.from(tradeTxidLookupData[i] as Map);
       TradeWalletLookup lookup = TradeWalletLookup.fromJson(json);
       // update walletIds
-      List<String> walletIds =
+      final List<String> walletIds =
           lookup.walletIds.map((e) => oldToNewWalletIdMap[e]!).toList();
       lookup = lookup.copyWith(walletIds: walletIds);
 
       final oldLookup = DB.instance.get<TradeWalletLookup>(
-          boxName: DB.boxNameTradeLookup, key: lookup.uuid);
+        boxName: DB.boxNameTradeLookup,
+        key: lookup.uuid,
+      );
       if (oldLookup != null) {
         if (oldLookup.txid == lookup.txid &&
             oldLookup.tradeId == lookup.tradeId) {
-          List<String> mergedList = oldLookup.walletIds;
+          final List<String> mergedList = oldLookup.walletIds;
           for (final id in lookup.walletIds) {
             if (!mergedList.contains(id)) {
               mergedList.add(id);
@@ -1308,7 +1336,9 @@ abstract class SWB {
     final tradeNotesService = TradeNotesService();
     for (final note in tradeNotes.entries) {
       await tradeNotesService.set(
-          tradeId: note.key, note: note.value as String);
+        tradeId: note.key,
+        note: note.value as String,
+      );
     }
   }
 }
diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart
index 36c3d7c81..53ad106b5 100644
--- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart
+++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart
@@ -20,8 +20,8 @@ import 'package:stackwallet/providers/stack_restore/stack_restoring_ui_state_pro
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
+import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/stack_restoring_status.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
@@ -89,9 +89,7 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> {
               height: 32,
               child: RoundedContainer(
                 padding: const EdgeInsets.all(0),
-                color: Theme.of(context)
-                    .extension<StackColors>()!
-                    .colorForCoin(coin),
+                color: ref.watch(pCoinColor(coin)),
                 child: Center(
                   child: SvgPicture.file(
                     File(
@@ -212,9 +210,7 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> {
                 height: 32,
                 child: RoundedContainer(
                   padding: const EdgeInsets.all(0),
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .colorForCoin(coin),
+                  color: ref.watch(pCoinColor(coin)),
                   child: Center(
                     child: SvgPicture.file(
                       File(
@@ -239,7 +235,7 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> {
                       try {
                         // final mnemonicList = await manager.mnemonic;
                         // int maxUnusedAddressGap = 20;
-                        // if (coin == Coin.firo) {
+                        // if (coin is Firo) {
                         //   maxUnusedAddressGap = 50;
                         // }
                         // const maxNumberOfIndexesToCheck = 1000;
diff --git a/lib/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart b/lib/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart
index 6e057eaf4..d636a8d5a 100644
--- a/lib/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart
+++ b/lib/pages/settings_views/global_settings_view/startup_preferences/startup_wallet_selection_view.dart
@@ -16,6 +16,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
+import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
@@ -63,165 +64,181 @@ class _StartupWalletSelectionViewState
             ),
           ),
         ),
-        body: LayoutBuilder(builder: (context, constraints) {
-          return Padding(
-            padding: const EdgeInsets.only(
-              left: 12,
-              top: 12,
-              right: 12,
-            ),
-            child: SingleChildScrollView(
-              child: ConstrainedBox(
-                constraints: BoxConstraints(
-                  minHeight: constraints.maxHeight - 24,
-                ),
-                child: IntrinsicHeight(
-                  child: Padding(
-                    padding: const EdgeInsets.all(4),
-                    child: Column(
-                      crossAxisAlignment: CrossAxisAlignment.start,
-                      children: [
-                        const SizedBox(
-                          height: 4,
-                        ),
-                        Text(
-                          "Select a wallet to load into immediately on startup",
-                          style: STextStyles.smallMed12(context),
-                        ),
-                        const SizedBox(
-                          height: 12,
-                        ),
-                        RoundedWhiteContainer(
-                          padding: const EdgeInsets.all(0),
-                          child: Column(
-                            children: [
-                              ...wallets.map(
-                                (wallet) => Padding(
-                                  padding: const EdgeInsets.all(12),
-                                  child: Row(
-                                    key: Key(
-                                        "startupWalletSelectionGroupKey_${wallet.walletId}"),
-                                    children: [
-                                      Container(
-                                        decoration: BoxDecoration(
-                                          color: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .colorForCoin(
-                                                ref.watch(pWalletCoin(
-                                                    wallet.walletId)),
-                                              )
-                                              .withOpacity(0.5),
-                                          borderRadius: BorderRadius.circular(
-                                            Constants.size.circularBorderRadius,
+        body: LayoutBuilder(
+          builder: (context, constraints) {
+            return Padding(
+              padding: const EdgeInsets.only(
+                left: 12,
+                top: 12,
+                right: 12,
+              ),
+              child: SingleChildScrollView(
+                child: ConstrainedBox(
+                  constraints: BoxConstraints(
+                    minHeight: constraints.maxHeight - 24,
+                  ),
+                  child: IntrinsicHeight(
+                    child: Padding(
+                      padding: const EdgeInsets.all(4),
+                      child: Column(
+                        crossAxisAlignment: CrossAxisAlignment.start,
+                        children: [
+                          const SizedBox(
+                            height: 4,
+                          ),
+                          Text(
+                            "Select a wallet to load into immediately on startup",
+                            style: STextStyles.smallMed12(context),
+                          ),
+                          const SizedBox(
+                            height: 12,
+                          ),
+                          RoundedWhiteContainer(
+                            padding: const EdgeInsets.all(0),
+                            child: Column(
+                              children: [
+                                ...wallets.map(
+                                  (wallet) => Padding(
+                                    padding: const EdgeInsets.all(12),
+                                    child: Row(
+                                      key: Key(
+                                        "startupWalletSelectionGroupKey_${wallet.walletId}",
+                                      ),
+                                      children: [
+                                        Container(
+                                          decoration: BoxDecoration(
+                                            color: ref
+                                                .watch(
+                                                  pCoinColor(
+                                                    ref.watch(
+                                                      pWalletCoin(
+                                                        wallet.walletId,
+                                                      ),
+                                                    ),
+                                                  ),
+                                                )
+                                                .withOpacity(0.5),
+                                            borderRadius: BorderRadius.circular(
+                                              Constants
+                                                  .size.circularBorderRadius,
+                                            ),
                                           ),
-                                        ),
-                                        child: Padding(
-                                          padding: const EdgeInsets.all(4),
-                                          child: SvgPicture.file(
-                                            File(
-                                              ref.watch(
-                                                coinIconProvider(
-                                                  ref.watch(pWalletCoin(
-                                                      wallet.walletId)),
+                                          child: Padding(
+                                            padding: const EdgeInsets.all(4),
+                                            child: SvgPicture.file(
+                                              File(
+                                                ref.watch(
+                                                  coinIconProvider(
+                                                    ref.watch(
+                                                      pWalletCoin(
+                                                        wallet.walletId,
+                                                      ),
+                                                    ),
+                                                  ),
                                                 ),
                                               ),
+                                              width: 20,
+                                              height: 20,
                                             ),
-                                            width: 20,
-                                            height: 20,
                                           ),
                                         ),
-                                      ),
-                                      const SizedBox(
-                                        width: 12,
-                                      ),
-                                      Expanded(
-                                        child: Column(
-                                          mainAxisAlignment:
-                                              MainAxisAlignment.spaceBetween,
-                                          crossAxisAlignment:
-                                              CrossAxisAlignment.start,
-                                          children: [
-                                            Text(
-                                              ref.watch(
-                                                  pWalletName(wallet.walletId)),
-                                              style: STextStyles.titleBold12(
-                                                  context),
-                                            ),
-                                            // const SizedBox(
-                                            //   height: 2,
-                                            // ),
-                                            // FutureBuilder(
-                                            //   future: manager.totalBalance,
-                                            //   builder: (builderContext,
-                                            //       AsyncSnapshot<Decimal> snapshot) {
-                                            //     if (snapshot.connectionState ==
-                                            //             ConnectionState.done &&
-                                            //         snapshot.hasData) {
-                                            //       return Text(
-                                            //         "${Format.localizedStringAsFixed(
-                                            //           value: snapshot.data!,
-                                            //           locale: ref.watch(
-                                            //               localeServiceChangeNotifierProvider
-                                            //                   .select((value) =>
-                                            //                       value.locale)),
-                                            //           decimalPlaces: 8,
-                                            //         )} ${manager.coin.ticker}",
-                                            //         style: STextStyles.itemSubtitle(context),
-                                            //       );
-                                            //     } else {
-                                            //       return AnimatedText(
-                                            //         stringsToLoopThrough: const [
-                                            //           "Loading balance",
-                                            //           "Loading balance.",
-                                            //           "Loading balance..",
-                                            //           "Loading balance..."
-                                            //         ],
-                                            //         style: STextStyles.itemSubtitle(context),
-                                            //       );
-                                            //     }
-                                            //   },
-                                            // ),
-                                          ],
+                                        const SizedBox(
+                                          width: 12,
                                         ),
-                                      ),
-                                      SizedBox(
-                                        height: 20,
-                                        width: 20,
-                                        child: Radio(
-                                          activeColor: Theme.of(context)
-                                              .extension<StackColors>()!
-                                              .radioButtonIconEnabled,
-                                          value: wallet.walletId,
-                                          groupValue: ref.watch(
-                                            prefsChangeNotifierProvider.select(
+                                        Expanded(
+                                          child: Column(
+                                            mainAxisAlignment:
+                                                MainAxisAlignment.spaceBetween,
+                                            crossAxisAlignment:
+                                                CrossAxisAlignment.start,
+                                            children: [
+                                              Text(
+                                                ref.watch(
+                                                  pWalletName(wallet.walletId),
+                                                ),
+                                                style: STextStyles.titleBold12(
+                                                  context,
+                                                ),
+                                              ),
+                                              // const SizedBox(
+                                              //   height: 2,
+                                              // ),
+                                              // FutureBuilder(
+                                              //   future: manager.totalBalance,
+                                              //   builder: (builderContext,
+                                              //       AsyncSnapshot<Decimal> snapshot) {
+                                              //     if (snapshot.connectionState ==
+                                              //             ConnectionState.done &&
+                                              //         snapshot.hasData) {
+                                              //       return Text(
+                                              //         "${Format.localizedStringAsFixed(
+                                              //           value: snapshot.data!,
+                                              //           locale: ref.watch(
+                                              //               localeServiceChangeNotifierProvider
+                                              //                   .select((value) =>
+                                              //                       value.locale)),
+                                              //           decimalPlaces: 8,
+                                              //         )} ${manager.coin.ticker}",
+                                              //         style: STextStyles.itemSubtitle(context),
+                                              //       );
+                                              //     } else {
+                                              //       return AnimatedText(
+                                              //         stringsToLoopThrough: const [
+                                              //           "Loading balance",
+                                              //           "Loading balance.",
+                                              //           "Loading balance..",
+                                              //           "Loading balance..."
+                                              //         ],
+                                              //         style: STextStyles.itemSubtitle(context),
+                                              //       );
+                                              //     }
+                                              //   },
+                                              // ),
+                                            ],
+                                          ),
+                                        ),
+                                        SizedBox(
+                                          height: 20,
+                                          width: 20,
+                                          child: Radio(
+                                            activeColor: Theme.of(context)
+                                                .extension<StackColors>()!
+                                                .radioButtonIconEnabled,
+                                            value: wallet.walletId,
+                                            groupValue: ref.watch(
+                                              prefsChangeNotifierProvider
+                                                  .select(
                                                 (value) =>
-                                                    value.startupWalletId),
+                                                    value.startupWalletId,
+                                              ),
+                                            ),
+                                            onChanged: (value) {
+                                              if (value is String) {
+                                                ref
+                                                    .read(
+                                                      prefsChangeNotifierProvider,
+                                                    )
+                                                    .startupWalletId = value;
+                                              }
+                                            },
                                           ),
-                                          onChanged: (value) {
-                                            if (value is String) {
-                                              ref
-                                                  .read(
-                                                      prefsChangeNotifierProvider)
-                                                  .startupWalletId = value;
-                                            }
-                                          },
                                         ),
-                                      ),
-                                    ],
+                                      ],
+                                    ),
                                   ),
                                 ),
-                              ),
-                            ],
+                              ],
+                            ),
                           ),
-                        ),
-                      ],
+                        ],
+                      ),
                     ),
                   ),
                 ),
               ),
-            ),
-          );
-        }),
+            );
+          },
+        ),
       ),
     );
   }
diff --git a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
index 8ded05dd6..375534e4a 100644
--- a/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
+++ b/lib/pages/settings_views/global_settings_view/syncing_preferences_views/wallet_syncing_options_view.dart
@@ -16,6 +16,7 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
+import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -117,9 +118,8 @@ class WalletSyncingOptionsView extends ConsumerWidget {
                                   children: [
                                     Container(
                                       decoration: BoxDecoration(
-                                        color: Theme.of(context)
-                                            .extension<StackColors>()!
-                                            .colorForCoin(info.coin)
+                                        color: ref
+                                            .watch(pCoinColor(info.coin))
                                             .withOpacity(0.5),
                                         borderRadius: BorderRadius.circular(
                                           Constants.size.circularBorderRadius,
diff --git a/lib/pages/settings_views/sub_widgets/nodes_list.dart b/lib/pages/settings_views/sub_widgets/nodes_list.dart
index 52d9b8861..de01c392c 100644
--- a/lib/pages/settings_views/sub_widgets/nodes_list.dart
+++ b/lib/pages/settings_views/sub_widgets/nodes_list.dart
@@ -11,39 +11,39 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/providers/global/node_service_provider.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/node_card.dart';
 
 class NodesList extends ConsumerWidget {
   const NodesList({
-    Key? key,
+    super.key,
     required this.coin,
     required this.popBackToRoute,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final String popBackToRoute;
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    final nodes = ref.watch(nodeServiceChangeNotifierProvider
-        .select((value) => value.getNodesFor(coin)));
+    final nodes = ref.watch(
+      nodeServiceChangeNotifierProvider
+          .select((value) => value.getNodesFor(coin)),
+    );
 
     return Column(
       children: [
-        ...nodes
-            .map(
-              (node) => Padding(
-                padding: const EdgeInsets.symmetric(vertical: 4),
-                child: NodeCard(
-                  key: Key("${node.id}_card_key"),
-                  nodeId: node.id,
-                  coin: coin,
-                  popBackToRoute: popBackToRoute,
-                ),
-              ),
-            )
-            .toList(),
+        ...nodes.map(
+          (node) => Padding(
+            padding: const EdgeInsets.symmetric(vertical: 4),
+            child: NodeCard(
+              key: Key("${node.id}_card_key"),
+              nodeId: node.id,
+              coin: coin,
+              popBackToRoute: popBackToRoute,
+            ),
+          ),
+        ),
       ],
     );
   }
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart
index 6fbf8df93..9eae180f9 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_network_settings_view/wallet_network_settings_view.dart
@@ -32,9 +32,11 @@ import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart';
 import 'package:stackwallet/wallets/wallet/impl/monero_wallet.dart';
@@ -57,12 +59,12 @@ import 'package:wakelock/wakelock.dart';
 /// [eventBus] should only be set during testing
 class WalletNetworkSettingsView extends ConsumerStatefulWidget {
   const WalletNetworkSettingsView({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.initialSyncStatus,
     required this.initialNodeStatus,
     this.eventBus,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final WalletSyncStatus initialSyncStatus;
@@ -260,7 +262,7 @@ class _WalletNetworkSettingsViewState
 
     final coin = ref.read(pWalletCoin(widget.walletId));
 
-    if (coin == Coin.monero || coin == Coin.wownero || coin == Coin.epicCash) {
+    if (coin is Monero || coin is Wownero || coin is Epiccash) {
       _blocksRemainingSubscription = eventBus.on<BlocksRemainingEvent>().listen(
         (event) async {
           if (event.walletId == widget.walletId) {
@@ -319,22 +321,22 @@ class _WalletNetworkSettingsViewState
 
     final coin = ref.watch(pWalletCoin(widget.walletId));
 
-    if (coin == Coin.monero) {
-      double highestPercent =
+    if (coin is Monero) {
+      final double highestPercent =
           (ref.read(pWallets).getWallet(widget.walletId) as MoneroWallet)
               .highestPercentCached;
       if (_percent < highestPercent) {
         _percent = highestPercent.clamp(0.0, 1.0);
       }
-    } else if (coin == Coin.wownero) {
-      double highestPercent =
+    } else if (coin is Wownero) {
+      final double highestPercent =
           (ref.watch(pWallets).getWallet(widget.walletId) as WowneroWallet)
               .highestPercentCached;
       if (_percent < highestPercent) {
         _percent = highestPercent.clamp(0.0, 1.0);
       }
-    } else if (coin == Coin.epicCash) {
-      double highestPercent =
+    } else if (coin is Epiccash) {
+      final double highestPercent =
           (ref.watch(pWallets).getWallet(widget.walletId) as EpiccashWallet)
               .highestPercent;
       if (_percent < highestPercent) {
@@ -360,7 +362,7 @@ class _WalletNetworkSettingsViewState
                 style: STextStyles.navBarTitle(context),
               ),
               actions: [
-                if (ref.watch(pWalletCoin(widget.walletId)) != Coin.epicCash)
+                if (ref.watch(pWalletCoin(widget.walletId)) is! Epiccash)
                   Padding(
                     padding: const EdgeInsets.only(
                       top: 10,
@@ -371,7 +373,8 @@ class _WalletNetworkSettingsViewState
                       aspectRatio: 1,
                       child: AppBarIconButton(
                         key: const Key(
-                            "walletNetworkSettingsAddNewNodeViewButton"),
+                          "walletNetworkSettingsAddNewNodeViewButton",
+                        ),
                         size: 36,
                         shadows: const [],
                         color: Theme.of(context)
@@ -402,8 +405,8 @@ class _WalletNetworkSettingsViewState
                                             .extension<StackColors>()!
                                             .popupBG,
                                         borderRadius: BorderRadius.circular(
-                                            Constants
-                                                .size.circularBorderRadius),
+                                          Constants.size.circularBorderRadius,
+                                        ),
                                         // boxShadow: [CFColors.standardBoxShadow],
                                         boxShadow: const [],
                                       ),
@@ -431,7 +434,8 @@ class _WalletNetworkSettingsViewState
                                                 child: Text(
                                                   "Rescan blockchain",
                                                   style: STextStyles.baseXS(
-                                                      context),
+                                                    context,
+                                                  ),
                                                 ),
                                               ),
                                             ),
@@ -620,9 +624,9 @@ class _WalletNetworkSettingsViewState
                                         .accentColorYellow,
                                   ),
                                 ),
-                                if (coin == Coin.monero ||
-                                    coin == Coin.wownero ||
-                                    coin == Coin.epicCash)
+                                if (coin is Monero ||
+                                    coin is Wownero ||
+                                    coin is Epiccash)
                                   Text(
                                     " (Blocks to go: ${_blocksRemaining == -1 ? "?" : _blocksRemaining})",
                                     style: STextStyles.syncPercent(context)
@@ -633,7 +637,7 @@ class _WalletNetworkSettingsViewState
                                     ),
                                   ),
                               ],
-                            )
+                            ),
                           ],
                         ),
                       ),
@@ -768,8 +772,9 @@ class _WalletNetworkSettingsViewState
                     : STextStyles.smallMed12(context),
               ),
               CustomTextButton(
-                text: ref.watch(prefsChangeNotifierProvider
-                        .select((value) => value.useTor))
+                text: ref.watch(
+                  prefsChangeNotifierProvider.select((value) => value.useTor),
+                )
                     ? "Disconnect"
                     : "Connect",
                 onTap: onTorTapped,
@@ -787,8 +792,9 @@ class _WalletNetworkSettingsViewState
                 isDesktop ? const EdgeInsets.all(16) : const EdgeInsets.all(12),
             child: Row(
               children: [
-                if (ref.watch(prefsChangeNotifierProvider
-                    .select((value) => value.useTor)))
+                if (ref.watch(
+                  prefsChangeNotifierProvider.select((value) => value.useTor),
+                ))
                   Container(
                     width: _iconSize,
                     height: _iconSize,
@@ -810,8 +816,9 @@ class _WalletNetworkSettingsViewState
                       ),
                     ),
                   ),
-                if (!ref.watch(prefsChangeNotifierProvider
-                    .select((value) => value.useTor)))
+                if (!ref.watch(
+                  prefsChangeNotifierProvider.select((value) => value.useTor),
+                ))
                   Container(
                     width: _iconSize,
                     height: _iconSize,
@@ -916,13 +923,11 @@ class _WalletNetworkSettingsViewState
             coin: ref.watch(pWalletCoin(widget.walletId)),
             popBackToRoute: WalletNetworkSettingsView.routeName,
           ),
-          if (isDesktop &&
-              ref.watch(pWalletCoin(widget.walletId)) != Coin.epicCash)
+          if (isDesktop && ref.watch(pWalletCoin(widget.walletId)) is! Epiccash)
             const SizedBox(
               height: 32,
             ),
-          if (isDesktop &&
-              ref.watch(pWalletCoin(widget.walletId)) != Coin.epicCash)
+          if (isDesktop && ref.watch(pWalletCoin(widget.walletId)) is! Epiccash)
             Padding(
               padding: const EdgeInsets.only(
                 bottom: 12,
@@ -938,8 +943,7 @@ class _WalletNetworkSettingsViewState
                 ],
               ),
             ),
-          if (isDesktop &&
-              ref.watch(pWalletCoin(widget.walletId)) != Coin.epicCash)
+          if (isDesktop && ref.watch(pWalletCoin(widget.walletId)) is! Epiccash)
             RoundedWhiteContainer(
               borderColor: isDesktop
                   ? Theme.of(context).extension<StackColors>()!.background
@@ -987,8 +991,8 @@ class _WalletNetworkSettingsViewState
                             Text(
                               "Advanced",
                               style: STextStyles.desktopTextExtraExtraSmall(
-                                      context)
-                                  .copyWith(
+                                context,
+                              ).copyWith(
                                 color: Theme.of(context)
                                     .extension<StackColors>()!
                                     .textDark,
@@ -997,10 +1001,11 @@ class _WalletNetworkSettingsViewState
                             Text(
                               "Rescan blockchain",
                               style: STextStyles.desktopTextExtraExtraSmall(
-                                  context),
+                                context,
+                              ),
                             ),
                           ],
-                        )
+                        ),
                       ],
                     ),
                     SvgPicture.asset(
diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
index 66dfb8c23..63130bbdd 100644
--- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
+++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_view.dart
@@ -36,10 +36,13 @@ import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_
 import 'package:stackwallet/services/event_bus/global_event_bus.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/frost_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 import 'package:stackwallet/wallets/wallet/impl/bitcoin_frost_wallet.dart';
 import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
@@ -64,7 +67,7 @@ class WalletSettingsView extends ConsumerStatefulWidget {
   static const String routeName = "/walletSettings";
 
   final String walletId;
-  final Coin coin;
+  final CryptoCurrency coin;
   final WalletSyncStatus initialSyncStatus;
   final NodeConnectionStatus initialNodeStatus;
   final EventBus? eventBus;
@@ -75,7 +78,7 @@ class WalletSettingsView extends ConsumerStatefulWidget {
 
 class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
   late final String walletId;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late String xpub;
   late final bool xPubEnabled;
 
@@ -206,11 +209,11 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
                                     );
                                   },
                                 ),
-                                if (coin.isFrost)
+                                if (coin is FrostCurrency)
                                   const SizedBox(
                                     height: 8,
                                   ),
-                                if (coin.isFrost)
+                                if (coin is FrostCurrency)
                                   SettingsListButton(
                                     iconAssetName: Assets.svg.addressBook2,
                                     iconSize: 16,
@@ -376,11 +379,11 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
                                       );
                                     },
                                   ),
-                                if (coin == Coin.firo)
+                                if (coin is Firo)
                                   const SizedBox(
                                     height: 8,
                                   ),
-                                if (coin == Coin.firo)
+                                if (coin is Firo)
                                   Consumer(
                                     builder: (_, ref, __) {
                                       return SettingsListButton(
@@ -419,7 +422,7 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
                                                   ),
                                                   DB.instance
                                                       .clearSharedTransactionCache(
-                                                    coin: coin,
+                                                    currency: coin,
                                                   ),
                                                 ],
                                               ),
@@ -431,11 +434,11 @@ class _WalletSettingsViewState extends ConsumerState<WalletSettingsView> {
                                       );
                                     },
                                   ),
-                                if (coin == Coin.nano || coin == Coin.banano)
+                                if (coin is NanoCurrency)
                                   const SizedBox(
                                     height: 8,
                                   ),
-                                if (coin == Coin.nano || coin == Coin.banano)
+                                if (coin is NanoCurrency)
                                   Consumer(
                                     builder: (_, ref, __) {
                                       return SettingsListButton(
diff --git a/lib/pages/token_view/sub_widgets/my_token_select_item.dart b/lib/pages/token_view/sub_widgets/my_token_select_item.dart
index 2fd42300d..af76effde 100644
--- a/lib/pages/token_view/sub_widgets/my_token_select_item.dart
+++ b/lib/pages/token_view/sub_widgets/my_token_select_item.dart
@@ -21,10 +21,11 @@ import 'package:stackwallet/services/ethereum/cached_eth_token_balance.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/token_balance_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
@@ -178,7 +179,10 @@ class _MyTokenSelectItemState extends ConsumerState<MyTokenSelectItem> {
                           ),
                           const Spacer(),
                           Text(
-                            ref.watch(pAmountFormatter(Coin.ethereum)).format(
+                            ref
+                                .watch(pAmountFormatter(
+                                    Ethereum(CryptoCurrencyNetwork.main)))
+                                .format(
                                   ref
                                       .watch(pTokenBalance(
                                         (
diff --git a/lib/pages/token_view/sub_widgets/token_summary.dart b/lib/pages/token_view/sub_widgets/token_summary.dart
index a852d0954..f4c97b960 100644
--- a/lib/pages/token_view/sub_widgets/token_summary.dart
+++ b/lib/pages/token_view/sub_widgets/token_summary.dart
@@ -30,8 +30,9 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/token_balance_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
@@ -41,10 +42,10 @@ import 'package:tuple/tuple.dart';
 
 class TokenSummary extends ConsumerWidget {
   const TokenSummary({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.initialSyncStatus,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final WalletSyncStatus initialSyncStatus;
@@ -54,7 +55,8 @@ class TokenSummary extends ConsumerWidget {
     final token =
         ref.watch(pCurrentTokenWallet.select((value) => value!.tokenContract));
     final balance = ref.watch(
-        pTokenBalance((walletId: walletId, contractAddress: token.address)));
+      pTokenBalance((walletId: walletId, contractAddress: token.address)),
+    );
 
     return Stack(
       children: [
@@ -96,7 +98,13 @@ class TokenSummary extends ConsumerWidget {
                 mainAxisAlignment: MainAxisAlignment.center,
                 children: [
                   Text(
-                    ref.watch(pAmountFormatter(Coin.ethereum)).format(
+                    ref
+                        .watch(
+                          pAmountFormatter(
+                            Ethereum(CryptoCurrencyNetwork.main),
+                          ),
+                        )
+                        .format(
                           balance.total,
                           ethContract: token,
                         ),
@@ -173,13 +181,14 @@ class TokenSummary extends ConsumerWidget {
 
 class TokenWalletOptions extends ConsumerWidget {
   const TokenWalletOptions({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.tokenContract,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final EthContract tokenContract;
+  CryptoCurrency get ethereum => Ethereum(CryptoCurrencyNetwork.main);
 
   void _onExchangePressed(BuildContext context) async {
     unawaited(
@@ -187,7 +196,7 @@ class TokenWalletOptions extends ConsumerWidget {
         WalletInitiatedExchangeView.routeName,
         arguments: Tuple3(
           walletId,
-          Coin.ethereum,
+          ethereum,
           tokenContract,
         ),
       ),
@@ -199,7 +208,7 @@ class TokenWalletOptions extends ConsumerWidget {
       Navigator.of(context).pushNamed(
         BuyInWalletView.routeName,
         arguments: Tuple2(
-          Coin.ethereum,
+          ethereum,
           tokenContract,
         ),
       ),
@@ -233,7 +242,7 @@ class TokenWalletOptions extends ConsumerWidget {
               TokenSendView.routeName,
               arguments: Tuple3(
                 walletId,
-                Coin.ethereum,
+                ethereum,
                 tokenContract,
               ),
             );
@@ -268,11 +277,11 @@ class TokenWalletOptions extends ConsumerWidget {
 
 class TokenOptionsButton extends StatelessWidget {
   const TokenOptionsButton({
-    Key? key,
+    super.key,
     required this.onPressed,
     required this.subLabel,
     required this.iconAssetPathSVG,
-  }) : super(key: key);
+  });
 
   final VoidCallback onPressed;
   final String subLabel;
@@ -344,7 +353,7 @@ class TokenOptionsButton extends StatelessWidget {
                 .extension<StackColors>()!
                 .tokenSummaryTextPrimary,
           ),
-        )
+        ),
       ],
     );
   }
diff --git a/lib/pages/wallet_view/sub_widgets/transactions_list.dart b/lib/pages/wallet_view/sub_widgets/transactions_list.dart
index d3886378e..dd89c74b1 100644
--- a/lib/pages/wallet_view/sub_widgets/transactions_list.dart
+++ b/lib/pages/wallet_view/sub_widgets/transactions_list.dart
@@ -23,9 +23,9 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
@@ -36,9 +36,9 @@ import 'package:tuple/tuple.dart';
 
 class TransactionsList extends ConsumerStatefulWidget {
   const TransactionsList({
-    Key? key,
+    super.key,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   final String walletId;
 
@@ -80,7 +80,7 @@ class _TransactionsListState extends ConsumerState<TransactionsList> {
     BuildContext context,
     Transaction tx,
     BorderRadius? radius,
-    Coin coin,
+    CryptoCurrency coin,
     int chainHeight,
   ) {
     final matchingTrades = ref
diff --git a/lib/pages/wallet_view/sub_widgets/tx_icon.dart b/lib/pages/wallet_view/sub_widgets/tx_icon.dart
index 11920f7c2..b8bfa2c1a 100644
--- a/lib/pages/wallet_view/sub_widgets/tx_icon.dart
+++ b/lib/pages/wallet_view/sub_widgets/tx_icon.dart
@@ -19,19 +19,19 @@ import 'package:stackwallet/models/isar/stack_theme.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class TxIcon extends ConsumerWidget {
   const TxIcon({
-    Key? key,
+    super.key,
     required this.transaction,
     required this.currentHeight,
     required this.coin,
-  }) : super(key: key);
+  });
 
   final Object transaction;
   final int currentHeight;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   static const Size size = Size(32, 32);
 
diff --git a/lib/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart b/lib/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart
index af0eca1c6..27d2ba4a1 100644
--- a/lib/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart
+++ b/lib/pages/wallet_view/sub_widgets/wallet_balance_toggle_sheet.dart
@@ -17,9 +17,10 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 
 enum _BalanceType {
@@ -44,7 +45,7 @@ class WalletBalanceToggleSheet extends ConsumerWidget {
     final maxHeight = MediaQuery.of(context).size.height * 0.90;
 
     final coin = ref.watch(pWalletCoin(walletId));
-    final isFiro = coin == Coin.firo || coin == Coin.firoTestNet;
+    final isFiro = coin is Firo;
 
     final balance = ref.watch(pWalletBalance(walletId));
 
@@ -305,7 +306,7 @@ class BalanceSelector<T> extends ConsumerWidget {
   });
 
   final String title;
-  final Coin coin;
+  final CryptoCurrency coin;
   final Amount balance;
   final VoidCallback onPressed;
   final void Function(T?) onChanged;
diff --git a/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart b/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart
index fa01d1ac6..9a6999ae4 100644
--- a/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart
+++ b/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart
@@ -26,19 +26,20 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/banano.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/impl/banano_wallet.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 
 class WalletSummaryInfo extends ConsumerWidget {
   const WalletSummaryInfo({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.initialSyncStatus,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final WalletSyncStatus initialSyncStatus;
@@ -86,7 +87,7 @@ class WalletSummaryInfo extends ConsumerWidget {
     final Amount balanceToShow;
     final String title;
 
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+    if (coin is Firo) {
       final type = ref.watch(publicPrivateBalanceStateProvider.state).state;
       title =
           "${_showAvailable ? "Available" : "Full"} ${type.name.capitalize()} balance";
@@ -113,7 +114,7 @@ class WalletSummaryInfo extends ConsumerWidget {
 
     List<int>? imageBytes;
 
-    if (coin == Coin.banano) {
+    if (coin is Banano) {
       imageBytes = (ref.watch(pWallets).getWallet(walletId) as BananoWallet)
           .getMonkeyImageBytes();
     }
diff --git a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
index a1f177457..1851acb4a 100644
--- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
+++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart
@@ -31,10 +31,11 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -58,9 +59,9 @@ typedef _GroupedTransactions = ({
 
 class AllTransactionsView extends ConsumerStatefulWidget {
   const AllTransactionsView({
-    Key? key,
+    super.key,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/allTransactions";
 
@@ -830,10 +831,10 @@ class TransactionFilterOptionBarItem extends StatelessWidget {
 
 class DesktopTransactionCardRow extends ConsumerStatefulWidget {
   const DesktopTransactionCardRow({
-    Key? key,
+    super.key,
     required this.transaction,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   final Transaction transaction;
   final String walletId;
@@ -849,8 +850,8 @@ class _DesktopTransactionCardRowState
   late final String walletId;
   late final int minConfirms;
 
-  String whatIsIt(TransactionType type, Coin coin, int height) {
-    if (coin == Coin.epicCash && _transaction.slateId == null) {
+  String whatIsIt(TransactionType type, CryptoCurrency coin, int height) {
+    if (coin is Epiccash && _transaction.slateId == null) {
       return "Restored Funds";
     }
 
@@ -934,7 +935,7 @@ class _DesktopTransactionCardRowState
           ),
         ),
         onPressed: () async {
-          if (coin == Coin.epicCash && _transaction.slateId == null) {
+          if (coin is Epiccash && _transaction.slateId == null) {
             unawaited(
               showFloatingFlushBar(
                 context: context,
diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
index 82a29b087..a0d6afff2 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart
@@ -32,11 +32,19 @@ import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/block_explorers.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ecash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart';
 import 'package:stackwallet/widgets/background.dart';
@@ -56,17 +64,17 @@ import 'package:url_launcher/url_launcher.dart';
 
 class TransactionDetailsView extends ConsumerStatefulWidget {
   const TransactionDetailsView({
-    Key? key,
+    super.key,
     required this.transaction,
     required this.walletId,
     required this.coin,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/transactionDetails";
 
   final Transaction transaction;
   final String walletId;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<TransactionDetailsView> createState() =>
@@ -79,7 +87,7 @@ class _TransactionDetailsViewState
   late Transaction _transaction;
   late final String walletId;
 
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final Amount amount;
   late final Amount fee;
   late final String amountPrefix;
@@ -104,10 +112,9 @@ class _TransactionDetailsViewState
         .minConfirms;
     coin = widget.coin;
     amount = _transaction.realAmount;
-    fee = _transaction.fee.toAmountAsRaw(fractionDigits: coin.decimals);
+    fee = _transaction.fee.toAmountAsRaw(fractionDigits: coin.fractionDigits);
 
-    if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
-        _transaction.subType == TransactionSubType.mint) {
+    if ((coin is Firo) && _transaction.subType == TransactionSubType.mint) {
       amountPrefix = "";
     } else {
       amountPrefix = _transaction.type == TransactionType.outgoing ? "-" : "+";
@@ -119,7 +126,7 @@ class _TransactionDetailsViewState
 
     unit = isTokenTx ? ethContract!.symbol : coin.ticker;
 
-    // if (coin == Coin.firo || coin == Coin.firoTestNet) {
+    // if (coin is Firo) {
     //   showFeePending = true;
     // } else {
     //   showFeePending = false;
@@ -134,7 +141,7 @@ class _TransactionDetailsViewState
 
   String whatIsIt(Transaction tx, int height) {
     final type = tx.type;
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+    if (coin is Firo) {
       if (tx.subType == TransactionSubType.mint) {
         if (tx.isConfirmed(height, minConfirms)) {
           return "Minted";
@@ -144,7 +151,7 @@ class _TransactionDetailsViewState
       }
     }
 
-    if (coin == Coin.epicCash) {
+    if (coin is Epiccash) {
       if (_transaction.isCancelled) {
         return "Cancelled";
       } else if (type == TransactionType.incoming) {
@@ -202,9 +209,10 @@ class _TransactionDetailsViewState
     }
     try {
       final contacts = ref.read(addressBookServiceProvider).contacts.where(
-          (element) => element.addresses
-              .where((element) => element.address == address)
-              .isNotEmpty);
+            (element) => element.addresses
+                .where((element) => element.address == address)
+                .isNotEmpty,
+          );
       if (contacts.isNotEmpty) {
         return contacts.first.name;
       } else {
@@ -218,20 +226,23 @@ class _TransactionDetailsViewState
 
   Future<bool> showExplorerWarning(String explorer) async {
     final bool? shouldContinue = await showDialog<bool>(
-        context: context,
-        barrierDismissible: false,
-        builder: (_) {
-          if (!isDesktop) {
-            return StackDialog(
-              title: "Attention",
-              message:
-                  "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
-              icon: Row(
-                children: [
-                  Consumer(builder: (_, ref, __) {
+      context: context,
+      barrierDismissible: false,
+      builder: (_) {
+        if (!isDesktop) {
+          return StackDialog(
+            title: "Attention",
+            message:
+                "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
+            icon: Row(
+              children: [
+                Consumer(
+                  builder: (_, ref, __) {
                     return Checkbox(
-                      value: ref.watch(prefsChangeNotifierProvider
-                          .select((value) => value.hideBlockExplorerWarning)),
+                      value: ref.watch(
+                        prefsChangeNotifierProvider
+                            .select((value) => value.hideBlockExplorerWarning),
+                      ),
                       onChanged: (value) {
                         if (value is bool) {
                           ref
@@ -241,61 +252,65 @@ class _TransactionDetailsViewState
                         }
                       },
                     );
-                  }),
-                  Text(
-                    "Never show again",
-                    style: STextStyles.smallMed14(context),
-                  )
-                ],
-              ),
-              leftButton: TextButton(
-                onPressed: () {
-                  Navigator.of(context).pop(false);
-                },
-                child: Text(
-                  "Cancel",
-                  style: STextStyles.button(context).copyWith(
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .accentColorDark),
+                  },
+                ),
+                Text(
+                  "Never show again",
+                  style: STextStyles.smallMed14(context),
+                ),
+              ],
+            ),
+            leftButton: TextButton(
+              onPressed: () {
+                Navigator.of(context).pop(false);
+              },
+              child: Text(
+                "Cancel",
+                style: STextStyles.button(context).copyWith(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .accentColorDark,
                 ),
               ),
-              rightButton: TextButton(
-                style: Theme.of(context)
-                    .extension<StackColors>()!
-                    .getPrimaryEnabledButtonStyle(context),
-                onPressed: () {
-                  Navigator.of(context).pop(true);
-                },
-                child: Text(
-                  "Continue",
-                  style: STextStyles.button(context),
-                ),
+            ),
+            rightButton: TextButton(
+              style: Theme.of(context)
+                  .extension<StackColors>()!
+                  .getPrimaryEnabledButtonStyle(context),
+              onPressed: () {
+                Navigator.of(context).pop(true);
+              },
+              child: Text(
+                "Continue",
+                style: STextStyles.button(context),
               ),
-            );
-          } else {
-            return DesktopDialog(
-              maxWidth: 550,
-              maxHeight: 300,
-              child: Padding(
-                padding:
-                    const EdgeInsets.symmetric(horizontal: 32, vertical: 20),
-                child: Column(
-                  children: [
-                    Row(
-                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                      children: [
-                        Text(
-                          "Attention",
-                          style: STextStyles.desktopH2(context),
-                        ),
-                        Row(
-                          children: [
-                            Consumer(builder: (_, ref, __) {
+            ),
+          );
+        } else {
+          return DesktopDialog(
+            maxWidth: 550,
+            maxHeight: 300,
+            child: Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 20),
+              child: Column(
+                children: [
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Text(
+                        "Attention",
+                        style: STextStyles.desktopH2(context),
+                      ),
+                      Row(
+                        children: [
+                          Consumer(
+                            builder: (_, ref, __) {
                               return Checkbox(
-                                value: ref.watch(prefsChangeNotifierProvider
-                                    .select((value) =>
-                                        value.hideBlockExplorerWarning)),
+                                value: ref.watch(
+                                  prefsChangeNotifierProvider.select(
+                                    (value) => value.hideBlockExplorerWarning,
+                                  ),
+                                ),
                                 onChanged: (value) {
                                   if (value is bool) {
                                     ref
@@ -305,55 +320,57 @@ class _TransactionDetailsViewState
                                   }
                                 },
                               );
-                            }),
-                            Text(
-                              "Never show again",
-                              style: STextStyles.smallMed14(context),
-                            )
-                          ],
-                        ),
-                      ],
-                    ),
-                    const SizedBox(height: 16),
-                    Text(
-                      "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
-                      style: STextStyles.desktopTextSmall(context),
-                    ),
-                    const SizedBox(height: 35),
-                    Row(
-                      mainAxisAlignment: MainAxisAlignment.center,
-                      children: [
-                        SecondaryButton(
-                          width: 200,
-                          buttonHeight: ButtonHeight.l,
-                          label: "Cancel",
-                          onPressed: () {
-                            Navigator.of(
-                              context,
-                              rootNavigator: true,
-                            ).pop(false);
-                          },
-                        ),
-                        const SizedBox(width: 20),
-                        PrimaryButton(
-                          width: 200,
-                          buttonHeight: ButtonHeight.l,
-                          label: "Continue",
-                          onPressed: () {
-                            Navigator.of(
-                              context,
-                              rootNavigator: true,
-                            ).pop(true);
-                          },
-                        ),
-                      ],
-                    ),
-                  ],
-                ),
+                            },
+                          ),
+                          Text(
+                            "Never show again",
+                            style: STextStyles.smallMed14(context),
+                          ),
+                        ],
+                      ),
+                    ],
+                  ),
+                  const SizedBox(height: 16),
+                  Text(
+                    "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
+                    style: STextStyles.desktopTextSmall(context),
+                  ),
+                  const SizedBox(height: 35),
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      SecondaryButton(
+                        width: 200,
+                        buttonHeight: ButtonHeight.l,
+                        label: "Cancel",
+                        onPressed: () {
+                          Navigator.of(
+                            context,
+                            rootNavigator: true,
+                          ).pop(false);
+                        },
+                      ),
+                      const SizedBox(width: 20),
+                      PrimaryButton(
+                        width: 200,
+                        buttonHeight: ButtonHeight.l,
+                        label: "Continue",
+                        onPressed: () {
+                          Navigator.of(
+                            context,
+                            rootNavigator: true,
+                          ).pop(true);
+                        },
+                      ),
+                    ],
+                  ),
+                ],
               ),
-            );
-          }
-        });
+            ),
+          );
+        }
+      },
+    );
     return shouldContinue ?? false;
   }
 
@@ -474,7 +491,7 @@ class _TransactionDetailsViewState
                                             ),
                                             SelectableText(
                                               _transaction.isCancelled
-                                                  ? coin == Coin.ethereum
+                                                  ? coin is Ethereum
                                                       ? "Failed"
                                                       : "Cancelled"
                                                   : whatIsIt(
@@ -483,7 +500,8 @@ class _TransactionDetailsViewState
                                                     ),
                                               style:
                                                   STextStyles.desktopTextMedium(
-                                                      context),
+                                                context,
+                                              ),
                                             ),
                                           ],
                                         ),
@@ -496,37 +514,43 @@ class _TransactionDetailsViewState
                                             "$amountPrefix${ref.watch(pAmountFormatter(coin)).format(amount, ethContract: ethContract)}",
                                             style: isDesktop
                                                 ? STextStyles
-                                                        .desktopTextExtraExtraSmall(
-                                                            context)
-                                                    .copyWith(
+                                                    .desktopTextExtraExtraSmall(
+                                                    context,
+                                                  ).copyWith(
                                                     color: Theme.of(context)
                                                         .extension<
                                                             StackColors>()!
                                                         .textDark,
                                                   )
                                                 : STextStyles.titleBold12(
-                                                    context),
+                                                    context,
+                                                  ),
                                           ),
                                           const SizedBox(
                                             height: 2,
                                           ),
                                           if (ref.watch(
-                                              prefsChangeNotifierProvider
-                                                  .select((value) =>
-                                                      value.externalCalls)))
+                                            prefsChangeNotifierProvider.select(
+                                              (value) => value.externalCalls,
+                                            ),
+                                          ))
                                             SelectableText(
                                               "$amountPrefix${(amount.decimal * ref.watch(
-                                                        priceAnd24hChangeNotifierProvider.select(
-                                                            (value) => isTokenTx
-                                                                ? value
-                                                                    .getTokenPrice(
-                                                                        _transaction
-                                                                            .otherData!)
-                                                                    .item1
-                                                                : value
-                                                                    .getPrice(
-                                                                        coin)
-                                                                    .item1),
+                                                        priceAnd24hChangeNotifierProvider
+                                                            .select(
+                                                          (value) => isTokenTx
+                                                              ? value
+                                                                  .getTokenPrice(
+                                                                    _transaction
+                                                                        .otherData!,
+                                                                  )
+                                                                  .item1
+                                                              : value
+                                                                  .getPrice(
+                                                                    coin,
+                                                                  )
+                                                                  .item1,
+                                                        ),
                                                       )).toAmount(fractionDigits: 2).fiatString(
                                                     locale: ref.watch(
                                                       localeServiceChangeNotifierProvider
@@ -543,9 +567,11 @@ class _TransactionDetailsViewState
                                               style: isDesktop
                                                   ? STextStyles
                                                       .desktopTextExtraExtraSmall(
-                                                          context)
+                                                      context,
+                                                    )
                                                   : STextStyles.itemSubtitle(
-                                                      context),
+                                                      context,
+                                                    ),
                                             ),
                                         ],
                                       ),
@@ -587,7 +613,7 @@ class _TransactionDetailsViewState
                                   //     child:
                                   SelectableText(
                                     _transaction.isCancelled
-                                        ? coin == Coin.ethereum
+                                        ? coin is Ethereum
                                             ? "Failed"
                                             : "Cancelled"
                                         : whatIsIt(
@@ -596,9 +622,9 @@ class _TransactionDetailsViewState
                                           ),
                                     style: isDesktop
                                         ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            .copyWith(
+                                            .desktopTextExtraExtraSmall(
+                                            context,
+                                          ).copyWith(
                                             color: _transaction.type ==
                                                     TransactionType.outgoing
                                                 ? Theme.of(context)
@@ -615,12 +641,10 @@ class _TransactionDetailsViewState
                                 ],
                               ),
                             ),
-                            if (!((coin == Coin.monero ||
-                                        coin == Coin.wownero) &&
+                            if (!((coin is Monero || coin is Wownero) &&
                                     _transaction.type ==
                                         TransactionType.outgoing) &&
-                                !((coin == Coin.firo ||
-                                        coin == Coin.firoTestNet) &&
+                                !((coin is Firo) &&
                                     _transaction.subType ==
                                         TransactionSubType.mint))
                               isDesktop
@@ -628,12 +652,10 @@ class _TransactionDetailsViewState
                                   : const SizedBox(
                                       height: 12,
                                     ),
-                            if (!((coin == Coin.monero ||
-                                        coin == Coin.wownero) &&
+                            if (!((coin is Monero || coin is Wownero) &&
                                     _transaction.type ==
                                         TransactionType.outgoing) &&
-                                !((coin == Coin.firo ||
-                                        coin == Coin.firoTestNet) &&
+                                !((coin is Firo) &&
                                     _transaction.subType ==
                                         TransactionSubType.mint))
                               RoundedWhiteContainer(
@@ -694,7 +716,7 @@ class _TransactionDetailsViewState
                                                         );
                                                       }
                                                     },
-                                                  )
+                                                  ),
                                                 ],
                                               );
                                             },
@@ -706,9 +728,11 @@ class _TransactionDetailsViewState
                                               style: isDesktop
                                                   ? STextStyles
                                                       .desktopTextExtraExtraSmall(
-                                                          context)
+                                                      context,
+                                                    )
                                                   : STextStyles.itemSubtitle(
-                                                      context),
+                                                      context,
+                                                    ),
                                             ),
                                           ),
                                           const SizedBox(
@@ -718,11 +742,14 @@ class _TransactionDetailsViewState
                                                   TransactionType.incoming
                                               ? FutureBuilder(
                                                   future: fetchContactNameFor(
-                                                      _transaction.address
-                                                          .value!.value),
-                                                  builder: (builderContext,
-                                                      AsyncSnapshot<String>
-                                                          snapshot) {
+                                                    _transaction
+                                                        .address.value!.value,
+                                                  ),
+                                                  builder: (
+                                                    builderContext,
+                                                    AsyncSnapshot<String>
+                                                        snapshot,
+                                                  ) {
                                                     String
                                                         addressOrContactName =
                                                         _transaction.address
@@ -738,18 +765,20 @@ class _TransactionDetailsViewState
                                                       addressOrContactName,
                                                       style: isDesktop
                                                           ? STextStyles
-                                                                  .desktopTextExtraExtraSmall(
-                                                                      context)
-                                                              .copyWith(
+                                                              .desktopTextExtraExtraSmall(
+                                                              context,
+                                                            ).copyWith(
                                                               color: Theme.of(
-                                                                      context)
+                                                                context,
+                                                              )
                                                                   .extension<
                                                                       StackColors>()!
                                                                   .textDark,
                                                             )
                                                           : STextStyles
                                                               .itemSubtitle12(
-                                                                  context),
+                                                              context,
+                                                            ),
                                                     );
                                                   },
                                                 )
@@ -758,18 +787,20 @@ class _TransactionDetailsViewState
                                                       .address.value!.value,
                                                   style: isDesktop
                                                       ? STextStyles
-                                                              .desktopTextExtraExtraSmall(
-                                                                  context)
-                                                          .copyWith(
+                                                          .desktopTextExtraExtraSmall(
+                                                          context,
+                                                        ).copyWith(
                                                           color: Theme.of(
-                                                                  context)
+                                                            context,
+                                                          )
                                                               .extension<
                                                                   StackColors>()!
                                                               .textDark,
                                                         )
                                                       : STextStyles
                                                           .itemSubtitle12(
-                                                              context),
+                                                          context,
+                                                        ),
                                                 ),
                                         ],
                                       ),
@@ -781,13 +812,13 @@ class _TransactionDetailsViewState
                                   ],
                                 ),
                               ),
-                            if (coin == Coin.epicCash)
+                            if (coin is Epiccash)
                               isDesktop
                                   ? const _Divider()
                                   : const SizedBox(
                                       height: 12,
                                     ),
-                            if (coin == Coin.epicCash)
+                            if (coin is Epiccash)
                               RoundedWhiteContainer(
                                 padding: isDesktop
                                     ? const EdgeInsets.all(16)
@@ -807,9 +838,11 @@ class _TransactionDetailsViewState
                                             style: isDesktop
                                                 ? STextStyles
                                                     .desktopTextExtraExtraSmall(
-                                                        context)
+                                                    context,
+                                                  )
                                                 : STextStyles.itemSubtitle(
-                                                    context),
+                                                    context,
+                                                  ),
                                           ),
                                           const SizedBox(
                                             height: 8,
@@ -818,16 +851,17 @@ class _TransactionDetailsViewState
                                             _transaction.otherData ?? "",
                                             style: isDesktop
                                                 ? STextStyles
-                                                        .desktopTextExtraExtraSmall(
-                                                            context)
-                                                    .copyWith(
+                                                    .desktopTextExtraExtraSmall(
+                                                    context,
+                                                  ).copyWith(
                                                     color: Theme.of(context)
                                                         .extension<
                                                             StackColors>()!
                                                         .textDark,
                                                   )
                                                 : STextStyles.itemSubtitle12(
-                                                    context),
+                                                    context,
+                                                  ),
                                           ),
                                         ],
                                       ),
@@ -856,13 +890,14 @@ class _TransactionDetailsViewState
                                         MainAxisAlignment.spaceBetween,
                                     children: [
                                       Text(
-                                        (coin == Coin.epicCash)
+                                        (coin is Epiccash)
                                             ? "Local Note"
                                             : "Note ",
                                         style: isDesktop
                                             ? STextStyles
                                                 .desktopTextExtraExtraSmall(
-                                                    context)
+                                                context,
+                                              )
                                             : STextStyles.itemSubtitle(context),
                                       ),
                                       isDesktop
@@ -910,7 +945,8 @@ class _TransactionDetailsViewState
                                                   Text(
                                                     "Edit",
                                                     style: STextStyles.link2(
-                                                        context),
+                                                      context,
+                                                    ),
                                                   ),
                                                 ],
                                               ),
@@ -934,9 +970,9 @@ class _TransactionDetailsViewState
                                         "",
                                     style: isDesktop
                                         ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            .copyWith(
+                                            .desktopTextExtraExtraSmall(
+                                            context,
+                                          ).copyWith(
                                             color: Theme.of(context)
                                                 .extension<StackColors>()!
                                                 .textDark,
@@ -969,7 +1005,8 @@ class _TransactionDetailsViewState
                                         style: isDesktop
                                             ? STextStyles
                                                 .desktopTextExtraExtraSmall(
-                                                    context)
+                                                context,
+                                              )
                                             : STextStyles.itemSubtitle(context),
                                       ),
                                       if (isDesktop)
@@ -983,15 +1020,16 @@ class _TransactionDetailsViewState
                                           ),
                                           style: isDesktop
                                               ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
+                                                  .desktopTextExtraExtraSmall(
+                                                  context,
+                                                ).copyWith(
                                                   color: Theme.of(context)
                                                       .extension<StackColors>()!
                                                       .textDark,
                                                 )
                                               : STextStyles.itemSubtitle12(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                     ],
                                   ),
@@ -1002,9 +1040,9 @@ class _TransactionDetailsViewState
                                       ),
                                       style: isDesktop
                                           ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
+                                              .desktopTextExtraExtraSmall(
+                                              context,
+                                            ).copyWith(
                                               color: Theme.of(context)
                                                   .extension<StackColors>()!
                                                   .textDark,
@@ -1020,36 +1058,138 @@ class _TransactionDetailsViewState
                                 ],
                               ),
                             ),
-                            if (coin != Coin.banano && coin != Coin.nano)
+                            if (coin is! NanoCurrency)
                               isDesktop
                                   ? const _Divider()
                                   : const SizedBox(
                                       height: 12,
                                     ),
-                            if (coin != Coin.banano && coin != Coin.nano)
+                            if (coin is! NanoCurrency)
                               RoundedWhiteContainer(
                                 padding: isDesktop
                                     ? const EdgeInsets.all(16)
                                     : const EdgeInsets.all(12),
-                                child: Builder(builder: (context) {
-                                  String feeString = showFeePending
-                                      ? _transaction.isConfirmed(
-                                          currentHeight,
-                                          minConfirms,
-                                        )
-                                          ? ref
-                                              .watch(pAmountFormatter(coin))
-                                              .format(
-                                                fee,
-                                                withUnitName: isTokenTx,
-                                              )
-                                          : "Pending"
-                                      : ref
-                                          .watch(pAmountFormatter(coin))
-                                          .format(
-                                            fee,
-                                            withUnitName: isTokenTx,
-                                          );
+                                child: Builder(
+                                  builder: (context) {
+                                    String feeString = showFeePending
+                                        ? _transaction.isConfirmed(
+                                            currentHeight,
+                                            minConfirms,
+                                          )
+                                            ? ref
+                                                .watch(pAmountFormatter(coin))
+                                                .format(
+                                                  fee,
+                                                  withUnitName: isTokenTx,
+                                                )
+                                            : "Pending"
+                                        : ref
+                                            .watch(pAmountFormatter(coin))
+                                            .format(
+                                              fee,
+                                              withUnitName: isTokenTx,
+                                            );
+
+                                    return Row(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceBetween,
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        Column(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            Text(
+                                              "Transaction fee",
+                                              style: isDesktop
+                                                  ? STextStyles
+                                                      .desktopTextExtraExtraSmall(
+                                                      context,
+                                                    )
+                                                  : STextStyles.itemSubtitle(
+                                                      context,
+                                                    ),
+                                            ),
+                                            if (isDesktop)
+                                              const SizedBox(
+                                                height: 2,
+                                              ),
+                                            if (isDesktop)
+                                              SelectableText(
+                                                feeString,
+                                                style: isDesktop
+                                                    ? STextStyles
+                                                        .desktopTextExtraExtraSmall(
+                                                        context,
+                                                      ).copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .textDark,
+                                                      )
+                                                    : STextStyles
+                                                        .itemSubtitle12(
+                                                        context,
+                                                      ),
+                                              ),
+                                          ],
+                                        ),
+                                        if (!isDesktop)
+                                          SelectableText(
+                                            feeString,
+                                            style: isDesktop
+                                                ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                    context,
+                                                  ).copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark,
+                                                  )
+                                                : STextStyles.itemSubtitle12(
+                                                    context,
+                                                  ),
+                                          ),
+                                        if (isDesktop)
+                                          IconCopyButton(data: feeString),
+                                      ],
+                                    );
+                                  },
+                                ),
+                              ),
+                            isDesktop
+                                ? const _Divider()
+                                : const SizedBox(
+                                    height: 12,
+                                  ),
+                            RoundedWhiteContainer(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(16)
+                                  : const EdgeInsets.all(12),
+                              child: Builder(
+                                builder: (context) {
+                                  final String height;
+
+                                  if (widget.coin is Bitcoincash ||
+                                      widget.coin is Ecash) {
+                                    height =
+                                        "${_transaction.height != null && _transaction.height! > 0 ? _transaction.height! : "Pending"}";
+                                  } else {
+                                    height = widget.coin is! Epiccash &&
+                                            _transaction.isConfirmed(
+                                              currentHeight,
+                                              minConfirms,
+                                            )
+                                        ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
+                                        : _transaction.getConfirmations(
+                                                  currentHeight,
+                                                ) >
+                                                0
+                                            ? "${_transaction.height}"
+                                            : "Pending";
+                                  }
 
                                   return Row(
                                     mainAxisAlignment:
@@ -1062,13 +1202,15 @@ class _TransactionDetailsViewState
                                             CrossAxisAlignment.start,
                                         children: [
                                           Text(
-                                            "Transaction fee",
+                                            "Block height",
                                             style: isDesktop
                                                 ? STextStyles
                                                     .desktopTextExtraExtraSmall(
-                                                        context)
+                                                    context,
+                                                  )
                                                 : STextStyles.itemSubtitle(
-                                                    context),
+                                                    context,
+                                                  ),
                                           ),
                                           if (isDesktop)
                                             const SizedBox(
@@ -1076,141 +1218,53 @@ class _TransactionDetailsViewState
                                             ),
                                           if (isDesktop)
                                             SelectableText(
-                                              feeString,
+                                              height,
                                               style: isDesktop
                                                   ? STextStyles
-                                                          .desktopTextExtraExtraSmall(
-                                                              context)
-                                                      .copyWith(
+                                                      .desktopTextExtraExtraSmall(
+                                                      context,
+                                                    ).copyWith(
                                                       color: Theme.of(context)
                                                           .extension<
                                                               StackColors>()!
                                                           .textDark,
                                                     )
                                                   : STextStyles.itemSubtitle12(
-                                                      context),
+                                                      context,
+                                                    ),
                                             ),
                                         ],
                                       ),
                                       if (!isDesktop)
                                         SelectableText(
-                                          feeString,
+                                          height,
                                           style: isDesktop
                                               ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
+                                                  .desktopTextExtraExtraSmall(
+                                                  context,
+                                                ).copyWith(
                                                   color: Theme.of(context)
                                                       .extension<StackColors>()!
                                                       .textDark,
                                                 )
                                               : STextStyles.itemSubtitle12(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                       if (isDesktop)
-                                        IconCopyButton(data: feeString)
+                                        IconCopyButton(data: height),
                                     ],
                                   );
-                                }),
+                                },
                               ),
-                            isDesktop
-                                ? const _Divider()
-                                : const SizedBox(
-                                    height: 12,
-                                  ),
-                            RoundedWhiteContainer(
-                              padding: isDesktop
-                                  ? const EdgeInsets.all(16)
-                                  : const EdgeInsets.all(12),
-                              child: Builder(builder: (context) {
-                                final String height;
-
-                                if (widget.coin == Coin.bitcoincash ||
-                                    widget.coin == Coin.eCash ||
-                                    widget.coin == Coin.bitcoincashTestnet) {
-                                  height =
-                                      "${_transaction.height != null && _transaction.height! > 0 ? _transaction.height! : "Pending"}";
-                                } else {
-                                  height = widget.coin != Coin.epicCash &&
-                                          _transaction.isConfirmed(
-                                            currentHeight,
-                                            minConfirms,
-                                          )
-                                      ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
-                                      : _transaction.getConfirmations(
-                                                  currentHeight) >
-                                              0
-                                          ? "${_transaction.height}"
-                                          : "Pending";
-                                }
-
-                                return Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Column(
-                                      crossAxisAlignment:
-                                          CrossAxisAlignment.start,
-                                      children: [
-                                        Text(
-                                          "Block height",
-                                          style: isDesktop
-                                              ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              : STextStyles.itemSubtitle(
-                                                  context),
-                                        ),
-                                        if (isDesktop)
-                                          const SizedBox(
-                                            height: 2,
-                                          ),
-                                        if (isDesktop)
-                                          SelectableText(
-                                            height,
-                                            style: isDesktop
-                                                ? STextStyles
-                                                        .desktopTextExtraExtraSmall(
-                                                            context)
-                                                    .copyWith(
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark,
-                                                  )
-                                                : STextStyles.itemSubtitle12(
-                                                    context),
-                                          ),
-                                      ],
-                                    ),
-                                    if (!isDesktop)
-                                      SelectableText(
-                                        height,
-                                        style: isDesktop
-                                            ? STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark,
-                                              )
-                                            : STextStyles.itemSubtitle12(
-                                                context),
-                                      ),
-                                    if (isDesktop) IconCopyButton(data: height),
-                                  ],
-                                );
-                              }),
                             ),
-                            if (coin == Coin.ethereum)
+                            if (coin is Ethereum)
                               isDesktop
                                   ? const _Divider()
                                   : const SizedBox(
                                       height: 12,
                                     ),
-                            if (coin == Coin.ethereum)
+                            if (coin is Ethereum)
                               RoundedWhiteContainer(
                                 padding: isDesktop
                                     ? const EdgeInsets.all(16)
@@ -1225,16 +1279,17 @@ class _TransactionDetailsViewState
                                       style: isDesktop
                                           ? STextStyles
                                               .desktopTextExtraExtraSmall(
-                                                  context)
+                                              context,
+                                            )
                                           : STextStyles.itemSubtitle(context),
                                     ),
                                     SelectableText(
                                       _transaction.nonce.toString(),
                                       style: isDesktop
                                           ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
+                                              .desktopTextExtraExtraSmall(
+                                              context,
+                                            ).copyWith(
                                               color: Theme.of(context)
                                                   .extension<StackColors>()!
                                                   .textDark,
@@ -1265,16 +1320,17 @@ class _TransactionDetailsViewState
                                       style: isDesktop
                                           ? STextStyles
                                               .desktopTextExtraExtraSmall(
-                                                  context)
+                                              context,
+                                            )
                                           : STextStyles.itemSubtitle(context),
                                     ),
                                     SelectableText(
                                       _transaction.subType.toString(),
                                       style: isDesktop
                                           ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
+                                              .desktopTextExtraExtraSmall(
+                                              context,
+                                            ).copyWith(
                                               color: Theme.of(context)
                                                   .extension<StackColors>()!
                                                   .textDark,
@@ -1308,9 +1364,11 @@ class _TransactionDetailsViewState
                                           style: isDesktop
                                               ? STextStyles
                                                   .desktopTextExtraExtraSmall(
-                                                      context)
+                                                  context,
+                                                )
                                               : STextStyles.itemSubtitle(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                         const SizedBox(
                                           height: 8,
@@ -1323,21 +1381,22 @@ class _TransactionDetailsViewState
                                           _transaction.txid,
                                           style: isDesktop
                                               ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
+                                                  .desktopTextExtraExtraSmall(
+                                                  context,
+                                                ).copyWith(
                                                   color: Theme.of(context)
                                                       .extension<StackColors>()!
                                                       .textDark,
                                                 )
                                               : STextStyles.itemSubtitle12(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
-                                        if (coin != Coin.epicCash)
+                                        if (coin is! Epiccash)
                                           const SizedBox(
                                             height: 8,
                                           ),
-                                        if (coin != Coin.epicCash)
+                                        if (coin is! Epiccash)
                                           CustomTextButton(
                                             text: "Open in block explorer",
                                             onTap: () async {
@@ -1349,12 +1408,14 @@ class _TransactionDetailsViewState
 
                                               if (ref
                                                       .read(
-                                                          prefsChangeNotifierProvider)
+                                                        prefsChangeNotifierProvider,
+                                                      )
                                                       .hideBlockExplorerWarning ==
                                                   false) {
                                                 final shouldContinue =
                                                     await showExplorerWarning(
-                                                        "${uri.scheme}://${uri.host}");
+                                                  "${uri.scheme}://${uri.host}",
+                                                );
 
                                                 if (!shouldContinue) {
                                                   return;
@@ -1415,12 +1476,12 @@ class _TransactionDetailsViewState
                                 ],
                               ),
                             ),
-                            // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                            // if ((coin is FiroTestNet || coin is Firo) &&
                             //     _transaction.subType == "mint")
                             //   const SizedBox(
                             //     height: 12,
                             //   ),
-                            // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                            // if ((coin is FiroTestNet || coin is Firo) &&
                             //     _transaction.subType == "mint")
                             //   RoundedWhiteContainer(
                             //     child: Column(
@@ -1492,13 +1553,13 @@ class _TransactionDetailsViewState
                             //       ],
                             //     ),
                             //   ),
-                            if (coin == Coin.epicCash)
+                            if (coin is Epiccash)
                               isDesktop
                                   ? const _Divider()
                                   : const SizedBox(
                                       height: 12,
                                     ),
-                            if (coin == Coin.epicCash)
+                            if (coin is Epiccash)
                               RoundedWhiteContainer(
                                 padding: isDesktop
                                     ? const EdgeInsets.all(16)
@@ -1517,9 +1578,11 @@ class _TransactionDetailsViewState
                                           style: isDesktop
                                               ? STextStyles
                                                   .desktopTextExtraExtraSmall(
-                                                      context)
+                                                  context,
+                                                )
                                               : STextStyles.itemSubtitle(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                         // Flexible(
                                         //   child: FittedBox(
@@ -1529,15 +1592,16 @@ class _TransactionDetailsViewState
                                           _transaction.slateId ?? "Unknown",
                                           style: isDesktop
                                               ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
+                                                  .desktopTextExtraExtraSmall(
+                                                  context,
+                                                ).copyWith(
                                                   color: Theme.of(context)
                                                       .extension<StackColors>()!
                                                       .textDark,
                                                 )
                                               : STextStyles.itemSubtitle12(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                         //   ),
                                         // ),
@@ -1569,7 +1633,7 @@ class _TransactionDetailsViewState
           ),
         ),
         floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
-        floatingActionButton: (coin == Coin.epicCash &&
+        floatingActionButton: (coin is Epiccash &&
                 _transaction.getConfirmations(currentHeight) < 1 &&
                 _transaction.isCancelled == false)
             ? ConditionalParent(
@@ -1595,20 +1659,24 @@ class _TransactionDetailsViewState
                       if (wallet is EpiccashWallet) {
                         final String? id = _transaction.slateId;
                         if (id == null) {
-                          unawaited(showFloatingFlushBar(
-                            type: FlushBarType.warning,
-                            message: "Could not find Epic transaction ID",
-                            context: context,
-                          ));
+                          unawaited(
+                            showFloatingFlushBar(
+                              type: FlushBarType.warning,
+                              message: "Could not find Epic transaction ID",
+                              context: context,
+                            ),
+                          );
                           return;
                         }
 
-                        unawaited(showDialog<dynamic>(
-                          barrierDismissible: false,
-                          context: context,
-                          builder: (_) =>
-                              const CancellingTransactionProgressDialog(),
-                        ));
+                        unawaited(
+                          showDialog<dynamic>(
+                            barrierDismissible: false,
+                            context: context,
+                            builder: (_) =>
+                                const CancellingTransactionProgressDialog(),
+                          ),
+                        );
 
                         final result =
                             await wallet.cancelPendingTransactionAndPost(id);
@@ -1624,8 +1692,10 @@ class _TransactionDetailsViewState
                                 onOkPressed: (_) {
                                   wallet.refresh();
                                   Navigator.of(context).popUntil(
-                                      ModalRoute.withName(
-                                          WalletView.routeName));
+                                    ModalRoute.withName(
+                                      WalletView.routeName,
+                                    ),
+                                  );
                                 },
                               ),
                             );
@@ -1640,11 +1710,13 @@ class _TransactionDetailsViewState
                           }
                         }
                       } else {
-                        unawaited(showFloatingFlushBar(
-                          type: FlushBarType.warning,
-                          message: "ERROR: Wallet type is not Epic Cash",
-                          context: context,
-                        ));
+                        unawaited(
+                          showFloatingFlushBar(
+                            type: FlushBarType.warning,
+                            message: "ERROR: Wallet type is not Epic Cash",
+                            context: context,
+                          ),
+                        );
                         return;
                       }
                     },
diff --git a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
index 10d34771c..84bb7c2af 100644
--- a/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
+++ b/lib/pages/wallet_view/transaction_views/transaction_search_filter_view.dart
@@ -22,10 +22,10 @@ import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/amount/amount_input_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/date_picker/date_picker.dart';
@@ -46,7 +46,7 @@ class TransactionSearchFilterView extends ConsumerStatefulWidget {
 
   static const String routeName = "/transactionSearchFilter";
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<TransactionSearchFilterView> createState() =>
@@ -665,7 +665,7 @@ class _TransactionSearchViewState
                     ),
               inputFormatters: [
                 AmountInputFormatter(
-                  decimals: widget.coin.decimals,
+                  decimals: widget.coin.fractionDigits,
                   unit: ref.watch(pAmountUnit(widget.coin)),
                   locale: ref.watch(
                     localeServiceChangeNotifierProvider
@@ -896,9 +896,9 @@ class _TransactionSearchViewState
     if (amountText.isNotEmpty && !(amountText == "," || amountText == ".")) {
       amount = amountText.contains(",")
           ? Decimal.parse(amountText.replaceFirst(",", "."))
-              .toAmount(fractionDigits: widget.coin.decimals)
+              .toAmount(fractionDigits: widget.coin.fractionDigits)
           : Decimal.parse(amountText)
-              .toAmount(fractionDigits: widget.coin.decimals);
+              .toAmount(fractionDigits: widget.coin.fractionDigits);
     }
 
     final TransactionFilter filter = TransactionFilter(
diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart
index 50a53291f..954285f0d 100644
--- a/lib/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart
+++ b/lib/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart
@@ -32,7 +32,6 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
@@ -59,10 +58,10 @@ typedef _GroupedTransactions = ({
 
 class AllTransactionsV2View extends ConsumerStatefulWidget {
   const AllTransactionsV2View({
-    Key? key,
+    super.key,
     required this.walletId,
     this.contractAddress,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/allTransactionsV2";
 
@@ -96,8 +95,10 @@ class _AllTransactionsV2ViewState extends ConsumerState<AllTransactionsV2View> {
   }
 
   // TODO: optimise search+filter
-  List<TransactionV2> filter(
-      {required List<TransactionV2> transactions, TransactionFilter? filter}) {
+  List<TransactionV2> filter({
+    required List<TransactionV2> transactions,
+    TransactionFilter? filter,
+  }) {
     if (filter == null) {
       return transactions;
     }
@@ -159,13 +160,15 @@ class _AllTransactionsV2ViewState extends ConsumerState<AllTransactionsV2View> {
 
     // check if address book name contains
     contains |= contacts
-        .where((e) =>
-            e.addresses
-                .map((e) => e.address)
-                .toSet()
-                .intersection(tx.associatedAddresses())
-                .isNotEmpty &&
-            e.name.toLowerCase().contains(keyword))
+        .where(
+          (e) =>
+              e.addresses
+                  .map((e) => e.address)
+                  .toSet()
+                  .intersection(tx.associatedAddresses())
+                  .isNotEmpty &&
+              e.name.toLowerCase().contains(keyword),
+        )
         .isNotEmpty;
 
     // check if address contains
@@ -224,9 +227,9 @@ class _AllTransactionsV2ViewState extends ConsumerState<AllTransactionsV2View> {
   List<_GroupedTransactions> groupTransactionsByMonth(
     List<TransactionV2> transactions,
   ) {
-    Map<String, _GroupedTransactions> map = {};
+    final Map<String, _GroupedTransactions> map = {};
 
-    for (var tx in transactions) {
+    for (final tx in transactions) {
       final date = DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000);
       final monthYear = "${Constants.monthMap[date.month]} ${date.year}";
       if (map[monthYear] == null) {
@@ -291,9 +294,10 @@ class _AllTransactionsV2ViewState extends ConsumerState<AllTransactionsV2View> {
                   if (FocusScope.of(context).hasFocus) {
                     FocusScope.of(context).unfocus();
                     await Future<void>.delayed(
-                        const Duration(milliseconds: 75));
+                      const Duration(milliseconds: 75),
+                    );
                   }
-                  if (mounted) {
+                  if (context.mounted) {
                     Navigator.of(context).pop();
                   }
                 },
@@ -494,32 +498,35 @@ class _AllTransactionsV2ViewState extends ConsumerState<AllTransactionsV2View> {
                         .isar
                         .transactionV2s
                         .buildQuery<TransactionV2>(
-                            whereClauses: [
-                              IndexWhereClause.equalTo(
-                                indexName: 'walletId',
-                                value: [widget.walletId],
-                              )
-                            ],
-                            filter: widget.contractAddress == null
-                                ? ref
-                                    .watch(pWallets)
-                                    .getWallet(widget.walletId)
-                                    .transactionFilterOperation
-                                : ref
-                                    .read(pCurrentTokenWallet)!
-                                    .transactionFilterOperation,
-                            sortBy: [
-                              const SortProperty(
-                                property: "timestamp",
-                                sort: Sort.desc,
-                              ),
-                            ])
+                          whereClauses: [
+                            IndexWhereClause.equalTo(
+                              indexName: 'walletId',
+                              value: [widget.walletId],
+                            ),
+                          ],
+                          filter: widget.contractAddress == null
+                              ? ref
+                                  .watch(pWallets)
+                                  .getWallet(widget.walletId)
+                                  .transactionFilterOperation
+                              : ref
+                                  .read(pCurrentTokenWallet)!
+                                  .transactionFilterOperation,
+                          sortBy: [
+                            const SortProperty(
+                              property: "timestamp",
+                              sort: Sort.desc,
+                            ),
+                          ],
+                        )
                         .findAll(),
                     builder: (_, AsyncSnapshot<List<TransactionV2>> snapshot) {
                       if (snapshot.connectionState == ConnectionState.done &&
                           snapshot.hasData) {
                         final filtered = filter(
-                            transactions: snapshot.data!, filter: criteria);
+                          transactions: snapshot.data!,
+                          filter: criteria,
+                        );
 
                         final searched = search(_searchString, filtered);
                         searched.sort((a, b) {
@@ -571,7 +578,8 @@ class _AllTransactionsV2ViewState extends ConsumerState<AllTransactionsV2View> {
                                           padding: const EdgeInsets.all(4),
                                           child: DesktopTransactionCardRow(
                                             key: Key(
-                                                "transactionCard_key_${month.transactions[index].txid}"),
+                                              "transactionCard_key_${month.transactions[index].txid}",
+                                            ),
                                             transaction:
                                                 month.transactions[index],
                                             walletId: walletId,
@@ -587,7 +595,8 @@ class _AllTransactionsV2ViewState extends ConsumerState<AllTransactionsV2View> {
                                           ...month.transactions.map(
                                             (tx) => TransactionCardV2(
                                               key: Key(
-                                                  "transactionCard_key_${tx.txid}"),
+                                                "transactionCard_key_${tx.txid}",
+                                              ),
                                               transaction: tx,
                                             ),
                                           ),
@@ -789,9 +798,10 @@ class TransactionFilterOptionBarItem extends StatelessWidget {
       child: Container(
         height: 32,
         decoration: BoxDecoration(
-            color:
-                Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
-            borderRadius: BorderRadius.circular(1000)),
+          color:
+              Theme.of(context).extension<StackColors>()!.buttonBackSecondary,
+          borderRadius: BorderRadius.circular(1000),
+        ),
         child: Padding(
           padding: const EdgeInsets.symmetric(
             horizontal: 14,
@@ -882,7 +892,8 @@ class _DesktopTransactionCardRowState
   @override
   Widget build(BuildContext context) {
     final locale = ref.watch(
-        localeServiceChangeNotifierProvider.select((value) => value.locale));
+      localeServiceChangeNotifierProvider.select((value) => value.locale),
+    );
 
     final baseCurrency = ref
         .watch(prefsChangeNotifierProvider.select((value) => value.currency));
@@ -890,8 +901,10 @@ class _DesktopTransactionCardRowState
     final coin = ref.watch(pWalletCoin(walletId));
 
     final price = ref
-        .watch(priceAnd24hChangeNotifierProvider
-            .select((value) => value.getPrice(coin)))
+        .watch(
+          priceAnd24hChangeNotifierProvider
+              .select((value) => value.getPrice(coin)),
+        )
         .item1;
 
     late final String prefix;
@@ -910,42 +923,48 @@ class _DesktopTransactionCardRowState
     final currentHeight = ref.watch(pWalletChainHeight(walletId));
 
     final Amount amount;
-    final fractionDigits = ethContract?.decimals ?? coin.decimals;
+    final fractionDigits = ethContract?.decimals ?? coin.fractionDigits;
     if (_transaction.subType == TransactionSubType.cashFusion) {
       amount = _transaction.getAmountReceivedInThisWallet(
-          fractionDigits: fractionDigits);
+        fractionDigits: fractionDigits,
+      );
     } else {
       switch (_transaction.type) {
         case TransactionType.outgoing:
           amount = _transaction.getAmountSentFromThisWallet(
-              fractionDigits: fractionDigits);
+            fractionDigits: fractionDigits,
+          );
           break;
 
         case TransactionType.incoming:
         case TransactionType.sentToSelf:
           if (_transaction.subType == TransactionSubType.sparkMint) {
             amount = _transaction.getAmountSparkSelfMinted(
-                fractionDigits: fractionDigits);
+              fractionDigits: fractionDigits,
+            );
           } else if (_transaction.subType == TransactionSubType.sparkSpend) {
             final changeAddress =
                 (ref.watch(pWallets).getWallet(walletId) as SparkInterface)
                     .sparkChangeAddress;
             amount = Amount(
               rawValue: _transaction.outputs
-                  .where((e) =>
-                      e.walletOwns && !e.addresses.contains(changeAddress))
+                  .where(
+                    (e) => e.walletOwns && !e.addresses.contains(changeAddress),
+                  )
                   .fold(BigInt.zero, (p, e) => p + e.value),
-              fractionDigits: coin.decimals,
+              fractionDigits: coin.fractionDigits,
             );
           } else {
             amount = _transaction.getAmountReceivedInThisWallet(
-                fractionDigits: fractionDigits);
+              fractionDigits: fractionDigits,
+            );
           }
           break;
 
         case TransactionType.unknown:
           amount = _transaction.getAmountSentFromThisWallet(
-              fractionDigits: fractionDigits);
+            fractionDigits: fractionDigits,
+          );
           break;
       }
     }
@@ -1043,8 +1062,10 @@ class _DesktopTransactionCardRowState
                   ),
                 ),
               ),
-              if (ref.watch(prefsChangeNotifierProvider
-                  .select((value) => value.externalCalls)))
+              if (ref.watch(
+                prefsChangeNotifierProvider
+                    .select((value) => value.externalCalls),
+              ))
                 Expanded(
                   flex: 4,
                   child: Text(
diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart
index 874d1fdba..b0094539f 100644
--- a/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart
@@ -14,9 +14,9 @@ import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2
 import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
@@ -24,17 +24,17 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class FusionGroupDetailsView extends ConsumerStatefulWidget {
   const FusionGroupDetailsView({
-    Key? key,
+    super.key,
     required this.transactions,
     required this.walletId,
     required this.coin,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/fusionGroupDetailsView";
 
   final List<TransactionV2> transactions;
   final String walletId;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<FusionGroupDetailsView> createState() =>
diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart
index 1401625c9..0ae867544 100644
--- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart
+++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart
@@ -15,19 +15,20 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 
 class TransactionCardV2 extends ConsumerStatefulWidget {
   const TransactionCardV2({
-    Key? key,
+    super.key,
     required this.transaction,
-  }) : super(key: key);
+  });
 
   final TransactionV2 transaction;
 
@@ -40,17 +41,17 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> {
   late final String walletId;
   late final String prefix;
   late final String unit;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final TransactionType txType;
   late final EthContract? tokenContract;
 
   bool get isTokenTx => tokenContract != null;
 
   String whatIsIt(
-    Coin coin,
+    CryptoCurrency coin,
     int currentHeight,
   ) =>
-      _transaction.isCancelled && coin == Coin.ethereum
+      _transaction.isCancelled && coin is Ethereum
           ? "Failed"
           : _transaction.statusLabel(
               currentChainHeight: currentHeight,
@@ -112,7 +113,7 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> {
 
     final Amount amount;
 
-    final fractionDigits = tokenContract?.decimals ?? coin.decimals;
+    final fractionDigits = tokenContract?.decimals ?? coin.fractionDigits;
 
     if (_transaction.subType == TransactionSubType.cashFusion) {
       amount = _transaction.getAmountReceivedInThisWallet(
@@ -138,7 +139,7 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> {
                   .where((e) =>
                       e.walletOwns && !e.addresses.contains(changeAddress))
                   .fold(BigInt.zero, (p, e) => p + e.value),
-              fractionDigits: coin.decimals,
+              fractionDigits: coin.fractionDigits,
             );
           } else {
             amount = _transaction.getAmountReceivedInThisWallet(
diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart
index 5a1ae2032..fe58b38a0 100644
--- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart
+++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart
@@ -33,11 +33,18 @@ import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/block_explorers.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ecash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 import 'package:stackwallet/wallets/isar/models/spark_coin.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart';
@@ -59,17 +66,17 @@ import 'package:url_launcher/url_launcher.dart';
 
 class TransactionV2DetailsView extends ConsumerStatefulWidget {
   const TransactionV2DetailsView({
-    Key? key,
+    super.key,
     required this.transaction,
     required this.walletId,
     required this.coin,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/transactionV2Details";
 
   final TransactionV2 transaction;
   final String walletId;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<TransactionV2DetailsView> createState() =>
@@ -82,7 +89,7 @@ class _TransactionV2DetailsViewState
   late TransactionV2 _transaction;
   late final String walletId;
 
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final Amount amount;
   late final Amount fee;
   late final String amountPrefix;
@@ -120,7 +127,7 @@ class _TransactionV2DetailsViewState
     minConfirms =
         ref.read(pWallets).getWallet(walletId).cryptoCurrency.minConfirms;
 
-    final fractionDigits = ethContract?.decimals ?? coin.decimals;
+    final fractionDigits = ethContract?.decimals ?? coin.fractionDigits;
 
     fee = _transaction.getFee(fractionDigits: fractionDigits);
 
@@ -136,43 +143,61 @@ class _TransactionV2DetailsViewState
         case TransactionType.outgoing:
         case TransactionType.unknown:
           amount = _transaction.getAmountSentFromThisWallet(
-              fractionDigits: fractionDigits);
+            fractionDigits: fractionDigits,
+          );
           break;
 
         case TransactionType.incoming:
         case TransactionType.sentToSelf:
           amount = _transaction.getAmountReceivedInThisWallet(
-              fractionDigits: fractionDigits);
+            fractionDigits: fractionDigits,
+          );
           break;
       }
       data = _transaction.outputs
-          .map((e) => (
-                addresses: e.addresses,
-                amount: Amount(rawValue: e.value, fractionDigits: coin.decimals)
-              ))
+          .map(
+            (e) => (
+              addresses: e.addresses,
+              amount: Amount(
+                rawValue: e.value,
+                fractionDigits: coin.fractionDigits,
+              )
+            ),
+          )
           .toList();
     } else if (_transaction.subType == TransactionSubType.cashFusion) {
       amount = _transaction.getAmountReceivedInThisWallet(
-          fractionDigits: fractionDigits);
+        fractionDigits: fractionDigits,
+      );
       data = _transaction.outputs
           .where((e) => e.walletOwns)
-          .map((e) => (
-                addresses: e.addresses,
-                amount: Amount(rawValue: e.value, fractionDigits: coin.decimals)
-              ))
+          .map(
+            (e) => (
+              addresses: e.addresses,
+              amount: Amount(
+                rawValue: e.value,
+                fractionDigits: coin.fractionDigits,
+              )
+            ),
+          )
           .toList();
     } else {
       switch (_transaction.type) {
         case TransactionType.outgoing:
           amount = _transaction.getAmountSentFromThisWallet(
-              fractionDigits: fractionDigits);
+            fractionDigits: fractionDigits,
+          );
           data = _transaction.outputs
               .where((e) => !e.walletOwns)
-              .map((e) => (
-                    addresses: e.addresses,
-                    amount:
-                        Amount(rawValue: e.value, fractionDigits: coin.decimals)
-                  ))
+              .map(
+                (e) => (
+                  addresses: e.addresses,
+                  amount: Amount(
+                    rawValue: e.value,
+                    fractionDigits: coin.fractionDigits,
+                  )
+                ),
+              )
               .toList();
           break;
 
@@ -191,56 +216,71 @@ class _TransactionV2DetailsViewState
                 .and()
                 .heightEqualTo(_transaction.height)
                 .anyOf(
-                    _transaction.outputs
-                        .where((e) =>
+                  _transaction.outputs
+                      .where(
+                        (e) =>
                             e.walletOwns &&
                             e.addresses.isEmpty &&
-                            e.scriptPubKeyHex.length >= 488)
-                        .map((e) => e.scriptPubKeyHex.substring(2, 488))
-                        .toList(),
-                    (q, element) => q.serializedCoinB64StartsWith(element))
+                            e.scriptPubKeyHex.length >= 488,
+                      )
+                      .map((e) => e.scriptPubKeyHex.substring(2, 488))
+                      .toList(),
+                  (q, element) => q.serializedCoinB64StartsWith(element),
+                )
                 .memoProperty()
                 .findFirstSync();
           }
 
           if (_transaction.subType == TransactionSubType.sparkMint) {
             amount = _transaction.getAmountSparkSelfMinted(
-                fractionDigits: fractionDigits);
+              fractionDigits: fractionDigits,
+            );
           } else if (_transaction.subType == TransactionSubType.sparkSpend) {
             final changeAddress =
                 (ref.read(pWallets).getWallet(walletId) as SparkInterface)
                     .sparkChangeAddress;
             amount = Amount(
               rawValue: _transaction.outputs
-                  .where((e) =>
-                      e.walletOwns && !e.addresses.contains(changeAddress))
+                  .where(
+                    (e) => e.walletOwns && !e.addresses.contains(changeAddress),
+                  )
                   .fold(BigInt.zero, (p, e) => p + e.value),
-              fractionDigits: coin.decimals,
+              fractionDigits: coin.fractionDigits,
             );
           } else {
             amount = _transaction.getAmountReceivedInThisWallet(
-                fractionDigits: fractionDigits);
+              fractionDigits: fractionDigits,
+            );
           }
           data = _transaction.outputs
               .where((e) => e.walletOwns)
-              .map((e) => (
-                    addresses: e.addresses,
-                    amount:
-                        Amount(rawValue: e.value, fractionDigits: coin.decimals)
-                  ))
+              .map(
+                (e) => (
+                  addresses: e.addresses,
+                  amount: Amount(
+                    rawValue: e.value,
+                    fractionDigits: coin.fractionDigits,
+                  )
+                ),
+              )
               .toList();
           break;
 
         case TransactionType.unknown:
           amount = _transaction.getAmountSentFromThisWallet(
-              fractionDigits: fractionDigits);
+            fractionDigits: fractionDigits,
+          );
           data = _transaction.inputs
               .where((e) => e.walletOwns)
-              .map((e) => (
-                    addresses: e.addresses,
-                    amount:
-                        Amount(rawValue: e.value, fractionDigits: coin.decimals)
-                  ))
+              .map(
+                (e) => (
+                  addresses: e.addresses,
+                  amount: Amount(
+                    rawValue: e.value,
+                    fractionDigits: coin.fractionDigits,
+                  )
+                ),
+              )
               .toList();
           break;
       }
@@ -265,9 +305,10 @@ class _TransactionV2DetailsViewState
     }
     try {
       final contacts = ref.read(addressBookServiceProvider).contacts.where(
-          (element) => element.addresses
-              .where((element) => element.address == address)
-              .isNotEmpty);
+            (element) => element.addresses
+                .where((element) => element.address == address)
+                .isNotEmpty,
+          );
       if (contacts.isNotEmpty) {
         return contacts.first.name;
       } else {
@@ -281,20 +322,23 @@ class _TransactionV2DetailsViewState
 
   Future<bool> showExplorerWarning(String explorer) async {
     final bool? shouldContinue = await showDialog<bool>(
-        context: context,
-        barrierDismissible: false,
-        builder: (_) {
-          if (!isDesktop) {
-            return StackDialog(
-              title: "Attention",
-              message:
-                  "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
-              icon: Row(
-                children: [
-                  Consumer(builder: (_, ref, __) {
+      context: context,
+      barrierDismissible: false,
+      builder: (_) {
+        if (!isDesktop) {
+          return StackDialog(
+            title: "Attention",
+            message:
+                "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
+            icon: Row(
+              children: [
+                Consumer(
+                  builder: (_, ref, __) {
                     return Checkbox(
-                      value: ref.watch(prefsChangeNotifierProvider
-                          .select((value) => value.hideBlockExplorerWarning)),
+                      value: ref.watch(
+                        prefsChangeNotifierProvider
+                            .select((value) => value.hideBlockExplorerWarning),
+                      ),
                       onChanged: (value) {
                         if (value is bool) {
                           ref
@@ -304,61 +348,65 @@ class _TransactionV2DetailsViewState
                         }
                       },
                     );
-                  }),
-                  Text(
-                    "Never show again",
-                    style: STextStyles.smallMed14(context),
-                  )
-                ],
-              ),
-              leftButton: TextButton(
-                onPressed: () {
-                  Navigator.of(context).pop(false);
-                },
-                child: Text(
-                  "Cancel",
-                  style: STextStyles.button(context).copyWith(
-                      color: Theme.of(context)
-                          .extension<StackColors>()!
-                          .accentColorDark),
+                  },
+                ),
+                Text(
+                  "Never show again",
+                  style: STextStyles.smallMed14(context),
+                ),
+              ],
+            ),
+            leftButton: TextButton(
+              onPressed: () {
+                Navigator.of(context).pop(false);
+              },
+              child: Text(
+                "Cancel",
+                style: STextStyles.button(context).copyWith(
+                  color: Theme.of(context)
+                      .extension<StackColors>()!
+                      .accentColorDark,
                 ),
               ),
-              rightButton: TextButton(
-                style: Theme.of(context)
-                    .extension<StackColors>()!
-                    .getPrimaryEnabledButtonStyle(context),
-                onPressed: () {
-                  Navigator.of(context).pop(true);
-                },
-                child: Text(
-                  "Continue",
-                  style: STextStyles.button(context),
-                ),
+            ),
+            rightButton: TextButton(
+              style: Theme.of(context)
+                  .extension<StackColors>()!
+                  .getPrimaryEnabledButtonStyle(context),
+              onPressed: () {
+                Navigator.of(context).pop(true);
+              },
+              child: Text(
+                "Continue",
+                style: STextStyles.button(context),
               ),
-            );
-          } else {
-            return DesktopDialog(
-              maxWidth: 550,
-              maxHeight: 300,
-              child: Padding(
-                padding:
-                    const EdgeInsets.symmetric(horizontal: 32, vertical: 20),
-                child: Column(
-                  children: [
-                    Row(
-                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
-                      children: [
-                        Text(
-                          "Attention",
-                          style: STextStyles.desktopH2(context),
-                        ),
-                        Row(
-                          children: [
-                            Consumer(builder: (_, ref, __) {
+            ),
+          );
+        } else {
+          return DesktopDialog(
+            maxWidth: 550,
+            maxHeight: 300,
+            child: Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 20),
+              child: Column(
+                children: [
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                    children: [
+                      Text(
+                        "Attention",
+                        style: STextStyles.desktopH2(context),
+                      ),
+                      Row(
+                        children: [
+                          Consumer(
+                            builder: (_, ref, __) {
                               return Checkbox(
-                                value: ref.watch(prefsChangeNotifierProvider
-                                    .select((value) =>
-                                        value.hideBlockExplorerWarning)),
+                                value: ref.watch(
+                                  prefsChangeNotifierProvider.select(
+                                    (value) => value.hideBlockExplorerWarning,
+                                  ),
+                                ),
                                 onChanged: (value) {
                                   if (value is bool) {
                                     ref
@@ -368,55 +416,57 @@ class _TransactionV2DetailsViewState
                                   }
                                 },
                               );
-                            }),
-                            Text(
-                              "Never show again",
-                              style: STextStyles.smallMed14(context),
-                            )
-                          ],
-                        ),
-                      ],
-                    ),
-                    const SizedBox(height: 16),
-                    Text(
-                      "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
-                      style: STextStyles.desktopTextSmall(context),
-                    ),
-                    const SizedBox(height: 35),
-                    Row(
-                      mainAxisAlignment: MainAxisAlignment.center,
-                      children: [
-                        SecondaryButton(
-                          width: 200,
-                          buttonHeight: ButtonHeight.l,
-                          label: "Cancel",
-                          onPressed: () {
-                            Navigator.of(
-                              context,
-                              rootNavigator: true,
-                            ).pop(false);
-                          },
-                        ),
-                        const SizedBox(width: 20),
-                        PrimaryButton(
-                          width: 200,
-                          buttonHeight: ButtonHeight.l,
-                          label: "Continue",
-                          onPressed: () {
-                            Navigator.of(
-                              context,
-                              rootNavigator: true,
-                            ).pop(true);
-                          },
-                        ),
-                      ],
-                    ),
-                  ],
-                ),
+                            },
+                          ),
+                          Text(
+                            "Never show again",
+                            style: STextStyles.smallMed14(context),
+                          ),
+                        ],
+                      ),
+                    ],
+                  ),
+                  const SizedBox(height: 16),
+                  Text(
+                    "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.",
+                    style: STextStyles.desktopTextSmall(context),
+                  ),
+                  const SizedBox(height: 35),
+                  Row(
+                    mainAxisAlignment: MainAxisAlignment.center,
+                    children: [
+                      SecondaryButton(
+                        width: 200,
+                        buttonHeight: ButtonHeight.l,
+                        label: "Cancel",
+                        onPressed: () {
+                          Navigator.of(
+                            context,
+                            rootNavigator: true,
+                          ).pop(false);
+                        },
+                      ),
+                      const SizedBox(width: 20),
+                      PrimaryButton(
+                        width: 200,
+                        buttonHeight: ButtonHeight.l,
+                        label: "Continue",
+                        onPressed: () {
+                          Navigator.of(
+                            context,
+                            rootNavigator: true,
+                          ).pop(true);
+                        },
+                      ),
+                    ],
+                  ),
+                ],
               ),
-            );
-          }
-        });
+            ),
+          );
+        }
+      },
+    );
     return shouldContinue ?? false;
   }
 
@@ -558,7 +608,8 @@ class _TransactionV2DetailsViewState
                                               ),
                                               style:
                                                   STextStyles.desktopTextMedium(
-                                                      context),
+                                                context,
+                                              ),
                                             ),
                                           ],
                                         ),
@@ -571,32 +622,36 @@ class _TransactionV2DetailsViewState
                                             "$amountPrefix${ref.watch(pAmountFormatter(coin)).format(amount, ethContract: ethContract)}",
                                             style: isDesktop
                                                 ? STextStyles
-                                                        .desktopTextExtraExtraSmall(
-                                                            context)
-                                                    .copyWith(
+                                                    .desktopTextExtraExtraSmall(
+                                                    context,
+                                                  ).copyWith(
                                                     color: Theme.of(context)
                                                         .extension<
                                                             StackColors>()!
                                                         .textDark,
                                                   )
                                                 : STextStyles.titleBold12(
-                                                    context),
+                                                    context,
+                                                  ),
                                           ),
                                           const SizedBox(
                                             height: 2,
                                           ),
                                           if (ref.watch(
-                                              prefsChangeNotifierProvider
-                                                  .select((value) =>
-                                                      value.externalCalls)))
+                                            prefsChangeNotifierProvider.select(
+                                              (value) => value.externalCalls,
+                                            ),
+                                          ))
                                             SelectableText(
                                               "$amountPrefix${(amount.decimal * ref.watch(
                                                         priceAnd24hChangeNotifierProvider
-                                                            .select((value) =>
-                                                                value
-                                                                    .getPrice(
-                                                                        coin)
-                                                                    .item1),
+                                                            .select(
+                                                          (value) => value
+                                                              .getPrice(
+                                                                coin,
+                                                              )
+                                                              .item1,
+                                                        ),
                                                       )).toAmount(fractionDigits: 2).fiatString(
                                                     locale: ref.watch(
                                                       localeServiceChangeNotifierProvider
@@ -613,9 +668,11 @@ class _TransactionV2DetailsViewState
                                               style: isDesktop
                                                   ? STextStyles
                                                       .desktopTextExtraExtraSmall(
-                                                          context)
+                                                      context,
+                                                    )
                                                   : STextStyles.itemSubtitle(
-                                                      context),
+                                                      context,
+                                                    ),
                                             ),
                                         ],
                                       ),
@@ -662,9 +719,9 @@ class _TransactionV2DetailsViewState
                                     ),
                                     style: isDesktop
                                         ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            .copyWith(
+                                            .desktopTextExtraExtraSmall(
+                                            context,
+                                          ).copyWith(
                                             color: _transaction.type ==
                                                         TransactionType
                                                             .outgoing &&
@@ -685,12 +742,10 @@ class _TransactionV2DetailsViewState
                                 ],
                               ),
                             ),
-                            if (!((coin == Coin.monero ||
-                                        coin == Coin.wownero) &&
+                            if (!((coin is Monero || coin is Wownero) &&
                                     _transaction.type ==
                                         TransactionType.outgoing) &&
-                                !((coin == Coin.firo ||
-                                        coin == Coin.firoTestNet) &&
+                                !((coin is Firo) &&
                                     _transaction.subType ==
                                         TransactionSubType.mint))
                               isDesktop
@@ -698,12 +753,10 @@ class _TransactionV2DetailsViewState
                                   : const SizedBox(
                                       height: 12,
                                     ),
-                            if (!((coin == Coin.monero ||
-                                        coin == Coin.wownero) &&
+                            if (!((coin is Monero || coin is Wownero) &&
                                     _transaction.type ==
                                         TransactionType.outgoing) &&
-                                !((coin == Coin.firo ||
-                                        coin == Coin.firoTestNet) &&
+                                !((coin is Firo) &&
                                     _transaction.subType ==
                                         TransactionSubType.mint))
                               RoundedWhiteContainer(
@@ -778,9 +831,11 @@ class _TransactionV2DetailsViewState
                                               style: isDesktop
                                                   ? STextStyles
                                                       .desktopTextExtraExtraSmall(
-                                                          context)
+                                                      context,
+                                                    )
                                                   : STextStyles.itemSubtitle(
-                                                      context),
+                                                      context,
+                                                    ),
                                             ),
                                           ),
                                           const SizedBox(
@@ -795,11 +850,13 @@ class _TransactionV2DetailsViewState
                                                       1)
                                                 FutureBuilder(
                                                   future: fetchContactNameFor(
-                                                      data.first.addresses
-                                                          .first),
-                                                  builder: (builderContext,
-                                                      AsyncSnapshot<String>
-                                                          snapshot) {
+                                                    data.first.addresses.first,
+                                                  ),
+                                                  builder: (
+                                                    builderContext,
+                                                    AsyncSnapshot<String>
+                                                        snapshot,
+                                                  ) {
                                                     String
                                                         addressOrContactName =
                                                         data.first.addresses
@@ -815,18 +872,20 @@ class _TransactionV2DetailsViewState
                                                       addressOrContactName,
                                                       style: isDesktop
                                                           ? STextStyles
-                                                                  .desktopTextExtraExtraSmall(
-                                                                      context)
-                                                              .copyWith(
+                                                              .desktopTextExtraExtraSmall(
+                                                              context,
+                                                            ).copyWith(
                                                               color: Theme.of(
-                                                                      context)
+                                                                context,
+                                                              )
                                                                   .extension<
                                                                       StackColors>()!
                                                                   .textDark,
                                                             )
                                                           : STextStyles
                                                               .itemSubtitle12(
-                                                                  context),
+                                                              context,
+                                                            ),
                                                     );
                                                   },
                                                 )
@@ -848,7 +907,8 @@ class _TransactionV2DetailsViewState
                                                     child: Padding(
                                                       padding:
                                                           const EdgeInsets.all(
-                                                              8.0),
+                                                        8.0,
+                                                      ),
                                                       child: Column(
                                                         crossAxisAlignment:
                                                             CrossAxisAlignment
@@ -861,11 +921,14 @@ class _TransactionV2DetailsViewState
                                                               return FutureBuilder(
                                                                 future:
                                                                     fetchContactNameFor(
-                                                                        e),
-                                                                builder: (builderContext,
-                                                                    AsyncSnapshot<
-                                                                            String>
-                                                                        snapshot) {
+                                                                  e,
+                                                                ),
+                                                                builder: (
+                                                                  builderContext,
+                                                                  AsyncSnapshot<
+                                                                          String>
+                                                                      snapshot,
+                                                                ) {
                                                                   final String
                                                                       addressOrContactName;
                                                                   if (snapshot.connectionState ==
@@ -909,29 +972,31 @@ class _TransactionV2DetailsViewState
                                   ],
                                 ),
                               ),
-                            if (coin == Coin.epicCash)
+                            if (coin is Epiccash)
                               RoundedWhiteContainer(
                                 padding: isDesktop
                                     ? const EdgeInsets.all(16)
                                     : const EdgeInsets.all(12),
                                 child: Row(
                                   mainAxisAlignment:
-                                  MainAxisAlignment.spaceBetween,
+                                      MainAxisAlignment.spaceBetween,
                                   crossAxisAlignment: CrossAxisAlignment.start,
                                   children: [
                                     Expanded(
                                       child: Column(
                                         crossAxisAlignment:
-                                        CrossAxisAlignment.start,
+                                            CrossAxisAlignment.start,
                                         children: [
                                           Text(
                                             "On chain note",
                                             style: isDesktop
                                                 ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                context)
+                                                    .desktopTextExtraExtraSmall(
+                                                    context,
+                                                  )
                                                 : STextStyles.itemSubtitle(
-                                                context),
+                                                    context,
+                                                  ),
                                           ),
                                           const SizedBox(
                                             height: 8,
@@ -940,16 +1005,17 @@ class _TransactionV2DetailsViewState
                                             _transaction.onChainNote ?? "",
                                             style: isDesktop
                                                 ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                context)
-                                                .copyWith(
-                                              color: Theme.of(context)
-                                                  .extension<
-                                                  StackColors>()!
-                                                  .textDark,
-                                            )
+                                                    .desktopTextExtraExtraSmall(
+                                                    context,
+                                                  ).copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark,
+                                                  )
                                                 : STextStyles.itemSubtitle12(
-                                                context),
+                                                    context,
+                                                  ),
                                           ),
                                         ],
                                       ),
@@ -978,13 +1044,14 @@ class _TransactionV2DetailsViewState
                                         MainAxisAlignment.spaceBetween,
                                     children: [
                                       Text(
-                                        (coin == Coin.epicCash)
+                                        (coin is Epiccash)
                                             ? "Local Note"
                                             : "Note ",
                                         style: isDesktop
                                             ? STextStyles
                                                 .desktopTextExtraExtraSmall(
-                                                    context)
+                                                context,
+                                              )
                                             : STextStyles.itemSubtitle(context),
                                       ),
                                       isDesktop
@@ -1032,7 +1099,8 @@ class _TransactionV2DetailsViewState
                                                   Text(
                                                     "Edit",
                                                     style: STextStyles.link2(
-                                                        context),
+                                                      context,
+                                                    ),
                                                   ),
                                                 ],
                                               ),
@@ -1047,8 +1115,9 @@ class _TransactionV2DetailsViewState
                                             .watch(
                                               pTransactionNote(
                                                 (
-                                                  txid: (coin == Coin.epicCash) ?
-                                                  _transaction.slateId.toString()
+                                                  txid: (coin is Epiccash)
+                                                      ? _transaction.slateId
+                                                          .toString()
                                                       : _transaction.txid,
                                                   walletId: walletId
                                                 ),
@@ -1058,9 +1127,9 @@ class _TransactionV2DetailsViewState
                                         "",
                                     style: isDesktop
                                         ? STextStyles
-                                                .desktopTextExtraExtraSmall(
-                                                    context)
-                                            .copyWith(
+                                            .desktopTextExtraExtraSmall(
+                                            context,
+                                          ).copyWith(
                                             color: Theme.of(context)
                                                 .extension<StackColors>()!
                                                 .textDark,
@@ -1091,9 +1160,11 @@ class _TransactionV2DetailsViewState
                                           style: isDesktop
                                               ? STextStyles
                                                   .desktopTextExtraExtraSmall(
-                                                      context)
+                                                  context,
+                                                )
                                               : STextStyles.itemSubtitle(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                       ],
                                     ),
@@ -1104,9 +1175,9 @@ class _TransactionV2DetailsViewState
                                       _sparkMemo!,
                                       style: isDesktop
                                           ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
+                                              .desktopTextExtraExtraSmall(
+                                              context,
+                                            ).copyWith(
                                               color: Theme.of(context)
                                                   .extension<StackColors>()!
                                                   .textDark,
@@ -1139,7 +1210,8 @@ class _TransactionV2DetailsViewState
                                         style: isDesktop
                                             ? STextStyles
                                                 .desktopTextExtraExtraSmall(
-                                                    context)
+                                                context,
+                                              )
                                             : STextStyles.itemSubtitle(context),
                                       ),
                                       if (isDesktop)
@@ -1153,15 +1225,16 @@ class _TransactionV2DetailsViewState
                                           ),
                                           style: isDesktop
                                               ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
+                                                  .desktopTextExtraExtraSmall(
+                                                  context,
+                                                ).copyWith(
                                                   color: Theme.of(context)
                                                       .extension<StackColors>()!
                                                       .textDark,
                                                 )
                                               : STextStyles.itemSubtitle12(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                     ],
                                   ),
@@ -1172,9 +1245,9 @@ class _TransactionV2DetailsViewState
                                       ),
                                       style: isDesktop
                                           ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
+                                              .desktopTextExtraExtraSmall(
+                                              context,
+                                            ).copyWith(
                                               color: Theme.of(context)
                                                   .extension<StackColors>()!
                                                   .textDark,
@@ -1190,34 +1263,136 @@ class _TransactionV2DetailsViewState
                                 ],
                               ),
                             ),
-                            if (coin != Coin.banano && coin != Coin.nano)
+                            if (coin is! NanoCurrency)
                               isDesktop
                                   ? const _Divider()
                                   : const SizedBox(
                                       height: 12,
                                     ),
-                            if (coin != Coin.banano && coin != Coin.nano)
+                            if (coin is! NanoCurrency)
                               RoundedWhiteContainer(
                                 padding: isDesktop
                                     ? const EdgeInsets.all(16)
                                     : const EdgeInsets.all(12),
-                                child: Builder(builder: (context) {
-                                  String feeString = showFeePending
-                                      ? _transaction.isConfirmed(
-                                          currentHeight,
-                                          minConfirms,
-                                        )
-                                          ? ref
-                                              .watch(pAmountFormatter(coin))
-                                              .format(
-                                                fee,
-                                              )
-                                          : "Pending"
-                                      : ref
-                                          .watch(pAmountFormatter(coin))
-                                          .format(
-                                            fee,
-                                          );
+                                child: Builder(
+                                  builder: (context) {
+                                    String feeString = showFeePending
+                                        ? _transaction.isConfirmed(
+                                            currentHeight,
+                                            minConfirms,
+                                          )
+                                            ? ref
+                                                .watch(pAmountFormatter(coin))
+                                                .format(
+                                                  fee,
+                                                )
+                                            : "Pending"
+                                        : ref
+                                            .watch(pAmountFormatter(coin))
+                                            .format(
+                                              fee,
+                                            );
+
+                                    return Row(
+                                      mainAxisAlignment:
+                                          MainAxisAlignment.spaceBetween,
+                                      crossAxisAlignment:
+                                          CrossAxisAlignment.start,
+                                      children: [
+                                        Column(
+                                          crossAxisAlignment:
+                                              CrossAxisAlignment.start,
+                                          children: [
+                                            Text(
+                                              "Transaction fee",
+                                              style: isDesktop
+                                                  ? STextStyles
+                                                      .desktopTextExtraExtraSmall(
+                                                      context,
+                                                    )
+                                                  : STextStyles.itemSubtitle(
+                                                      context,
+                                                    ),
+                                            ),
+                                            if (isDesktop)
+                                              const SizedBox(
+                                                height: 2,
+                                              ),
+                                            if (isDesktop)
+                                              SelectableText(
+                                                feeString,
+                                                style: isDesktop
+                                                    ? STextStyles
+                                                        .desktopTextExtraExtraSmall(
+                                                        context,
+                                                      ).copyWith(
+                                                        color: Theme.of(context)
+                                                            .extension<
+                                                                StackColors>()!
+                                                            .textDark,
+                                                      )
+                                                    : STextStyles
+                                                        .itemSubtitle12(
+                                                        context,
+                                                      ),
+                                              ),
+                                          ],
+                                        ),
+                                        if (!isDesktop)
+                                          SelectableText(
+                                            feeString,
+                                            style: isDesktop
+                                                ? STextStyles
+                                                    .desktopTextExtraExtraSmall(
+                                                    context,
+                                                  ).copyWith(
+                                                    color: Theme.of(context)
+                                                        .extension<
+                                                            StackColors>()!
+                                                        .textDark,
+                                                  )
+                                                : STextStyles.itemSubtitle12(
+                                                    context,
+                                                  ),
+                                          ),
+                                        if (isDesktop)
+                                          IconCopyButton(data: feeString),
+                                      ],
+                                    );
+                                  },
+                                ),
+                              ),
+                            isDesktop
+                                ? const _Divider()
+                                : const SizedBox(
+                                    height: 12,
+                                  ),
+                            RoundedWhiteContainer(
+                              padding: isDesktop
+                                  ? const EdgeInsets.all(16)
+                                  : const EdgeInsets.all(12),
+                              child: Builder(
+                                builder: (context) {
+                                  final String height;
+
+                                  if (widget.coin is Bitcoincash ||
+                                      widget.coin is Ecash) {
+                                    height =
+                                        "${_transaction.height != null && _transaction.height! > 0 ? _transaction.height! : "Pending"}";
+                                  } else {
+                                    height = widget.coin is! Epiccash &&
+                                            _transaction.isConfirmed(
+                                              currentHeight,
+                                              minConfirms,
+                                            )
+                                        ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
+                                        : _transaction.getConfirmations(
+                                                  currentHeight,
+                                                ) >
+                                                0
+                                            ? "${_transaction.height}"
+                                            : "Pending";
+                                  }
 
                                   return Row(
                                     mainAxisAlignment:
@@ -1230,13 +1405,15 @@ class _TransactionV2DetailsViewState
                                             CrossAxisAlignment.start,
                                         children: [
                                           Text(
-                                            "Transaction fee",
+                                            "Block height",
                                             style: isDesktop
                                                 ? STextStyles
                                                     .desktopTextExtraExtraSmall(
-                                                        context)
+                                                    context,
+                                                  )
                                                 : STextStyles.itemSubtitle(
-                                                    context),
+                                                    context,
+                                                  ),
                                           ),
                                           if (isDesktop)
                                             const SizedBox(
@@ -1244,133 +1421,45 @@ class _TransactionV2DetailsViewState
                                             ),
                                           if (isDesktop)
                                             SelectableText(
-                                              feeString,
+                                              height,
                                               style: isDesktop
                                                   ? STextStyles
-                                                          .desktopTextExtraExtraSmall(
-                                                              context)
-                                                      .copyWith(
+                                                      .desktopTextExtraExtraSmall(
+                                                      context,
+                                                    ).copyWith(
                                                       color: Theme.of(context)
                                                           .extension<
                                                               StackColors>()!
                                                           .textDark,
                                                     )
                                                   : STextStyles.itemSubtitle12(
-                                                      context),
+                                                      context,
+                                                    ),
                                             ),
                                         ],
                                       ),
                                       if (!isDesktop)
                                         SelectableText(
-                                          feeString,
+                                          height,
                                           style: isDesktop
                                               ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
+                                                  .desktopTextExtraExtraSmall(
+                                                  context,
+                                                ).copyWith(
                                                   color: Theme.of(context)
                                                       .extension<StackColors>()!
                                                       .textDark,
                                                 )
                                               : STextStyles.itemSubtitle12(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                       if (isDesktop)
-                                        IconCopyButton(data: feeString)
+                                        IconCopyButton(data: height),
                                     ],
                                   );
-                                }),
+                                },
                               ),
-                            isDesktop
-                                ? const _Divider()
-                                : const SizedBox(
-                                    height: 12,
-                                  ),
-                            RoundedWhiteContainer(
-                              padding: isDesktop
-                                  ? const EdgeInsets.all(16)
-                                  : const EdgeInsets.all(12),
-                              child: Builder(builder: (context) {
-                                final String height;
-
-                                if (widget.coin == Coin.bitcoincash ||
-                                    widget.coin == Coin.eCash ||
-                                    widget.coin == Coin.bitcoincashTestnet) {
-                                  height =
-                                      "${_transaction.height != null && _transaction.height! > 0 ? _transaction.height! : "Pending"}";
-                                } else {
-                                  height = widget.coin != Coin.epicCash &&
-                                          _transaction.isConfirmed(
-                                            currentHeight,
-                                            minConfirms,
-                                          )
-                                      ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}"
-                                      : _transaction.getConfirmations(
-                                                  currentHeight) >
-                                              0
-                                          ? "${_transaction.height}"
-                                          : "Pending";
-                                }
-
-                                return Row(
-                                  mainAxisAlignment:
-                                      MainAxisAlignment.spaceBetween,
-                                  crossAxisAlignment: CrossAxisAlignment.start,
-                                  children: [
-                                    Column(
-                                      crossAxisAlignment:
-                                          CrossAxisAlignment.start,
-                                      children: [
-                                        Text(
-                                          "Block height",
-                                          style: isDesktop
-                                              ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              : STextStyles.itemSubtitle(
-                                                  context),
-                                        ),
-                                        if (isDesktop)
-                                          const SizedBox(
-                                            height: 2,
-                                          ),
-                                        if (isDesktop)
-                                          SelectableText(
-                                            height,
-                                            style: isDesktop
-                                                ? STextStyles
-                                                        .desktopTextExtraExtraSmall(
-                                                            context)
-                                                    .copyWith(
-                                                    color: Theme.of(context)
-                                                        .extension<
-                                                            StackColors>()!
-                                                        .textDark,
-                                                  )
-                                                : STextStyles.itemSubtitle12(
-                                                    context),
-                                          ),
-                                      ],
-                                    ),
-                                    if (!isDesktop)
-                                      SelectableText(
-                                        height,
-                                        style: isDesktop
-                                            ? STextStyles
-                                                    .desktopTextExtraExtraSmall(
-                                                        context)
-                                                .copyWith(
-                                                color: Theme.of(context)
-                                                    .extension<StackColors>()!
-                                                    .textDark,
-                                              )
-                                            : STextStyles.itemSubtitle12(
-                                                context),
-                                      ),
-                                    if (isDesktop) IconCopyButton(data: height),
-                                  ],
-                                );
-                              }),
                             ),
 
                             if (kDebugMode)
@@ -1394,16 +1483,17 @@ class _TransactionV2DetailsViewState
                                       style: isDesktop
                                           ? STextStyles
                                               .desktopTextExtraExtraSmall(
-                                                  context)
+                                              context,
+                                            )
                                           : STextStyles.itemSubtitle(context),
                                     ),
                                     SelectableText(
                                       _transaction.subType.toString(),
                                       style: isDesktop
                                           ? STextStyles
-                                                  .desktopTextExtraExtraSmall(
-                                                      context)
-                                              .copyWith(
+                                              .desktopTextExtraExtraSmall(
+                                              context,
+                                            ).copyWith(
                                               color: Theme.of(context)
                                                   .extension<StackColors>()!
                                                   .textDark,
@@ -1437,9 +1527,11 @@ class _TransactionV2DetailsViewState
                                           style: isDesktop
                                               ? STextStyles
                                                   .desktopTextExtraExtraSmall(
-                                                      context)
+                                                  context,
+                                                )
                                               : STextStyles.itemSubtitle(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                         const SizedBox(
                                           height: 8,
@@ -1452,21 +1544,22 @@ class _TransactionV2DetailsViewState
                                           _transaction.txid,
                                           style: isDesktop
                                               ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
+                                                  .desktopTextExtraExtraSmall(
+                                                  context,
+                                                ).copyWith(
                                                   color: Theme.of(context)
                                                       .extension<StackColors>()!
                                                       .textDark,
                                                 )
                                               : STextStyles.itemSubtitle12(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
-                                        if (coin != Coin.epicCash)
+                                        if (coin is! Epiccash)
                                           const SizedBox(
                                             height: 8,
                                           ),
-                                        if (coin != Coin.epicCash)
+                                        if (coin is! Epiccash)
                                           CustomTextButton(
                                             text: "Open in block explorer",
                                             onTap: () async {
@@ -1478,12 +1571,14 @@ class _TransactionV2DetailsViewState
 
                                               if (ref
                                                       .read(
-                                                          prefsChangeNotifierProvider)
+                                                        prefsChangeNotifierProvider,
+                                                      )
                                                       .hideBlockExplorerWarning ==
                                                   false) {
                                                 final shouldContinue =
                                                     await showExplorerWarning(
-                                                        "${uri.scheme}://${uri.host}");
+                                                  "${uri.scheme}://${uri.host}",
+                                                );
 
                                                 if (!shouldContinue) {
                                                   return;
@@ -1544,12 +1639,12 @@ class _TransactionV2DetailsViewState
                                 ],
                               ),
                             ),
-                            // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                            // if ((coin is FiroTestNet || coin is Firo) &&
                             //     _transaction.subType == "mint")
                             //   const SizedBox(
                             //     height: 12,
                             //   ),
-                            // if ((coin == Coin.firoTestNet || coin == Coin.firo) &&
+                            // if ((coin is FiroTestNet || coin is Firo) &&
                             //     _transaction.subType == "mint")
                             //   RoundedWhiteContainer(
                             //     child: Column(
@@ -1621,13 +1716,13 @@ class _TransactionV2DetailsViewState
                             //       ],
                             //     ),
                             //   ),
-                            if (coin == Coin.epicCash)
+                            if (coin is Epiccash)
                               isDesktop
                                   ? const _Divider()
                                   : const SizedBox(
                                       height: 12,
                                     ),
-                            if (coin == Coin.epicCash)
+                            if (coin is Epiccash)
                               RoundedWhiteContainer(
                                 padding: isDesktop
                                     ? const EdgeInsets.all(16)
@@ -1646,9 +1741,11 @@ class _TransactionV2DetailsViewState
                                           style: isDesktop
                                               ? STextStyles
                                                   .desktopTextExtraExtraSmall(
-                                                      context)
+                                                  context,
+                                                )
                                               : STextStyles.itemSubtitle(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                         // Flexible(
                                         //   child: FittedBox(
@@ -1658,15 +1755,16 @@ class _TransactionV2DetailsViewState
                                           _transaction.slateId ?? "Unknown",
                                           style: isDesktop
                                               ? STextStyles
-                                                      .desktopTextExtraExtraSmall(
-                                                          context)
-                                                  .copyWith(
+                                                  .desktopTextExtraExtraSmall(
+                                                  context,
+                                                ).copyWith(
                                                   color: Theme.of(context)
                                                       .extension<StackColors>()!
                                                       .textDark,
                                                 )
                                               : STextStyles.itemSubtitle12(
-                                                  context),
+                                                  context,
+                                                ),
                                         ),
                                         //   ),
                                         // ),
@@ -1698,7 +1796,7 @@ class _TransactionV2DetailsViewState
           ),
         ),
         floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
-        floatingActionButton: (coin == Coin.epicCash &&
+        floatingActionButton: (coin is Epiccash &&
                 _transaction.getConfirmations(currentHeight) < 1 &&
                 _transaction.isCancelled == false)
             ? ConditionalParent(
@@ -1724,11 +1822,13 @@ class _TransactionV2DetailsViewState
                       if (wallet is EpiccashWallet) {
                         final String? id = _transaction.slateId;
                         if (id == null) {
-                          unawaited(showFloatingFlushBar(
-                            type: FlushBarType.warning,
-                            message: "Could not find Epic transaction ID",
-                            context: context,
-                          ));
+                          unawaited(
+                            showFloatingFlushBar(
+                              type: FlushBarType.warning,
+                              message: "Could not find Epic transaction ID",
+                              context: context,
+                            ),
+                          );
                           return;
                         }
 
@@ -1773,11 +1873,13 @@ class _TransactionV2DetailsViewState
                           }
                         }
                       } else {
-                        unawaited(showFloatingFlushBar(
-                          type: FlushBarType.warning,
-                          message: "ERROR: Wallet type is not Epic Cash",
-                          context: context,
-                        ));
+                        unawaited(
+                          showFloatingFlushBar(
+                            type: FlushBarType.warning,
+                            message: "ERROR: Wallet type is not Epic Cash",
+                            context: context,
+                          ),
+                        );
                         return;
                       }
                     },
@@ -1804,7 +1906,7 @@ class OutputCard extends ConsumerWidget {
 
   final String address;
   final Amount amount;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
@@ -1847,14 +1949,14 @@ class OutputCard extends ConsumerWidget {
                   : STextStyles.itemSubtitle12(context),
             ),
           ],
-        )
+        ),
       ],
     );
   }
 }
 
 class _Divider extends StatelessWidget {
-  const _Divider({Key? key}) : super(key: key);
+  const _Divider({super.key});
 
   @override
   Widget build(BuildContext context) {
@@ -1867,9 +1969,9 @@ class _Divider extends StatelessWidget {
 
 class IconCopyButton extends StatelessWidget {
   const IconCopyButton({
-    Key? key,
+    super.key,
     required this.data,
-  }) : super(key: key);
+  });
 
   final String data;
 
@@ -1913,9 +2015,9 @@ class IconCopyButton extends StatelessWidget {
 
 class IconPencilButton extends StatelessWidget {
   const IconPencilButton({
-    Key? key,
+    super.key,
     this.onPressed,
-  }) : super(key: key);
+  });
 
   final VoidCallback? onPressed;
 
diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart
index ac868aee9..21c0cbb9e 100644
--- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart
+++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart
@@ -23,8 +23,8 @@ import 'package:stackwallet/providers/db/main_db_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
 
 class TransactionsV2List extends ConsumerStatefulWidget {
@@ -45,7 +45,7 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> {
 
   late final StreamSubscription<List<TransactionV2>> _subscription;
   late final Query<TransactionV2> _query;
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   BorderRadius get _borderRadiusFirst {
     return BorderRadius.only(
diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart
index ec5c50183..2c18faee1 100644
--- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart
+++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart
@@ -10,9 +10,9 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transactio
 import 'package:stackwallet/providers/global/trades_service_provider.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
@@ -29,7 +29,7 @@ class TxListItem extends ConsumerWidget {
 
   final Object tx;
   final BorderRadius? radius;
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart
index 8abbd4d16..76c2b5d74 100644
--- a/lib/pages/wallet_view/wallet_view.dart
+++ b/lib/pages/wallet_view/wallet_view.dart
@@ -60,11 +60,15 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/banano.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/frost_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/impl/bitcoin_frost_wallet.dart';
 import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
@@ -120,7 +124,7 @@ class WalletView extends ConsumerStatefulWidget {
 class _WalletViewState extends ConsumerState<WalletView> {
   late final EventBus eventBus;
   late final String walletId;
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   late final bool isSparkWallet;
 
@@ -184,8 +188,7 @@ class _WalletViewState extends ConsumerState<WalletView> {
 
     isSparkWallet = wallet is SparkInterface;
 
-    if (coin == Coin.firo &&
-        (wallet as FiroWallet).lelantusCoinIsarRescanRequired) {
+    if (coin is Firo && (wallet as FiroWallet).lelantusCoinIsarRescanRequired) {
       _rescanningOnOpen = true;
       _lelantusRescanRecovery = true;
       _firoRescanRecovery();
@@ -384,9 +387,9 @@ class _WalletViewState extends ConsumerState<WalletView> {
   }
 
   Future<void> _onExchangePressed(BuildContext context) async {
-    final Coin coin = ref.read(pWalletCoin(walletId));
+    final CryptoCurrency coin = ref.read(pWalletCoin(walletId));
 
-    if (coin.isTestNet) {
+    if (coin.network == CryptoCurrencyNetwork.test) {
       await showDialog<void>(
         context: context,
         builder: (_) => const StackOkDialog(
@@ -421,7 +424,7 @@ class _WalletViewState extends ConsumerState<WalletView> {
             WalletInitiatedExchangeView.routeName,
             arguments: Tuple2(
               walletId,
-              currency == null ? Coin.bitcoin : coin,
+              currency == null ? Bitcoin(CryptoCurrencyNetwork.main) : coin,
             ),
           ),
         );
@@ -430,9 +433,9 @@ class _WalletViewState extends ConsumerState<WalletView> {
   }
 
   Future<void> _onBuyPressed(BuildContext context) async {
-    final Coin coin = ref.read(pWalletCoin(walletId));
+    final CryptoCurrency coin = ref.read(pWalletCoin(walletId));
 
-    if (coin.isTestNet) {
+    if (coin.network == CryptoCurrencyNetwork.test) {
       await showDialog<void>(
         context: context,
         builder: (_) => const StackOkDialog(
@@ -444,7 +447,8 @@ class _WalletViewState extends ConsumerState<WalletView> {
         unawaited(
           Navigator.of(context).pushNamed(
             BuyInWalletView.routeName,
-            arguments: coin.hasBuySupport ? coin : Coin.bitcoin,
+            arguments:
+                coin.hasBuySupport ? coin : Bitcoin(CryptoCurrencyNetwork.main),
           ),
         );
       }
@@ -1020,7 +1024,7 @@ class _WalletViewState extends ConsumerState<WalletView> {
                       }
                     },
                   ),
-                  if (ref.watch(pWalletCoin(walletId)).isFrost)
+                  if (ref.watch(pWalletCoin(walletId)) is FrostCurrency)
                     WalletNavigationBarItemData(
                       label: "Sign",
                       icon: const FrostSignNavIcon(),
@@ -1058,14 +1062,14 @@ class _WalletViewState extends ConsumerState<WalletView> {
                     },
                   ),
                   if (Constants.enableExchange &&
-                      !ref.watch(pWalletCoin(walletId)).isFrost)
+                      ref.watch(pWalletCoin(walletId)) is! FrostCurrency)
                     WalletNavigationBarItemData(
                       label: "Swap",
                       icon: const ExchangeNavIcon(),
                       onTap: () => _onExchangePressed(context),
                     ),
                   if (Constants.enableExchange &&
-                      !ref.watch(pWalletCoin(walletId)).isFrost)
+                      ref.watch(pWalletCoin(walletId)) is! FrostCurrency)
                     WalletNavigationBarItemData(
                       label: "Buy",
                       icon: const BuyNavIcon(),
@@ -1091,7 +1095,7 @@ class _WalletViewState extends ConsumerState<WalletView> {
                         );
                       },
                     ),
-                  if (coin == Coin.banano)
+                  if (coin is Banano)
                     WalletNavigationBarItemData(
                       icon: SvgPicture.asset(
                         Assets.svg.monkey,
diff --git a/lib/pages/wallets_view/sub_widgets/favorite_card.dart b/lib/pages/wallets_view/sub_widgets/favorite_card.dart
index 4ef59bf0b..008f9c39a 100644
--- a/lib/pages/wallets_view/sub_widgets/favorite_card.dart
+++ b/lib/pages/wallets_view/sub_widgets/favorite_card.dart
@@ -21,10 +21,10 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
 import 'package:stackwallet/widgets/coin_card.dart';
@@ -32,11 +32,11 @@ import 'package:stackwallet/widgets/conditional_parent.dart';
 
 class FavoriteCard extends ConsumerStatefulWidget {
   const FavoriteCard({
-    Key? key,
+    super.key,
     required this.walletId,
     required this.width,
     required this.height,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final double width;
@@ -192,7 +192,7 @@ class _FavoriteCardState extends ConsumerState<FavoriteCard> {
                       );
 
                       Amount total = balance.total;
-                      if (coin == Coin.firo || coin == Coin.firoTestNet) {
+                      if (coin is Firo) {
                         total += ref
                             .watch(
                               pWalletBalanceSecondary(walletId),
diff --git a/lib/pages/wallets_view/sub_widgets/wallet_list_item.dart b/lib/pages/wallets_view/sub_widgets/wallet_list_item.dart
index a708267a9..15d069c5d 100644
--- a/lib/pages/wallets_view/sub_widgets/wallet_list_item.dart
+++ b/lib/pages/wallets_view/sub_widgets/wallet_list_item.dart
@@ -17,27 +17,27 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
 import 'package:stackwallet/pages/wallets_view/wallets_overview.dart';
 import 'package:stackwallet/providers/providers.dart';
-import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
 import 'package:stackwallet/widgets/dialogs/tor_warning_dialog.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class WalletListItem extends ConsumerWidget {
   const WalletListItem({
-    Key? key,
+    super.key,
     required this.coin,
     required this.walletCount,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final int walletCount;
 
   @override
@@ -52,7 +52,7 @@ class WalletListItem extends ConsumerWidget {
       padding: const EdgeInsets.all(0),
       child: MaterialButton(
         // splashColor: Theme.of(context).extension<StackColors>()!.highlight,
-        key: Key("walletListItemButtonKey_${coin.name}"),
+        key: Key("walletListItemButtonKey_${coin.identifier}"),
         padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 13),
         materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
         shape: RoundedRectangleBorder(
@@ -63,8 +63,7 @@ class WalletListItem extends ConsumerWidget {
           // Check if Tor is enabled...
           if (ref.read(prefsChangeNotifierProvider).useTor) {
             // ... and if the coin supports Tor.
-            final cryptocurrency = SupportedCoins.getCryptoCurrencyFor(coin);
-            if (!cryptocurrency.torSupport) {
+            if (!coin.torSupport) {
               // If not, show a Tor warning dialog.
               final shouldContinue = await showDialog<bool>(
                     context: context,
@@ -79,7 +78,7 @@ class WalletListItem extends ConsumerWidget {
             }
           }
 
-          if (walletCount == 1 && coin != Coin.ethereum) {
+          if (walletCount == 1 && coin is! Ethereum) {
             final wallet = ref
                 .read(pWallets)
                 .wallets
diff --git a/lib/pages/wallets_view/wallets_overview.dart b/lib/pages/wallets_view/wallets_overview.dart
index 0f6cef1a6..c70357434 100644
--- a/lib/pages/wallets_view/wallets_overview.dart
+++ b/lib/pages/wallets_view/wallets_overview.dart
@@ -21,9 +21,10 @@ import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet.dart';
@@ -40,12 +41,12 @@ import 'package:tuple/tuple.dart';
 
 class WalletsOverview extends ConsumerStatefulWidget {
   const WalletsOverview({
-    Key? key,
+    super.key,
     required this.coin,
     this.navigatorState,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final NavigatorState? navigatorState;
 
   static const routeName = "/walletsOverview";
@@ -116,7 +117,7 @@ class _EthWalletsOverviewState extends ConsumerState<WalletsOverview> {
         ref.read(mainDBProvider).isar.walletInfo.where().findAllSync();
     walletsData.removeWhere((e) => e.coin != widget.coin);
 
-    if (widget.coin == Coin.ethereum) {
+    if (widget.coin is Ethereum) {
       for (final data in walletsData) {
         final List<EthContract> contracts = [];
         final contractAddresses =
diff --git a/lib/pages_desktop_specific/address_book_view/desktop_address_book.dart b/lib/pages_desktop_specific/address_book_view/desktop_address_book.dart
index 5932c0826..7546b84fc 100644
--- a/lib/pages_desktop_specific/address_book_view/desktop_address_book.dart
+++ b/lib/pages_desktop_specific/address_book_view/desktop_address_book.dart
@@ -22,12 +22,14 @@ import 'package:stackwallet/providers/db/main_db_provider.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/providers/ui/address_book_providers/address_book_filter_provider.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart';
 import 'package:stackwallet/widgets/address_book_card.dart';
 import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
@@ -97,8 +99,10 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
     ref.refresh(addressBookFilterProvider);
 
     // if (widget.coin == null) {
-    final List<Coin> coins = Coin.values.toList();
-    coins.remove(Coin.firoTestNet);
+    final coins = SupportedCoins.cryptocurrencies.toList();
+    coins.removeWhere(
+      (e) => e is Firo && e.network == CryptoCurrencyNetwork.test,
+    );
 
     final bool showTestNet =
         ref.read(prefsChangeNotifierProvider).showTestNetCoins;
@@ -106,9 +110,10 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
     if (showTestNet) {
       ref.read(addressBookFilterProvider).addAll(coins, false);
     } else {
-      ref
-          .read(addressBookFilterProvider)
-          .addAll(coins.where((e) => !e.isTestNet), false);
+      ref.read(addressBookFilterProvider).addAll(
+            coins.where((e) => e.network != CryptoCurrencyNetwork.test),
+            false,
+          );
     }
     // } else {
     //   ref.read(addressBookFilterProvider).add(widget.coin!, false);
@@ -133,7 +138,7 @@ class _DesktopAddressBook extends ConsumerState<DesktopAddressBook> {
 
         addresses.add(
           ContactAddressEntry()
-            ..coinName = wallet.info.coin.name
+            ..coinName = wallet.info.coin.identifier
             ..address = addressString
             ..label = "Current Receiving"
             ..other = wallet.info.name,
diff --git a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart
index 13cdc24e4..684c16025 100644
--- a/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart
+++ b/lib/pages_desktop_specific/address_book_view/subwidgets/desktop_address_card.dart
@@ -22,7 +22,7 @@ import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart
index e8aa2436a..7c8a394a3 100644
--- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart
+++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart
@@ -25,8 +25,8 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -60,7 +60,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> {
   late final FocusNode portFocusNode;
   late final TextEditingController fusionRoundController;
   late final FocusNode fusionRoundFocusNode;
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   bool _enableStartButton = false;
   bool _enableSSLCheckbox = false;
diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart
index 6d4225fab..3eb98c0ba 100644
--- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart
+++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart
@@ -7,9 +7,9 @@ import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provi
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -30,9 +30,9 @@ class CashFusionState {
 
 class FusionDialogView extends ConsumerStatefulWidget {
   const FusionDialogView({
-    Key? key,
+    super.key,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   final String walletId;
 
@@ -41,13 +41,13 @@ class FusionDialogView extends ConsumerStatefulWidget {
 }
 
 class _FusionDialogViewState extends ConsumerState<FusionDialogView> {
-  late final Coin coin;
+  late final CryptoCurrency coin;
 
   Future<bool> _requestAndProcessCancel() async {
     if (!ref.read(fusionProgressUIStateProvider(widget.walletId)).running) {
       return true;
     } else {
-      bool? shouldCancel = await showDialog<bool?>(
+      final bool? shouldCancel = await showDialog<bool?>(
         context: context,
         barrierDismissible: false,
         builder: (_) => DesktopDialog(
diff --git a/lib/pages_desktop_specific/coin_control/desktop_coin_control_use_dialog.dart b/lib/pages_desktop_specific/coin_control/desktop_coin_control_use_dialog.dart
index 3ef549e83..5c46236ae 100644
--- a/lib/pages_desktop_specific/coin_control/desktop_coin_control_use_dialog.dart
+++ b/lib/pages_desktop_specific/coin_control/desktop_coin_control_use_dialog.dart
@@ -22,8 +22,8 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/animated_widgets/rotate_icon.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
@@ -43,10 +43,10 @@ final desktopUseUTXOs = StateProvider((ref) => <UTXO>{});
 
 class DesktopCoinControlUseDialog extends ConsumerStatefulWidget {
   const DesktopCoinControlUseDialog({
-    Key? key,
+    super.key,
     required this.walletId,
     this.amountToSend,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final Amount? amountToSend;
@@ -59,7 +59,7 @@ class DesktopCoinControlUseDialog extends ConsumerStatefulWidget {
 class _DesktopCoinControlUseDialogState
     extends ConsumerState<DesktopCoinControlUseDialog> {
   late final TextEditingController _searchController;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   final searchFieldFocusNode = FocusNode();
 
   final Set<UtxoRowData> _selectedUTXOsData = {};
@@ -110,7 +110,7 @@ class _DesktopCoinControlUseDialogState
         filter: _filter,
         sort: _sort,
         searchTerm: _searchString,
-        coin: coin,
+        cryptoCurrency: coin,
       );
     } else {
       _map = null;
@@ -119,18 +119,18 @@ class _DesktopCoinControlUseDialogState
         filter: _filter,
         sort: _sort,
         searchTerm: _searchString,
-        coin: coin,
+        cryptoCurrency: coin,
       );
     }
 
     final Amount selectedSum = _selectedUTXOs.map((e) => e.value).fold(
           Amount(
             rawValue: BigInt.zero,
-            fractionDigits: coin.decimals,
+            fractionDigits: coin.fractionDigits,
           ),
           (value, element) => value += Amount(
             rawValue: BigInt.from(element),
-            fractionDigits: coin.decimals,
+            fractionDigits: coin.fractionDigits,
           ),
         );
 
@@ -486,7 +486,7 @@ class _DesktopCoinControlUseDialogState
                                   ),
                                   Text(
                                     "${widget.amountToSend!.decimal.toStringAsFixed(
-                                      coin.decimals,
+                                      coin.fractionDigits,
                                     )}"
                                     " ${coin.ticker}",
                                     style:
@@ -521,7 +521,7 @@ class _DesktopCoinControlUseDialogState
                             ),
                             Text(
                               "${selectedSum.decimal.toStringAsFixed(
-                                coin.decimals,
+                                coin.fractionDigits,
                               )} ${coin.ticker}",
                               style: STextStyles.desktopTextExtraExtraSmall(
                                       context)
diff --git a/lib/pages_desktop_specific/coin_control/desktop_coin_control_view.dart b/lib/pages_desktop_specific/coin_control/desktop_coin_control_view.dart
index 2b58652a7..e19f6f7d8 100644
--- a/lib/pages_desktop_specific/coin_control/desktop_coin_control_view.dart
+++ b/lib/pages_desktop_specific/coin_control/desktop_coin_control_view.dart
@@ -22,8 +22,8 @@ import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/animated_widgets/rotate_icon.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -55,7 +55,7 @@ class DesktopCoinControlView extends ConsumerStatefulWidget {
 class _DesktopCoinControlViewState
     extends ConsumerState<DesktopCoinControlView> {
   late final TextEditingController _searchController;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   final searchFieldFocusNode = FocusNode();
 
   final Set<UtxoRowData> _selectedUTXOs = {};
@@ -93,7 +93,7 @@ class _DesktopCoinControlViewState
         filter: _filter,
         sort: _sort,
         searchTerm: _searchString,
-        coin: coin,
+        cryptoCurrency: coin,
       );
     } else {
       _map = null;
@@ -102,7 +102,7 @@ class _DesktopCoinControlViewState
         filter: _filter,
         sort: _sort,
         searchTerm: _searchString,
-        coin: coin,
+        cryptoCurrency: coin,
       );
     }
 
diff --git a/lib/pages_desktop_specific/coin_control/utxo_row.dart b/lib/pages_desktop_specific/coin_control/utxo_row.dart
index dbb2d8afe..fcc8aebf7 100644
--- a/lib/pages_desktop_specific/coin_control/utxo_row.dart
+++ b/lib/pages_desktop_specific/coin_control/utxo_row.dart
@@ -18,7 +18,6 @@ import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
@@ -158,7 +157,7 @@ class _UtxoRowState extends ConsumerState<UtxoRow> {
                   ref.watch(pAmountFormatter(coin)).format(
                         Amount(
                           rawValue: BigInt.from(utxo.value),
-                          fractionDigits: coin.decimals,
+                          fractionDigits: coin.fractionDigits,
                         ),
                       ),
                   textAlign: TextAlign.right,
@@ -180,7 +179,7 @@ class _UtxoRowState extends ConsumerState<UtxoRow> {
                           ref.watch(pAmountFormatter(coin)).format(
                                 Amount(
                                   rawValue: BigInt.from(utxo.value),
-                                  fractionDigits: coin.decimals,
+                                  fractionDigits: coin.fractionDigits,
                                 ),
                               ),
                           textAlign: TextAlign.right,
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
index b01cf6898..a5c9fa0db 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart
@@ -28,10 +28,10 @@ import 'package:stackwallet/providers/global/trades_service_provider.dart';
 import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/services/exchange/exchange_response.dart';
 import 'package:stackwallet/services/notifications_api.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@@ -51,9 +51,9 @@ final desktopExchangeModelProvider =
 
 class StepScaffold extends ConsumerStatefulWidget {
   const StepScaffold({
-    Key? key,
+    super.key,
     required this.initialStep,
-  }) : super(key: key);
+  });
 
   final int initialStep;
 
@@ -194,9 +194,9 @@ class _StepScaffoldState extends ConsumerState<StepScaffold> {
   void sendFromStack() {
     final trade = ref.read(desktopExchangeModelProvider)!.trade!;
     final address = trade.payInAddress;
-    final coin = coinFromTickerCaseInsensitive(trade.payInCurrency);
+    final coin = SupportedCoins.getCryptoCurrencyForTicker(trade.payInCurrency);
     final amount = Decimal.parse(trade.payInAmount).toAmount(
-      fractionDigits: coin.decimals,
+      fractionDigits: coin.fractionDigits,
     );
 
     showDialog<void>(
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart
index c3178b809..6f50a7347 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart
@@ -17,10 +17,10 @@ import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/d
 import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
 import 'package:stackwallet/providers/exchange/exchange_send_from_wallet_id_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
@@ -59,7 +59,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
 
   bool isStackCoin(String ticker) {
     try {
-      coinFromTickerCaseInsensitive(ticker);
+      SupportedCoins.getCryptoCurrencyForTicker(ticker);
       return true;
     } on ArgumentError catch (_) {
       return false;
@@ -68,7 +68,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
 
   void selectRecipientAddressFromStack() async {
     try {
-      final coin = coinFromTickerCaseInsensitive(
+      final coin = SupportedCoins.getCryptoCurrencyForTicker(
         ref.read(desktopExchangeModelProvider)!.receiveTicker,
       );
 
@@ -101,7 +101,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
 
   void selectRefundAddressFromStack() async {
     try {
-      final coin = coinFromTickerCaseInsensitive(
+      final coin = SupportedCoins.getCryptoCurrencyForTicker(
         ref.read(desktopExchangeModelProvider)!.sendTicker,
       );
 
@@ -131,7 +131,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
   }
 
   void selectRecipientFromAddressBook() async {
-    final coin = coinFromTickerCaseInsensitive(
+    final coin = SupportedCoins.getCryptoCurrencyForTicker(
       ref.read(desktopExchangeModelProvider)!.receiveTicker,
     );
 
@@ -178,7 +178,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
   }
 
   void selectRefundFromAddressBook() async {
-    final coin = coinFromTickerCaseInsensitive(
+    final coin = SupportedCoins.getCryptoCurrencyForTicker(
       ref.read(desktopExchangeModelProvider)!.sendTicker,
     );
 
diff --git a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
index 1787f1add..4c579647e 100644
--- a/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart
@@ -15,8 +15,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
 import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -37,7 +37,7 @@ class _DesktopStep4State extends ConsumerState<DesktopStep4> {
 
   bool _isWalletCoinAndHasWallet(String ticker) {
     try {
-      final coin = coinFromTickerCaseInsensitive(ticker);
+      final coin = SupportedCoins.getCryptoCurrencyForTicker(ticker);
       return ref
           .read(pWallets)
           .wallets
diff --git a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart
index f1ffa7fed..a30387f24 100644
--- a/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart
+++ b/lib/pages_desktop_specific/desktop_exchange/subwidgets/desktop_choose_from_stack.dart
@@ -17,8 +17,9 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
@@ -31,11 +32,11 @@ import 'package:tuple/tuple.dart';
 
 class DesktopChooseFromStack extends ConsumerStatefulWidget {
   const DesktopChooseFromStack({
-    Key? key,
+    super.key,
     required this.coin,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<DesktopChooseFromStack> createState() =>
@@ -282,9 +283,9 @@ class _DesktopChooseFromStackState
 
 class _BalanceDisplay extends ConsumerWidget {
   const _BalanceDisplay({
-    Key? key,
+    super.key,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   final String walletId;
 
@@ -292,7 +293,7 @@ class _BalanceDisplay extends ConsumerWidget {
   Widget build(BuildContext context, WidgetRef ref) {
     final coin = ref.watch(pWalletCoin(walletId));
     Amount total = ref.watch(pWalletBalance(walletId)).total;
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+    if (coin is Firo) {
       total += ref.watch(pWalletBalanceSecondary(walletId)).total;
       total += ref.watch(pWalletBalanceTertiary(walletId)).total;
     }
diff --git a/lib/pages_desktop_specific/my_stack_view/coin_wallets_table.dart b/lib/pages_desktop_specific/my_stack_view/coin_wallets_table.dart
index 94cdf75f8..8624eca28 100644
--- a/lib/pages_desktop_specific/my_stack_view/coin_wallets_table.dart
+++ b/lib/pages_desktop_specific/my_stack_view/coin_wallets_table.dart
@@ -15,20 +15,20 @@ import 'package:stackwallet/providers/global/active_wallet_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
 import 'package:stackwallet/widgets/rounded_container.dart';
 import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart';
 
 class CoinWalletsTable extends ConsumerWidget {
   const CoinWalletsTable({
-    Key? key,
+    super.key,
     required this.coin,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
@@ -57,7 +57,7 @@ class CoinWalletsTable extends ConsumerWidget {
           children: [
             for (int i = 0; i < walletIds.length; i++)
               Column(
-                key: Key("${coin.name}_$runtimeType${walletIds[i]}_key"),
+                key: Key("${coin.identifier}_$runtimeType${walletIds[i]}_key"),
                 children: [
                   if (i != 0)
                     const SizedBox(
diff --git a/lib/pages_desktop_specific/my_stack_view/paynym/desktop_paynym_send_dialog.dart b/lib/pages_desktop_specific/my_stack_view/paynym/desktop_paynym_send_dialog.dart
index b77135f96..9d9b8b802 100644
--- a/lib/pages_desktop_specific/my_stack_view/paynym/desktop_paynym_send_dialog.dart
+++ b/lib/pages_desktop_specific/my_stack_view/paynym/desktop_paynym_send_dialog.dart
@@ -25,7 +25,6 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart
index 3b3c6f32f..b7be2c2d4 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_summary_table.dart
@@ -15,12 +15,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/wallets_view/wallets_overview.dart';
 import 'package:stackwallet/providers/providers.dart';
-import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/all_wallets_info_provider.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
@@ -54,7 +53,7 @@ class _WalletTableState extends ConsumerState<WalletSummaryTable> {
             child: child,
           ),
           child: DesktopWalletSummaryRow(
-            key: Key("DesktopWalletSummaryRow_key_${coin.name}"),
+            key: Key("DesktopWalletSummaryRow_key_${coin.identifier}"),
             coin: coin,
             walletCount: walletsByCoin[index].wallets.length,
           ),
@@ -75,7 +74,7 @@ class DesktopWalletSummaryRow extends ConsumerStatefulWidget {
     required this.walletCount,
   });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final int walletCount;
 
   @override
@@ -91,8 +90,7 @@ class _DesktopWalletSummaryRowState
     // Check if Tor is enabled...
     if (ref.read(prefsChangeNotifierProvider).useTor) {
       // ... and if the coin supports Tor.
-      final cryptocurrency = SupportedCoins.getCryptoCurrencyFor(widget.coin);
-      if (!cryptocurrency.torSupport) {
+      if (!widget.coin.torSupport) {
         // If not, show a Tor warning dialog.
         final shouldContinue = await showDialog<bool>(
               context: context,
@@ -222,7 +220,7 @@ class _DesktopWalletSummaryRowState
 class TablePriceInfo extends ConsumerWidget {
   const TablePriceInfo({Key? key, required this.coin}) : super(key: key);
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
index ee10acb54..9f220ddca 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart
@@ -17,20 +17,20 @@ import 'package:stackwallet/providers/global/address_book_service_provider.dart'
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
 import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
 class AddressBookAddressChooser extends StatefulWidget {
   const AddressBookAddressChooser({
-    Key? key,
+    super.key,
     this.coin,
-  }) : super(key: key);
+  });
 
-  final Coin? coin;
+  final CryptoCurrency? coin;
 
   @override
   State<AddressBookAddressChooser> createState() =>
@@ -92,7 +92,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
     }
     for (int i = 0; i < contact.addresses.length; i++) {
       if (contact.addresses[i].label.toLowerCase().contains(text) ||
-          contact.addresses[i].coin.name.toLowerCase().contains(text) ||
+          contact.addresses[i].coin.identifier.toLowerCase().contains(text) ||
           contact.addresses[i].coin.prettyName.toLowerCase().contains(text) ||
           contact.addresses[i].coin.ticker.toLowerCase().contains(text) ||
           contact.addresses[i].address.toLowerCase().contains(text)) {
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
index 7d0be498e..5c6856a1f 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart
@@ -12,8 +12,8 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/address_book_card.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/expandable.dart';
@@ -22,13 +22,13 @@ import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_
 
 class ContactListItem extends ConsumerStatefulWidget {
   const ContactListItem({
-    Key? key,
+    super.key,
     required this.contactId,
     this.filterByCoin,
-  }) : super(key: key);
+  });
 
   final String contactId;
-  final Coin? filterByCoin;
+  final CryptoCurrency? filterByCoin;
 
   @override
   ConsumerState<ContactListItem> createState() => _ContactListItemState();
@@ -36,7 +36,7 @@ class ContactListItem extends ConsumerStatefulWidget {
 
 class _ContactListItemState extends ConsumerState<ContactListItem> {
   late final String contactId;
-  late final Coin? filterByCoin;
+  late final CryptoCurrency? filterByCoin;
 
   ExpandableState _state = ExpandableState.collapsed;
 
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
index aba28300b..561781cf6 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart
@@ -17,8 +17,8 @@ import 'package:stackwallet/providers/desktop/storage_crypto_handler_provider.da
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/loading_indicator.dart';
@@ -30,7 +30,7 @@ class DesktopAuthSend extends ConsumerStatefulWidget {
     required this.coin,
   });
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<DesktopAuthSend> createState() => _DesktopAuthSendState();
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart
index 255d64c63..f32f36a23 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_fee_dropdown.dart
@@ -23,9 +23,13 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
@@ -38,10 +42,10 @@ final tokenFeeSessionCacheProvider =
 
 class DesktopFeeDropDown extends ConsumerStatefulWidget {
   const DesktopFeeDropDown({
-    Key? key,
+    super.key,
     required this.walletId,
     this.isToken = false,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final bool isToken;
@@ -67,7 +71,7 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
     required Amount amount,
     required FeeRateType feeRateType,
     required int feeRate,
-    required Coin coin,
+    required CryptoCurrency coin,
   }) async {
     switch (feeRateType) {
       case FeeRateType.fast:
@@ -80,11 +84,11 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
           if (widget.isToken == false) {
             final wallet = ref.read(pWallets).getWallet(walletId);
 
-            if (coin == Coin.monero || coin == Coin.wownero) {
+            if (coin is Monero || coin is Wownero) {
               final fee = await wallet.estimateFeeFor(
                   amount, MoneroTransactionPriority.fast.raw!);
               ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
-            } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+            } else if (coin is Firo) {
               final Amount fee;
               switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
                 case FiroType.spark:
@@ -124,11 +128,11 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
           if (widget.isToken == false) {
             final wallet = ref.read(pWallets).getWallet(walletId);
 
-            if (coin == Coin.monero || coin == Coin.wownero) {
+            if (coin is Monero || coin is Wownero) {
               final fee = await wallet.estimateFeeFor(
                   amount, MoneroTransactionPriority.regular.raw!);
               ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
-            } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+            } else if (coin is Firo) {
               final Amount fee;
               switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
                 case FiroType.spark:
@@ -168,11 +172,11 @@ class _DesktopFeeDropDownState extends ConsumerState<DesktopFeeDropDown> {
           if (widget.isToken == false) {
             final wallet = ref.read(pWallets).getWallet(walletId);
 
-            if (coin == Coin.monero || coin == Coin.wownero) {
+            if (coin is Monero || coin is Wownero) {
               final fee = await wallet.estimateFeeFor(
                   amount, MoneroTransactionPriority.slow.raw!);
               ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
-            } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+            } else if (coin is Firo) {
               final Amount fee;
               switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
                 case FiroType.spark:
@@ -306,7 +310,7 @@ class FeeDropDownChild extends ConsumerWidget {
     required Amount amount,
     required FeeRateType feeRateType,
     required int feeRate,
-    required Coin coin,
+    required CryptoCurrency coin,
   }) feeFor;
   final bool isSelected;
 
@@ -390,10 +394,10 @@ class FeeDropDownChild extends ConsumerWidget {
                 ),
                 if (feeObject != null)
                   Text(
-                    coin == Coin.ethereum
+                    coin is Ethereum
                         ? ""
                         : estimatedTimeToBeIncludedInNextBlock(
-                            Constants.targetBlockTimeInSeconds(coin),
+                            coin.targetBlockTimeSeconds,
                             feeRateType == FeeRateType.fast
                                 ? feeObject!.numberOfBlocksFast
                                 : feeRateType == FeeRateType.slow
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
index 6250dfd8e..3f69ccaaf 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_receive.dart
@@ -28,9 +28,9 @@ import 'package:stackwallet/utilities/address_utils.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/multi_address_interface.dart';
@@ -45,11 +45,11 @@ import 'package:tuple/tuple.dart';
 
 class DesktopReceive extends ConsumerStatefulWidget {
   const DesktopReceive({
-    Key? key,
+    super.key,
     required this.walletId,
     this.contractAddress,
     this.clipboard = const ClipboardWrapper(),
-  }) : super(key: key);
+  });
 
   final String walletId;
   final String? contractAddress;
@@ -60,7 +60,7 @@ class DesktopReceive extends ConsumerStatefulWidget {
 }
 
 class _DesktopReceiveState extends ConsumerState<DesktopReceive> {
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final String walletId;
   late final ClipboardInterface clipboard;
   late final bool supportsSpark;
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
index 2614a58d4..d7ed9ceca 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart
@@ -41,13 +41,20 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
@@ -73,13 +80,13 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
 
 class DesktopSend extends ConsumerStatefulWidget {
   const DesktopSend({
-    Key? key,
+    super.key,
     required this.walletId,
     this.autoFillData,
     this.clipboard = const ClipboardWrapper(),
     this.barcodeScanner = const BarcodeScannerWrapper(),
     this.accountLite,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final SendViewAutoFillData? autoFillData;
@@ -93,7 +100,7 @@ class DesktopSend extends ConsumerStatefulWidget {
 
 class _DesktopSendState extends ConsumerState<DesktopSend> {
   late final String walletId;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final ClipboardInterface clipboard;
   late final BarcodeScannerInterface scanner;
 
@@ -141,7 +148,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
 
     final Amount amount = ref.read(pSendAmount)!;
     final Amount availableBalance;
-    if ((coin == Coin.firo || coin == Coin.firoTestNet)) {
+    if ((coin is Firo)) {
       switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
         case FiroType.public:
           availableBalance = wallet.info.cachedBalance.spendable;
@@ -447,7 +454,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           txData = txData.copyWith(
             note: _note ?? "",
           );
-          if (coin == Coin.epicCash) {
+          if (coin is Epiccash) {
             txData = txData.copyWith(
               noteOnChain: _onChainNote ?? "",
             );
@@ -658,7 +665,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         // autofill amount field
         if (results["amount"] != null) {
           final amount = Decimal.parse(results["amount"]!).toAmount(
-            fractionDigits: coin.decimals,
+            fractionDigits: coin.fractionDigits,
           );
           cryptoAmountController.text = ref
               .read(pAmountFormatter(coin))
@@ -721,7 +728,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         content = content.substring(0, content.indexOf("\n"));
       }
 
-      if (coin == Coin.epicCash) {
+      if (coin is Epiccash) {
         // strip http:// and https:// if content contains @
         content = formatAddress(content);
       }
@@ -764,13 +771,13 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           ref.read(priceAnd24hChangeNotifierProvider).getPrice(coin).item1;
 
       if (_price == Decimal.zero) {
-        amount = Decimal.zero.toAmount(fractionDigits: coin.decimals);
+        amount = Decimal.zero.toAmount(fractionDigits: coin.fractionDigits);
       } else {
         amount = baseAmount <= Amount.zero
-            ? Decimal.zero.toAmount(fractionDigits: coin.decimals)
+            ? Decimal.zero.toAmount(fractionDigits: coin.fractionDigits)
             : (baseAmount.decimal / _price)
-                .toDecimal(scaleOnInfinitePrecision: coin.decimals)
-                .toAmount(fractionDigits: coin.decimals);
+                .toDecimal(scaleOnInfinitePrecision: coin.fractionDigits)
+                .toAmount(fractionDigits: coin.fractionDigits);
       }
       if (_cachedAmountToSend != null && _cachedAmountToSend == amount) {
         return;
@@ -788,7 +795,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
       cryptoAmountController.text = amountString;
       _cryptoAmountChangeLock = false;
     } else {
-      amount = Decimal.zero.toAmount(fractionDigits: coin.decimals);
+      amount = Decimal.zero.toAmount(fractionDigits: coin.fractionDigits);
       _cryptoAmountChangeLock = true;
       cryptoAmountController.text = "";
       _cryptoAmountChangeLock = false;
@@ -804,26 +811,26 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
   Future<void> sendAllTapped() async {
     final info = ref.read(pWalletInfo(walletId));
 
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+    if (coin is Firo) {
       switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
         case FiroType.public:
           cryptoAmountController.text = info.cachedBalance.spendable.decimal
-              .toStringAsFixed(coin.decimals);
+              .toStringAsFixed(coin.fractionDigits);
           break;
         case FiroType.lelantus:
           cryptoAmountController.text = info
               .cachedBalanceSecondary.spendable.decimal
-              .toStringAsFixed(coin.decimals);
+              .toStringAsFixed(coin.fractionDigits);
           break;
         case FiroType.spark:
           cryptoAmountController.text = info
               .cachedBalanceTertiary.spendable.decimal
-              .toStringAsFixed(coin.decimals);
+              .toStringAsFixed(coin.fractionDigits);
           break;
       }
     } else {
-      cryptoAmountController.text =
-          info.cachedBalance.spendable.decimal.toStringAsFixed(coin.decimals);
+      cryptoAmountController.text = info.cachedBalance.spendable.decimal
+          .toStringAsFixed(coin.fractionDigits);
     }
   }
 
@@ -852,7 +859,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
     coin = ref.read(pWalletInfo(walletId)).coin;
     clipboard = widget.clipboard;
     scanner = widget.barcodeScanner;
-    isStellar = coin == Coin.stellar || coin == Coin.stellarTestnet;
+    isStellar = coin is Stellar;
 
     sendToController = TextEditingController();
     cryptoAmountController = TextEditingController();
@@ -927,7 +934,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
     );
 
     // add listener for epic cash to strip http:// and https:// prefixes if the address also ocntains an @ symbol (indicating an epicbox address)
-    if (coin == Coin.epicCash) {
+    if (coin is Epiccash) {
       sendToController.addListener(() {
         _address = sendToController.text;
 
@@ -955,7 +962,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
         const SizedBox(
           height: 4,
         ),
-        if (coin == Coin.firo || coin == Coin.firoTestNet)
+        if (coin is Firo)
           Text(
             "Send from",
             style: STextStyles.desktopTextExtraSmall(context).copyWith(
@@ -965,11 +972,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             ),
             textAlign: TextAlign.left,
           ),
-        if (coin == Coin.firo || coin == Coin.firoTestNet)
+        if (coin is Firo)
           const SizedBox(
             height: 10,
           ),
-        if (coin == Coin.firo || coin == Coin.firoTestNet)
+        if (coin is Firo)
           DropdownButtonHideUnderline(
             child: DropdownButton2(
               isExpanded: true,
@@ -1076,7 +1083,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
               ),
             ),
           ),
-        if (coin == Coin.firo || coin == Coin.firoTestNet)
+        if (coin is Firo)
           const SizedBox(
             height: 20,
           ),
@@ -1122,7 +1129,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
               ),
               textAlign: TextAlign.left,
             ),
-            if (coin != Coin.ethereum && coin != Coin.tezos)
+            if (coin is! Ethereum && coin is! Tezos)
               CustomTextButton(
                 text: "Send all ${coin.ticker}",
                 onTap: sendAllTapped,
@@ -1150,7 +1157,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           textAlign: TextAlign.right,
           inputFormatters: [
             AmountInputFormatter(
-              decimals: coin.decimals,
+              decimals: coin.fractionDigits,
               unit: ref.watch(pAmountUnit(coin)),
               locale: locale,
             ),
@@ -1455,13 +1462,13 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
 
               if (_address == null || _address!.isEmpty) {
                 error = null;
-              } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+              } else if (coin is Firo) {
                 if (ref.watch(publicPrivateBalanceStateProvider) ==
                     FiroType.lelantus) {
                   if (_data != null && _data!.contactLabel == _address) {
                     error = SparkInterface.validateSparkAddress(
                       address: _data!.address,
-                      isTestNet: coin.isTestNet,
+                      isTestNet: coin.network == CryptoCurrencyNetwork.test,
                     )
                         ? "Lelantus to Spark not supported"
                         : null;
@@ -1532,8 +1539,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
               Constants.size.circularBorderRadius,
             ),
             child: TextField(
-              maxLength:
-                  (coin == Coin.firo || coin == Coin.firoTestNet) ? 31 : null,
+              maxLength: (coin is Firo) ? 31 : null,
               minLines: 1,
               maxLines: 5,
               key: const Key("sendViewMemoFieldKey"),
@@ -1590,12 +1596,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
           const SizedBox(
             height: 20,
           ),
-        if (!([Coin.nano, Coin.banano, Coin.epicCash, Coin.tezos]
-            .contains(coin)))
+        if (coin is! NanoCurrency && coin is! Epiccash && coin is! Tezos)
           ConditionalParent(
             condition: ref.watch(pWallets).getWallet(walletId)
                     is ElectrumXInterface &&
-                !(((coin == Coin.firo || coin == Coin.firoTestNet) &&
+                !(((coin is Firo) &&
                     (ref.watch(publicPrivateBalanceStateProvider.state).state ==
                             FiroType.lelantus ||
                         ref
@@ -1638,7 +1643,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
             ),
             child: Text(
               "Transaction fee"
-              "${isCustomFee ? "" : " (${coin == Coin.ethereum ? "max" : "estimated"})"}",
+              "${isCustomFee ? "" : " (${coin is Ethereum ? "max" : "estimated"})"}",
               style: STextStyles.desktopTextExtraSmall(context).copyWith(
                 color: Theme.of(context)
                     .extension<StackColors>()!
@@ -1647,13 +1652,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
               textAlign: TextAlign.left,
             ),
           ),
-        if (!([Coin.nano, Coin.banano, Coin.epicCash, Coin.tezos]
-            .contains(coin)))
+        if (coin is! NanoCurrency && coin is! Epiccash && coin is! Tezos)
           const SizedBox(
             height: 10,
           ),
-        if (!([Coin.nano, Coin.banano, Coin.epicCash, Coin.tezos]
-            .contains(coin)))
+        if (coin is! NanoCurrency && coin is! Epiccash && coin is! Tezos)
           if (!isCustomFee)
             Padding(
               padding: const EdgeInsets.all(10),
@@ -1676,7 +1679,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                               required Amount amount,
                               required FeeRateType feeRateType,
                               required int feeRate,
-                              required Coin coin,
+                              required CryptoCurrency coin,
                             }) async {
                               if (ref
                                       .read(feeSheetSessionCacheProvider)
@@ -1685,8 +1688,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                                 final wallet =
                                     ref.read(pWallets).getWallet(walletId);
 
-                                if (coin == Coin.monero ||
-                                    coin == Coin.wownero) {
+                                if (coin is Monero || coin is Wownero) {
                                   final fee = await wallet.estimateFeeFor(
                                     amount,
                                     MoneroTransactionPriority.regular.raw!,
@@ -1694,8 +1696,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                                   ref
                                       .read(feeSheetSessionCacheProvider)
                                       .average[amount] = fee;
-                                } else if ((coin == Coin.firo ||
-                                        coin == Coin.firoTestNet) &&
+                                } else if ((coin is Firo) &&
                                     ref
                                             .read(
                                               publicPrivateBalanceStateProvider
@@ -1764,7 +1765,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                         }
                       },
                     )
-                  : (coin == Coin.firo || coin == Coin.firoTestNet) &&
+                  : (coin is Firo) &&
                           ref
                                   .watch(
                                     publicPrivateBalanceStateProvider.state,
@@ -1775,7 +1776,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
                           "~${ref.watch(pAmountFormatter(coin)).format(
                                 Amount(
                                   rawValue: BigInt.parse("3794"),
-                                  fractionDigits: coin.decimals,
+                                  fractionDigits: coin.fractionDigits,
                                 ),
                                 indicatePrecisionLoss: false,
                               )}",
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart
index eef67e694..b93850b0b 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart
@@ -33,11 +33,12 @@ import 'package:stackwallet/utilities/amount/amount_input_formatter.dart';
 import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
 import 'package:stackwallet/utilities/clipboard_interface.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/token_balance_provider.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
@@ -76,7 +77,7 @@ class DesktopTokenSend extends ConsumerStatefulWidget {
 
 class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
   late final String walletId;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final ClipboardInterface clipboard;
   late final BarcodeScannerInterface scanner;
 
@@ -224,7 +225,7 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
                 child: Padding(
                   padding: const EdgeInsets.all(32),
                   child: BuildingTransactionDialog(
-                    coin: tokenWallet.cryptoCurrency.coin,
+                    coin: tokenWallet.cryptoCurrency,
                     isSpark: false,
                     onCancel: () {
                       wasCancelled = true;
@@ -719,7 +720,7 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
         const SizedBox(
           height: 4,
         ),
-        if (coin == Coin.firo)
+        if (coin is Firo)
           Text(
             "Send from",
             style: STextStyles.desktopTextExtraSmall(context).copyWith(
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart
index d655879e8..3cef858d3 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart
@@ -34,9 +34,10 @@ import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/banano.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
 import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
@@ -50,9 +51,9 @@ import 'package:stackwallet/widgets/loading_indicator.dart';
 
 class DesktopWalletFeatures extends ConsumerStatefulWidget {
   const DesktopWalletFeatures({
-    Key? key,
+    super.key,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   final String walletId;
 
@@ -357,10 +358,9 @@ class _DesktopWalletFeaturesState extends ConsumerState<DesktopWalletFeatures> {
                 (value) => value.enableCoinControl,
               ),
             )) ||
-        coin == Coin.firo ||
-        coin == Coin.firoTestNet ||
+        coin is Firo ||
         // manager.hasWhirlpoolSupport ||
-        coin == Coin.banano ||
+        coin is Banano ||
         wallet is OrdinalsInterface ||
         wallet is CashFusionInterface;
 
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
index 77a5f0f5f..a52ee3d71 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart
@@ -20,9 +20,9 @@ import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/token_balance_provider.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
@@ -63,7 +63,7 @@ class _WDesktopWalletSummaryState extends ConsumerState<DesktopWalletSummary> {
       ),
     );
     final coin = ref.watch(pWalletCoin(widget.walletId));
-    final isFiro = coin == Coin.firo || coin == Coin.firoTestNet;
+    final isFiro = coin is Firo;
     final locale = ref.watch(
         localeServiceChangeNotifierProvider.select((value) => value.locale));
 
@@ -154,12 +154,11 @@ class _WDesktopWalletSummaryState extends ConsumerState<DesktopWalletSummary> {
                   ? ref.watch(pCurrentTokenWallet)!.tokenContract.address
                   : null,
             ),
-            if (coin == Coin.firo || coin == Coin.firoTestNet)
+            if (coin is Firo)
               const SizedBox(
                 width: 8,
               ),
-            if (coin == Coin.firo || coin == Coin.firoTestNet)
-              const DesktopPrivateBalanceToggleButton(),
+            if (coin is Firo) const DesktopPrivateBalanceToggleButton(),
             const SizedBox(
               width: 8,
             ),
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart
index 1eaccd885..70ce9e32b 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart
@@ -15,8 +15,9 @@ import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/banano.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart';
@@ -85,8 +86,7 @@ class _MoreFeaturesDialogState extends ConsumerState<MoreFeaturesDialog> {
               const DesktopDialogCloseButton(),
             ],
           ),
-          if (wallet.info.coin == Coin.firo ||
-              wallet.info.coin == Coin.firoTestNet)
+          if (wallet.info.coin is Firo)
             _MoreFeaturesItem(
               label: "Anonymize funds",
               detail: "Anonymize funds",
@@ -122,7 +122,7 @@ class _MoreFeaturesDialogState extends ConsumerState<MoreFeaturesDialog> {
               iconAsset: Assets.svg.ordinal,
               onPressed: () => widget.onOrdinalsPressed?.call(),
             ),
-          if (wallet.info.coin == Coin.banano)
+          if (wallet.info.coin is Banano)
             _MoreFeaturesItem(
               label: "MonKey",
               detail: "Generate Banano MonKey",
@@ -147,12 +147,12 @@ class _MoreFeaturesDialogState extends ConsumerState<MoreFeaturesDialog> {
 
 class _MoreFeaturesItem extends StatelessWidget {
   const _MoreFeaturesItem({
-    Key? key,
+    super.key,
     required this.label,
     required this.detail,
     required this.iconAsset,
     this.onPressed,
-  }) : super(key: key);
+  });
 
   static const double iconSizeBG = 46;
   static const double iconSize = 24;
@@ -209,7 +209,7 @@ class _MoreFeaturesItem extends StatelessWidget {
                   style: STextStyles.desktopTextExtraExtraSmall(context),
                 ),
               ],
-            )
+            ),
           ],
         ),
       ),
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/my_wallet.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/my_wallet.dart
index 63974518b..e7596dd2d 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/my_wallet.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/my_wallet.dart
@@ -18,7 +18,8 @@ import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub
 import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_send.dart';
 import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_token_send.dart';
 import 'package:stackwallet/providers/global/wallets_provider.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/wallet/impl/bitcoin_frost_wallet.dart';
 import 'package:stackwallet/widgets/custom_tab_view.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
@@ -46,7 +47,7 @@ class _MyWalletState extends ConsumerState<MyWallet> {
   ];
 
   late final bool isEth;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final bool isFrost;
 
   @override
@@ -54,7 +55,7 @@ class _MyWalletState extends ConsumerState<MyWallet> {
     final wallet = ref.read(pWallets).getWallet(widget.walletId);
     coin = wallet.info.coin;
     isFrost = wallet is BitcoinFrostWallet;
-    isEth = coin == Coin.ethereum;
+    isEth = coin is Ethereum;
 
     if (isEth && widget.contractAddress == null) {
       titles.add("Transactions");
diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart
index c27b7855d..916201c8f 100644
--- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart
+++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/wallet_options_button.dart
@@ -25,8 +25,10 @@ import 'package:stackwallet/route_generator.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/frost_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 
 enum _WalletOptions {
@@ -60,9 +62,9 @@ enum _WalletOptions {
 
 class WalletOptionsButton extends StatelessWidget {
   const WalletOptionsButton({
-    Key? key,
+    super.key,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   final String walletId;
 
@@ -250,7 +252,7 @@ class WalletOptionsButton extends StatelessWidget {
 
 class WalletOptionsPopupMenu extends ConsumerWidget {
   const WalletOptionsPopupMenu({
-    Key? key,
+    super.key,
     required this.onDeletePressed,
     required this.onAddressListPressed,
     required this.onShowXpubPressed,
@@ -259,7 +261,7 @@ class WalletOptionsPopupMenu extends ConsumerWidget {
     required this.onFiroShowSparkCoins,
     required this.onFrostMSWalletOptionsPressed,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   final VoidCallback onDeletePressed;
   final VoidCallback onAddressListPressed;
@@ -274,17 +276,15 @@ class WalletOptionsPopupMenu extends ConsumerWidget {
   Widget build(BuildContext context, WidgetRef ref) {
     final coin = ref.watch(pWalletCoin(walletId));
 
-    final firoDebug =
-        kDebugMode && (coin == Coin.firo || coin == Coin.firoTestNet);
+    final firoDebug = kDebugMode && (coin is Firo);
 
     // TODO: [prio=low]
     // final bool xpubEnabled = manager.hasXPub;
     final bool xpubEnabled = false;
 
-    final bool canChangeRep = coin == Coin.nano || coin == Coin.banano;
+    final bool canChangeRep = coin is NanoCurrency;
 
-    final bool isFrost =
-        coin == Coin.bitcoinFrost || coin == Coin.bitcoinFrostTestNet;
+    final bool isFrost = coin is FrostCurrency;
 
     return Stack(
       children: [
diff --git a/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart b/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart
index b258d0a5e..b4a4af07f 100644
--- a/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart
+++ b/lib/pages_desktop_specific/ordinals/desktop_ordinal_details_view.dart
@@ -18,7 +18,6 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
@@ -298,7 +297,7 @@ class _DesktopOrdinalDetailsViewState
                                     : ref.watch(pAmountFormatter(coin)).format(
                                           Amount(
                                             rawValue: BigInt.from(utxo!.value),
-                                            fractionDigits: coin.decimals,
+                                            fractionDigits: coin.fractionDigits,
                                           ),
                                         ),
                               );
diff --git a/lib/pages_desktop_specific/settings/settings_menu/advanced_settings/desktop_manage_block_explorers_dialog.dart b/lib/pages_desktop_specific/settings/settings_menu/advanced_settings/desktop_manage_block_explorers_dialog.dart
index 2fd6431c1..0d4d88328 100644
--- a/lib/pages_desktop_specific/settings/settings_menu/advanced_settings/desktop_manage_block_explorers_dialog.dart
+++ b/lib/pages_desktop_specific/settings/settings_menu/advanced_settings/desktop_manage_block_explorers_dialog.dart
@@ -14,13 +14,14 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/block_explorers.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
@@ -29,18 +30,22 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class DesktopManageBlockExplorersDialog extends ConsumerWidget {
   const DesktopManageBlockExplorersDialog({
-    Key? key,
-  }) : super(key: key);
+    super.key,
+  });
 
   @override
   Widget build(BuildContext context, WidgetRef ref) {
-    bool showTestNet = ref.watch(
+    final bool showTestNet = ref.watch(
       prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
     );
 
-    final List<Coin> coins = showTestNet
-        ? Coin.values
-        : Coin.values.where((e) => !e.isTestNet).toList();
+    final coins = showTestNet
+        ? SupportedCoins.cryptocurrencies
+        : SupportedCoins.cryptocurrencies
+            .where(
+              (e) => e.network == CryptoCurrencyNetwork.main,
+            )
+            .toList();
 
     return DesktopDialog(
       maxHeight: 850,
@@ -139,7 +144,7 @@ class _DesktopEditBlockExplorerDialog extends ConsumerStatefulWidget {
   const _DesktopEditBlockExplorerDialog({Key? key, required this.coin})
       : super(key: key);
 
-  final Coin coin;
+  final CryptoCurrency coin;
 
   @override
   ConsumerState<_DesktopEditBlockExplorerDialog> createState() =>
diff --git a/lib/pages_desktop_specific/settings/settings_menu/nodes_settings.dart b/lib/pages_desktop_specific/settings/settings_menu/nodes_settings.dart
index eec6e1a5f..53cc15f37 100644
--- a/lib/pages_desktop_specific/settings/settings_menu/nodes_settings.dart
+++ b/lib/pages_desktop_specific/settings/settings_menu/nodes_settings.dart
@@ -16,13 +16,17 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/coin_nodes_view.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/route_generator.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:stackwallet/widgets/stack_text_field.dart';
@@ -38,7 +42,7 @@ class NodesSettings extends ConsumerStatefulWidget {
 }
 
 class _NodesSettings extends ConsumerState<NodesSettings> {
-  List<Coin> _coins = [...Coin.values];
+  List<CryptoCurrency> _coins = [...SupportedCoins.cryptocurrencies];
 
   late final TextEditingController searchNodeController;
   late final FocusNode searchNodeFocusNode;
@@ -47,14 +51,14 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
 
   String filter = "";
 
-  List<Coin> _search(String filter, List<Coin> coins) {
+  List<CryptoCurrency> _search(String filter, List<CryptoCurrency> coins) {
     if (filter.isEmpty) {
       return coins;
     }
     return coins
         .where((coin) =>
             coin.prettyName.contains(filter) ||
-            coin.name.contains(filter) ||
+            coin.identifier.contains(filter) ||
             coin.ticker.toLowerCase().contains(filter.toLowerCase()))
         .toList();
   }
@@ -64,12 +68,15 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
   @override
   void initState() {
     _coins = _coins.toList();
-    _coins.remove(Coin.firoTestNet);
+    _coins.removeWhere(
+      (e) => e is Firo && e.network == CryptoCurrencyNetwork.test,
+    );
     if (Platform.isWindows) {
-      _coins.remove(Coin.monero);
-      _coins.remove(Coin.wownero);
+      _coins.removeWhere(
+        (e) => e is Monero && e is Wownero,
+      );
     } else if (Platform.isLinux) {
-      _coins.remove(Coin.wownero);
+      _coins.removeWhere((e) => e is Wownero);
     }
 
     searchNodeController = TextEditingController();
@@ -93,12 +100,17 @@ class _NodesSettings extends ConsumerState<NodesSettings> {
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
 
-    bool showTestNet = ref.watch(
+    final bool showTestNet = ref.watch(
       prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
     );
 
-    List<Coin> coins =
-        showTestNet ? _coins : _coins.where((e) => !e.isTestNet).toList();
+    List<CryptoCurrency> coins = showTestNet
+        ? _coins
+        : _coins
+            .where(
+              (e) => e.network == CryptoCurrencyNetwork.main,
+            )
+            .toList();
 
     coins = _search(filter, coins);
 
diff --git a/lib/providers/exchange/exchange_form_state_provider.dart b/lib/providers/exchange/exchange_form_state_provider.dart
index b4a923b78..b8ad1c2f9 100644
--- a/lib/providers/exchange/exchange_form_state_provider.dart
+++ b/lib/providers/exchange/exchange_form_state_provider.dart
@@ -18,8 +18,10 @@ import 'package:stackwallet/services/exchange/exchange.dart';
 import 'package:stackwallet/services/exchange/exchange_response.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_unit.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+
 import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/nano.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:tuple/tuple.dart';
 
 final efEstimatesListProvider = StateProvider.family<
@@ -56,8 +58,9 @@ final efSendAmountStringProvider = StateProvider<String>((ref) {
       string = AmountUnit.normal.displayAmount(
         amount: amount,
         locale: locale,
-        coin: Coin
-            .nano, // use nano just to ensure decimal.scale < Coin.value.decimals
+        coin: Nano(
+          CryptoCurrencyNetwork.main,
+        ), // use nano just to ensure decimal.scale < Coin.value.decimals
         withUnitName: false,
         maxDecimalPlaces: decimal.scale,
       );
@@ -81,8 +84,9 @@ final efReceiveAmountStringProvider = StateProvider<String>((ref) {
       string = AmountUnit.normal.displayAmount(
         amount: amount,
         locale: locale,
-        coin: Coin
-            .nano, // use nano just to ensure decimal.scale < Coin.value.decimals
+        coin: Nano(
+          CryptoCurrencyNetwork.main,
+        ), // use nano just to ensure decimal.scale < Coin.value.decimals
         withUnitName: false,
         maxDecimalPlaces: decimal.scale,
       );
diff --git a/lib/providers/exchange/exchange_send_from_wallet_id_provider.dart b/lib/providers/exchange/exchange_send_from_wallet_id_provider.dart
index b2fbec990..3a1c4c452 100644
--- a/lib/providers/exchange/exchange_send_from_wallet_id_provider.dart
+++ b/lib/providers/exchange/exchange_send_from_wallet_id_provider.dart
@@ -9,8 +9,8 @@
  */
 
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:tuple/tuple.dart';
 
 final exchangeSendFromWalletIdStateProvider =
-    StateProvider<Tuple2<String, Coin>?>((ref) => null);
+    StateProvider<Tuple2<String, CryptoCurrency>?>((ref) => null);
diff --git a/lib/providers/ui/preview_tx_button_state_provider.dart b/lib/providers/ui/preview_tx_button_state_provider.dart
index 768edf301..0c3b1061f 100644
--- a/lib/providers/ui/preview_tx_button_state_provider.dart
+++ b/lib/providers/ui/preview_tx_button_state_provider.dart
@@ -11,18 +11,18 @@
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/providers/wallet/public_private_balance_state_provider.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 final pSendAmount = StateProvider.autoDispose<Amount?>((_) => null);
 final pValidSendToAddress = StateProvider.autoDispose<bool>((_) => false);
 final pValidSparkSendToAddress = StateProvider.autoDispose<bool>((_) => false);
 
 final pPreviewTxButtonEnabled =
-    Provider.autoDispose.family<bool, Coin>((ref, coin) {
+    Provider.autoDispose.family<bool, CryptoCurrency>((ref, coin) {
   final amount = ref.watch(pSendAmount) ?? Amount.zero;
 
-  // TODO [prio=low]: move away from Coin
-  if (coin == Coin.firo || coin == Coin.firoTestNet) {
+  if (coin is Firo) {
     if (ref.watch(publicPrivateBalanceStateProvider) == FiroType.lelantus) {
       return ref.watch(pValidSendToAddress) &&
           !ref.watch(pValidSparkSendToAddress) &&
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 62bae2bbd..1e32c9969 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -188,7 +188,7 @@ import 'package:stackwallet/services/event_bus/events/global/node_connection_sta
 import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/frost_currency.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/wallet.dart';
@@ -211,21 +211,24 @@ class RouteGenerator {
     switch (settings.name) {
       case IntroView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const IntroView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const IntroView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DeleteAccountView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DeleteAccountView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DeleteAccountView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case HomeView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const HomeView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const HomeView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case CreatePinView.routeName:
         if (args is bool) {
@@ -240,9 +243,10 @@ class RouteGenerator {
           );
         }
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const CreatePinView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const CreatePinView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case StackPrivacyCalls.routeName:
         if (args is bool) {
@@ -253,9 +257,10 @@ class RouteGenerator {
           );
         }
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const StackPrivacyCalls(isSettings: false),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const StackPrivacyCalls(isSettings: false),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case ChooseCoinView.routeName:
         if (args is Tuple3<String, String, String>) {
@@ -274,7 +279,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case ManageExplorerView.routeName:
-        if (args is Coin) {
+        if (args is CryptoCurrency) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => ManageExplorerView(
@@ -303,15 +308,17 @@ class RouteGenerator {
 
       case WalletsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const WalletsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const WalletsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case AddWalletView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AddWalletView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AddWalletView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case EditWalletTokensView.routeName:
         if (args is String) {
@@ -376,7 +383,7 @@ class RouteGenerator {
         );
 
       case WalletsOverview.routeName:
-        if (args is Coin) {
+        if (args is CryptoCurrency) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => WalletsOverview(
@@ -556,7 +563,7 @@ class RouteGenerator {
       case FrostSendView.routeName:
         if (args is ({
           String walletId,
-          Coin coin,
+          CryptoCurrency coin,
         })) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
@@ -675,9 +682,10 @@ class RouteGenerator {
 
       case OrdinalsFilterView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const OrdinalsFilterView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const OrdinalsFilterView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case UtxoDetailsView.routeName:
         if (args is Tuple2<Id, String>) {
@@ -780,12 +788,13 @@ class RouteGenerator {
 
       case GlobalSettingsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const GlobalSettingsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const GlobalSettingsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case AddressBookView.routeName:
-        if (args is Coin) {
+        if (args is CryptoCurrency) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => AddressBookView(
@@ -797,87 +806,101 @@ class RouteGenerator {
           );
         }
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AddressBookView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AddressBookView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case AddressBookFilterView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AddressBookFilterView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AddressBookFilterView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case StackBackupView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const StackBackupView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const StackBackupView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case AutoBackupView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AutoBackupView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AutoBackupView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case EditAutoBackupView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const EditAutoBackupView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const EditAutoBackupView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case CreateAutoBackupView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const CreateAutoBackupView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const CreateAutoBackupView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case SecurityView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const SecurityView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const SecurityView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case ChangePinView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const ChangePinView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const ChangePinView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case BaseCurrencySettingsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const BaseCurrencySettingsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const BaseCurrencySettingsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case LanguageSettingsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const LanguageSettingsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const LanguageSettingsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case TorSettingsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const TorSettingsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const TorSettingsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case TorSettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const TorSettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const TorSettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case AboutView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AboutView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AboutView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DebugView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DebugView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DebugView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case XPubView.routeName:
         if (args is String) {
@@ -909,69 +932,80 @@ class RouteGenerator {
 
       case AppearanceSettingsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AppearanceSettingsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AppearanceSettingsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case SyncingPreferencesView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const SyncingPreferencesView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const SyncingPreferencesView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case StartupPreferencesView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const StartupPreferencesView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const StartupPreferencesView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case StartupWalletSelectionView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const StartupWalletSelectionView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const StartupWalletSelectionView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case ManageNodesView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const ManageNodesView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const ManageNodesView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case SyncingOptionsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const SyncingOptionsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const SyncingOptionsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case WalletSyncingOptionsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const WalletSyncingOptionsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const WalletSyncingOptionsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case AdvancedSettingsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AdvancedSettingsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AdvancedSettingsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case SupportView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const SupportView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const SupportView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case AddAddressBookEntryView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AddAddressBookEntryView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AddAddressBookEntryView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case RestoreFromFileView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const RestoreFromFileView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const RestoreFromFileView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case RestoreFromEncryptedStringView.routeName:
         if (args is String) {
@@ -989,12 +1023,13 @@ class RouteGenerator {
 
       case ManageCoinUnitsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const ManageCoinUnitsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const ManageCoinUnitsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case EditCoinUnitsView.routeName:
-        if (args is Coin) {
+        if (args is CryptoCurrency) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => EditCoinUnitsView(
@@ -1009,24 +1044,27 @@ class RouteGenerator {
 
       case CreateBackupInfoView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const CreateBackupInfoView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const CreateBackupInfoView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case CreateBackupView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const CreateBackupView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const CreateBackupView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case HiddenSettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: false,
-            builder: (_) => const HiddenSettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: false,
+          builder: (_) => const HiddenSettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case CoinNodesView.routeName:
-        if (args is Coin) {
+        if (args is CryptoCurrency) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => CoinNodesView(
@@ -1040,7 +1078,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case NodeDetailsView.routeName:
-        if (args is Tuple3<Coin, String, String>) {
+        if (args is Tuple3<CryptoCurrency, String, String>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => NodeDetailsView(
@@ -1100,7 +1138,8 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case AddEditNodeView.routeName:
-        if (args is Tuple4<AddEditNodeViewType, Coin, String?, String>) {
+        if (args
+            is Tuple4<AddEditNodeViewType, CryptoCurrency, String?, String>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => AddEditNodeView(
@@ -1291,7 +1330,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case NameYourWalletView.routeName:
-        if (args is Tuple2<AddWalletType, Coin>) {
+        if (args is Tuple2<AddWalletType, CryptoCurrency>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => NameYourWalletView(
@@ -1306,7 +1345,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case NewWalletRecoveryPhraseWarningView.routeName:
-        if (args is Tuple2<String, Coin>) {
+        if (args is Tuple2<String, CryptoCurrency>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => NewWalletRecoveryPhraseWarningView(
@@ -1321,7 +1360,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case RestoreOptionsView.routeName:
-        if (args is Tuple2<String, Coin>) {
+        if (args is Tuple2<String, CryptoCurrency>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => RestoreOptionsView(
@@ -1336,7 +1375,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case NewWalletOptionsView.routeName:
-        if (args is Tuple2<String, Coin>) {
+        if (args is Tuple2<String, CryptoCurrency>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => NewWalletOptionsView(
@@ -1351,15 +1390,16 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case RestoreWalletView.routeName:
-        if (args is Tuple5<String, Coin, int, DateTime, String>) {
+        if (args is Tuple5<String, CryptoCurrency, int, DateTime, String>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => RestoreWalletView(
-                walletName: args.item1,
-                coin: args.item2,
-                seedWordsLength: args.item3,
-                restoreFromDate: args.item4,
-                mnemonicPassphrase: args.item5),
+              walletName: args.item1,
+              coin: args.item2,
+              seedWordsLength: args.item3,
+              restoreFromDate: args.item4,
+              mnemonicPassphrase: args.item5,
+            ),
             settings: RouteSettings(
               name: settings.name,
             ),
@@ -1399,8 +1439,9 @@ class RouteGenerator {
 
       case ManageFavoritesView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const ManageFavoritesView());
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const ManageFavoritesView(),
+        );
 
       case WalletView.routeName:
         if (args is String) {
@@ -1417,7 +1458,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case TransactionDetailsView.routeName:
-        if (args is Tuple3<Transaction, Coin, String>) {
+        if (args is Tuple3<Transaction, CryptoCurrency, String>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => TransactionDetailsView(
@@ -1433,7 +1474,11 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case TransactionV2DetailsView.routeName:
-        if (args is ({TransactionV2 tx, Coin coin, String walletId})) {
+        if (args is ({
+          TransactionV2 tx,
+          CryptoCurrency coin,
+          String walletId
+        })) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => TransactionV2DetailsView(
@@ -1451,7 +1496,7 @@ class RouteGenerator {
       case FusionGroupDetailsView.routeName:
         if (args is ({
           List<TransactionV2> transactions,
-          Coin coin,
+          CryptoCurrency coin,
           String walletId
         })) {
           return getRoute(
@@ -1509,7 +1554,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case TransactionSearchFilterView.routeName:
-        if (args is Coin) {
+        if (args is CryptoCurrency) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => TransactionSearchFilterView(
@@ -1577,7 +1622,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case SendView.routeName:
-        if (args is Tuple2<String, Coin>) {
+        if (args is Tuple2<String, CryptoCurrency>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => SendView(
@@ -1588,7 +1633,8 @@ class RouteGenerator {
               name: settings.name,
             ),
           );
-        } else if (args is Tuple3<String, Coin, SendViewAutoFillData>) {
+        } else if (args
+            is Tuple3<String, CryptoCurrency, SendViewAutoFillData>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => SendView(
@@ -1600,7 +1646,7 @@ class RouteGenerator {
               name: settings.name,
             ),
           );
-        } else if (args is Tuple3<String, Coin, PaynymAccountLite>) {
+        } else if (args is Tuple3<String, CryptoCurrency, PaynymAccountLite>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => SendView(
@@ -1612,7 +1658,7 @@ class RouteGenerator {
               name: settings.name,
             ),
           );
-        } else if (args is ({Coin coin, String walletId})) {
+        } else if (args is ({CryptoCurrency coin, String walletId})) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => SendView(
@@ -1628,7 +1674,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case TokenSendView.routeName:
-        if (args is Tuple3<String, Coin, EthContract>) {
+        if (args is Tuple3<String, CryptoCurrency, EthContract>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => TokenSendView(
@@ -1660,7 +1706,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case WalletInitiatedExchangeView.routeName:
-        if (args is Tuple2<String, Coin>) {
+        if (args is Tuple2<String, CryptoCurrency>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => Stack(
@@ -1679,7 +1725,7 @@ class RouteGenerator {
             ),
           );
         }
-        if (args is Tuple3<String, Coin, EthContract?>) {
+        if (args is Tuple3<String, CryptoCurrency, EthContract?>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => Stack(
@@ -1716,8 +1762,8 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case WalletSettingsView.routeName:
-        if (args
-            is Tuple4<String, Coin, WalletSyncStatus, NodeConnectionStatus>) {
+        if (args is Tuple4<String, CryptoCurrency, WalletSyncStatus,
+            NodeConnectionStatus>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => WalletSettingsView(
@@ -1845,7 +1891,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case ChooseFromStackView.routeName:
-        if (args is Coin) {
+        if (args is CryptoCurrency) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => ChooseFromStackView(
@@ -1859,7 +1905,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case SendFromView.routeName:
-        if (args is Tuple4<Coin, Amount, String, Trade>) {
+        if (args is Tuple4<CryptoCurrency, Amount, String, Trade>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => SendFromView(
@@ -1876,7 +1922,7 @@ class RouteGenerator {
         return _routeError("${settings.name} invalid args: ${args.toString()}");
 
       case GenerateUriQrCodeView.routeName:
-        if (args is Tuple2<Coin, String>) {
+        if (args is Tuple2<CryptoCurrency, String>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => GenerateUriQrCodeView(
@@ -1918,21 +1964,24 @@ class RouteGenerator {
           );
         }
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const CreatePasswordView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const CreatePasswordView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case ForgotPasswordDesktopView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const ForgotPasswordDesktopView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const ForgotPasswordDesktopView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case ForgottenPassphraseRestoreFromSWB.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const ForgottenPassphraseRestoreFromSWB(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const ForgottenPassphraseRestoreFromSWB(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DeletePasswordWarningView.routeName:
         if (args is bool) {
@@ -1950,30 +1999,34 @@ class RouteGenerator {
 
       case DesktopHomeView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DesktopHomeView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DesktopHomeView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DesktopNotificationsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DesktopNotificationsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DesktopNotificationsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DesktopExchangeView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DesktopExchangeView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DesktopExchangeView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case BuyView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const BuyView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const BuyView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case BuyInWalletView.routeName:
-        if (args is Coin) {
+        if (args is CryptoCurrency) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => BuyInWalletView(coin: args),
@@ -1982,7 +2035,7 @@ class RouteGenerator {
             ),
           );
         }
-        if (args is Tuple2<Coin, EthContract?>) {
+        if (args is Tuple2<CryptoCurrency, EthContract?>) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => BuyInWalletView(
@@ -1998,27 +2051,31 @@ class RouteGenerator {
 
       case DesktopBuyView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DesktopBuyView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DesktopBuyView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DesktopAllTradesView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DesktopAllTradesView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DesktopAllTradesView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DesktopSettingsView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DesktopSettingsView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DesktopSettingsView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case MyStackView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const MyStackView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const MyStackView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DesktopWalletView.routeName:
         if (args is String) {
@@ -2092,75 +2149,87 @@ class RouteGenerator {
 
       case BackupRestoreSettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const BackupRestoreSettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const BackupRestoreSettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case SecuritySettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const SecuritySettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const SecuritySettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case CurrencySettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const CurrencySettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const CurrencySettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case LanguageOptionSettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const LanguageOptionSettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const LanguageOptionSettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case NodesSettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const NodesSettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const NodesSettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case SyncingPreferencesSettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const SyncingPreferencesSettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const SyncingPreferencesSettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case AppearanceOptionSettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AppearanceOptionSettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AppearanceOptionSettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case ManageThemesView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const ManageThemesView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const ManageThemesView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case AdvancedSettings.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const AdvancedSettings(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const AdvancedSettings(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DesktopSupportView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DesktopSupportView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DesktopSupportView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DesktopAboutView.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DesktopAboutView(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DesktopAboutView(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case DesktopAddressBook.routeName:
         return getRoute(
-            shouldUseMaterialRoute: useMaterialPageRoute,
-            builder: (_) => const DesktopAddressBook(),
-            settings: RouteSettings(name: settings.name));
+          shouldUseMaterialRoute: useMaterialPageRoute,
+          builder: (_) => const DesktopAddressBook(),
+          settings: RouteSettings(name: settings.name),
+        );
 
       case WalletKeysDesktopPopup.routeName:
         if (args is ({
@@ -2413,13 +2482,15 @@ class RouteGenerator {
       ),
       body: Center(
         child: Text(
-            'Error handling route, this is not supposed to happen. Try restarting the app.\n$message'),
+          'Error handling route, this is not supposed to happen. Try restarting the app.\n$message',
+        ),
       ),
     );
 
     return getRoute(
-        shouldUseMaterialRoute: useMaterialPageRoute,
-        builder: (_) => errorView);
+      shouldUseMaterialRoute: useMaterialPageRoute,
+      builder: (_) => errorView,
+    );
   }
 }
 
diff --git a/lib/services/address_book_service.dart b/lib/services/address_book_service.dart
index d925a3b0d..43bbc2ff7 100644
--- a/lib/services/address_book_service.dart
+++ b/lib/services/address_book_service.dart
@@ -12,11 +12,10 @@ import 'package:flutter/cupertino.dart';
 import 'package:flutter/foundation.dart';
 import 'package:stackwallet/db/isar/main_db.dart';
 import 'package:stackwallet/models/isar/models/contact_entry.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 class AddressBookService extends ChangeNotifier {
   ContactEntry getContactById(String id) {
-    ContactEntry? contactEntry = MainDB.instance.getContactEntry(id: id);
+    final ContactEntry? contactEntry = MainDB.instance.getContactEntry(id: id);
     if (contactEntry == null) {
       throw Exception('Contact ID "$id" not found!');
     } else {
@@ -30,7 +29,7 @@ class AddressBookService extends ChangeNotifier {
   //TODO search using isar queries
   Future<List<ContactEntry>> search(String text) async {
     if (text.isEmpty) return contacts;
-    var results = contacts.toList();
+    final results = contacts.toList();
 
     results.retainWhere((contact) => matches(text, contact));
 
@@ -47,7 +46,7 @@ class AddressBookService extends ChangeNotifier {
     }
     for (int i = 0; i < contact.addresses.length; i++) {
       if (contact.addresses[i].label.toLowerCase().contains(text) ||
-          contact.addresses[i].coin.name.toLowerCase().contains(text) ||
+          contact.addresses[i].coin.identifier.toLowerCase().contains(text) ||
           contact.addresses[i].coin.prettyName.toLowerCase().contains(text) ||
           contact.addresses[i].coin.ticker.toLowerCase().contains(text) ||
           contact.addresses[i].address.toLowerCase().contains(text)) {
diff --git a/lib/services/buy/simplex/simplex_api.dart b/lib/services/buy/simplex/simplex_api.dart
index 6ab2736e4..e0e00dd5d 100644
--- a/lib/services/buy/simplex/simplex_api.dart
+++ b/lib/services/buy/simplex/simplex_api.dart
@@ -19,7 +19,7 @@ import 'package:stackwallet/models/buy/response_objects/quote.dart';
 import 'package:stackwallet/networking/http.dart';
 import 'package:stackwallet/services/buy/buy_response.dart';
 import 'package:stackwallet/services/tor_service.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/enums/fiat_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
@@ -47,30 +47,34 @@ class SimplexAPI {
 
   Future<BuyResponse<List<Crypto>>> getSupportedCryptos() async {
     try {
-      Map<String, String> headers = {
+      final Map<String, String> headers = {
         'Content-Type': 'application/x-www-form-urlencoded',
       };
-      Map<String, String> data = {
+      final Map<String, String> data = {
         'ROUTE': 'supported_cryptos',
       };
-      Uri url = _buildUri('api.php', data);
+      final Uri url = _buildUri('api.php', data);
 
-      var res = await client.post(
+      final res = await client.post(
         url: url,
         headers: headers,
-        proxyInfo:
-            Prefs.instance.useTor ? TorService.sharedInstance.getProxyInfo() : null,
+        proxyInfo: Prefs.instance.useTor
+            ? TorService.sharedInstance.getProxyInfo()
+            : null,
       );
       if (res.code != 200) {
         throw Exception(
-            'getAvailableCurrencies exception: statusCode= ${res.code}');
+          'getAvailableCurrencies exception: statusCode= ${res.code}',
+        );
       }
       final jsonArray = jsonDecode(res.body); // TODO handle if invalid json
 
       return _parseSupportedCryptos(jsonArray);
     } catch (e, s) {
-      Logging.instance.log("getAvailableCurrencies exception: $e\n$s",
-          level: LogLevel.Error);
+      Logging.instance.log(
+        "getAvailableCurrencies exception: $e\n$s",
+        level: LogLevel.Error,
+      );
       return BuyResponse(
         exception: BuyException(
           e.toString(),
@@ -82,19 +86,20 @@ class SimplexAPI {
 
   BuyResponse<List<Crypto>> _parseSupportedCryptos(dynamic jsonArray) {
     try {
-      List<Crypto> cryptos = [];
-      List<Fiat> fiats = [];
+      final List<Crypto> cryptos = [];
 
       for (final crypto in jsonArray as List) {
         // TODO validate jsonArray
         if (isStackCoin("${crypto['ticker_symbol']}")) {
-          cryptos.add(Crypto.fromJson({
-            'ticker': "${crypto['ticker_symbol']}",
-            'name': crypto['name'],
-            'network': "${crypto['network']}",
-            'contractAddress': "${crypto['contractAddress']}",
-            'image': "",
-          }));
+          cryptos.add(
+            Crypto.fromJson({
+              'ticker': "${crypto['ticker_symbol']}",
+              'name': crypto['name'],
+              'network': "${crypto['network']}",
+              'contractAddress': "${crypto['contractAddress']}",
+              'image': "",
+            }),
+          );
         }
       }
 
@@ -113,30 +118,34 @@ class SimplexAPI {
 
   Future<BuyResponse<List<Fiat>>> getSupportedFiats() async {
     try {
-      Map<String, String> headers = {
+      final Map<String, String> headers = {
         'Content-Type': 'application/x-www-form-urlencoded',
       };
-      Map<String, String> data = {
+      final Map<String, String> data = {
         'ROUTE': 'supported_fiats',
       };
-      Uri url = _buildUri('api.php', data);
+      final Uri url = _buildUri('api.php', data);
 
-      var res = await client.post(
+      final res = await client.post(
         url: url,
         headers: headers,
-        proxyInfo:
-            Prefs.instance.useTor ? TorService.sharedInstance.getProxyInfo() : null,
+        proxyInfo: Prefs.instance.useTor
+            ? TorService.sharedInstance.getProxyInfo()
+            : null,
       );
       if (res.code != 200) {
         throw Exception(
-            'getAvailableCurrencies exception: statusCode= ${res.code}');
+          'getAvailableCurrencies exception: statusCode= ${res.code}',
+        );
       }
       final jsonArray = jsonDecode(res.body); // TODO validate json
 
       return _parseSupportedFiats(jsonArray);
     } catch (e, s) {
-      Logging.instance.log("getAvailableCurrencies exception: $e\n$s",
-          level: LogLevel.Error);
+      Logging.instance.log(
+        "getAvailableCurrencies exception: $e\n$s",
+        level: LogLevel.Error,
+      );
       return BuyResponse(
         exception: BuyException(
           e.toString(),
@@ -148,20 +157,22 @@ class SimplexAPI {
 
   BuyResponse<List<Fiat>> _parseSupportedFiats(dynamic jsonArray) {
     try {
-      List<Crypto> cryptos = [];
-      List<Fiat> fiats = [];
+      final List<Crypto> cryptos = [];
+      final List<Fiat> fiats = [];
 
       for (final fiat in jsonArray as List) {
         if (isSimplexFiat("${fiat['ticker_symbol']}")) {
           // TODO validate list
-          fiats.add(Fiat.fromJson({
-            'ticker': "${fiat['ticker_symbol']}",
-            'name': fiatFromTickerCaseInsensitive("${fiat['ticker_symbol']}")
-                .prettyName,
-            'minAmount': "${fiat['min_amount']}",
-            'maxAmount': "${fiat['max_amount']}",
-            'image': "",
-          }));
+          fiats.add(
+            Fiat.fromJson({
+              'ticker': "${fiat['ticker_symbol']}",
+              'name': fiatFromTickerCaseInsensitive("${fiat['ticker_symbol']}")
+                  .prettyName,
+              'minAmount': "${fiat['min_amount']}",
+              'maxAmount': "${fiat['max_amount']}",
+              'image': "",
+            }),
+          );
         } // TODO handle else
       }
 
@@ -181,12 +192,12 @@ class SimplexAPI {
   Future<BuyResponse<SimplexQuote>> getQuote(SimplexQuote quote) async {
     try {
       await _prefs.init();
-      String? userID = _prefs.userID;
+      final String? userID = _prefs.userID;
 
-      Map<String, String> headers = {
+      final Map<String, String> headers = {
         'Content-Type': 'application/x-www-form-urlencoded',
       };
-      Map<String, String> data = {
+      final Map<String, String> data = {
         'ROUTE': 'quote',
         'CRYPTO_TICKER': quote.crypto.ticker.toUpperCase(),
         'FIAT_TICKER': quote.fiat.ticker.toUpperCase(),
@@ -200,13 +211,14 @@ class SimplexAPI {
       if (userID != null) {
         data['USER_ID'] = userID;
       }
-      Uri url = _buildUri('api.php', data);
+      final Uri url = _buildUri('api.php', data);
 
-      var res = await client.get(
+      final res = await client.get(
         url: url,
         headers: headers,
-        proxyInfo:
-            Prefs.instance.useTor ? TorService.sharedInstance.getProxyInfo() : null,
+        proxyInfo: Prefs.instance.useTor
+            ? TorService.sharedInstance.getProxyInfo()
+            : null,
       );
       if (res.code != 200) {
         throw Exception('getQuote exception: statusCode= ${res.code}');
@@ -238,10 +250,11 @@ class SimplexAPI {
       // final Map<String, dynamic> lol =
       //     Map<String, dynamic>.from(jsonArray as Map);
 
-      double? cryptoAmount = jsonArray['digital_money']?['amount'] as double?;
+      final double? cryptoAmount =
+          jsonArray['digital_money']?['amount'] as double?;
 
       if (cryptoAmount == null) {
-        String error = jsonArray['error'] as String;
+        final String error = jsonArray['error'] as String;
         return BuyResponse(
           exception: BuyException(
             error,
@@ -250,7 +263,7 @@ class SimplexAPI {
         );
       }
 
-      SimplexQuote quote = jsonArray['quote'] as SimplexQuote;
+      final SimplexQuote quote = jsonArray['quote'] as SimplexQuote;
       final SimplexQuote _quote = SimplexQuote(
         crypto: quote.crypto,
         fiat: quote.fiat,
@@ -287,13 +300,13 @@ class SimplexAPI {
     //      -d '{"account_details": {"app_provider_id": "$publicKey", "app_version_id": "123", "app_end_user_id": "01e7a0b9-8dfc-4988-a28d-84a34e5f0a63", "signup_login": {"timestamp": "1994-11-05T08:15:30-05:00", "ip": "207.66.86.226"}}, "transaction_details": {"payment_details": {"quote_id": "3b58f4b4-ed6f-447c-b96a-ffe97d7b6803", "payment_id": "baaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", "order_id": "789", "original_http_ref_url": "https://stackwallet.com/simplex", "destination_wallet": {"currency": "BTC", "address": "bc1qjvj9ca8gdsv3g58yrzrk6jycvgnjh9uj35rja2"}}}}'
     try {
       await _prefs.init();
-      String? userID = _prefs.userID;
-      int? signupEpoch = _prefs.signupEpoch;
+      final String? userID = _prefs.userID;
+      final int? signupEpoch = _prefs.signupEpoch;
 
-      Map<String, String> headers = {
+      final Map<String, String> headers = {
         'Content-Type': 'application/x-www-form-urlencoded',
       };
-      Map<String, String> data = {
+      final Map<String, String> data = {
         'ROUTE': 'order',
         'QUOTE_ID': quote.id,
         'ADDRESS': quote.receivingAddress,
@@ -303,17 +316,19 @@ class SimplexAPI {
         data['USER_ID'] = userID;
       }
       if (signupEpoch != null && signupEpoch != 0) {
-        DateTime date = DateTime.fromMillisecondsSinceEpoch(signupEpoch * 1000);
+        final DateTime date =
+            DateTime.fromMillisecondsSinceEpoch(signupEpoch * 1000);
         data['SIGNUP_TIMESTAMP'] =
             date.toIso8601String() + timeZoneFormatter(date.timeZoneOffset);
       }
-      Uri url = _buildUri('api.php', data);
+      final Uri url = _buildUri('api.php', data);
 
-      var res = await client.get(
+      final res = await client.get(
         url: url,
         headers: headers,
-        proxyInfo:
-            Prefs.instance.useTor ? TorService.sharedInstance.getProxyInfo() : null,
+        proxyInfo: Prefs.instance.useTor
+            ? TorService.sharedInstance.getProxyInfo()
+            : null,
       );
       if (res.code != 200) {
         throw Exception('newOrder exception: statusCode= ${res.code}');
@@ -325,7 +340,7 @@ class SimplexAPI {
         }
       }
 
-      SimplexOrder _order = SimplexOrder(
+      final SimplexOrder _order = SimplexOrder(
         quote: quote,
         paymentId: "${jsonArray['paymentId']}",
         orderId: "${jsonArray['orderId']}",
@@ -346,16 +361,16 @@ class SimplexAPI {
 
   Future<BuyResponse<bool>> redirect(SimplexOrder order) async {
     try {
-      Map<String, String> headers = {
+      final Map<String, String> headers = {
         'Content-Type': 'application/x-www-form-urlencoded',
       };
-      Map<String, String> data = {
+      final Map<String, String> data = {
         'ROUTE': 'redirect',
         'PAYMENT_ID': order.paymentId,
       };
-      Uri url = _buildUri('api.php', data);
+      final Uri url = _buildUri('api.php', data);
 
-      bool status = await launchUrl(
+      final bool status = await launchUrl(
         url,
         mode: LaunchMode.externalApplication,
       );
@@ -364,10 +379,11 @@ class SimplexAPI {
     } catch (e, s) {
       Logging.instance.log("newOrder exception: $e\n$s", level: LogLevel.Error);
       return BuyResponse(
-          exception: BuyException(
-        e.toString(),
-        BuyExceptionType.generic,
-      ));
+        exception: BuyException(
+          e.toString(),
+          BuyExceptionType.generic,
+        ),
+      );
     }
   }
 
@@ -389,7 +405,7 @@ bool isStackCoin(String? ticker) {
   if (ticker == null) return false;
 
   try {
-    coinFromTickerCaseInsensitive(ticker);
+    SupportedCoins.getCryptoCurrencyForTicker(ticker);
     return true;
   } on ArgumentError catch (_) {
     return false;
diff --git a/lib/services/ethereum/ethereum_api.dart b/lib/services/ethereum/ethereum_api.dart
index b9ac2224b..8d1aec4ae 100644
--- a/lib/services/ethereum/ethereum_api.dart
+++ b/lib/services/ethereum/ethereum_api.dart
@@ -20,11 +20,12 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart';
 import 'package:stackwallet/networking/http.dart';
 import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
 import 'package:stackwallet/utilities/eth_commons.dart';
 import 'package:stackwallet/utilities/extensions/extensions.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:tuple/tuple.dart';
 
 class EthApiException implements Exception {
@@ -47,7 +48,8 @@ class EthereumResponse<T> {
 }
 
 abstract class EthereumAPI {
-  static String get stackBaseServer => DefaultNodes.ethereum.host;
+  static String get stackBaseServer =>
+      Ethereum(CryptoCurrencyNetwork.main).defaultNode.host;
 
   static HTTP client = HTTP();
 
diff --git a/lib/services/event_bus/events/global/node_connection_status_changed_event.dart b/lib/services/event_bus/events/global/node_connection_status_changed_event.dart
index 0361f3720..a0698409b 100644
--- a/lib/services/event_bus/events/global/node_connection_status_changed_event.dart
+++ b/lib/services/event_bus/events/global/node_connection_status_changed_event.dart
@@ -8,19 +8,20 @@
  *
  */
 
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 enum NodeConnectionStatus { disconnected, connected }
 
 class NodeConnectionStatusChangedEvent {
   NodeConnectionStatus newStatus;
   String walletId;
-  Coin coin;
+  CryptoCurrency coin;
 
   NodeConnectionStatusChangedEvent(this.newStatus, this.walletId, this.coin) {
     Logging.instance.log(
-        "NodeConnectionStatusChangedEvent fired in $walletId with arg newStatus = $newStatus",
-        level: LogLevel.Info);
+      "NodeConnectionStatusChangedEvent fired in $walletId with arg newStatus = $newStatus",
+      level: LogLevel.Info,
+    );
   }
 }
diff --git a/lib/services/event_bus/events/global/wallet_sync_status_changed_event.dart b/lib/services/event_bus/events/global/wallet_sync_status_changed_event.dart
index fb2a47614..4cb616909 100644
--- a/lib/services/event_bus/events/global/wallet_sync_status_changed_event.dart
+++ b/lib/services/event_bus/events/global/wallet_sync_status_changed_event.dart
@@ -8,19 +8,20 @@
  *
  */
 
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 enum WalletSyncStatus { unableToSync, synced, syncing }
 
 class WalletSyncStatusChangedEvent {
   WalletSyncStatus newStatus;
   String walletId;
-  Coin coin;
+  CryptoCurrency coin;
 
   WalletSyncStatusChangedEvent(this.newStatus, this.walletId, this.coin) {
     Logging.instance.log(
-        "WalletSyncStatusChangedEvent fired in $walletId with arg newStatus = $newStatus",
-        level: LogLevel.Info);
+      "WalletSyncStatusChangedEvent fired in $walletId with arg newStatus = $newStatus",
+      level: LogLevel.Info,
+    );
   }
 }
diff --git a/lib/services/node_service.dart b/lib/services/node_service.dart
index 88d032940..31e624be5 100644
--- a/lib/services/node_service.dart
+++ b/lib/services/node_service.dart
@@ -14,10 +14,11 @@ import 'package:flutter/material.dart';
 import 'package:http/http.dart';
 import 'package:stackwallet/db/hive/db.dart';
 import 'package:stackwallet/models/node_model.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 const kStackCommunityNodesEndpoint = "https://extras.stackwallet.com";
 
@@ -30,12 +31,18 @@ class NodeService extends ChangeNotifier {
   });
 
   Future<void> updateDefaults() async {
-    for (final defaultNode in DefaultNodes.all) {
+    for (final defaultNode in SupportedCoins.cryptocurrencies.map(
+      (e) => e.defaultNode,
+    )) {
       final savedNode = DB.instance
           .get<NodeModel>(boxName: DB.boxNameNodeModels, key: defaultNode.id);
       if (savedNode == null) {
         // save the default node to hive only if no other nodes for the specific coin exist
-        if (getNodesFor(coinFromPrettyName(defaultNode.coinName)).isEmpty) {
+        if (getNodesFor(
+          SupportedCoins.getCryptoCurrencyByPrettyName(
+            defaultNode.coinName,
+          ),
+        ).isEmpty) {
           await DB.instance.put<NodeModel>(
             boxName: DB.boxNameNodeModels,
             key: defaultNode.id,
@@ -45,19 +52,21 @@ class NodeService extends ChangeNotifier {
       } else {
         // update all fields but copy over previously set enabled and trusted states
         await DB.instance.put<NodeModel>(
-            boxName: DB.boxNameNodeModels,
-            key: savedNode.id,
-            value: defaultNode.copyWith(
-              enabled: savedNode.enabled,
-              isFailover: savedNode.isFailover,
-              trusted: savedNode.trusted,
-            ));
+          boxName: DB.boxNameNodeModels,
+          key: savedNode.id,
+          value: defaultNode.copyWith(
+            enabled: savedNode.enabled,
+            isFailover: savedNode.isFailover,
+            trusted: savedNode.trusted,
+          ),
+        );
       }
 
       // check if a default node is the primary node for the crypto currency
       // and update it if needed
-      final coin = coinFromPrettyName(defaultNode.coinName);
-      final primaryNode = getPrimaryNodeFor(coin: coin);
+      final coin =
+          SupportedCoins.getCryptoCurrencyByPrettyName(defaultNode.coinName);
+      final primaryNode = getPrimaryNodeFor(currency: coin);
       if (primaryNode != null && primaryNode.id == defaultNode.id) {
         await setPrimaryNodeFor(
           coin: coin,
@@ -72,20 +81,25 @@ class NodeService extends ChangeNotifier {
   }
 
   Future<void> setPrimaryNodeFor({
-    required Coin coin,
+    required CryptoCurrency coin,
     required NodeModel node,
     bool shouldNotifyListeners = false,
   }) async {
     await DB.instance.put<NodeModel>(
-        boxName: DB.boxNamePrimaryNodes, key: coin.name, value: node);
+      boxName: DB.boxNamePrimaryNodes,
+      key: coin.identifier,
+      value: node,
+    );
     if (shouldNotifyListeners) {
       notifyListeners();
     }
   }
 
-  NodeModel? getPrimaryNodeFor({required Coin coin}) {
-    return DB.instance
-        .get<NodeModel>(boxName: DB.boxNamePrimaryNodes, key: coin.name);
+  NodeModel? getPrimaryNodeFor({required CryptoCurrency currency}) {
+    return DB.instance.get<NodeModel>(
+      boxName: DB.boxNamePrimaryNodes,
+      key: currency.identifier,
+    );
   }
 
   List<NodeModel> get primaryNodes {
@@ -96,21 +110,27 @@ class NodeService extends ChangeNotifier {
     return DB.instance.values<NodeModel>(boxName: DB.boxNameNodeModels);
   }
 
-  List<NodeModel> getNodesFor(Coin coin) {
+  List<NodeModel> getNodesFor(CryptoCurrency coin) {
     final list = DB.instance
         .values<NodeModel>(boxName: DB.boxNameNodeModels)
-        .where((e) =>
-            e.coinName == coin.name &&
-            !e.id.startsWith(DefaultNodes.defaultNodeIdPrefix))
+        .where(
+          (e) =>
+              e.coinName == coin.identifier &&
+              !e.id.startsWith(DefaultNodes.defaultNodeIdPrefix),
+        )
         .toList();
 
     // add default to end of list
-    list.addAll(DB.instance
-        .values<NodeModel>(boxName: DB.boxNameNodeModels)
-        .where((e) =>
-            e.coinName == coin.name &&
-            e.id.startsWith(DefaultNodes.defaultNodeIdPrefix))
-        .toList());
+    list.addAll(
+      DB.instance
+          .values<NodeModel>(boxName: DB.boxNameNodeModels)
+          .where(
+            (e) =>
+                e.coinName == coin.identifier &&
+                e.id.startsWith(DefaultNodes.defaultNodeIdPrefix),
+          )
+          .toList(),
+    );
 
     // return reversed list so default node appears at beginning
     return list.reversed.toList();
@@ -120,8 +140,10 @@ class NodeService extends ChangeNotifier {
     return DB.instance.get<NodeModel>(boxName: DB.boxNameNodeModels, key: id);
   }
 
-  List<NodeModel> failoverNodesFor({required Coin coin}) {
-    return getNodesFor(coin).where((e) => e.isFailover && !e.isDown).toList();
+  List<NodeModel> failoverNodesFor({required CryptoCurrency currency}) {
+    return getNodesFor(currency)
+        .where((e) => e.isFailover && !e.isDown)
+        .toList();
   }
 
   // should probably just combine this and edit into a save() func at some point
@@ -133,11 +155,16 @@ class NodeService extends ChangeNotifier {
     bool shouldNotifyListeners,
   ) async {
     await DB.instance.put<NodeModel>(
-        boxName: DB.boxNameNodeModels, key: node.id, value: node);
+      boxName: DB.boxNameNodeModels,
+      key: node.id,
+      value: node,
+    );
 
     if (password != null) {
       await secureStorageInterface.write(
-          key: "${node.id}_nodePW", value: password);
+        key: "${node.id}_nodePW",
+        value: password,
+      );
     }
     if (shouldNotifyListeners) {
       notifyListeners();
@@ -163,9 +190,10 @@ class NodeService extends ChangeNotifier {
       key: id,
     )!;
     await DB.instance.put<NodeModel>(
-        boxName: DB.boxNameNodeModels,
-        key: model.id,
-        value: model.copyWith(enabled: enabled));
+      boxName: DB.boxNameNodeModels,
+      key: model.id,
+      value: model.copyWith(enabled: enabled),
+    );
     if (shouldNotifyListeners) {
       notifyListeners();
     }
@@ -178,8 +206,9 @@ class NodeService extends ChangeNotifier {
     bool shouldNotifyListeners,
   ) async {
     // check if the node being edited is the primary one; if it is, setPrimaryNodeFor coin
-    final coin = coinFromPrettyName(editedNode.coinName);
-    var primaryNode = getPrimaryNodeFor(coin: coin);
+    final coin =
+        SupportedCoins.getCryptoCurrencyByPrettyName(editedNode.coinName);
+    final primaryNode = getPrimaryNodeFor(currency: coin);
     if (primaryNode?.id == editedNode.id) {
       await setPrimaryNodeFor(
         coin: coin,
@@ -211,9 +240,10 @@ class NodeService extends ChangeNotifier {
       final map = jsonDecode(result as String);
       Logging.instance.log(map, level: LogLevel.Info);
 
-      for (final coin in Coin.values) {
+      for (final coin in SupportedCoins.cryptocurrencies) {
         final nodeList = List<Map<String, dynamic>>.from(
-            map["nodes"][coin.name] as List? ?? []);
+          map["nodes"][coin.identifier] as List? ?? [],
+        );
         for (final nodeMap in nodeList) {
           NodeModel node = NodeModel(
             host: nodeMap["host"] as String,
@@ -222,7 +252,7 @@ class NodeService extends ChangeNotifier {
             id: nodeMap["id"] as String,
             useSSL: nodeMap["useSSL"] == "true",
             enabled: true,
-            coinName: coin.name,
+            coinName: coin.identifier,
             isFailover: true,
             isDown: nodeMap["isDown"] == "true",
           );
diff --git a/lib/services/notifications_service.dart b/lib/services/notifications_service.dart
index 182de8747..528fe9ae5 100644
--- a/lib/services/notifications_service.dart
+++ b/lib/services/notifications_service.dart
@@ -21,9 +21,10 @@ import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/services/notifications_api.dart';
 import 'package:stackwallet/services/trade_service.dart';
 import 'package:stackwallet/services/wallets.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
 import 'exchange/exchange.dart';
@@ -55,15 +56,19 @@ class NotificationsService extends ChangeNotifier {
 
   Future<void> _addWatchedTxNotification(NotificationModel notification) async {
     await DB.instance.put<NotificationModel>(
-        boxName: DB.boxNameWatchedTransactions,
-        key: notification.id,
-        value: notification);
+      boxName: DB.boxNameWatchedTransactions,
+      key: notification.id,
+      value: notification,
+    );
   }
 
   Future<void> _deleteWatchedTxNotification(
-      NotificationModel notification) async {
+    NotificationModel notification,
+  ) async {
     await DB.instance.delete<NotificationModel>(
-        boxName: DB.boxNameWatchedTransactions, key: notification.id);
+      boxName: DB.boxNameWatchedTransactions,
+      key: notification.id,
+    );
   }
 
   // watched trades
@@ -73,17 +78,22 @@ class NotificationsService extends ChangeNotifier {
   }
 
   Future<void> _addWatchedTradeNotification(
-      NotificationModel notification) async {
+    NotificationModel notification,
+  ) async {
     await DB.instance.put<NotificationModel>(
-        boxName: DB.boxNameWatchedTrades,
-        key: notification.id,
-        value: notification);
+      boxName: DB.boxNameWatchedTrades,
+      key: notification.id,
+      value: notification,
+    );
   }
 
   Future<void> _deleteWatchedTradeNotification(
-      NotificationModel notification) async {
+    NotificationModel notification,
+  ) async {
     await DB.instance.delete<NotificationModel>(
-        boxName: DB.boxNameWatchedTrades, key: notification.id);
+      boxName: DB.boxNameWatchedTrades,
+      key: notification.id,
+    );
   }
 
   static Timer? _timer;
@@ -118,11 +128,12 @@ class NotificationsService extends ChangeNotifier {
   void _checkTransactions() async {
     for (final notification in _watchedTransactionNotifications) {
       try {
-        final Coin coin = coinFromPrettyName(notification.coinName);
+        final CryptoCurrency coin =
+            SupportedCoins.getCryptoCurrencyByPrettyName(notification.coinName);
         final txid = notification.txid!;
         final wallet = Wallets.sharedInstance.getWallet(notification.walletId);
 
-        final node = nodeService.getPrimaryNodeFor(coin: coin);
+        final node = nodeService.getPrimaryNodeFor(currency: coin);
         if (node != null) {
           if (wallet is ElectrumXInterface) {
             final eNode = ElectrumXNode(
@@ -133,14 +144,16 @@ class NotificationsService extends ChangeNotifier {
               useSSL: node.useSSL,
             );
             final failovers = nodeService
-                .failoverNodesFor(coin: coin)
-                .map((e) => ElectrumXNode(
-                      address: e.host,
-                      port: e.port,
-                      name: e.name,
-                      id: e.id,
-                      useSSL: e.useSSL,
-                    ))
+                .failoverNodesFor(currency: coin)
+                .map(
+                  (e) => ElectrumXNode(
+                    address: e.host,
+                    port: e.port,
+                    name: e.name,
+                    id: e.id,
+                    useSSL: e.useSSL,
+                  ),
+                )
                 .toList();
 
             final client = ElectrumXClient.from(
@@ -280,7 +293,8 @@ class NotificationsService extends ChangeNotifier {
     return DB.instance
         .values<NotificationModel>(boxName: DB.boxNameNotifications)
         .where(
-            (element) => element.read == false && element.walletId == walletId)
+          (element) => element.read == false && element.walletId == walletId,
+        )
         .isNotEmpty;
   }
 
@@ -320,7 +334,9 @@ class NotificationsService extends ChangeNotifier {
     bool shouldNotifyListeners,
   ) async {
     await DB.instance.delete<NotificationModel>(
-        boxName: DB.boxNameNotifications, key: notification.id);
+      boxName: DB.boxNameNotifications,
+      key: notification.id,
+    );
 
     await _deleteWatchedTradeNotification(notification);
     await _deleteWatchedTxNotification(notification);
diff --git a/lib/services/price.dart b/lib/services/price.dart
index 281372dcd..e572f4b3f 100644
--- a/lib/services/price.dart
+++ b/lib/services/price.dart
@@ -16,9 +16,10 @@ import 'package:flutter/foundation.dart';
 import 'package:stackwallet/db/hive/db.dart';
 import 'package:stackwallet/networking/http.dart';
 import 'package:stackwallet/services/tor_service.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:tuple/tuple.dart';
 
 class PriceAPI {
@@ -43,10 +44,11 @@ class PriceAPI {
   }
 
   Future<void> _updateCachedPrices(
-      Map<Coin, Tuple2<Decimal, double>> data) async {
+    Map<CryptoCurrency, Tuple2<Decimal, double>> data,
+  ) async {
     final Map<String, dynamic> map = {};
 
-    for (final coin in Coin.values) {
+    for (final coin in SupportedCoins.cryptocurrencies) {
       final entry = data[coin];
       if (entry == null) {
         map[coin.prettyName] = ["0", 0.0];
@@ -59,26 +61,32 @@ class PriceAPI {
         .put<dynamic>(boxName: DB.boxNamePriceCache, key: 'cache', value: map);
   }
 
-  Map<Coin, Tuple2<Decimal, double>> get _cachedPrices {
+  Map<CryptoCurrency, Tuple2<Decimal, double>> get _cachedPrices {
     final map =
         DB.instance.get<dynamic>(boxName: DB.boxNamePriceCache, key: 'cache')
                 as Map? ??
             {};
     // init with 0
     final result = {
-      for (final coin in Coin.values) coin: Tuple2(Decimal.zero, 0.0)
+      for (final coin in SupportedCoins.cryptocurrencies)
+        coin: Tuple2(Decimal.zero, 0.0),
     };
 
     for (final entry in map.entries) {
-      result[coinFromPrettyName(entry.key as String)] = Tuple2(
-          Decimal.parse(entry.value[0] as String), entry.value[1] as double);
+      result[SupportedCoins.getCryptoCurrencyByPrettyName(
+        entry.key as String,
+      )] = Tuple2(
+        Decimal.parse(entry.value[0] as String),
+        entry.value[1] as double,
+      );
     }
 
     return result;
   }
 
-  Future<Map<Coin, Tuple2<Decimal, double>>> getPricesAnd24hChange(
-      {required String baseCurrency}) async {
+  Future<Map<CryptoCurrency, Tuple2<Decimal, double>>> getPricesAnd24hChange({
+    required String baseCurrency,
+  }) async {
     final now = DateTime.now();
     if (_lastUsedBaseCurrency != baseCurrency ||
         now.difference(_lastCalled) > refreshIntervalDuration) {
@@ -91,11 +99,13 @@ class PriceAPI {
     final externalCalls = Prefs.instance.externalCalls;
     if ((!Logger.isTestEnv && !externalCalls) ||
         !(await Prefs.instance.isExternalCallsSet())) {
-      Logging.instance.log("User does not want to use external calls",
-          level: LogLevel.Info);
+      Logging.instance.log(
+        "User does not want to use external calls",
+        level: LogLevel.Info,
+      );
       return _cachedPrices;
     }
-    Map<Coin, Tuple2<Decimal, double>> result = {};
+    final Map<CryptoCurrency, Tuple2<Decimal, double>> result = {};
     try {
       final uri = Uri.parse(
           "https://api.coingecko.com/api/v3/coins/markets?vs_currency"
@@ -116,7 +126,7 @@ class PriceAPI {
 
       for (final map in coinGeckoData) {
         final String coinName = map["name"] as String;
-        final coin = coinFromPrettyName(coinName);
+        final coin = SupportedCoins.getCryptoCurrencyByPrettyName(coinName);
 
         final price = Decimal.parse(map["current_price"].toString());
         final change24h = map["price_change_percentage_24h"] != null
@@ -131,8 +141,10 @@ class PriceAPI {
 
       return _cachedPrices;
     } catch (e, s) {
-      Logging.instance.log("getPricesAnd24hChange($baseCurrency): $e\n$s",
-          level: LogLevel.Error);
+      Logging.instance.log(
+        "getPricesAnd24hChange($baseCurrency): $e\n$s",
+        level: LogLevel.Error,
+      );
       // return previous cached values
       return _cachedPrices;
     }
@@ -140,12 +152,14 @@ class PriceAPI {
 
   static Future<List<String>?> availableBaseCurrencies() async {
     final externalCalls = Prefs.instance.externalCalls;
-    HTTP client = HTTP();
+    final HTTP client = HTTP();
 
     if ((!Logger.isTestEnv && !externalCalls) ||
         !(await Prefs.instance.isExternalCallsSet())) {
-      Logging.instance.log("User does not want to use external calls",
-          level: LogLevel.Info);
+      Logging.instance.log(
+        "User does not want to use external calls",
+        level: LogLevel.Info,
+      );
       return null;
     }
     const uriString =
@@ -163,8 +177,10 @@ class PriceAPI {
       final json = jsonDecode(response.body) as List<dynamic>;
       return List<String>.from(json);
     } catch (e, s) {
-      Logging.instance.log("availableBaseCurrencies() using $uriString: $e\n$s",
-          level: LogLevel.Error);
+      Logging.instance.log(
+        "availableBaseCurrencies() using $uriString: $e\n$s",
+        level: LogLevel.Error,
+      );
       return null;
     }
   }
@@ -181,8 +197,10 @@ class PriceAPI {
     final externalCalls = Prefs.instance.externalCalls;
     if ((!Logger.isTestEnv && !externalCalls) ||
         !(await Prefs.instance.isExternalCallsSet())) {
-      Logging.instance.log("User does not want to use external calls",
-          level: LogLevel.Info);
+      Logging.instance.log(
+        "User does not want to use external calls",
+        level: LogLevel.Info,
+      );
       return tokenPrices;
     }
 
diff --git a/lib/services/price_service.dart b/lib/services/price_service.dart
index 561aa184c..15e5dc437 100644
--- a/lib/services/price_service.dart
+++ b/lib/services/price_service.dart
@@ -17,7 +17,8 @@ import 'package:stackwallet/db/isar/main_db.dart';
 import 'package:stackwallet/models/isar/models/isar_models.dart';
 import 'package:stackwallet/networking/http.dart';
 import 'package:stackwallet/services/price.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:tuple/tuple.dart';
 
 class PriceService extends ChangeNotifier {
@@ -28,15 +29,16 @@ class PriceService extends ChangeNotifier {
   final Duration updateInterval = const Duration(seconds: 60);
 
   Timer? _timer;
-  final Map<Coin, Tuple2<Decimal, double>> _cachedPrices = {
-    for (final coin in Coin.values) coin: Tuple2(Decimal.zero, 0.0)
+  final Map<CryptoCurrency, Tuple2<Decimal, double>> _cachedPrices = {
+    for (final coin in SupportedCoins.cryptocurrencies)
+      coin: Tuple2(Decimal.zero, 0.0)
   };
 
   final Map<String, Tuple2<Decimal, double>> _cachedTokenPrices = {};
 
   final _priceAPI = PriceAPI(HTTP());
 
-  Tuple2<Decimal, double> getPrice(Coin coin) => _cachedPrices[coin]!;
+  Tuple2<Decimal, double> getPrice(CryptoCurrency coin) => _cachedPrices[coin]!;
 
   Tuple2<Decimal, double> getTokenPrice(String contractAddress) =>
       _cachedTokenPrices[contractAddress.toLowerCase()] ??
diff --git a/lib/services/wallets.dart b/lib/services/wallets.dart
index bba7bfe90..22daf7716 100644
--- a/lib/services/wallets.dart
+++ b/lib/services/wallets.dart
@@ -18,11 +18,11 @@ import 'package:stackwallet/db/isar/main_db.dart';
 import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/services/notifications_service.dart';
 import 'package:stackwallet/services/trade_sent_from_stack_service.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet.dart';
@@ -79,19 +79,19 @@ class Wallets {
         key: Wallet.mnemonicPassphraseKey(walletId: walletId));
     await secureStorage.delete(key: Wallet.privateKeyKey(walletId: walletId));
 
-    if (info.coin == Coin.wownero) {
+    if (info.coin is Wownero) {
       final wowService =
           wownero.createWowneroWalletService(DB.instance.moneroWalletInfoBox);
       await wowService.remove(walletId);
       Logging.instance
           .log("monero wallet: $walletId deleted", level: LogLevel.Info);
-    } else if (info.coin == Coin.monero) {
+    } else if (info.coin is Monero) {
       final xmrService =
           monero.createMoneroWalletService(DB.instance.moneroWalletInfoBox);
       await xmrService.remove(walletId);
       Logging.instance
           .log("monero wallet: $walletId deleted", level: LogLevel.Info);
-    } else if (info.coin == Coin.epicCash) {
+    } else if (info.coin is Epiccash) {
       final deleteResult = await deleteEpicWallet(
           walletId: walletId, secureStore: secureStorage);
       Logging.instance.log(
diff --git a/lib/services/wallets_service.dart b/lib/services/wallets_service.dart
index 738c9d6c6..8aab994d5 100644
--- a/lib/services/wallets_service.dart
+++ b/lib/services/wallets_service.dart
@@ -12,18 +12,18 @@ import 'dart:convert';
 
 import 'package:flutter/material.dart';
 import 'package:stackwallet/db/hive/db.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/logger.dart';
 
 @Deprecated("Legacy support only. Do not use.")
 class WalletInfo {
-  final Coin coin;
+  final String coinIdentifier;
   final String walletId;
   final String name;
 
   @Deprecated("Legacy support only. Do not use.")
   const WalletInfo({
-    required this.coin,
+    required this.coinIdentifier,
     required this.walletId,
     required this.name,
   });
@@ -31,7 +31,7 @@ class WalletInfo {
   @Deprecated("Legacy support only. Do not use.")
   factory WalletInfo.fromJson(Map<String, dynamic> jsonObject) {
     return WalletInfo(
-      coin: Coin.values.byName(jsonObject["coin"] as String),
+      coinIdentifier: jsonObject["coin"] as String,
       walletId: jsonObject["id"] as String,
       name: jsonObject["name"] as String,
     );
@@ -42,7 +42,7 @@ class WalletInfo {
     return {
       "name": name,
       "id": walletId,
-      "coin": coin.name,
+      "coin": coinIdentifier,
     };
   }
 
@@ -75,12 +75,14 @@ class WalletsService extends ChangeNotifier {
         .get<dynamic>(boxName: DB.boxNameAllWalletsData, key: 'names') as Map?;
     if (names == null) {
       Logging.instance.log(
-          "Fetched wallet 'names' returned null. Setting initializing 'names'",
-          level: LogLevel.Info);
+        "Fetched wallet 'names' returned null. Setting initializing 'names'",
+        level: LogLevel.Info,
+      );
       await DB.instance.put<dynamic>(
-          boxName: DB.boxNameAllWalletsData,
-          key: 'names',
-          value: <String, dynamic>{});
+        boxName: DB.boxNameAllWalletsData,
+        key: 'names',
+        value: <String, dynamic>{},
+      );
       return {};
     }
     Logging.instance.log("Fetched wallet names: $names", level: LogLevel.Info);
@@ -88,16 +90,22 @@ class WalletsService extends ChangeNotifier {
     mapped.removeWhere((name, dyn) {
       final jsonObject = Map<String, dynamic>.from(dyn as Map);
       try {
-        Coin.values.byName(jsonObject["coin"] as String);
+        SupportedCoins.getCryptoCurrencyFor(jsonObject["coin"] as String);
         return false;
       } catch (e, s) {
-        Logging.instance.log("Error, ${jsonObject["coin"]} does not exist",
-            level: LogLevel.Error);
+        Logging.instance.log(
+          "Error, ${jsonObject["coin"]} does not exist",
+          level: LogLevel.Error,
+        );
         return true;
       }
     });
 
-    return mapped.map((name, dyn) => MapEntry(
-        name, WalletInfo.fromJson(Map<String, dynamic>.from(dyn as Map))));
+    return mapped.map(
+      (name, dyn) => MapEntry(
+        name,
+        WalletInfo.fromJson(Map<String, dynamic>.from(dyn as Map)),
+      ),
+    );
   }
 }
diff --git a/lib/supported_coins.dart b/lib/supported_coins.dart
index 70ee44ad8..70b6deae7 100644
--- a/lib/supported_coins.dart
+++ b/lib/supported_coins.dart
@@ -1,4 +1,3 @@
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/banano.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin_frost.dart';
@@ -19,72 +18,68 @@ import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/frost_currency.dart';
 
 /// The supported coins. Eventually move away from the Coin enum
 class SupportedCoins {
-  /// A List of our supported coins. Piggy back on [Coin] for now
-  static final List<CryptoCurrency> cryptocurrencies =
-      Coin.values.map((e) => getCryptoCurrencyFor(e)).toList(growable: false);
+  /// A List of our supported coins.
+  static final List<CryptoCurrency> cryptocurrencies = [
+    Bitcoin(CryptoCurrencyNetwork.main),
+    BitcoinFrost(CryptoCurrencyNetwork.main),
+    Litecoin(CryptoCurrencyNetwork.main),
+    Bitcoincash(CryptoCurrencyNetwork.main),
+    Dogecoin(CryptoCurrencyNetwork.main),
+    Epiccash(CryptoCurrencyNetwork.main),
+    Ecash(CryptoCurrencyNetwork.main),
+    Ethereum(CryptoCurrencyNetwork.main),
+    Firo(CryptoCurrencyNetwork.main),
+    Monero(CryptoCurrencyNetwork.main),
+    Particl(CryptoCurrencyNetwork.main),
+    Peercoin(CryptoCurrencyNetwork.main),
+    Solana(CryptoCurrencyNetwork.main),
+    Stellar(CryptoCurrencyNetwork.main),
+    Tezos(CryptoCurrencyNetwork.main),
+    Wownero(CryptoCurrencyNetwork.main),
+    Namecoin(CryptoCurrencyNetwork.main),
+    Nano(CryptoCurrencyNetwork.main),
+    Banano(CryptoCurrencyNetwork.main),
+    Bitcoin(CryptoCurrencyNetwork.test),
+    BitcoinFrost(CryptoCurrencyNetwork.test),
+    Litecoin(CryptoCurrencyNetwork.test),
+    Bitcoincash(CryptoCurrencyNetwork.test),
+    Firo(CryptoCurrencyNetwork.test),
+    Dogecoin(CryptoCurrencyNetwork.test),
+    Stellar(CryptoCurrencyNetwork.test),
+    Peercoin(CryptoCurrencyNetwork.test),
+  ];
 
-  /// A getter function linking a [CryptoCurrency] with its associated [Coin].
-  ///
-  /// Temporary: Remove when the Coin enum is removed.
-  static CryptoCurrency getCryptoCurrencyFor(Coin coin) {
-    switch (coin) {
-      case Coin.bitcoin:
-        return Bitcoin(CryptoCurrencyNetwork.main);
-      case Coin.bitcoinFrost:
-        return BitcoinFrost(CryptoCurrencyNetwork.main);
-      case Coin.litecoin:
-        return Litecoin(CryptoCurrencyNetwork.main);
-      case Coin.bitcoincash:
-        return Bitcoincash(CryptoCurrencyNetwork.main);
-      case Coin.dogecoin:
-        return Dogecoin(CryptoCurrencyNetwork.main);
-      case Coin.epicCash:
-        return Epiccash(CryptoCurrencyNetwork.main);
-      case Coin.eCash:
-        return Ecash(CryptoCurrencyNetwork.main);
-      case Coin.ethereum:
-        return Ethereum(CryptoCurrencyNetwork.main);
-      case Coin.firo:
-        return Firo(CryptoCurrencyNetwork.main);
-      case Coin.monero:
-        return Monero(CryptoCurrencyNetwork.main);
-      case Coin.particl:
-        return Particl(CryptoCurrencyNetwork.main);
-      case Coin.peercoin:
-        return Peercoin(CryptoCurrencyNetwork.main);
-      case Coin.solana:
-        return Solana(CryptoCurrencyNetwork.main);
-      case Coin.stellar:
-        return Stellar(CryptoCurrencyNetwork.main);
-      case Coin.tezos:
-        return Tezos(CryptoCurrencyNetwork.main);
-      case Coin.wownero:
-        return Wownero(CryptoCurrencyNetwork.main);
-      case Coin.namecoin:
-        return Namecoin(CryptoCurrencyNetwork.main);
-      case Coin.nano:
-        return Nano(CryptoCurrencyNetwork.main);
-      case Coin.banano:
-        return Banano(CryptoCurrencyNetwork.main);
-      case Coin.bitcoinTestNet:
-        return Bitcoin(CryptoCurrencyNetwork.test);
-      case Coin.bitcoinFrostTestNet:
-        return BitcoinFrost(CryptoCurrencyNetwork.test);
-      case Coin.litecoinTestNet:
-        return Litecoin(CryptoCurrencyNetwork.test);
-      case Coin.bitcoincashTestnet:
-        return Bitcoincash(CryptoCurrencyNetwork.test);
-      case Coin.firoTestNet:
-        return Firo(CryptoCurrencyNetwork.test);
-      case Coin.dogecoinTestNet:
-        return Dogecoin(CryptoCurrencyNetwork.test);
-      case Coin.stellarTestnet:
-        return Stellar(CryptoCurrencyNetwork.test);
-      case Coin.peercoinTestNet:
-        return Peercoin(CryptoCurrencyNetwork.test);
+  static CryptoCurrency getCryptoCurrencyFor(String coinIdentifier) =>
+      cryptocurrencies.firstWhere(
+        (e) => e.identifier == coinIdentifier,
+      );
+
+  static CryptoCurrency getCryptoCurrencyForTicker(
+    final String ticker, {
+    bool caseInsensitive = true,
+  }) {
+    final _ticker = caseInsensitive ? ticker.toLowerCase() : ticker;
+    return cryptocurrencies.firstWhere(
+      caseInsensitive
+          ? (e) => e.ticker.toLowerCase() == _ticker && e is! FrostCurrency
+          : (e) => e.ticker == _ticker && e is! FrostCurrency,
+    );
+  }
+
+  /// Fuzzy logic. Use with caution!!
+  @Deprecated("dangerous")
+  static CryptoCurrency getCryptoCurrencyByPrettyName(final String prettyName) {
+    final name = prettyName.replaceAll(" ", "").toLowerCase();
+    try {
+      return cryptocurrencies.firstWhere(
+        (e) => e.identifier.toLowerCase() == name || e.prettyName == prettyName,
+      );
+    } catch (_) {
+      throw Exception("getCryptoCurrencyByPrettyName($prettyName) failed!");
     }
   }
 }
diff --git a/lib/themes/coin_card_provider.dart b/lib/themes/coin_card_provider.dart
index b34e9e6f1..1e1b98ee8 100644
--- a/lib/themes/coin_card_provider.dart
+++ b/lib/themes/coin_card_provider.dart
@@ -11,24 +11,25 @@
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/isar/stack_theme.dart';
 import 'package:stackwallet/themes/theme_providers.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
-final coinCardProvider = Provider.family<String?, Coin>((ref, coin) {
+final coinCardProvider = Provider.family<String?, CryptoCurrency>((ref, coin) {
   final assets = ref.watch(themeAssetsProvider);
 
   if (assets is ThemeAssetsV3) {
-    return assets.coinCardImages?[coin.mainNetVersion];
+    return assets.coinCardImages?[coin.mainNetId];
   } else {
     return null;
   }
 });
 
-final coinCardFavoritesProvider = Provider.family<String?, Coin>((ref, coin) {
+final coinCardFavoritesProvider =
+    Provider.family<String?, CryptoCurrency>((ref, coin) {
   final assets = ref.watch(themeAssetsProvider);
 
   if (assets is ThemeAssetsV3) {
-    return assets.coinCardFavoritesImages?[coin.mainNetVersion] ??
-        assets.coinCardImages?[coin.mainNetVersion];
+    return assets.coinCardFavoritesImages?[coin.mainNetId] ??
+        assets.coinCardImages?[coin.mainNetId];
   } else {
     return null;
   }
diff --git a/lib/themes/coin_icon_provider.dart b/lib/themes/coin_icon_provider.dart
index 9bd3990bb..6415bc9c1 100644
--- a/lib/themes/coin_icon_provider.dart
+++ b/lib/themes/coin_icon_provider.dart
@@ -11,46 +11,52 @@
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/isar/stack_theme.dart';
 import 'package:stackwallet/themes/theme_providers.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/dogecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/litecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/namecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/particl.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
-final coinIconProvider = Provider.family<String, Coin>((ref, coin) {
+final coinIconProvider = Provider.family<String, CryptoCurrency>((ref, coin) {
   final assets = ref.watch(themeAssetsProvider);
 
   if (assets is ThemeAssets) {
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.bitcoinTestNet:
+    switch (coin.runtimeType) {
+      case const (Bitcoin):
         return assets.bitcoin;
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
+      case const (Litecoin):
         return assets.litecoin;
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
+      case const (Bitcoincash):
         return assets.bitcoincash;
-      case Coin.dogecoin:
-      case Coin.dogecoinTestNet:
+      case const (Dogecoin):
         return assets.dogecoin;
-      case Coin.epicCash:
+      case const (Epiccash):
         return assets.epicCash;
-      case Coin.firo:
-      case Coin.firoTestNet:
+      case const (Firo):
         return assets.firo;
-      case Coin.monero:
+      case const (Monero):
         return assets.monero;
-      case Coin.wownero:
+      case const (Wownero):
         return assets.wownero;
-      case Coin.namecoin:
+      case const (Namecoin):
         return assets.namecoin;
-      case Coin.particl:
+      case const (Particl):
         return assets.particl;
-      case Coin.ethereum:
+      case const (Ethereum):
         return assets.ethereum;
       default:
         return assets.stackIcon;
     }
   } else if (assets is ThemeAssetsV2) {
-    return (assets).coinIcons[coin.mainNetVersion]!;
+    return (assets).coinIcons[coin.mainNetId]!;
   } else {
-    return (assets as ThemeAssetsV3).coinIcons[coin.mainNetVersion]!;
+    return (assets as ThemeAssetsV3).coinIcons[coin.mainNetId]!;
   }
 });
diff --git a/lib/themes/coin_image_provider.dart b/lib/themes/coin_image_provider.dart
index 6ca839fb9..c73fc6af3 100644
--- a/lib/themes/coin_image_provider.dart
+++ b/lib/themes/coin_image_provider.dart
@@ -11,101 +11,31 @@
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/isar/stack_theme.dart';
 import 'package:stackwallet/themes/theme_providers.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
-final coinImageProvider = Provider.family<String, Coin>((ref, coin) {
+final coinImageProvider = Provider.family<String, CryptoCurrency>((ref, coin) {
   final assets = ref.watch(themeAssetsProvider);
 
   if (assets is ThemeAssets) {
-    switch (coin) {
-      case Coin.bitcoin:
-        return assets.bitcoinImage;
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-        return assets.litecoinImage;
-      case Coin.bitcoincash:
-        return assets.bitcoincashImage;
-      case Coin.dogecoin:
-        return assets.dogecoinImage;
-      case Coin.eCash:
-        return assets.bitcoinImage;
-      case Coin.epicCash:
-        return assets.epicCashImage;
-      case Coin.firo:
-        return assets.firoImage;
-      case Coin.monero:
-        return assets.moneroImage;
-      case Coin.wownero:
-        return assets.wowneroImage;
-      case Coin.namecoin:
-        return assets.namecoinImage;
-      case Coin.particl:
-        return assets.particlImage;
-      case Coin.bitcoinTestNet:
-        return assets.bitcoinImage;
-      case Coin.bitcoincashTestnet:
-        return assets.bitcoincashImage;
-      case Coin.firoTestNet:
-        return assets.firoImage;
-      case Coin.dogecoinTestNet:
-        return assets.dogecoinImage;
-      case Coin.ethereum:
-        return assets.ethereumImage;
-      default:
-        return assets.stackIcon;
-    }
+    // just update your wallet or theme
+    return assets.stackIcon;
   } else if (assets is ThemeAssetsV2) {
-    return (assets).coinImages[coin.mainNetVersion]!;
+    return (assets).coinImages[coin.mainNetId]!;
   } else {
-    return (assets as ThemeAssetsV3).coinImages[coin.mainNetVersion]!;
+    return (assets as ThemeAssetsV3).coinImages[coin.mainNetId]!;
   }
 });
 
-final coinImageSecondaryProvider = Provider.family<String, Coin>((ref, coin) {
+final coinImageSecondaryProvider =
+    Provider.family<String, CryptoCurrency>((ref, coin) {
   final assets = ref.watch(themeAssetsProvider);
 
   if (assets is ThemeAssets) {
-    switch (coin) {
-      case Coin.bitcoin:
-        return assets.bitcoinImageSecondary;
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-        return assets.litecoinImageSecondary;
-      case Coin.bitcoincash:
-        return assets.bitcoincashImageSecondary;
-      case Coin.dogecoin:
-        return assets.dogecoinImageSecondary;
-      case Coin.eCash:
-        return assets.bitcoinImageSecondary;
-      case Coin.epicCash:
-        return assets.epicCashImageSecondary;
-      case Coin.firo:
-        return assets.firoImageSecondary;
-      case Coin.monero:
-        return assets.moneroImageSecondary;
-      case Coin.wownero:
-        return assets.wowneroImageSecondary;
-      case Coin.namecoin:
-        return assets.namecoinImageSecondary;
-      case Coin.particl:
-        return assets.particlImageSecondary;
-      case Coin.bitcoinTestNet:
-        return assets.bitcoinImageSecondary;
-      case Coin.bitcoincashTestnet:
-        return assets.bitcoincashImageSecondary;
-      case Coin.firoTestNet:
-        return assets.firoImageSecondary;
-      case Coin.dogecoinTestNet:
-        return assets.dogecoinImageSecondary;
-      case Coin.ethereum:
-        return assets.ethereumImageSecondary;
-
-      default:
-        return assets.stackIcon;
-    }
+    // just update your wallet or theme
+    return assets.stackIcon;
   } else if (assets is ThemeAssetsV2) {
-    return (assets).coinSecondaryImages[coin.mainNetVersion]!;
+    return (assets).coinSecondaryImages[coin.mainNetId]!;
   } else {
-    return (assets as ThemeAssetsV3).coinSecondaryImages[coin.mainNetVersion]!;
+    return (assets as ThemeAssetsV3).coinSecondaryImages[coin.mainNetId]!;
   }
 });
diff --git a/lib/themes/color_theme.dart b/lib/themes/color_theme.dart
deleted file mode 100644
index e4dbcabc3..000000000
--- a/lib/themes/color_theme.dart
+++ /dev/null
@@ -1,88 +0,0 @@
-/* 
- * This file is part of Stack Wallet.
- * 
- * Copyright (c) 2023 Cypher Stack
- * All Rights Reserved.
- * The code is distributed under GPLv3 license, see LICENSE file for details.
- * Generated by Cypher Stack on 2023-05-26
- *
- */
-
-import 'package:flutter/material.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
-
-const kCoinThemeColorDefaults = CoinThemeColorDefault();
-
-class CoinThemeColorDefault {
-  const CoinThemeColorDefault();
-
-  Color get bitcoin => const Color(0xFFFCC17B);
-  Color get litecoin => const Color(0xFF7FA6E1);
-  Color get bitcoincash => const Color(0xFF7BCFB8);
-  Color get firo => const Color(0xFFFF897A);
-  Color get dogecoin => const Color(0xFFFFE079);
-  Color get epicCash => const Color(0xFFC5C7CB);
-  Color get eCash => const Color(0xFFC5C7CB);
-  Color get ethereum => const Color(0xFFA7ADE9);
-  Color get monero => const Color(0xFFFF9E6B);
-  Color get namecoin => const Color(0xFF91B1E1);
-  Color get wownero => const Color(0xFFED80C1);
-  Color get particl => const Color(0xFF8175BD);
-  Color get peercoin => const Color(0xFF3CB054);
-  Color get solana => const Color(0xFFC696FF);
-  Color get stellar => const Color(0xFF6600FF);
-  Color get nano => const Color(0xFF209CE9);
-  Color get banano => const Color(0xFFFBDD11);
-  Color get tezos => const Color(0xFF0F61FF);
-
-  Color forCoin(Coin coin) {
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-        return bitcoin;
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-        return litecoin;
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-        return bitcoincash;
-      case Coin.dogecoin:
-      case Coin.dogecoinTestNet:
-        return dogecoin;
-      case Coin.eCash:
-        return eCash;
-      case Coin.epicCash:
-        return epicCash;
-      case Coin.ethereum:
-        return ethereum;
-      case Coin.firo:
-      case Coin.firoTestNet:
-        return firo;
-      case Coin.monero:
-        return monero;
-      case Coin.namecoin:
-        return namecoin;
-      case Coin.wownero:
-        return wownero;
-      case Coin.particl:
-        return particl;
-      case Coin.peercoin:
-        return peercoin;
-      case Coin.peercoinTestNet:
-        return peercoin;
-      case Coin.solana:
-        return solana;
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        return stellar;
-      case Coin.nano:
-        return nano;
-      case Coin.banano:
-        return banano;
-      case Coin.tezos:
-        return tezos;
-    }
-  }
-}
diff --git a/lib/themes/stack_colors.dart b/lib/themes/stack_colors.dart
index 11e146d1b..5f6823f86 100644
--- a/lib/themes/stack_colors.dart
+++ b/lib/themes/stack_colors.dart
@@ -10,8 +10,6 @@
 
 import 'package:flutter/material.dart';
 import 'package:stackwallet/models/isar/stack_theme.dart';
-import 'package:stackwallet/themes/color_theme.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 class StackColors extends ThemeExtension<StackColors> {
   final String themeId;
@@ -1676,58 +1674,6 @@ class StackColors extends ThemeExtension<StackColors> {
     );
   }
 
-  Color colorForCoin(Coin coin) {
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-        return _coin.bitcoin;
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-        return _coin.litecoin;
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-        return _coin.bitcoincash;
-      case Coin.dogecoin:
-      case Coin.dogecoinTestNet:
-        return _coin.dogecoin;
-      case Coin.epicCash:
-        return _coin.epicCash;
-      case Coin.eCash:
-        return _coin.eCash;
-      case Coin.ethereum:
-        return _coin.ethereum;
-      case Coin.firo:
-      case Coin.firoTestNet:
-        return _coin.firo;
-      case Coin.monero:
-        return _coin.monero;
-      case Coin.namecoin:
-        return _coin.namecoin;
-      case Coin.wownero:
-        return _coin.wownero;
-      case Coin.particl:
-        return _coin.particl;
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-        return _coin.peercoin;
-      case Coin.solana:
-        return _coin.solana;
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        return _coin.stellar;
-      case Coin.nano:
-        return _coin.nano;
-      case Coin.banano:
-        return _coin.banano;
-      case Coin.tezos:
-        return _coin.tezos;
-    }
-  }
-
-  static const _coin = CoinThemeColorDefault();
-
   Color colorForStatus(String status) {
     switch (status) {
       case "New":
diff --git a/lib/themes/theme_providers.dart b/lib/themes/theme_providers.dart
index eb622e8cc..e1ab4a5e9 100644
--- a/lib/themes/theme_providers.dart
+++ b/lib/themes/theme_providers.dart
@@ -13,7 +13,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/models/isar/stack_theme.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/themes/theme_service.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 final applicationThemesDirectoryPathProvider = StateProvider((ref) => "");
 
@@ -41,10 +41,10 @@ final themeAssetsProvider = StateProvider<IThemeAssets>(
   ),
 );
 
-final pCoinColor = StateProvider.family<Color, Coin>(
+final pCoinColor = StateProvider.family<Color, CryptoCurrency>(
   (ref, coin) =>
       ref.watch(
-        themeProvider.select((value) => value.coinColors[coin.mainNetVersion]),
+        themeProvider.select((value) => value.coinColors[coin.mainNetId]),
       ) ??
       Colors.deepOrangeAccent,
 );
diff --git a/lib/utilities/address_utils.dart b/lib/utilities/address_utils.dart
index 65e0231fe..3420a8217 100644
--- a/lib/utilities/address_utils.dart
+++ b/lib/utilities/address_utils.dart
@@ -10,191 +10,172 @@
 
 import 'dart:convert';
 
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/banano.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin_frost.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/dogecoin.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/ecash.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/litecoin.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/namecoin.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/nano.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/particl.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/solana.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart';
-import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
-import '../wallets/crypto_currency/coins/peercoin.dart';
-
 class AddressUtils {
   static String condenseAddress(String address) {
     return '${address.substring(0, 5)}...${address.substring(address.length - 5)}';
   }
 
-  static bool validateAddress(String address, Coin coin) {
-    //This calls the validate address for each crypto coin, validateAddress is
-    //only used in 2 places, so I just replaced the old functionality here
-    switch (coin) {
-      case Coin.bitcoin:
-        return Bitcoin(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.bitcoinFrost:
-        return BitcoinFrost(CryptoCurrencyNetwork.main)
-            .validateAddress(address);
-      case Coin.litecoin:
-        return Litecoin(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.bitcoincash:
-        return Bitcoincash(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.dogecoin:
-        return Dogecoin(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.epicCash:
-        return Epiccash(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.ethereum:
-        return Ethereum(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.firo:
-        return Firo(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.eCash:
-        return Ecash(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.monero:
-        return Monero(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.wownero:
-        return Wownero(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.namecoin:
-        return Namecoin(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.particl:
-        return Particl(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.peercoin:
-        return Peercoin(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.solana:
-        return Solana(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.stellar:
-        return Stellar(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.nano:
-        return Nano(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.banano:
-        return Banano(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.tezos:
-        return Tezos(CryptoCurrencyNetwork.main).validateAddress(address);
-      case Coin.bitcoinTestNet:
-        return Bitcoin(CryptoCurrencyNetwork.test).validateAddress(address);
-      case Coin.bitcoinFrostTestNet:
-        return BitcoinFrost(CryptoCurrencyNetwork.test)
-            .validateAddress(address);
-      case Coin.litecoinTestNet:
-        return Litecoin(CryptoCurrencyNetwork.test).validateAddress(address);
-      case Coin.bitcoincashTestnet:
-        return Bitcoincash(CryptoCurrencyNetwork.test).validateAddress(address);
-      case Coin.firoTestNet:
-        return Firo(CryptoCurrencyNetwork.test).validateAddress(address);
-      case Coin.dogecoinTestNet:
-        return Dogecoin(CryptoCurrencyNetwork.test).validateAddress(address);
-      case Coin.peercoinTestNet:
-        return Peercoin(CryptoCurrencyNetwork.test).validateAddress(address);
-      case Coin.stellarTestnet:
-        return Stellar(CryptoCurrencyNetwork.test).validateAddress(address);
-    }
-    // throw Exception("moved");
-    // switch (coin) {
-    //   case Coin.bitcoin:
-    //     return Address.validateAddress(address, bitcoin);
-    //   case Coin.litecoin:
-    //     return Address.validateAddress(address, litecoin);
-    //   case Coin.bitcoincash:
-    //     try {
-    //       // 0 for bitcoincash: address scheme, 1 for legacy address
-    //       final format = bitbox.Address.detectFormat(address);
-    //
-    //       if (coin == Coin.bitcoincashTestnet) {
-    //         return true;
-    //       }
-    //
-    //       if (format == bitbox.Address.formatCashAddr) {
-    //         String addr = address;
-    //         if (addr.contains(":")) {
-    //           addr = addr.split(":").last;
-    //         }
-    //
-    //         return addr.startsWith("q");
-    //       } else {
-    //         return address.startsWith("1");
-    //       }
-    //     } catch (e) {
-    //       return false;
-    //     }
-    //   case Coin.dogecoin:
-    //     return Address.validateAddress(address, dogecoin);
-    //   case Coin.epicCash:
-    //     return validateSendAddress(address) == "1";
-    //   case Coin.ethereum:
-    //     return true; //TODO - validate ETH address
-    //   case Coin.firo:
-    //     return Address.validateAddress(address, firoNetwork);
-    //   case Coin.eCash:
-    //     return Address.validateAddress(address, eCashNetwork);
-    //   case Coin.monero:
-    //     return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
-    //         RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
-    //   case Coin.wownero:
-    //     return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
-    //         RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
-    //   case Coin.namecoin:
-    //     return Address.validateAddress(address, namecoin, namecoin.bech32!);
-    //   case Coin.particl:
-    //     return Address.validateAddress(address, particl);
-    //   case Coin.stellar:
-    //     return RegExp(r"^[G][A-Z0-9]{55}$").hasMatch(address);
-    //   case Coin.nano:
-    //     return NanoAccounts.isValid(NanoAccountType.NANO, address);
-    //   case Coin.banano:
-    //     return NanoAccounts.isValid(NanoAccountType.BANANO, address);
-    //   case Coin.tezos:
-    //     return RegExp(r"^tz[1-9A-HJ-NP-Za-km-z]{34}$").hasMatch(address);
-    //   case Coin.bitcoinTestNet:
-    //     return Address.validateAddress(address, testnet);
-    //   case Coin.litecoinTestNet:
-    //     return Address.validateAddress(address, litecointestnet);
-    //   case Coin.bitcoincashTestnet:
-    //     try {
-    //       // 0 for bitcoincash: address scheme, 1 for legacy address
-    //       final format = bitbox.Address.detectFormat(address);
-    //
-    //       if (coin == Coin.bitcoincashTestnet) {
-    //         return true;
-    //       }
-    //
-    //       if (format == bitbox.Address.formatCashAddr) {
-    //         String addr = address;
-    //         if (addr.contains(":")) {
-    //           addr = addr.split(":").last;
-    //         }
-    //
-    //         return addr.startsWith("q");
-    //       } else {
-    //         return address.startsWith("1");
-    //       }
-    //     } catch (e) {
-    //       return false;
-    //     }
-    //   case Coin.firoTestNet:
-    //     return Address.validateAddress(address, firoTestNetwork);
-    //   case Coin.dogecoinTestNet:
-    //     return Address.validateAddress(address, dogecointestnet);
-    //   case Coin.stellarTestnet:
-    //     return RegExp(r"^[G][A-Z0-9]{55}$").hasMatch(address);
-    // }
-  }
+  // static bool validateAddress(String address, Coin coin) {
+  //   //This calls the validate address for each crypto coin, validateAddress is
+  //   //only used in 2 places, so I just replaced the old functionality here
+  //   switch (coin) {
+  //     case Coin.bitcoin:
+  //       return Bitcoin(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.bitcoinFrost:
+  //       return BitcoinFrost(CryptoCurrencyNetwork.main)
+  //           .validateAddress(address);
+  //     case Coin.litecoin:
+  //       return Litecoin(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.bitcoincash:
+  //       return Bitcoincash(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.dogecoin:
+  //       return Dogecoin(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.epicCash:
+  //       return Epiccash(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.ethereum:
+  //       return Ethereum(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.firo:
+  //       return Firo(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.eCash:
+  //       return Ecash(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.monero:
+  //       return Monero(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.wownero:
+  //       return Wownero(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.namecoin:
+  //       return Namecoin(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.particl:
+  //       return Particl(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.peercoin:
+  //       return Peercoin(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.solana:
+  //       return Solana(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.stellar:
+  //       return Stellar(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.nano:
+  //       return Nano(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.banano:
+  //       return Banano(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.tezos:
+  //       return Tezos(CryptoCurrencyNetwork.main).validateAddress(address);
+  //     case Coin.bitcoinTestNet:
+  //       return Bitcoin(CryptoCurrencyNetwork.test).validateAddress(address);
+  //     case Coin.bitcoinFrostTestNet:
+  //       return BitcoinFrost(CryptoCurrencyNetwork.test)
+  //           .validateAddress(address);
+  //     case Coin.litecoinTestNet:
+  //       return Litecoin(CryptoCurrencyNetwork.test).validateAddress(address);
+  //     case Coin.bitcoincashTestnet:
+  //       return Bitcoincash(CryptoCurrencyNetwork.test).validateAddress(address);
+  //     case Coin.firoTestNet:
+  //       return Firo(CryptoCurrencyNetwork.test).validateAddress(address);
+  //     case Coin.dogecoinTestNet:
+  //       return Dogecoin(CryptoCurrencyNetwork.test).validateAddress(address);
+  //     case Coin.peercoinTestNet:
+  //       return Peercoin(CryptoCurrencyNetwork.test).validateAddress(address);
+  //     case Coin.stellarTestnet:
+  //       return Stellar(CryptoCurrencyNetwork.test).validateAddress(address);
+  //   }
+  //   // throw Exception("moved");
+  //   // switch (coin) {
+  //   //   case Coin.bitcoin:
+  //   //     return Address.validateAddress(address, bitcoin);
+  //   //   case Coin.litecoin:
+  //   //     return Address.validateAddress(address, litecoin);
+  //   //   case Coin.bitcoincash:
+  //   //     try {
+  //   //       // 0 for bitcoincash: address scheme, 1 for legacy address
+  //   //       final format = bitbox.Address.detectFormat(address);
+  //   //
+  //   //       if (coin == Coin.bitcoincashTestnet) {
+  //   //         return true;
+  //   //       }
+  //   //
+  //   //       if (format == bitbox.Address.formatCashAddr) {
+  //   //         String addr = address;
+  //   //         if (addr.contains(":")) {
+  //   //           addr = addr.split(":").last;
+  //   //         }
+  //   //
+  //   //         return addr.startsWith("q");
+  //   //       } else {
+  //   //         return address.startsWith("1");
+  //   //       }
+  //   //     } catch (e) {
+  //   //       return false;
+  //   //     }
+  //   //   case Coin.dogecoin:
+  //   //     return Address.validateAddress(address, dogecoin);
+  //   //   case Coin.epicCash:
+  //   //     return validateSendAddress(address) == "1";
+  //   //   case Coin.ethereum:
+  //   //     return true; //TODO - validate ETH address
+  //   //   case Coin.firo:
+  //   //     return Address.validateAddress(address, firoNetwork);
+  //   //   case Coin.eCash:
+  //   //     return Address.validateAddress(address, eCashNetwork);
+  //   //   case Coin.monero:
+  //   //     return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
+  //   //         RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
+  //   //   case Coin.wownero:
+  //   //     return RegExp("[a-zA-Z0-9]{95}").hasMatch(address) ||
+  //   //         RegExp("[a-zA-Z0-9]{106}").hasMatch(address);
+  //   //   case Coin.namecoin:
+  //   //     return Address.validateAddress(address, namecoin, namecoin.bech32!);
+  //   //   case Coin.particl:
+  //   //     return Address.validateAddress(address, particl);
+  //   //   case Coin.stellar:
+  //   //     return RegExp(r"^[G][A-Z0-9]{55}$").hasMatch(address);
+  //   //   case Coin.nano:
+  //   //     return NanoAccounts.isValid(NanoAccountType.NANO, address);
+  //   //   case Coin.banano:
+  //   //     return NanoAccounts.isValid(NanoAccountType.BANANO, address);
+  //   //   case Coin.tezos:
+  //   //     return RegExp(r"^tz[1-9A-HJ-NP-Za-km-z]{34}$").hasMatch(address);
+  //   //   case Coin.bitcoinTestNet:
+  //   //     return Address.validateAddress(address, testnet);
+  //   //   case Coin.litecoinTestNet:
+  //   //     return Address.validateAddress(address, litecointestnet);
+  //   //   case Coin.bitcoincashTestnet:
+  //   //     try {
+  //   //       // 0 for bitcoincash: address scheme, 1 for legacy address
+  //   //       final format = bitbox.Address.detectFormat(address);
+  //   //
+  //   //       if (coin == Coin.bitcoincashTestnet) {
+  //   //         return true;
+  //   //       }
+  //   //
+  //   //       if (format == bitbox.Address.formatCashAddr) {
+  //   //         String addr = address;
+  //   //         if (addr.contains(":")) {
+  //   //           addr = addr.split(":").last;
+  //   //         }
+  //   //
+  //   //         return addr.startsWith("q");
+  //   //       } else {
+  //   //         return address.startsWith("1");
+  //   //       }
+  //   //     } catch (e) {
+  //   //       return false;
+  //   //     }
+  //   //   case Coin.firoTestNet:
+  //   //     return Address.validateAddress(address, firoTestNetwork);
+  //   //   case Coin.dogecoinTestNet:
+  //   //     return Address.validateAddress(address, dogecointestnet);
+  //   //   case Coin.stellarTestnet:
+  //   //     return RegExp(r"^[G][A-Z0-9]{55}$").hasMatch(address);
+  //   // }
+  // }
 
   /// parse an address uri
   /// returns an empty map if the input string does not begin with "firo:"
   static Map<String, String> parseUri(String uri) {
-    Map<String, String> result = {};
+    final Map<String, String> result = {};
     try {
       final u = Uri.parse(uri);
       if (u.hasScheme) {
@@ -211,15 +192,13 @@ class AddressUtils {
 
   /// builds a uri string with the given address and query parameters if any
   static String buildUriString(
-    Coin coin,
+    CryptoCurrency coin,
     String address,
     Map<String, String> params,
   ) {
     // TODO: other sanitation as well ?
     String sanitizedAddress = address;
-    if (coin == Coin.bitcoincash ||
-        coin == Coin.bitcoincashTestnet ||
-        coin == Coin.eCash) {
+    if (coin is Bitcoincash || coin is Ecash) {
       final prefix = "${coin.uriScheme}:";
       if (address.startsWith(prefix)) {
         sanitizedAddress = address.replaceFirst(prefix, "");
diff --git a/lib/utilities/amount/amount_formatter.dart b/lib/utilities/amount/amount_formatter.dart
index 1ae577507..937636069 100644
--- a/lib/utilities/amount/amount_formatter.dart
+++ b/lib/utilities/amount/amount_formatter.dart
@@ -4,16 +4,16 @@ import 'package:stackwallet/providers/global/locale_provider.dart';
 import 'package:stackwallet/providers/global/prefs_provider.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_unit.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
-final pAmountUnit = Provider.family<AmountUnit, Coin>(
+final pAmountUnit = Provider.family<AmountUnit, CryptoCurrency>(
   (ref, coin) => ref.watch(
     prefsChangeNotifierProvider.select(
       (value) => value.amountUnit(coin),
     ),
   ),
 );
-final pMaxDecimals = Provider.family<int, Coin>(
+final pMaxDecimals = Provider.family<int, CryptoCurrency>(
   (ref, coin) => ref.watch(
     prefsChangeNotifierProvider.select(
       (value) => value.maxDecimals(coin),
@@ -21,7 +21,8 @@ final pMaxDecimals = Provider.family<int, Coin>(
   ),
 );
 
-final pAmountFormatter = Provider.family<AmountFormatter, Coin>((ref, coin) {
+final pAmountFormatter =
+    Provider.family<AmountFormatter, CryptoCurrency>((ref, coin) {
   final locale = ref.watch(
     localeServiceChangeNotifierProvider.select((value) => value.locale),
   );
@@ -37,7 +38,7 @@ final pAmountFormatter = Provider.family<AmountFormatter, Coin>((ref, coin) {
 class AmountFormatter {
   final AmountUnit unit;
   final String locale;
-  final Coin coin;
+  final CryptoCurrency coin;
   final int maxDecimals;
 
   AmountFormatter({
diff --git a/lib/utilities/amount/amount_unit.dart b/lib/utilities/amount/amount_unit.dart
index e74de6510..a81559556 100644
--- a/lib/utilities/amount/amount_unit.dart
+++ b/lib/utilities/amount/amount_unit.dart
@@ -13,8 +13,12 @@ import 'dart:math' as math;
 import 'package:decimal/decimal.dart';
 import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 
 // preserve index order as index is used to store value in preferences
 enum AmountUnit {
@@ -34,48 +38,56 @@ enum AmountUnit {
   const AmountUnit(this.shift);
   final int shift;
 
-  static List<AmountUnit> valuesForCoin(Coin coin) {
-    switch (coin) {
-      case Coin.firo:
-      case Coin.litecoin:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.namecoin:
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.bitcoinTestNet:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincashTestnet:
-      case Coin.dogecoinTestNet:
-      case Coin.firoTestNet:
-      case Coin.peercoinTestNet:
-      case Coin.bitcoin:
-      case Coin.bitcoincash:
-      case Coin.dogecoin:
-      case Coin.eCash:
-      case Coin.epicCash:
-      case Coin.stellar: // TODO: check if this is correct
-      case Coin.stellarTestnet:
-      case Coin.tezos:
-      case Coin.solana:
-        return AmountUnit.values.sublist(0, 4);
-
-      case Coin.monero:
-      case Coin.wownero:
-        return AmountUnit.values.sublist(0, 5);
-
-      case Coin.ethereum:
-        return AmountUnit.values.sublist(0, 7);
-
-      case Coin.nano:
-      case Coin.banano:
-        return AmountUnit.values;
+  static List<AmountUnit> valuesForCoin(CryptoCurrency coin) {
+    final remainder = coin.fractionDigits % 3;
+    int n = (coin.fractionDigits ~/ 3) + 1;
+    if (remainder > 0) {
+      n++;
     }
+
+    return AmountUnit.values.sublist(0, n);
+    //
+    // switch (coin) {
+    //   case Coin.firo:
+    //   case Coin.litecoin:
+    //   case Coin.particl:
+    //   case Coin.peercoin:
+    //   case Coin.namecoin:
+    //   case Coin.bitcoinFrost:
+    //   case Coin.bitcoinFrostTestNet:
+    //   case Coin.bitcoinTestNet:
+    //   case Coin.litecoinTestNet:
+    //   case Coin.bitcoincashTestnet:
+    //   case Coin.dogecoinTestNet:
+    //   case Coin.firoTestNet:
+    //   case Coin.peercoinTestNet:
+    //   case Coin.bitcoin:
+    //   case Coin.bitcoincash:
+    //   case Coin.dogecoin:
+    //   case Coin.eCash:
+    //   case Coin.epicCash:
+    //   case Coin.stellar: // TODO: check if this is correct
+    //   case Coin.stellarTestnet:
+    //   case Coin.tezos:
+    //   case Coin.solana:
+    //     return AmountUnit.values.sublist(0, 4);
+    //
+    //   case Coin.monero:
+    //   case Coin.wownero:
+    //     return AmountUnit.values.sublist(0, 5);
+    //
+    //   case Coin.ethereum:
+    //     return AmountUnit.values.sublist(0, 7);
+    //
+    //   case Coin.nano:
+    //   case Coin.banano:
+    //     return AmountUnit.values;
+    // }
   }
 }
 
 extension AmountUnitExt on AmountUnit {
-  String unitForCoin(Coin coin) {
+  String unitForCoin(CryptoCurrency coin) {
     switch (this) {
       case AmountUnit.normal:
         return coin.ticker;
@@ -84,63 +96,57 @@ extension AmountUnitExt on AmountUnit {
       case AmountUnit.micro:
         return "µ${coin.ticker}";
       case AmountUnit.nano:
-        if (coin == Coin.ethereum) {
+        if (coin is Ethereum) {
           return "gwei";
-        } else if (coin == Coin.wownero ||
-            coin == Coin.monero ||
-            coin == Coin.nano ||
-            coin == Coin.banano) {
+        } else if (coin is Wownero || coin is Monero || coin is NanoCurrency) {
           return "n${coin.ticker}";
         } else {
           return "sats";
         }
       case AmountUnit.pico:
-        if (coin == Coin.ethereum) {
+        if (coin is Ethereum) {
           return "mwei";
-        } else if (coin == Coin.wownero ||
-            coin == Coin.monero ||
-            coin == Coin.nano ||
-            coin == Coin.banano) {
+        } else if (coin is Wownero || coin is Monero || coin is NanoCurrency) {
           return "p${coin.ticker}";
         } else {
           return "invalid";
         }
       case AmountUnit.femto:
-        if (coin == Coin.ethereum) {
+        if (coin is Ethereum) {
           return "kwei";
-        } else if (coin == Coin.nano || coin == Coin.banano) {
+        } else if (coin is NanoCurrency) {
           return "f${coin.ticker}";
         } else {
           return "invalid";
         }
       case AmountUnit.atto:
-        if (coin == Coin.ethereum) {
+        if (coin is Ethereum) {
           return "wei";
-        } else if (coin == Coin.nano || coin == Coin.banano) {
+        } else if (coin is NanoCurrency) {
           return "a${coin.ticker}";
         } else {
           return "invalid";
         }
       case AmountUnit.zepto:
-        if (coin == Coin.nano || coin == Coin.banano) {
+        if (coin is NanoCurrency) {
           return "z${coin.ticker}";
         } else {
           return "invalid";
         }
       case AmountUnit.yocto:
-        if (coin == Coin.nano || coin == Coin.banano) {
+        if (coin is NanoCurrency) {
           return "y${coin.ticker}";
         } else {
           return "invalid";
         }
       case AmountUnit.ronto:
-        if (coin == Coin.nano || coin == Coin.banano) {
+        if (coin is NanoCurrency) {
           return "r${coin.ticker}";
         } else {
           return "invalid";
         }
       case AmountUnit.quecto:
-        if (coin == Coin.nano || coin == Coin.banano) {
+        if (coin is NanoCurrency) {
           return "q${coin.ticker}";
         } else {
           return "invalid";
@@ -174,7 +180,7 @@ extension AmountUnitExt on AmountUnit {
   Amount? tryParse(
     String value, {
     required String locale,
-    required Coin coin,
+    required CryptoCurrency coin,
     EthContract? tokenContract,
     bool overrideWithDecimalPlacesFromString = false,
   }) {
@@ -212,7 +218,7 @@ extension AmountUnitExt on AmountUnit {
 
     final decimalPlaces = overrideWithDecimalPlacesFromString
         ? decimal.scale
-        : tokenContract?.decimals ?? coin.decimals;
+        : tokenContract?.decimals ?? coin.fractionDigits;
     final realShift = math.min(shift, decimalPlaces);
 
     return decimal.shift(0 - realShift).toAmount(fractionDigits: decimalPlaces);
@@ -221,7 +227,7 @@ extension AmountUnitExt on AmountUnit {
   String displayAmount({
     required Amount amount,
     required String locale,
-    required Coin coin,
+    required CryptoCurrency coin,
     required int maxDecimalPlaces,
     bool withUnitName = true,
     bool indicatePrecisionLoss = true,
@@ -271,8 +277,9 @@ extension AmountUnitExt on AmountUnit {
             ? tokenContract.decimals
             : maxDecimalPlaces;
       } else {
-        updatedMax =
-            maxDecimalPlaces > coin.decimals ? coin.decimals : maxDecimalPlaces;
+        updatedMax = maxDecimalPlaces > coin.fractionDigits
+            ? coin.fractionDigits
+            : maxDecimalPlaces;
       }
       final int actualDecimalPlaces = math.min(places, updatedMax);
 
diff --git a/lib/utilities/block_explorers.dart b/lib/utilities/block_explorers.dart
index cf67697b6..b72b4a851 100644
--- a/lib/utilities/block_explorers.dart
+++ b/lib/utilities/block_explorers.dart
@@ -10,75 +10,11 @@
 
 import 'package:stackwallet/db/isar/main_db.dart';
 import 'package:stackwallet/models/isar/models/block_explorer.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
-
-// Returns the default block explorer URL for the given coin and txid
-Uri getDefaultBlockExplorerUrlFor({
-  required Coin coin,
-  required String txid,
-}) {
-  switch (coin) {
-    case Coin.bitcoinFrost:
-    case Coin.bitcoin:
-      return Uri.parse("https://mempool.space/tx/$txid");
-    case Coin.litecoin:
-      return Uri.parse("https://chain.so/tx/LTC/$txid");
-    case Coin.litecoinTestNet:
-      return Uri.parse("https://chain.so/tx/LTCTEST/$txid");
-    case Coin.bitcoinTestNet:
-    case Coin.bitcoinFrostTestNet:
-      return Uri.parse("https://mempool.space/testnet/tx/$txid");
-    case Coin.dogecoin:
-      return Uri.parse("https://chain.so/tx/DOGE/$txid");
-    case Coin.eCash:
-      return Uri.parse("https://explorer.e.cash/tx/$txid");
-    case Coin.dogecoinTestNet:
-      return Uri.parse("https://chain.so/tx/DOGETEST/$txid");
-    case Coin.epicCash:
-      // TODO: Handle this case.
-      throw UnimplementedError("missing block explorer for epic cash");
-    case Coin.ethereum:
-      return Uri.parse("https://etherscan.io/tx/$txid");
-    case Coin.monero:
-      return Uri.parse("https://xmrchain.net/tx/$txid");
-    case Coin.wownero:
-      return Uri.parse("https://explore.wownero.com/search?value=$txid");
-    case Coin.firo:
-      return Uri.parse("https://explorer.firo.org/tx/$txid");
-    case Coin.firoTestNet:
-      return Uri.parse("https://testexplorer.firo.org/tx/$txid");
-    case Coin.bitcoincash:
-      return Uri.parse("https://blockchair.com/bitcoin-cash/transaction/$txid");
-    case Coin.bitcoincashTestnet:
-      return Uri.parse(
-          "https://blockexplorer.one/bitcoin-cash/testnet/tx/$txid");
-    case Coin.namecoin:
-      return Uri.parse("https://chainz.cryptoid.info/nmc/tx.dws?$txid.htm");
-    case Coin.particl:
-      return Uri.parse("https://chainz.cryptoid.info/part/tx.dws?$txid.htm");
-    case Coin.stellar:
-      return Uri.parse("https://stellarchain.io/tx/$txid");
-    case Coin.nano:
-      return Uri.parse("https://www.nanolooker.com/block/$txid");
-    case Coin.banano:
-      return Uri.parse("https://www.bananolooker.com/block/$txid");
-    case Coin.stellarTestnet:
-      return Uri.parse("https://testnet.stellarchain.io/transactions/$txid");
-    case Coin.tezos:
-      return Uri.parse("https://tzstats.com/$txid");
-    case Coin.solana:
-      return Uri.parse("https://explorer.solana.com/tx/$txid");
-    case Coin.peercoin:
-      return Uri.parse("https://chainz.cryptoid.info/ppc/tx.dws?$txid.htm");
-    case Coin.peercoinTestNet:
-      return Uri.parse(
-          "https://chainz.cryptoid.info/ppc-test/search.dws?q=$txid.htm");
-  }
-}
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 // Returns internal Isar ID for the inserted object/record
 Future<int> setBlockExplorerForCoin({
-  required Coin coin,
+  required CryptoCurrency coin,
   required Uri url,
 }) async {
   return await MainDB.instance.putTransactionBlockExplorer(
@@ -91,12 +27,13 @@ Future<int> setBlockExplorerForCoin({
 
 // Returns the block explorer URL for the given coin and txid
 Uri getBlockExplorerTransactionUrlFor({
-  required Coin coin,
+  required CryptoCurrency coin,
   required String txid,
 }) {
-  String? url = MainDB.instance.getTransactionBlockExplorer(coin: coin)?.url;
+  String? url =
+      MainDB.instance.getTransactionBlockExplorer(cryptoCurrency: coin)?.url;
   if (url == null) {
-    return getDefaultBlockExplorerUrlFor(coin: coin, txid: txid);
+    return coin.defaultBlockExplorer(txid);
   } else {
     url = url.replaceAll("%5BTXID%5D", txid);
     return Uri.parse(url);
diff --git a/lib/utilities/constants.dart b/lib/utilities/constants.dart
index d3fedc666..5971d02f3 100644
--- a/lib/utilities/constants.dart
+++ b/lib/utilities/constants.dart
@@ -10,7 +10,6 @@
 
 import 'dart:io';
 
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/util.dart';
 
 class _LayoutSizing {
@@ -34,31 +33,6 @@ abstract class Constants {
   // just use enable exchange flag
   // static bool enableBuy = enableExchange;
   // // true; // true for development,
-  static final BigInt _satsPerCoinECash = BigInt.from(100);
-  static final BigInt _satsPerCoinEthereum = BigInt.from(1000000000000000000);
-  static final BigInt _satsPerCoinMonero = BigInt.from(1000000000000);
-  static final BigInt _satsPerCoinWownero = BigInt.from(100000000000);
-  static final BigInt _satsPerCoinNano =
-      BigInt.parse("1000000000000000000000000000000"); // 1*10^30
-  static final BigInt _satsPerCoinBanano =
-      BigInt.parse("100000000000000000000000000000"); // 1*10^29
-  static final BigInt _satsPerCoinStellar = BigInt.from(
-      10000000); // https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-data-structures/assets#amount-precision
-  static final BigInt _satsPerCoin = BigInt.from(100000000);
-  static final BigInt _satsPerCoinTezos = BigInt.from(1000000);
-  static final BigInt _satsPerCoinSolana = BigInt.from(1000000000);
-  static final BigInt _satsPerCoinPeercoin = BigInt.from(1000000); // 1*10^6.
-  static const int _decimalPlaces = 8;
-  static const int _decimalPlacesNano = 30;
-  static const int _decimalPlacesBanano = 29;
-  static const int _decimalPlacesWownero = 11;
-  static const int _decimalPlacesMonero = 12;
-  static const int _decimalPlacesEthereum = 18;
-  static const int _decimalPlacesECash = 2;
-  static const int _decimalPlacesStellar = 7;
-  static const int _decimalPlacesTezos = 6;
-  static const int _decimalPlacesSolana = 9;
-  static const int _decimalPlacesPeercoin = 6;
 
   static const int notificationsMax = 0xFFFFFFFF;
   static const Duration networkAliveTimerDuration = Duration(seconds: 10);
@@ -70,264 +44,6 @@ abstract class Constants {
 
   static const int rescanV1 = 1;
 
-  static BigInt satsPerCoin(Coin coin) {
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.bitcoinFrost:
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.dogecoinTestNet:
-      case Coin.firoTestNet:
-      case Coin.epicCash:
-      case Coin.namecoin:
-      case Coin.particl:
-        return _satsPerCoin;
-
-      case Coin.nano:
-        return _satsPerCoinNano;
-
-      case Coin.banano:
-        return _satsPerCoinBanano;
-
-      case Coin.wownero:
-        return _satsPerCoinWownero;
-
-      case Coin.monero:
-        return _satsPerCoinMonero;
-
-      case Coin.ethereum:
-        return _satsPerCoinEthereum;
-
-      case Coin.eCash:
-        return _satsPerCoinECash;
-
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        return _satsPerCoinStellar;
-
-      case Coin.tezos:
-        return _satsPerCoinTezos;
-
-      case Coin.solana:
-        return _satsPerCoinSolana;
-
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-        return _satsPerCoinPeercoin;
-    }
-  }
-
-  static int decimalPlacesForCoin(Coin coin) {
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.bitcoinFrost:
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.dogecoinTestNet:
-      case Coin.firoTestNet:
-      case Coin.epicCash:
-      case Coin.namecoin:
-      case Coin.particl:
-        return _decimalPlaces;
-
-      case Coin.nano:
-        return _decimalPlacesNano;
-
-      case Coin.banano:
-        return _decimalPlacesBanano;
-
-      case Coin.wownero:
-        return _decimalPlacesWownero;
-
-      case Coin.monero:
-        return _decimalPlacesMonero;
-
-      case Coin.ethereum:
-        return _decimalPlacesEthereum;
-
-      case Coin.eCash:
-        return _decimalPlacesECash;
-
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        return _decimalPlacesStellar;
-
-      case Coin.tezos:
-        return _decimalPlacesTezos;
-
-      case Coin.solana:
-        return _decimalPlacesSolana;
-
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-        return _decimalPlacesPeercoin;
-    }
-  }
-
-  static List<int> possibleLengthsForCoin(Coin coin) {
-    final List<int> values = [];
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.bitcoinTestNet:
-      case Coin.dogecoinTestNet:
-      case Coin.firoTestNet:
-      case Coin.eCash:
-      case Coin.epicCash:
-      case Coin.ethereum:
-      case Coin.namecoin:
-      case Coin.particl:
-        values.addAll([12, 24]);
-        break;
-      case Coin.solana:
-      case Coin.nano:
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        values.addAll([24, 12]);
-        break;
-      case Coin.banano:
-        values.addAll([24, 12]);
-        break;
-      case Coin.tezos:
-        values.addAll([24, 12]);
-
-      case Coin.monero:
-        values.addAll([25]);
-        break;
-      case Coin.wownero:
-        values.addAll([14, 25]);
-        break;
-
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-        throw ArgumentError("Frost mnemonic lengths unsupported");
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-        values.addAll([12, /*15, 18, 21,*/ 24]); // TODO [prio=low]: Test rest.
-        break;
-    }
-    return values;
-  }
-
-  static int targetBlockTimeInSeconds(Coin coin) {
-    // TODO verify values
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-      case Coin.eCash:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-        return 600;
-
-      case Coin.dogecoin:
-      case Coin.dogecoinTestNet:
-        return 60;
-
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-        return 150;
-
-      case Coin.firo:
-      case Coin.firoTestNet:
-        return 150;
-
-      case Coin.epicCash:
-        return 60;
-
-      case Coin.ethereum:
-        return 15;
-
-      case Coin.monero:
-        return 120;
-
-      case Coin.wownero:
-        return 120;
-
-      case Coin.namecoin:
-        return 600;
-
-      case Coin.particl:
-        return 600;
-
-      case Coin.nano: // TODO: Verify this
-      case Coin.banano: // TODO: Verify this
-      case Coin.solana:
-        return 1;
-
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        return 5;
-
-      case Coin.tezos:
-        return 60;
-    }
-  }
-
-  static int defaultSeedPhraseLengthFor({required Coin coin}) {
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-      case Coin.eCash:
-      case Coin.dogecoin:
-      case Coin.dogecoinTestNet:
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-      case Coin.firo:
-      case Coin.firoTestNet:
-      case Coin.namecoin:
-      case Coin.particl:
-      case Coin.ethereum:
-      case Coin.solana:
-        return 12;
-
-      case Coin.wownero:
-        return 14;
-
-      case Coin.nano:
-      case Coin.banano:
-      case Coin.epicCash:
-      case Coin.peercoin: // TODO [prio=low]: Verify default seed length.
-      case Coin.peercoinTestNet:
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-      case Coin.tezos:
-        return 24;
-
-      case Coin.monero:
-        return 25;
-
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-        throw ArgumentError("Frost mnemonic length unsupported");
-      //
-      // default:
-      //   -1;
-    }
-  }
-
   static const Map<int, String> monthMapShort = {
     1: 'Jan',
     2: 'Feb',
diff --git a/lib/utilities/default_nodes.dart b/lib/utilities/default_nodes.dart
index 2e2bd71cc..f7f09583a 100644
--- a/lib/utilities/default_nodes.dart
+++ b/lib/utilities/default_nodes.dart
@@ -8,401 +8,11 @@
  *
  */
 
-import 'package:stackwallet/models/node_model.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 abstract class DefaultNodes {
   static const String defaultNodeIdPrefix = "default_";
-  static String buildId(Coin coin) => "$defaultNodeIdPrefix${coin.name}";
+  static String buildId(CryptoCurrency cryptoCurrency) =>
+      "$defaultNodeIdPrefix${cryptoCurrency.identifier}";
   static const String defaultName = "Stack Default";
-
-  @Deprecated("old and decrepit")
-  static List<NodeModel> get all => Coin.values
-      .map((e) => DefaultNodes.getNodeFor(e))
-      .toList(growable: false);
-
-  static NodeModel get bitcoin => NodeModel(
-        host: "bitcoin.stackwallet.com",
-        port: 50002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.bitcoin),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.bitcoin.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get litecoin => NodeModel(
-        host: "litecoin.stackwallet.com",
-        port: 20063,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.litecoin),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.litecoin.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get litecoinTestNet => NodeModel(
-        host: "litecoin.stackwallet.com",
-        port: 51002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.litecoinTestNet),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.litecoinTestNet.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get bitcoincash => NodeModel(
-        host: "bitcoincash.stackwallet.com",
-        port: 50002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.bitcoincash),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.bitcoincash.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get dogecoin => NodeModel(
-        host: "dogecoin.stackwallet.com",
-        port: 50022,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.dogecoin),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.dogecoin.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get firo => NodeModel(
-        host: "firo.stackwallet.com",
-        port: 50002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.firo),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.firo.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get monero => NodeModel(
-        host: "https://monero.stackwallet.com",
-        port: 18081,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.monero),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.monero.name,
-        isFailover: true,
-        isDown: false,
-        trusted: true,
-      );
-
-  static NodeModel get wownero => NodeModel(
-        host: "https://wownero.stackwallet.com",
-        port: 34568,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.wownero),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.wownero.name,
-        isFailover: true,
-        isDown: false,
-        trusted: true,
-      );
-
-  static NodeModel get epicCash => NodeModel(
-        host: "http://epiccash.stackwallet.com",
-        port: 3413,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.epicCash),
-        useSSL: false,
-        enabled: true,
-        coinName: Coin.epicCash.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get ethereum => NodeModel(
-        host: "https://eth.stackwallet.com",
-        port: 443,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.ethereum),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.ethereum.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get namecoin => NodeModel(
-        host: "namecoin.stackwallet.com",
-        port: 57002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.namecoin),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.namecoin.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get particl => NodeModel(
-        host: "particl.stackwallet.com",
-        port: 58002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.particl),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.particl.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get peercoin => NodeModel(
-        host: "electrum.peercoinexplorer.net",
-        port: 50002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.peercoin),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.peercoin.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get solana => NodeModel(
-        host:
-            "https://api.mainnet-beta.solana.com", // TODO: Change this to stack wallet one
-        port: 443,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.solana),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.solana.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get stellar => NodeModel(
-        host: "https://horizon.stellar.org",
-        port: 443,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.stellar),
-        useSSL: false,
-        enabled: true,
-        coinName: Coin.stellar.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get tezos => NodeModel(
-        // TODO: Change this to stack wallet one
-        host: "https://mainnet.api.tez.ie",
-        port: 443,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.tezos),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.tezos.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get nano => NodeModel(
-        host: "https://rainstorm.city/api",
-        port: 443,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.nano),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.nano.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get banano => NodeModel(
-        host: "https://kaliumapi.appditto.com/api",
-        port: 443,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.banano),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.banano.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get bitcoinTestnet => NodeModel(
-        host: "bitcoin-testnet.stackwallet.com",
-        port: 51002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.bitcoinTestNet),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.bitcoinTestNet.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get firoTestnet => NodeModel(
-        host: "firo-testnet.stackwallet.com",
-        port: 50002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.firoTestNet),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.firoTestNet.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get dogecoinTestnet => NodeModel(
-        host: "dogecoin-testnet.stackwallet.com",
-        port: 50022,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.dogecoinTestNet),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.dogecoinTestNet.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get bitcoincashTestnet => NodeModel(
-        host: "bitcoincash-testnet.stackwallet.com",
-        port: 60002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.bitcoincashTestnet),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.bitcoincashTestnet.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get eCash => NodeModel(
-        host: "ecash.stackwallet.com",
-        port: 59002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.eCash),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.eCash.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get peercoinTestNet => NodeModel(
-        host: "testnet-electrum.peercoinexplorer.net",
-        port: 50002,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.peercoinTestNet),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.peercoinTestNet.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel get stellarTestnet => NodeModel(
-        host: "https://horizon-testnet.stellar.org/",
-        port: 50022,
-        name: DefaultNodes.defaultName,
-        id: DefaultNodes.buildId(Coin.stellarTestnet),
-        useSSL: true,
-        enabled: true,
-        coinName: Coin.stellarTestnet.name,
-        isFailover: true,
-        isDown: false,
-      );
-
-  static NodeModel getNodeFor(Coin coin) {
-    switch (coin) {
-      case Coin.bitcoin:
-      case Coin.bitcoinFrost:
-        return bitcoin;
-
-      case Coin.litecoin:
-        return litecoin;
-
-      case Coin.bitcoincash:
-        return bitcoincash;
-
-      case Coin.dogecoin:
-        return dogecoin;
-
-      case Coin.eCash:
-        return eCash;
-
-      case Coin.epicCash:
-        return epicCash;
-
-      case Coin.ethereum:
-        return ethereum;
-
-      case Coin.firo:
-        return firo;
-
-      case Coin.monero:
-        return monero;
-
-      case Coin.wownero:
-        return wownero;
-
-      case Coin.namecoin:
-        return namecoin;
-
-      case Coin.particl:
-        return particl;
-
-      case Coin.peercoin:
-        return peercoin;
-
-      case Coin.peercoinTestNet:
-        return peercoinTestNet;
-
-      case Coin.solana:
-        return solana;
-
-      case Coin.stellar:
-        return stellar;
-
-      case Coin.nano:
-        return nano;
-
-      case Coin.banano:
-        return banano;
-
-      case Coin.tezos:
-        return tezos;
-
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoinFrostTestNet:
-        return bitcoinTestnet;
-
-      case Coin.litecoinTestNet:
-        return litecoinTestNet;
-
-      case Coin.bitcoincashTestnet:
-        return bitcoincashTestnet;
-
-      case Coin.firoTestNet:
-        return firoTestnet;
-
-      case Coin.dogecoinTestNet:
-        return dogecoinTestnet;
-
-      case Coin.stellarTestnet:
-        return stellarTestnet;
-    }
-  }
 }
diff --git a/lib/utilities/enums/coin_enum.dart b/lib/utilities/enums/coin_enum.dart
deleted file mode 100644
index 903054b09..000000000
--- a/lib/utilities/enums/coin_enum.dart
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * This file is part of Stack Wallet.
- *
- * Copyright (c) 2023 Cypher Stack
- * All Rights Reserved.
- * The code is distributed under GPLv3 license, see LICENSE file for details.
- * Generated by Cypher Stack on 2023-05-26
- *
- */
-
-import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
-import 'package:stackwallet/utilities/constants.dart';
-
-enum Coin {
-  bitcoin,
-  monero,
-  banano,
-  bitcoincash,
-  bitcoinFrost,
-  dogecoin,
-  eCash,
-  epicCash,
-  ethereum,
-  firo,
-  litecoin,
-  namecoin,
-  nano,
-  particl,
-  peercoin,
-  solana,
-  stellar,
-  tezos,
-  wownero,
-
-  ///
-
-  ///
-  ///
-
-  bitcoinTestNet,
-  bitcoincashTestnet,
-  bitcoinFrostTestNet,
-  dogecoinTestNet,
-  firoTestNet,
-  litecoinTestNet,
-  peercoinTestNet,
-  stellarTestnet,
-}
-
-extension CoinExt on Coin {
-  String get prettyName {
-    switch (this) {
-      case Coin.bitcoin:
-        return "Bitcoin";
-      case Coin.bitcoinFrost:
-        return "Bitcoin Frost";
-      case Coin.litecoin:
-        return "Litecoin";
-      case Coin.bitcoincash:
-        return "Bitcoin Cash";
-      case Coin.dogecoin:
-        return "Dogecoin";
-      case Coin.epicCash:
-        return "Epic Cash";
-      case Coin.eCash:
-        return "eCash";
-      case Coin.ethereum:
-        return "Ethereum";
-      case Coin.firo:
-        return "Firo";
-      case Coin.monero:
-        return "Monero";
-      case Coin.particl:
-        return "Particl";
-      case Coin.peercoin:
-        return "Peercoin";
-      case Coin.solana:
-        return "Solana";
-      case Coin.stellar:
-        return "Stellar";
-      case Coin.tezos:
-        return "Tezos";
-      case Coin.wownero:
-        return "Wownero";
-      case Coin.namecoin:
-        return "Namecoin";
-      case Coin.nano:
-        return "Nano";
-      case Coin.banano:
-        return "Banano";
-      case Coin.bitcoinTestNet:
-        return "tBitcoin";
-      case Coin.bitcoinFrostTestNet:
-        return "tBitcoin Frost";
-      case Coin.litecoinTestNet:
-        return "tLitecoin";
-      case Coin.bitcoincashTestnet:
-        return "tBitcoin Cash";
-      case Coin.firoTestNet:
-        return "tFiro";
-      case Coin.dogecoinTestNet:
-        return "tDogecoin";
-      case Coin.peercoinTestNet:
-        return "tPeercoin";
-      case Coin.stellarTestnet:
-        return "tStellar";
-    }
-  }
-
-  String get ticker {
-    switch (this) {
-      case Coin.bitcoin:
-      case Coin.bitcoinFrost:
-        return "BTC";
-      case Coin.litecoin:
-        return "LTC";
-      case Coin.bitcoincash:
-        return "BCH";
-      case Coin.dogecoin:
-        return "DOGE";
-      case Coin.epicCash:
-        return "EPIC";
-      case Coin.ethereum:
-        return "ETH";
-      case Coin.eCash:
-        return "XEC";
-      case Coin.firo:
-        return "FIRO";
-      case Coin.monero:
-        return "XMR";
-      case Coin.particl:
-        return "PART";
-      case Coin.peercoin:
-        return "PPC";
-      case Coin.solana:
-        return "SOL";
-      case Coin.stellar:
-        return "XLM";
-      case Coin.tezos:
-        return "XTZ";
-      case Coin.wownero:
-        return "WOW";
-      case Coin.namecoin:
-        return "NMC";
-      case Coin.nano:
-        return "XNO";
-      case Coin.banano:
-        return "BAN";
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoinFrostTestNet:
-        return "tBTC";
-      case Coin.litecoinTestNet:
-        return "tLTC";
-      case Coin.bitcoincashTestnet:
-        return "tBCH";
-      case Coin.firoTestNet:
-        return "tFIRO";
-      case Coin.dogecoinTestNet:
-        return "tDOGE";
-      case Coin.peercoinTestNet:
-        return "tPPC";
-      case Coin.stellarTestnet:
-        return "tXLM";
-    }
-  }
-
-  String get uriScheme {
-    switch (this) {
-      case Coin.bitcoin:
-      case Coin.bitcoinFrost:
-        return "bitcoin";
-      case Coin.litecoin:
-        return "litecoin";
-      case Coin.bitcoincash:
-        return "bitcoincash";
-      case Coin.dogecoin:
-        return "dogecoin";
-      case Coin.epicCash:
-        // TODO: is this actually the right one?
-        return "epic";
-      case Coin.ethereum:
-        return "ethereum";
-      case Coin.eCash:
-        return "ecash";
-      case Coin.firo:
-        return "firo";
-      case Coin.monero:
-        return "monero";
-      case Coin.particl:
-        return "particl";
-      case Coin.peercoin:
-        return "peercoin";
-      case Coin.solana:
-        return "solana";
-      case Coin.stellar:
-        return "stellar";
-      case Coin.tezos:
-        return "tezos";
-      case Coin.wownero:
-        return "wownero";
-      case Coin.namecoin:
-        return "namecoin";
-      case Coin.nano:
-        return "nano";
-      case Coin.banano:
-        return "ban";
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoinFrostTestNet:
-        return "bitcoin";
-      case Coin.litecoinTestNet:
-        return "litecoin";
-      case Coin.bitcoincashTestnet:
-        return "bchtest";
-      case Coin.firoTestNet:
-        return "firo";
-      case Coin.dogecoinTestNet:
-        return "dogecoin";
-      case Coin.peercoinTestNet:
-        return "peercoin";
-      case Coin.stellarTestnet:
-        return "stellar";
-    }
-  }
-
-  bool get hasMnemonicPassphraseSupport {
-    switch (this) {
-      case Coin.bitcoin:
-      case Coin.bitcoinTestNet:
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-      case Coin.dogecoin:
-      case Coin.dogecoinTestNet:
-      case Coin.firo:
-      case Coin.firoTestNet:
-      case Coin.namecoin:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-      case Coin.ethereum:
-      case Coin.eCash:
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        return true;
-
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.epicCash:
-      case Coin.monero:
-      case Coin.wownero:
-      case Coin.nano:
-      case Coin.banano:
-      case Coin.tezos:
-      case Coin.solana:
-        return false;
-    }
-  }
-
-  bool get hasBuySupport {
-    switch (this) {
-      case Coin.bitcoin:
-      case Coin.litecoin:
-      case Coin.bitcoincash:
-      case Coin.dogecoin:
-      case Coin.ethereum:
-        return true;
-
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.firo:
-      case Coin.namecoin:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-      case Coin.eCash:
-      case Coin.epicCash:
-      case Coin.monero:
-      case Coin.tezos:
-      case Coin.wownero:
-      case Coin.dogecoinTestNet:
-      case Coin.bitcoinTestNet:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincashTestnet:
-      case Coin.firoTestNet:
-      case Coin.nano:
-      case Coin.banano:
-      case Coin.solana:
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        return false;
-    }
-  }
-
-  bool get isTestNet {
-    switch (this) {
-      case Coin.bitcoin:
-      case Coin.bitcoinFrost:
-      case Coin.litecoin:
-      case Coin.bitcoincash:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.namecoin:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.epicCash:
-      case Coin.ethereum:
-      case Coin.monero:
-      case Coin.tezos:
-      case Coin.wownero:
-      case Coin.nano:
-      case Coin.banano:
-      case Coin.eCash:
-      case Coin.stellar:
-      case Coin.solana:
-        return false;
-
-      case Coin.dogecoinTestNet:
-      case Coin.bitcoinTestNet:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.litecoinTestNet:
-      case Coin.bitcoincashTestnet:
-      case Coin.firoTestNet:
-      case Coin.peercoinTestNet:
-      case Coin.stellarTestnet:
-        return true;
-    }
-  }
-
-  bool get isFrost {
-    switch (this) {
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-        return true;
-
-      default:
-        return false;
-    }
-  }
-
-  Coin get mainNetVersion {
-    switch (this) {
-      case Coin.bitcoin:
-      case Coin.bitcoinFrost:
-      case Coin.litecoin:
-      case Coin.bitcoincash:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.namecoin:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.epicCash:
-      case Coin.ethereum:
-      case Coin.monero:
-      case Coin.tezos:
-      case Coin.wownero:
-      case Coin.nano:
-      case Coin.banano:
-      case Coin.eCash:
-      case Coin.stellar:
-      case Coin.solana:
-        return this;
-
-      case Coin.dogecoinTestNet:
-        return Coin.dogecoin;
-
-      case Coin.bitcoinTestNet:
-        return Coin.bitcoin;
-
-      case Coin.bitcoinFrostTestNet:
-        return Coin.bitcoinFrost;
-
-      case Coin.litecoinTestNet:
-        return Coin.litecoin;
-
-      case Coin.bitcoincashTestnet:
-        return Coin.bitcoincash;
-
-      case Coin.firoTestNet:
-        return Coin.firo;
-
-      case Coin.peercoinTestNet:
-        return Coin.peercoin;
-
-      case Coin.stellarTestnet:
-        return Coin.stellar;
-    }
-  }
-
-  int get decimals => Constants.decimalPlacesForCoin(this);
-
-  // Note: this must relate to DerivePathType for certain coins!
-  AddressType get primaryAddressType {
-    switch (this) {
-      case Coin.bitcoin:
-      case Coin.bitcoinTestNet:
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-      case Coin.namecoin:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-        return AddressType.p2wpkh;
-
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-        return AddressType.frostMS;
-
-      case Coin.eCash:
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.firoTestNet:
-      case Coin.dogecoinTestNet:
-        return AddressType.p2pkh;
-
-      case Coin.monero:
-      case Coin.wownero:
-        return AddressType.cryptonote;
-
-      case Coin.epicCash:
-        return AddressType.mimbleWimble;
-
-      case Coin.ethereum:
-        return AddressType.ethereum;
-
-      case Coin.tezos:
-        return AddressType.tezos;
-
-      case Coin.nano:
-        return AddressType.nano;
-
-      case Coin.banano:
-        return AddressType.banano;
-
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        return AddressType.stellar;
-
-      case Coin.solana:
-        return AddressType.solana;
-    }
-  }
-}
-
-Coin coinFromPrettyName(String name) {
-  switch (name) {
-    case "Bitcoin":
-    case "bitcoin":
-      return Coin.bitcoin;
-
-    case "Litecoin":
-    case "litecoin":
-      return Coin.litecoin;
-
-    case "Bitcoincash":
-    case "bitcoincash":
-    case "Bitcoin Cash":
-      return Coin.bitcoincash;
-
-    case "Dogecoin":
-    case "dogecoin":
-      return Coin.dogecoin;
-
-    case "Epic Cash":
-    case "epicCash":
-      return Coin.epicCash;
-
-    case "Ethereum":
-    case "ethereum":
-      return Coin.ethereum;
-
-    case "Firo":
-    case "firo":
-      return Coin.firo;
-
-    case "E-Cash":
-    case "ecash":
-    case "eCash":
-      return Coin.eCash;
-
-    case "Monero":
-    case "monero":
-      return Coin.monero;
-
-    case "Particl":
-    case "particl":
-      return Coin.particl;
-
-    case "Peercoin":
-    case "peercoin":
-      return Coin.peercoin;
-
-    case "tPeercoin":
-    case "Peercoin Testnet":
-    case "peercoinTestNet":
-      return Coin.peercoinTestNet;
-
-    case "Solana":
-    case "solana":
-      return Coin.solana;
-
-    case "Stellar":
-    case "stellar":
-      return Coin.stellar;
-
-    case "Tezos":
-    case "tezos":
-      return Coin.tezos;
-
-    case "Namecoin":
-    case "namecoin":
-      return Coin.namecoin;
-
-    case "Bitcoin Testnet":
-    case "tBitcoin":
-    case "bitcoinTestNet":
-      return Coin.bitcoinTestNet;
-
-    case "Litecoin Testnet":
-    case "tlitecoin":
-    case "litecoinTestNet":
-    case "tLitecoin":
-      return Coin.litecoinTestNet;
-
-    case "Bitcoincash Testnet":
-    case "tBitcoin Cash":
-    case "Bitcoin Cash Testnet":
-    case "bitcoincashTestnet":
-      return Coin.bitcoincashTestnet;
-
-    case "Firo Testnet":
-    case "tFiro":
-    case "firoTestNet":
-      return Coin.firoTestNet;
-
-    case "Dogecoin Testnet":
-    case "tDogecoin":
-    case "dogecoinTestNet":
-      return Coin.dogecoinTestNet;
-
-    case "Wownero":
-    case "tWownero":
-    case "wownero":
-      return Coin.wownero;
-
-    case "Nano":
-    case "nano":
-      return Coin.nano;
-
-    case "Banano":
-    case "banano":
-      return Coin.banano;
-
-    case "Stellar Testnet":
-    case "stellarTestnet":
-    case "stellarTestNet":
-    case "tStellar":
-      return Coin.stellarTestnet;
-
-    case "Bitcoin Frost":
-    case "bitcoinFrost":
-      return Coin.bitcoinFrost;
-
-    case "Bitcoin Frost Testnet":
-    case "tBitcoin Frost":
-    case "bitcoinFrostTestNet":
-      return Coin.bitcoinFrostTestNet;
-
-    default:
-      throw ArgumentError.value(
-        name,
-        "name",
-        "No Coin enum value with that prettyName",
-      );
-  }
-}
-
-Coin coinFromTickerCaseInsensitive(String ticker) {
-  switch (ticker.toLowerCase()) {
-    case "btc":
-      return Coin.bitcoin;
-    case "ltc":
-      return Coin.litecoin;
-    case "bch":
-      return Coin.bitcoincash;
-    case "doge":
-      return Coin.dogecoin;
-    case "epic":
-      return Coin.epicCash;
-    case "xec":
-      return Coin.eCash;
-    case "eth":
-      return Coin.ethereum;
-    case "firo":
-      return Coin.firo;
-    case "xmr":
-      return Coin.monero;
-    case "nmc":
-      return Coin.namecoin;
-    case "part":
-      return Coin.particl;
-    case "sol":
-      return Coin.solana;
-    case "xlm":
-      return Coin.stellar;
-    case "xtz":
-      return Coin.tezos;
-    case "tltc":
-      return Coin.litecoinTestNet;
-    case "tbtc":
-      return Coin.bitcoinTestNet;
-    case "tbch":
-      return Coin.bitcoincashTestnet;
-    case "tfiro":
-      return Coin.firoTestNet;
-    case "tdoge":
-      return Coin.dogecoinTestNet;
-    case "wow":
-      return Coin.wownero;
-    case "xno":
-      return Coin.nano;
-    case "ban":
-      return Coin.banano;
-    case "txlm":
-      return Coin.stellarTestnet;
-    default:
-      throw ArgumentError.value(
-          ticker, "name", "No Coin enum value with that ticker");
-  }
-}
diff --git a/lib/utilities/enums/derive_path_type_enum.dart b/lib/utilities/enums/derive_path_type_enum.dart
index 4dcaef022..d17a6584a 100644
--- a/lib/utilities/enums/derive_path_type_enum.dart
+++ b/lib/utilities/enums/derive_path_type_enum.dart
@@ -9,7 +9,6 @@
  */
 
 import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 enum DerivePathType {
   bip44,
@@ -45,49 +44,3 @@ enum DerivePathType {
     }
   }
 }
-
-extension DerivePathTypeExt on DerivePathType {
-  static DerivePathType primaryFor(Coin coin) {
-    switch (coin) {
-      case Coin.bitcoincash:
-      case Coin.bitcoincashTestnet:
-      case Coin.dogecoin:
-      case Coin.dogecoinTestNet:
-      case Coin.firo:
-      case Coin.firoTestNet:
-        return DerivePathType.bip44;
-
-      case Coin.bitcoin:
-      case Coin.bitcoinTestNet:
-      case Coin.litecoin:
-      case Coin.litecoinTestNet:
-      case Coin.namecoin:
-      case Coin.particl:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-        return DerivePathType.bip84;
-
-      case Coin.eCash:
-        return DerivePathType.eCash44;
-
-      case Coin.ethereum: // TODO: do we need something here?
-        return DerivePathType.eth;
-
-      case Coin.solana:
-        return DerivePathType.solana;
-
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.epicCash:
-      case Coin.monero:
-      case Coin.wownero:
-      case Coin.nano:
-      case Coin.banano:
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-      case Coin.tezos: // TODO: Is this true?
-        throw UnsupportedError(
-            "$coin does not use bitcoin style derivation paths");
-    }
-  }
-}
diff --git a/lib/utilities/eth_commons.dart b/lib/utilities/eth_commons.dart
index f6561c8d5..f2c802111 100644
--- a/lib/utilities/eth_commons.dart
+++ b/lib/utilities/eth_commons.dart
@@ -12,8 +12,8 @@ import 'package:bip32/bip32.dart' as bip32;
 import 'package:bip39/bip39.dart' as bip39;
 import 'package:decimal/decimal.dart';
 import "package:hex/hex.dart";
-import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class GasTracker {
   final Decimal average;
@@ -37,7 +37,8 @@ class GasTracker {
   });
 
   factory GasTracker.fromJson(Map<String, dynamic> json) {
-    final targetTime = Constants.targetBlockTimeInSeconds(Coin.ethereum);
+    final targetTime =
+        Ethereum(CryptoCurrencyNetwork.main).targetBlockTimeSeconds;
     return GasTracker(
       fast: Decimal.parse(json["FastGasPrice"].toString()),
       average: Decimal.parse(json["ProposeGasPrice"].toString()),
diff --git a/lib/utilities/prefs.dart b/lib/utilities/prefs.dart
index 07726bdf1..74453c50c 100644
--- a/lib/utilities/prefs.dart
+++ b/lib/utilities/prefs.dart
@@ -14,12 +14,13 @@ import 'package:flutter/cupertino.dart';
 import 'package:stackwallet/db/hive/db.dart';
 import 'package:stackwallet/services/event_bus/events/global/tor_status_changed_event.dart';
 import 'package:stackwallet/services/event_bus/global_event_bus.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/utilities/amount/amount_unit.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/languages_enum.dart';
 import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart';
 import 'package:uuid/uuid.dart';
 
@@ -847,15 +848,17 @@ class Prefs extends ChangeNotifier {
 
   // coin amount unit settings
 
-  final Map<Coin, AmountUnit> _amountUnits = {};
+  final Map<CryptoCurrency, AmountUnit> _amountUnits = {};
 
-  AmountUnit amountUnit(Coin coin) => _amountUnits[coin] ?? AmountUnit.normal;
+  AmountUnit amountUnit(CryptoCurrency coin) =>
+      _amountUnits[coin] ?? AmountUnit.normal;
 
-  void updateAmountUnit({required Coin coin, required AmountUnit amountUnit}) {
+  void updateAmountUnit(
+      {required CryptoCurrency coin, required AmountUnit amountUnit}) {
     if (this.amountUnit(coin) != amountUnit) {
       DB.instance.put<dynamic>(
         boxName: DB.boxNamePrefs,
-        key: "amountUnitFor${coin.name}",
+        key: "amountUnitFor${coin.identifier}",
         value: amountUnit.index,
       );
       _amountUnits[coin] = amountUnit;
@@ -864,10 +867,10 @@ class Prefs extends ChangeNotifier {
   }
 
   Future<void> _setAmountUnits() async {
-    for (final coin in Coin.values) {
+    for (final coin in SupportedCoins.cryptocurrencies) {
       final unitIndex = await DB.instance.get<dynamic>(
             boxName: DB.boxNamePrefs,
-            key: "amountUnitFor${coin.name}",
+            key: "amountUnitFor${coin.identifier}",
           ) as int? ??
           0; // 0 is "normal"
       _amountUnits[coin] = AmountUnit.values[unitIndex];
@@ -876,31 +879,35 @@ class Prefs extends ChangeNotifier {
 
   // coin precision setting (max decimal places to show)
 
-  final Map<Coin, int> _amountDecimals = {};
+  final Map<String, int> _amountDecimals = {};
 
-  int maxDecimals(Coin coin) => _amountDecimals[coin] ?? coin.decimals;
+  int maxDecimals(CryptoCurrency coin) =>
+      _amountDecimals[coin.identifier] ?? coin.fractionDigits;
 
-  void updateMaxDecimals({required Coin coin, required int maxDecimals}) {
+  void updateMaxDecimals({
+    required CryptoCurrency coin,
+    required int maxDecimals,
+  }) {
     if (this.maxDecimals(coin) != maxDecimals) {
       DB.instance.put<dynamic>(
         boxName: DB.boxNamePrefs,
-        key: "maxDecimalsFor${coin.name}",
+        key: "maxDecimalsFor${coin.identifier}",
         value: maxDecimals,
       );
-      _amountDecimals[coin] = maxDecimals;
+      _amountDecimals[coin.identifier] = maxDecimals;
       notifyListeners();
     }
   }
 
   Future<void> _setMaxDecimals() async {
-    for (final coin in Coin.values) {
+    for (final coin in SupportedCoins.cryptocurrencies) {
       final decimals = await DB.instance.get<dynamic>(
             boxName: DB.boxNamePrefs,
-            key: "maxDecimalsFor${coin.name}",
+            key: "maxDecimalsFor${coin.identifier}",
           ) as int? ??
-          (coin.decimals > 18 ? 18 : coin.decimals);
+          (coin.fractionDigits > 18 ? 18 : coin.fractionDigits);
       // use some sane max rather than up to 30 that nano uses
-      _amountDecimals[coin] = decimals;
+      _amountDecimals[coin.identifier] = decimals;
     }
   }
 
@@ -938,22 +945,23 @@ class Prefs extends ChangeNotifier {
 
   // fusion server info
 
-  Map<Coin, FusionInfo> _fusionServerInfo = {};
+  Map<String, FusionInfo> _fusionServerInfo = {};
 
-  FusionInfo getFusionServerInfo(Coin coin) {
-    return _fusionServerInfo[coin] ?? kFusionServerInfoDefaults[coin]!;
+  FusionInfo getFusionServerInfo(CryptoCurrency coin) {
+    return _fusionServerInfo[coin.identifier] ??
+        kFusionServerInfoDefaults[coin.identifier]!;
   }
 
-  void setFusionServerInfo(Coin coin, FusionInfo fusionServerInfo) {
-    if (_fusionServerInfo[coin] != fusionServerInfo) {
-      _fusionServerInfo[coin] = fusionServerInfo;
+  void setFusionServerInfo(CryptoCurrency coin, FusionInfo fusionServerInfo) {
+    if (_fusionServerInfo[coin.identifier] != fusionServerInfo) {
+      _fusionServerInfo[coin.identifier] = fusionServerInfo;
 
       DB.instance.put<dynamic>(
         boxName: DB.boxNamePrefs,
         key: "fusionServerInfoMap",
         value: _fusionServerInfo.map(
           (key, value) => MapEntry(
-            key.name,
+            key,
             value.toJsonString(),
           ),
         ),
@@ -962,7 +970,7 @@ class Prefs extends ChangeNotifier {
     }
   }
 
-  Future<Map<Coin, FusionInfo>> _getFusionServerInfo() async {
+  Future<Map<String, FusionInfo>> _getFusionServerInfo() async {
     final map = await DB.instance.get<dynamic>(
       boxName: DB.boxNamePrefs,
       key: "fusionServerInfoMap",
@@ -974,14 +982,14 @@ class Prefs extends ChangeNotifier {
 
     final actualMap = Map<String, String>.from(map).map(
       (key, value) => MapEntry(
-        coinFromPrettyName(key),
+        key,
         FusionInfo.fromJsonString(value),
       ),
     );
 
     // legacy bch check
-    if (actualMap[Coin.bitcoincash] == null ||
-        actualMap[Coin.bitcoincashTestnet] == null) {
+    if (actualMap["bitcoincash"] == null ||
+        actualMap["bitcoincashTestnet"] == null) {
       final saved = await DB.instance.get<dynamic>(
         boxName: DB.boxNamePrefs,
         key: "fusionServerInfo",
@@ -989,15 +997,15 @@ class Prefs extends ChangeNotifier {
 
       if (saved != null) {
         final bchInfo = FusionInfo.fromJsonString(saved);
-        actualMap[Coin.bitcoincash] = bchInfo;
-        actualMap[Coin.bitcoincashTestnet] = bchInfo;
+        actualMap["bitcoincash"] = bchInfo;
+        actualMap["bitcoincashTestnet"] = bchInfo;
         unawaited(
           DB.instance.put<dynamic>(
             boxName: DB.boxNamePrefs,
             key: "fusionServerInfoMap",
             value: actualMap.map(
               (key, value) => MapEntry(
-                key.name,
+                key,
                 value.toJsonString(),
               ),
             ),
diff --git a/lib/utilities/test_node_connection.dart b/lib/utilities/test_node_connection.dart
new file mode 100644
index 000000000..2113766b1
--- /dev/null
+++ b/lib/utilities/test_node_connection.dart
@@ -0,0 +1,198 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:solana/solana.dart';
+import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart';
+import 'package:stackwallet/providers/global/prefs_provider.dart';
+import 'package:stackwallet/services/tor_service.dart';
+import 'package:stackwallet/utilities/connection_check/electrum_connection_check.dart';
+import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/utilities/test_epic_box_connection.dart';
+import 'package:stackwallet/utilities/test_eth_node_connection.dart';
+import 'package:stackwallet/utilities/test_monero_node_connection.dart';
+import 'package:stackwallet/utilities/test_stellar_node_connection.dart';
+import 'package:stackwallet/wallets/api/tezos/tezos_rpc_api.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin_frost.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/solana.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/cryptonote_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
+
+Future<bool> _xmrHelper(
+  NodeFormData nodeFormData,
+  BuildContext context,
+  void Function(NodeFormData)? onSuccess,
+) async {
+  final data = nodeFormData;
+  final url = data.host!;
+  final port = data.port;
+
+  final uri = Uri.parse(url);
+
+  final String path = uri.path.isEmpty ? "/json_rpc" : uri.path;
+
+  final uriString = "${uri.scheme}://${uri.host}:${port ?? 0}$path";
+
+  final response = await testMoneroNodeConnection(
+    Uri.parse(uriString),
+    false,
+  );
+
+  if (response.cert != null) {
+    if (context.mounted) {
+      final shouldAllowBadCert = await showBadX509CertificateDialog(
+        response.cert!,
+        response.url!,
+        response.port!,
+        context,
+      );
+
+      if (shouldAllowBadCert) {
+        final response =
+            await testMoneroNodeConnection(Uri.parse(uriString), true);
+        onSuccess?.call(data..host = url);
+        return response.success;
+      }
+    }
+  } else {
+    onSuccess?.call(data..host = url);
+    return response.success;
+  }
+
+  return false;
+}
+
+// TODO: probably pull this into each coin's functionality otherwise updating this separately will get irritating
+Future<bool> testNodeConnection({
+  required BuildContext context,
+  required NodeFormData nodeFormData,
+  required CryptoCurrency cryptoCurrency,
+  required WidgetRef ref,
+  void Function(NodeFormData)? onSuccess,
+}) async {
+  final formData = nodeFormData;
+
+  bool testPassed = false;
+
+  switch (cryptoCurrency) {
+    case Epiccash():
+      try {
+        final data = await testEpicNodeConnection(formData);
+
+        if (data != null) {
+          testPassed = true;
+          onSuccess?.call(data);
+        }
+      } catch (e, s) {
+        Logging.instance.log("$e\n$s", level: LogLevel.Warning);
+      }
+      break;
+
+    case CryptonoteCurrency():
+      try {
+        final url = formData.host!;
+        final uri = Uri.tryParse(url);
+        if (uri != null) {
+          if (!uri.hasScheme) {
+            // try https first
+            testPassed = await _xmrHelper(
+              formData
+                ..host = "https://$url"
+                ..useSSL = true,
+              context,
+              onSuccess,
+            );
+
+            if (testPassed == false) {
+              // try http
+              testPassed = await _xmrHelper(
+                formData
+                  ..host = "http://$url"
+                  ..useSSL = false,
+                context,
+                onSuccess,
+              );
+            }
+          } else {
+            testPassed = await _xmrHelper(
+              formData
+                ..host = url
+                ..useSSL = true,
+              context,
+              onSuccess,
+            );
+          }
+        }
+      } catch (e, s) {
+        Logging.instance.log("$e\n$s", level: LogLevel.Warning);
+      }
+
+      break;
+
+    case ElectrumXCurrencyInterface():
+    case BitcoinFrost():
+      try {
+        testPassed = await checkElectrumServer(
+          host: formData.host!,
+          port: formData.port!,
+          useSSL: formData.useSSL!,
+          overridePrefs: ref.read(prefsChangeNotifierProvider),
+          overrideTorService: ref.read(pTorService),
+        );
+      } catch (_) {
+        testPassed = false;
+      }
+
+      break;
+
+    case Ethereum():
+      try {
+        testPassed = await testEthNodeConnection(formData.host!);
+      } catch (_) {
+        testPassed = false;
+      }
+      break;
+
+    case Stellar():
+      try {
+        testPassed =
+            await testStellarNodeConnection(formData.host!, formData.port!);
+      } catch (_) {}
+      break;
+
+    case NanoCurrency():
+      //TODO: check network/node
+      throw UnimplementedError();
+
+    case Tezos():
+      try {
+        testPassed = await TezosRpcAPI.testNetworkConnection(
+          nodeInfo: (host: formData.host!, port: formData.port!),
+        );
+      } catch (_) {}
+      break;
+
+    case Solana():
+      try {
+        RpcClient rpcClient;
+        if (formData.host!.startsWith("http") ||
+            formData.host!.startsWith("https")) {
+          rpcClient = RpcClient("${formData.host}:${formData.port}");
+        } else {
+          rpcClient = RpcClient("http://${formData.host}:${formData.port}");
+        }
+        await rpcClient.getEpochInfo().then((value) => testPassed = true);
+      } catch (_) {
+        testPassed = false;
+      }
+      break;
+  }
+
+  return testPassed;
+}
diff --git a/lib/wallets/crypto_currency/coins/banano.dart b/lib/wallets/crypto_currency/coins/banano.dart
index dfae1b78c..c2cb52345 100644
--- a/lib/wallets/crypto_currency/coins/banano.dart
+++ b/lib/wallets/crypto_currency/coins/banano.dart
@@ -1,7 +1,8 @@
 import 'package:nanodart/nanodart.dart';
+import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 
@@ -9,15 +10,50 @@ class Banano extends NanoCurrency {
   Banano(super.network) {
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.banano;
+        _id = "banano";
+        _idMain = "banano";
+        _name = "Banano";
+        _uriScheme = "ban";
+        _ticker = "BAN";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
+  @override
+  int get fractionDigits => 29;
+
+  @override
+  BigInt get satsPerCoin => BigInt.parse(
+        "100000000000000000000000000000",
+      ); // 1*10^29
+
   @override
   int get minConfirms => 1;
 
+  @override
+  AddressType get primaryAddressType => AddressType.banano;
+
   @override
   String get defaultRepresentative =>
       "ban_1ka1ium4pfue3uxtntqsrib8mumxgazsjf58gidh1xeo5te3whsq8z476goo";
@@ -33,10 +69,10 @@ class Banano extends NanoCurrency {
           host: "https://kaliumapi.appditto.com/api",
           port: 443,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.banano),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.banano.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -47,10 +83,19 @@ class Banano extends NanoCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Banano && other.network == network;
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://www.bananolooker.com/block/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
   }
 
   @override
-  int get hashCode => Object.hash(Banano, network);
+  DerivePathType get primaryDerivePathType => throw UnsupportedError(
+        "$runtimeType does not use bitcoin style derivation paths",
+      );
 }
diff --git a/lib/wallets/crypto_currency/coins/bitcoin.dart b/lib/wallets/crypto_currency/coins/bitcoin.dart
index e0126ede1..e989e51e5 100644
--- a/lib/wallets/crypto_currency/coins/bitcoin.dart
+++ b/lib/wallets/crypto_currency/coins/bitcoin.dart
@@ -3,24 +3,51 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/interfaces/paynym_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 
-class Bitcoin extends Bip39HDCurrency with PaynymCurrencyInterface {
+class Bitcoin extends Bip39HDCurrency
+    with ElectrumXCurrencyInterface, PaynymCurrencyInterface {
   Bitcoin(super.network) {
+    _idMain = "bitcoin";
+    _uriScheme = "bitcoin";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.bitcoin;
+        _id = _idMain;
+        _name = "Bitcoin";
+        _ticker = "BTC";
       case CryptoCurrencyNetwork.test:
-        coin = Coin.bitcoinTestNet;
+        _id = "bitcoinTestNet";
+        _name = "tBitcoin";
+        _ticker = "tBTC";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   // change this to change the number of confirms a tx needs in order to show as confirmed
   int get minConfirms => 1;
@@ -194,10 +221,30 @@ class Bitcoin extends Bip39HDCurrency with PaynymCurrencyInterface {
   NodeModel get defaultNode {
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        return DefaultNodes.bitcoin;
+        return NodeModel(
+          host: "bitcoin.stackwallet.com",
+          port: 50002,
+          name: DefaultNodes.defaultName,
+          id: DefaultNodes.buildId(this),
+          useSSL: true,
+          enabled: true,
+          coinName: identifier,
+          isFailover: true,
+          isDown: false,
+        );
 
       case CryptoCurrencyNetwork.test:
-        return DefaultNodes.bitcoinTestnet;
+        return NodeModel(
+          host: "bitcoin-testnet.stackwallet.com",
+          port: 51002,
+          name: DefaultNodes.defaultName,
+          id: DefaultNodes.buildId(this),
+          useSSL: true,
+          enabled: true,
+          coinName: identifier,
+          isFailover: true,
+          isDown: false,
+        );
 
       default:
         throw UnimplementedError();
@@ -205,10 +252,43 @@ class Bitcoin extends Bip39HDCurrency with PaynymCurrencyInterface {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Bitcoin && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Bitcoin, network);
+  int get fractionDigits => 8;
+
+  @override
+  bool get hasBuySupport => true;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.p2wpkh;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000);
+
+  @override
+  int get targetBlockTimeSeconds => 600;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.bip84;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://mempool.space/tx/$txid");
+      case CryptoCurrencyNetwork.test:
+        return Uri.parse("https://mempool.space/testnet/tx/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/bitcoin_frost.dart b/lib/wallets/crypto_currency/coins/bitcoin_frost.dart
index bd5216350..3c7973599 100644
--- a/lib/wallets/crypto_currency/coins/bitcoin_frost.dart
+++ b/lib/wallets/crypto_currency/coins/bitcoin_frost.dart
@@ -1,25 +1,53 @@
 import 'dart:typed_data';
 
+import 'package:coinlib_flutter/coinlib_flutter.dart' as coinlib;
+import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/frost_currency.dart';
 
 class BitcoinFrost extends FrostCurrency {
   BitcoinFrost(super.network) {
+    _idMain = "bitcoinFrost";
+    _uriScheme = "bitcoin";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.bitcoinFrost;
+        _id = _idMain;
+        _name = "Bitcoin Frost";
+        _ticker = "BTC";
       case CryptoCurrencyNetwork.test:
-        coin = Coin.bitcoinFrostTestNet;
+        _id = "bitcoinFrostTestNet";
+        _name = "tBitcoin Frost";
+        _ticker = "tBTC";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   int get minConfirms => 1;
 
@@ -30,10 +58,30 @@ class BitcoinFrost extends FrostCurrency {
   NodeModel get defaultNode {
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        return DefaultNodes.bitcoin;
+        return NodeModel(
+          host: "bitcoin.stackwallet.com",
+          port: 50002,
+          name: DefaultNodes.defaultName,
+          id: DefaultNodes.buildId(this),
+          useSSL: true,
+          enabled: true,
+          coinName: identifier,
+          isFailover: true,
+          isDown: false,
+        );
 
       case CryptoCurrencyNetwork.test:
-        return DefaultNodes.bitcoinTestnet;
+        return NodeModel(
+          host: "bitcoin-testnet.stackwallet.com",
+          port: 51002,
+          name: DefaultNodes.defaultName,
+          id: DefaultNodes.buildId(this),
+          useSSL: true,
+          enabled: true,
+          coinName: identifier,
+          isFailover: true,
+          isDown: false,
+        );
 
       default:
         throw UnimplementedError();
@@ -67,17 +115,89 @@ class BitcoinFrost extends FrostCurrency {
     }
   }
 
+  coinlib.Network get networkParams {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return coinlib.Network(
+          wifPrefix: 0x80,
+          p2pkhPrefix: 0x00,
+          p2shPrefix: 0x05,
+          privHDPrefix: 0x0488ade4,
+          pubHDPrefix: 0x0488b21e,
+          bech32Hrp: "bc",
+          messagePrefix: '\x18Bitcoin Signed Message:\n',
+          minFee: BigInt.from(1), // TODO [prio=high].
+          minOutput: dustLimit.raw, // TODO.
+          feePerKb: BigInt.from(1), // TODO.
+        );
+      case CryptoCurrencyNetwork.test:
+        return coinlib.Network(
+          wifPrefix: 0xef,
+          p2pkhPrefix: 0x6f,
+          p2shPrefix: 0xc4,
+          privHDPrefix: 0x04358394,
+          pubHDPrefix: 0x043587cf,
+          bech32Hrp: "tb",
+          messagePrefix: "\x18Bitcoin Signed Message:\n",
+          minFee: BigInt.from(1), // TODO [prio=high].
+          minOutput: dustLimit.raw, // TODO.
+          feePerKb: BigInt.from(1), // TODO.
+        );
+      default:
+        throw Exception("Unsupported network: $network");
+    }
+  }
+
   @override
   bool validateAddress(String address) {
-    // TODO: implement validateAddress for frost addresses
-    return true;
+    try {
+      coinlib.Address.fromString(address, networkParams);
+      return true;
+    } catch (_) {
+      return false;
+    }
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is BitcoinFrost && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 0;
 
   @override
-  int get hashCode => Object.hash(BitcoinFrost, network);
+  int get fractionDigits => 8;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => false;
+
+  @override
+  List<int> get possibleMnemonicLengths => [];
+
+  @override
+  AddressType get primaryAddressType => AddressType.frostMS;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000);
+
+  @override
+  int get targetBlockTimeSeconds => 600;
+
+  @override
+  DerivePathType get primaryDerivePathType => throw UnsupportedError(
+        "$runtimeType does not use bitcoin style derivation paths",
+      );
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://mempool.space/tx/$txid");
+      case CryptoCurrencyNetwork.test:
+        return Uri.parse("https://mempool.space/testnet/tx/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/bitcoincash.dart b/lib/wallets/crypto_currency/coins/bitcoincash.dart
index 168e0223a..9059e0358 100644
--- a/lib/wallets/crypto_currency/coins/bitcoincash.dart
+++ b/lib/wallets/crypto_currency/coins/bitcoincash.dart
@@ -8,23 +8,50 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 
-class Bitcoincash extends Bip39HDCurrency {
+class Bitcoincash extends Bip39HDCurrency with ElectrumXCurrencyInterface {
   Bitcoincash(super.network) {
+    _idMain = "bitcoincash";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.bitcoincash;
+        _id = _idMain;
+        _name = "Bitcoin Cash";
+        _ticker = "BCH";
+        _uriScheme = "bitcoincash";
       case CryptoCurrencyNetwork.test:
-        coin = Coin.bitcoincashTestnet;
+        _id = "bitcoincashTestnet";
+        _name = "tBitcoin Cash";
+        _ticker = "tBCH";
+        _uriScheme = "bchtest";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   int get maxUnusedAddressGap => 50;
   @override
@@ -40,7 +67,7 @@ class Bitcoincash extends Bip39HDCurrency {
   @override
   List<DerivePathType> get supportedDerivationPathTypes => [
         DerivePathType.bip44,
-        if (coin != Coin.bitcoincashTestnet) DerivePathType.bch44,
+        if (network != CryptoCurrencyNetwork.test) DerivePathType.bch44,
       ];
 
   @override
@@ -181,7 +208,7 @@ class Bitcoincash extends Bip39HDCurrency {
       // 0 for bitcoincash: address scheme, 1 for legacy address
       final format = bitbox.Address.detectFormat(address);
 
-      if (coin == Coin.bitcoincashTestnet) {
+      if (network == CryptoCurrencyNetwork.test) {
         return true;
       }
 
@@ -264,10 +291,10 @@ class Bitcoincash extends Bip39HDCurrency {
           host: "bitcoincash.stackwallet.com",
           port: 50002,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.bitcoincash),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.bitcoincash.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -277,10 +304,10 @@ class Bitcoincash extends Bip39HDCurrency {
           host: "bitcoincash-testnet.stackwallet.com",
           port: 60002,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.bitcoincashTestnet),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.bitcoincashTestnet.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -291,10 +318,47 @@ class Bitcoincash extends Bip39HDCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Bitcoincash && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Bitcoincash, network);
+  int get fractionDigits => 8;
+
+  @override
+  bool get hasBuySupport => true;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.p2pkh;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000);
+
+  @override
+  int get targetBlockTimeSeconds => 600;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.bip44;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse(
+          "https://blockchair.com/bitcoin-cash/transaction/$txid",
+        );
+      case CryptoCurrencyNetwork.test:
+        return Uri.parse(
+          "https://blockexplorer.one/bitcoin-cash/testnet/tx/$txid",
+        );
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/dogecoin.dart b/lib/wallets/crypto_currency/coins/dogecoin.dart
index 26abdaa85..7019df2f6 100644
--- a/lib/wallets/crypto_currency/coins/dogecoin.dart
+++ b/lib/wallets/crypto_currency/coins/dogecoin.dart
@@ -3,23 +3,49 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 
-class Dogecoin extends Bip39HDCurrency {
+class Dogecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
   Dogecoin(super.network) {
+    _idMain = "dogecoin";
+    _uriScheme = "dogecoin";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.dogecoin;
+        _id = _idMain;
+        _name = "Dogecoin";
+        _ticker = "DOGE";
       case CryptoCurrencyNetwork.test:
-        coin = Coin.dogecoinTestNet;
+        _id = "dogecoinTestNet";
+        _name = "tDogecoin";
+        _ticker = "tDOGE";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   bool get torSupport => true;
 
@@ -64,7 +90,7 @@ class Dogecoin extends Bip39HDCurrency {
   @override
   Amount get dustLimit => Amount(
         rawValue: BigInt.from(1000000),
-        fractionDigits: Coin.particl.decimals,
+        fractionDigits: fractionDigits,
       );
 
   @override
@@ -156,10 +182,10 @@ class Dogecoin extends Bip39HDCurrency {
           host: "dogecoin.stackwallet.com",
           port: 50022,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.dogecoin),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.dogecoin.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -169,10 +195,10 @@ class Dogecoin extends Bip39HDCurrency {
           host: "dogecoin-testnet.stackwallet.com",
           port: 50022,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.dogecoinTestNet),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.dogecoinTestNet.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -183,10 +209,43 @@ class Dogecoin extends Bip39HDCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Dogecoin && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Dogecoin, network);
+  int get fractionDigits => 8;
+
+  @override
+  bool get hasBuySupport => true;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.p2pkh;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000);
+
+  @override
+  int get targetBlockTimeSeconds => 60;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.bip44;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://chain.so/tx/DOGE/$txid");
+      case CryptoCurrencyNetwork.test:
+        return Uri.parse("https://chain.so/tx/DOGETEST/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/ecash.dart b/lib/wallets/crypto_currency/coins/ecash.dart
index 6c068ed4d..9cec2f9cb 100644
--- a/lib/wallets/crypto_currency/coins/ecash.dart
+++ b/lib/wallets/crypto_currency/coins/ecash.dart
@@ -8,21 +8,45 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 
-class Ecash extends Bip39HDCurrency {
+class Ecash extends Bip39HDCurrency with ElectrumXCurrencyInterface {
   Ecash(super.network) {
+    _idMain = "eCash";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.eCash;
+        _id = _idMain;
+        _name = "eCash";
+        _ticker = "XEC";
+        _uriScheme = "ecash";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   int get maxUnusedAddressGap => 50;
   @override
@@ -254,13 +278,15 @@ class Ecash extends Bip39HDCurrency {
     switch (network) {
       case CryptoCurrencyNetwork.main:
         return NodeModel(
+          // host: "ecash.stackwallet.com",
+          // port: 59002,
           host: "electrum.bitcoinabc.org",
           port: 50002,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.eCash),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.eCash.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -271,10 +297,41 @@ class Ecash extends Bip39HDCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Ecash && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Ecash, network);
+  int get fractionDigits => 2;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.p2pkh;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100);
+
+  @override
+  int get targetBlockTimeSeconds => 600;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.eCash44;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://explorer.e.cash/tx/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/epiccash.dart b/lib/wallets/crypto_currency/coins/epiccash.dart
index 49d7a7a7f..4c49bee5e 100644
--- a/lib/wallets/crypto_currency/coins/epiccash.dart
+++ b/lib/wallets/crypto_currency/coins/epiccash.dart
@@ -1,20 +1,45 @@
 import 'package:flutter_libepiccash/lib.dart' as epic;
+import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_currency.dart';
 
 class Epiccash extends Bip39Currency {
   Epiccash(super.network) {
+    _idMain = "epicCash";
+    _uriScheme = "epic"; // ?
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.epicCash;
+        _id = _idMain;
+        _name = "Epic Cash";
+        _ticker = "EPIC";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   String get genesisHash {
     return "not used in epiccash";
@@ -45,16 +70,15 @@ class Epiccash extends Bip39Currency {
     switch (network) {
       case CryptoCurrencyNetwork.main:
         return NodeModel(
-          host: "https://wownero.stackwallet.com",
-          port: 34568,
+          host: "http://epiccash.stackwallet.com",
+          port: 3413,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.wownero),
-          useSSL: true,
+          id: DefaultNodes.buildId(this),
+          useSSL: false,
           enabled: true,
-          coinName: Coin.wownero.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
-          trusted: true,
         );
 
       default:
@@ -63,10 +87,41 @@ class Epiccash extends Bip39Currency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Epiccash && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 24;
 
   @override
-  int get hashCode => Object.hash(Epiccash, network);
+  int get fractionDigits => 8;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => false;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
+
+  @override
+  AddressType get primaryAddressType => AddressType.mimbleWimble;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000);
+
+  @override
+  int get targetBlockTimeSeconds => 60;
+
+  @override
+  DerivePathType get primaryDerivePathType => throw UnsupportedError(
+        "$runtimeType does not use bitcoin style derivation paths",
+      );
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/ethereum.dart b/lib/wallets/crypto_currency/coins/ethereum.dart
index a9bc81380..5c6c4f0a1 100644
--- a/lib/wallets/crypto_currency/coins/ethereum.dart
+++ b/lib/wallets/crypto_currency/coins/ethereum.dart
@@ -1,31 +1,66 @@
 import 'package:ethereum_addresses/ethereum_addresses.dart';
+import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_currency.dart';
 
 class Ethereum extends Bip39Currency {
   Ethereum(super.network) {
+    _idMain = "ethereum";
+    _uriScheme = "ethereum";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.ethereum;
+        _id = _idMain;
+        _name = "Ethereum";
+        _ticker = "ETH";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   int get gasLimit => 21000;
 
   @override
   bool get hasTokenSupport => true;
 
   @override
-  NodeModel get defaultNode => DefaultNodes.ethereum;
+  NodeModel get defaultNode => NodeModel(
+        host: "https://eth.stackwallet.com",
+        port: 443,
+        name: DefaultNodes.defaultName,
+        id: DefaultNodes.buildId(this),
+        useSSL: true,
+        enabled: true,
+        coinName: identifier,
+        isFailover: true,
+        isDown: false,
+      );
 
   @override
   // Not used for eth
-  String get genesisHash => throw UnimplementedError();
+  String get genesisHash => throw UnimplementedError("Not used for eth");
 
   @override
   int get minConfirms => 3;
@@ -36,10 +71,41 @@ class Ethereum extends Bip39Currency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Ethereum && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Ethereum, network);
+  int get fractionDigits => 18;
+
+  @override
+  bool get hasBuySupport => true;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.ethereum;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(1000000000000000000);
+
+  @override
+  int get targetBlockTimeSeconds => 15;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.eth;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://etherscan.io/tx/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/firo.dart b/lib/wallets/crypto_currency/coins/firo.dart
index 36ad7d763..fbad32ec2 100644
--- a/lib/wallets/crypto_currency/coins/firo.dart
+++ b/lib/wallets/crypto_currency/coins/firo.dart
@@ -3,24 +3,50 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart';
 
-class Firo extends Bip39HDCurrency {
+class Firo extends Bip39HDCurrency with ElectrumXCurrencyInterface {
   Firo(super.network) {
+    _idMain = "firo";
+    _uriScheme = "firo";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.firo;
+        _id = _idMain;
+        _name = "Firo";
+        _ticker = "FIRO";
       case CryptoCurrencyNetwork.test:
-        coin = Coin.firoTestNet;
+        _id = "firoTestNet";
+        _name = "tFiro";
+        _ticker = "tFIRO";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   int get minConfirms => 1;
 
@@ -161,10 +187,10 @@ class Firo extends Bip39HDCurrency {
           host: "firo.stackwallet.com",
           port: 50002,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.firo),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.firo.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -187,10 +213,10 @@ class Firo extends Bip39HDCurrency {
           host: "95.179.164.13",
           port: 51002,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.firoTestNet),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.firoTestNet.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -201,10 +227,43 @@ class Firo extends Bip39HDCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Firo && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Firo, network);
+  int get fractionDigits => 8;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.p2pkh;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000);
+
+  @override
+  int get targetBlockTimeSeconds => 150;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.bip44;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://explorer.firo.org/tx/$txid");
+      case CryptoCurrencyNetwork.test:
+        return Uri.parse("https://testexplorer.firo.org/tx/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/litecoin.dart b/lib/wallets/crypto_currency/coins/litecoin.dart
index efccbb3de..e4b491cef 100644
--- a/lib/wallets/crypto_currency/coins/litecoin.dart
+++ b/lib/wallets/crypto_currency/coins/litecoin.dart
@@ -3,23 +3,49 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 
-class Litecoin extends Bip39HDCurrency {
+class Litecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
   Litecoin(super.network) {
+    _idMain = "litecoin";
+    _uriScheme = "litecoin";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.litecoin;
+        _id = _idMain;
+        _name = "Litecoin";
+        _ticker = "LTC";
       case CryptoCurrencyNetwork.test:
-        coin = Coin.litecoinTestNet;
+        _id = "litecoinTestNet";
+        _name = "tLitecoin";
+        _ticker = "tLTC";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   // change this to change the number of confirms a tx needs in order to show as confirmed
   int get minConfirms => 1;
@@ -187,10 +213,10 @@ class Litecoin extends Bip39HDCurrency {
           host: "litecoin.stackwallet.com",
           port: 20063,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.litecoin),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.litecoin.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -200,10 +226,10 @@ class Litecoin extends Bip39HDCurrency {
           host: "litecoin.stackwallet.com",
           port: 51002,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.litecoinTestNet),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.litecoinTestNet.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -214,10 +240,43 @@ class Litecoin extends Bip39HDCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Litecoin && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Litecoin, network);
+  int get fractionDigits => 8;
+
+  @override
+  bool get hasBuySupport => true;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.p2wpkh;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000);
+
+  @override
+  int get targetBlockTimeSeconds => 150;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.bip84;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://chain.so/tx/LTC/$txid");
+      case CryptoCurrencyNetwork.test:
+        return Uri.parse("https://chain.so/tx/LTCTEST/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/monero.dart b/lib/wallets/crypto_currency/coins/monero.dart
index 34eff8203..42afdf8df 100644
--- a/lib/wallets/crypto_currency/coins/monero.dart
+++ b/lib/wallets/crypto_currency/coins/monero.dart
@@ -1,20 +1,44 @@
 import 'package:cw_monero/api/wallet.dart' as monero_wallet;
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/cryptonote_currency.dart';
 
 class Monero extends CryptonoteCurrency {
   Monero(super.network) {
+    _idMain = "monero";
+    _uriScheme = "monero";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.monero;
+        _id = _idMain;
+        _name = "Monero";
+        _ticker = "XMR";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   int get minConfirms => 10;
 
@@ -31,10 +55,10 @@ class Monero extends CryptonoteCurrency {
           host: "https://monero.stackwallet.com",
           port: 18081,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.monero),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.monero.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
           trusted: true,
@@ -46,10 +70,40 @@ class Monero extends CryptonoteCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Monero && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 25;
 
   @override
-  int get hashCode => Object.hash(Monero, network);
+  int get fractionDigits => 12;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => false;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength];
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(1000000000000);
+
+  @override
+  int get targetBlockTimeSeconds => 120;
+
+  @override
+  DerivePathType get primaryDerivePathType => throw UnsupportedError(
+        "$runtimeType does not use bitcoin style derivation paths",
+      );
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://xmrchain.net/tx/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/namecoin.dart b/lib/wallets/crypto_currency/coins/namecoin.dart
index c2cff8e57..53c0be5f9 100644
--- a/lib/wallets/crypto_currency/coins/namecoin.dart
+++ b/lib/wallets/crypto_currency/coins/namecoin.dart
@@ -3,21 +3,45 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 
-class Namecoin extends Bip39HDCurrency {
+class Namecoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
   Namecoin(super.network) {
+    _idMain = "namecoin";
+    _uriScheme = "namecoin";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.namecoin;
+        _id = _idMain;
+        _name = "Namecoin";
+        _ticker = "NMC";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   // See https://github.com/cypherstack/stack_wallet/blob/621aff47969761014e0a6c4e699cb637d5687ab3/lib/services/coins/namecoin/namecoin_wallet.dart#L58
   int get minConfirms => 2;
@@ -71,10 +95,10 @@ class Namecoin extends Bip39HDCurrency {
           host: "namecoin.stackwallet.com",
           port: 57002,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.namecoin),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.namecoin.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -87,8 +111,10 @@ class Namecoin extends Bip39HDCurrency {
 
   @override
   // See https://github.com/cypherstack/stack_wallet/blob/621aff47969761014e0a6c4e699cb637d5687ab3/lib/services/coins/namecoin/namecoin_wallet.dart#L60
-  Amount get dustLimit =>
-      Amount(rawValue: BigInt.from(546), fractionDigits: Coin.particl.decimals);
+  Amount get dustLimit => Amount(
+        rawValue: BigInt.from(546),
+        fractionDigits: fractionDigits,
+      );
 
   @override
   // See https://github.com/cypherstack/stack_wallet/blob/621aff47969761014e0a6c4e699cb637d5687ab3/lib/services/coins/namecoin/namecoin_wallet.dart#L6
@@ -187,10 +213,41 @@ class Namecoin extends Bip39HDCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Namecoin && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Namecoin, network);
+  int get fractionDigits => 8;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
+
+  @override
+  AddressType get primaryAddressType => AddressType.p2wpkh;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000);
+
+  @override
+  int get targetBlockTimeSeconds => 600;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.bip84;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://chainz.cryptoid.info/nmc/tx.dws?$txid.htm");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/nano.dart b/lib/wallets/crypto_currency/coins/nano.dart
index 277a4601f..03632e352 100644
--- a/lib/wallets/crypto_currency/coins/nano.dart
+++ b/lib/wallets/crypto_currency/coins/nano.dart
@@ -1,7 +1,8 @@
 import 'package:nanodart/nanodart.dart';
+import 'package:stackwallet/models/isar/models/isar_models.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
 
@@ -9,15 +10,50 @@ class Nano extends NanoCurrency {
   Nano(super.network) {
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.nano;
+        _id = "nano";
+        _idMain = "nano";
+        _name = "Nano";
+        _uriScheme = "nano";
+        _ticker = "XNO";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
+  @override
+  int get fractionDigits => 30;
+
+  @override
+  BigInt get satsPerCoin => BigInt.parse(
+        "1000000000000000000000000000000",
+      ); // 1*10^30
+
   @override
   int get minConfirms => 1;
 
+  @override
+  AddressType get primaryAddressType => AddressType.nano;
+
   @override
   String get defaultRepresentative =>
       "nano_38713x95zyjsqzx6nm1dsom1jmm668owkeb9913ax6nfgj15az3nu8xkx579";
@@ -33,10 +69,10 @@ class Nano extends NanoCurrency {
           host: "https://rainstorm.city/api",
           port: 443,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.nano),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.nano.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -47,10 +83,19 @@ class Nano extends NanoCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Nano && other.network == network;
-  }
+  DerivePathType get primaryDerivePathType => throw UnsupportedError(
+        "$runtimeType does not use bitcoin style derivation paths",
+      );
 
   @override
-  int get hashCode => Object.hash(Nano, network);
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://www.nanolooker.com/block/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/particl.dart b/lib/wallets/crypto_currency/coins/particl.dart
index ae73d46e5..7db0053f7 100644
--- a/lib/wallets/crypto_currency/coins/particl.dart
+++ b/lib/wallets/crypto_currency/coins/particl.dart
@@ -3,21 +3,45 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 
-class Particl extends Bip39HDCurrency {
+class Particl extends Bip39HDCurrency with ElectrumXCurrencyInterface {
   Particl(super.network) {
+    _idMain = "particl";
+    _uriScheme = "particl";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.particl;
+        _id = _idMain;
+        _name = "Particl";
+        _ticker = "PART";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   // See https://github.com/cypherstack/stack_wallet/blob/d08b5c9b22b58db800ad07b2ceeb44c6d05f9cf3/lib/services/coins/particl/particl_wallet.dart#L57
   int get minConfirms => 1;
@@ -65,10 +89,10 @@ class Particl extends Bip39HDCurrency {
           host: "particl.stackwallet.com",
           port: 58002,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.particl),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.particl.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -83,7 +107,7 @@ class Particl extends Bip39HDCurrency {
   // See https://github.com/cypherstack/stack_wallet/blob/d08b5c9b22b58db800ad07b2ceeb44c6d05f9cf3/lib/services/coins/particl/particl_wallet.dart#L58
   Amount get dustLimit => Amount(
         rawValue: BigInt.from(294),
-        fractionDigits: Coin.particl.decimals,
+        fractionDigits: fractionDigits,
       );
 
   @override
@@ -167,10 +191,41 @@ class Particl extends Bip39HDCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Particl && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Particl, network);
+  int get fractionDigits => 8;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.p2wpkh;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000);
+
+  @override
+  int get targetBlockTimeSeconds => 600;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.bip84;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://chainz.cryptoid.info/part/tx.dws?$txid.htm");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/peercoin.dart b/lib/wallets/crypto_currency/coins/peercoin.dart
index 4e54329de..c14aa5303 100644
--- a/lib/wallets/crypto_currency/coins/peercoin.dart
+++ b/lib/wallets/crypto_currency/coins/peercoin.dart
@@ -4,23 +4,49 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 
-class Peercoin extends Bip39HDCurrency {
+class Peercoin extends Bip39HDCurrency with ElectrumXCurrencyInterface {
   Peercoin(super.network) {
+    _idMain = "peercoin";
+    _uriScheme = "peercoin";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.peercoin;
+        _id = "peercoin";
+        _name = "Peercoin";
+        _ticker = "PPC";
       case CryptoCurrencyNetwork.test:
-        coin = Coin.peercoinTestNet;
+        _id = "peercoinTestNet";
+        _name = "tPeercoin";
+        _ticker = "tPPC";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   int get minConfirms => 1;
 
@@ -66,9 +92,31 @@ class Peercoin extends Bip39HDCurrency {
   NodeModel get defaultNode {
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        return DefaultNodes.peercoin;
+        return NodeModel(
+          host: "electrum.peercoinexplorer.net",
+          port: 50002,
+          name: DefaultNodes.defaultName,
+          id: DefaultNodes.buildId(this),
+          useSSL: true,
+          enabled: true,
+          coinName: identifier,
+          isFailover: true,
+          isDown: false,
+        );
+
       case CryptoCurrencyNetwork.test:
-        return DefaultNodes.peercoinTestNet;
+        return NodeModel(
+          host: "testnet-electrum.peercoinexplorer.net",
+          port: 50002,
+          name: DefaultNodes.defaultName,
+          id: DefaultNodes.buildId(this),
+          useSSL: true,
+          enabled: true,
+          coinName: identifier,
+          isFailover: true,
+          isDown: false,
+        );
+
       default:
         throw UnimplementedError();
     }
@@ -76,8 +124,9 @@ class Peercoin extends Bip39HDCurrency {
 
   @override
   Amount get dustLimit => Amount(
+        // TODO should this be 10000 instead of 294 for peercoin?
         rawValue: BigInt.from(294),
-        fractionDigits: Coin.peercoin.decimals,
+        fractionDigits: fractionDigits,
       );
 
   @override
@@ -162,10 +211,45 @@ class Peercoin extends Bip39HDCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Peercoin && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Peercoin, network);
+  int get fractionDigits => 6;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.p2wpkh;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(1000000); // 1*10^6.
+
+  @override
+  int get targetBlockTimeSeconds => 600;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.bip84;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://chainz.cryptoid.info/ppc/tx.dws?$txid.htm");
+      case CryptoCurrencyNetwork.test:
+        return Uri.parse(
+          "https://chainz.cryptoid.info/ppc-test/search.dws?q=$txid.htm",
+        );
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/solana.dart b/lib/wallets/crypto_currency/coins/solana.dart
index 6b01b5b6d..3916c5320 100644
--- a/lib/wallets/crypto_currency/coins/solana.dart
+++ b/lib/wallets/crypto_currency/coins/solana.dart
@@ -1,20 +1,45 @@
 import 'package:solana/solana.dart';
+import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_currency.dart';
 
 class Solana extends Bip39Currency {
   Solana(super.network) {
+    _idMain = "solana";
+    _uriScheme = "solana";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.solana;
+        _id = _idMain;
+        _name = "Solana";
+        _ticker = "SOL";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   NodeModel get defaultNode {
     switch (network) {
@@ -24,10 +49,10 @@ class Solana extends Bip39Currency {
               "https://api.mainnet-beta.solana.com/", // TODO: Change this to stack wallet one
           port: 443,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.solana),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.solana.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -52,10 +77,41 @@ class Solana extends Bip39Currency {
   String get genesisHash => throw UnimplementedError();
 
   @override
-  bool operator ==(Object other) {
-    return other is Solana && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 12;
 
   @override
-  int get hashCode => Object.hash(Solana, network);
+  int get fractionDigits => 9;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => false;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 24];
+
+  @override
+  AddressType get primaryAddressType => AddressType.solana;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(1000000000);
+
+  @override
+  int get targetBlockTimeSeconds => 1;
+
+  @override
+  DerivePathType get primaryDerivePathType => DerivePathType.solana;
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://explorer.solana.com/tx/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/stellar.dart b/lib/wallets/crypto_currency/coins/stellar.dart
index e9a7e605b..28165179a 100644
--- a/lib/wallets/crypto_currency/coins/stellar.dart
+++ b/lib/wallets/crypto_currency/coins/stellar.dart
@@ -1,21 +1,48 @@
+import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_currency.dart';
 
 class Stellar extends Bip39Currency {
   Stellar(super.network) {
+    _idMain = "stellar";
+    _uriScheme = "stellar";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.stellar;
+        _id = _idMain;
+        _name = "Stellar";
+        _ticker = "XLM";
       case CryptoCurrencyNetwork.test:
-        coin = Coin.stellarTestnet;
+        _id = "stellarTestnet";
+        _name = "tStellar";
+        _ticker = "tXLM";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   int get minConfirms => 1;
 
@@ -31,9 +58,31 @@ class Stellar extends Bip39Currency {
   NodeModel get defaultNode {
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        return DefaultNodes.stellar;
+        return NodeModel(
+          host: "https://horizon.stellar.org",
+          port: 443,
+          name: DefaultNodes.defaultName,
+          id: DefaultNodes.buildId(this),
+          useSSL: false,
+          enabled: true,
+          coinName: identifier,
+          isFailover: true,
+          isDown: false,
+        );
+
       case CryptoCurrencyNetwork.test:
-        return DefaultNodes.stellarTestnet;
+        return NodeModel(
+          host: "https://horizon-testnet.stellar.org/",
+          port: 50022,
+          name: DefaultNodes.defaultName,
+          id: DefaultNodes.buildId(this),
+          useSSL: true,
+          enabled: true,
+          coinName: identifier,
+          isFailover: true,
+          isDown: false,
+        );
+
       default:
         throw Exception("Unsupported network");
     }
@@ -44,10 +93,46 @@ class Stellar extends Bip39Currency {
       RegExp(r"^[G][A-Z0-9]{55}$").hasMatch(address);
 
   @override
-  bool operator ==(Object other) {
-    return other is Stellar && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 24;
 
   @override
-  int get hashCode => Object.hash(Stellar, network);
+  int get fractionDigits => 7;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => true;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
+
+  @override
+  AddressType get primaryAddressType => AddressType.stellar;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(
+        10000000,
+      ); // https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-data-structures/assets#amount-precision
+
+  @override
+  int get targetBlockTimeSeconds => 5;
+
+  @override
+  DerivePathType get primaryDerivePathType => throw UnsupportedError(
+    "$runtimeType does not use bitcoin style derivation paths",);
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://stellarchain.io/tx/$txid");
+      case CryptoCurrencyNetwork.test:
+        return Uri.parse("https://testnet.stellarchain.io/transactions/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/coins/tezos.dart b/lib/wallets/crypto_currency/coins/tezos.dart
index efb982867..e8eb63a97 100644
--- a/lib/wallets/crypto_currency/coins/tezos.dart
+++ b/lib/wallets/crypto_currency/coins/tezos.dart
@@ -6,7 +6,7 @@ import 'package:coinlib_flutter/coinlib_flutter.dart';
 import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_currency.dart';
 import 'package:tezart/src/crypto/crypto.dart';
@@ -14,14 +14,38 @@ import 'package:tezart/tezart.dart';
 
 class Tezos extends Bip39Currency {
   Tezos(super.network) {
+    _idMain = "tezos";
+    _uriScheme = "tezos";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.tezos;
+        _id = _idMain;
+        _name = "Tezos";
+        _ticker = "XTZ";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   // ===========================================================================
   // =========== Public ========================================================
 
@@ -83,13 +107,14 @@ class Tezos extends Bip39Currency {
     switch (network) {
       case CryptoCurrencyNetwork.main:
         return NodeModel(
+          // TODO: ?Change this to stack wallet one?
           host: "https://mainnet.api.tez.ie",
           port: 443,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.tezos),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.tezos.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
         );
@@ -148,13 +173,43 @@ class Tezos extends Bip39Currency {
     }).toList();
   }
 
-  // ===========================================================================
+  @override
+  int get defaultSeedPhraseLength => 24;
 
   @override
-  bool operator ==(Object other) {
-    return other is Tezos && other.network == network;
+  int get fractionDigits => 6;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => false;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
+
+  @override
+  AddressType get primaryAddressType => AddressType.tezos;
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(1000000);
+
+  @override
+  int get targetBlockTimeSeconds => 60;
+
+  @override
+  DerivePathType get primaryDerivePathType =>
+      throw UnsupportedError("Is this even used?");
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://tzstats.com/$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
   }
-
-  @override
-  int get hashCode => Object.hash(Tezos, network);
 }
diff --git a/lib/wallets/crypto_currency/coins/wownero.dart b/lib/wallets/crypto_currency/coins/wownero.dart
index 549d1739f..788c810e0 100644
--- a/lib/wallets/crypto_currency/coins/wownero.dart
+++ b/lib/wallets/crypto_currency/coins/wownero.dart
@@ -1,20 +1,44 @@
 import 'package:cw_wownero/api/wallet.dart' as wownero_wallet;
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/cryptonote_currency.dart';
 
 class Wownero extends CryptonoteCurrency {
   Wownero(super.network) {
+    _idMain = "wownero";
+    _uriScheme = "wownero";
     switch (network) {
       case CryptoCurrencyNetwork.main:
-        coin = Coin.wownero;
+        _id = _idMain;
+        _name = "Wownero";
+        _ticker = "WOW";
       default:
         throw Exception("Unsupported network: $network");
     }
   }
 
+  late final String _id;
+  @override
+  String get identifier => _id;
+
+  late final String _idMain;
+  @override
+  String get mainNetId => _idMain;
+
+  late final String _name;
+  @override
+  String get prettyName => _name;
+
+  late final String _uriScheme;
+  @override
+  String get uriScheme => _uriScheme;
+
+  late final String _ticker;
+  @override
+  String get ticker => _ticker;
+
   @override
   int get minConfirms => 15;
 
@@ -31,10 +55,10 @@ class Wownero extends CryptonoteCurrency {
           host: "https://wownero.stackwallet.com",
           port: 34568,
           name: DefaultNodes.defaultName,
-          id: DefaultNodes.buildId(Coin.wownero),
+          id: DefaultNodes.buildId(this),
           useSSL: true,
           enabled: true,
-          coinName: Coin.wownero.name,
+          coinName: identifier,
           isFailover: true,
           isDown: false,
           trusted: true,
@@ -46,10 +70,40 @@ class Wownero extends CryptonoteCurrency {
   }
 
   @override
-  bool operator ==(Object other) {
-    return other is Wownero && other.network == network;
-  }
+  int get defaultSeedPhraseLength => 14;
 
   @override
-  int get hashCode => Object.hash(Wownero, network);
+  int get fractionDigits => 11;
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  bool get hasMnemonicPassphraseSupport => false;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 25];
+
+  @override
+  BigInt get satsPerCoin => BigInt.from(100000000000);
+
+  @override
+  int get targetBlockTimeSeconds => 120;
+
+  @override
+  DerivePathType get primaryDerivePathType => throw UnsupportedError(
+        "$runtimeType does not use bitcoin style derivation paths",
+      );
+
+  @override
+  Uri defaultBlockExplorer(String txid) {
+    switch (network) {
+      case CryptoCurrencyNetwork.main:
+        return Uri.parse("https://explore.wownero.com/search?value=$txid");
+      default:
+        throw Exception(
+          "Unsupported network for defaultBlockExplorer(): $network",
+        );
+    }
+  }
 }
diff --git a/lib/wallets/crypto_currency/crypto_currency.dart b/lib/wallets/crypto_currency/crypto_currency.dart
index 8b6f5cdb6..5a8e3e723 100644
--- a/lib/wallets/crypto_currency/crypto_currency.dart
+++ b/lib/wallets/crypto_currency/crypto_currency.dart
@@ -1,6 +1,6 @@
+import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/node_model.dart';
-import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 
 enum CryptoCurrencyNetwork {
   main,
@@ -9,13 +9,26 @@ enum CryptoCurrencyNetwork {
 }
 
 abstract class CryptoCurrency {
-  @Deprecated("[prio=low] Should eventually move away from Coin enum")
-  late final Coin coin;
+  // @Deprecated("[prio=low] Should eventually move away from Coin enum")
+  // late final CryptoCurrency coin;
 
   final CryptoCurrencyNetwork network;
 
   CryptoCurrency(this.network);
 
+  // Identifier should be unique.
+  /// This [identifier] should also match the old `Coin` enum name for each
+  /// respective coin as it is used to differentiate between coins in persistent
+  /// storage.
+  String get identifier;
+
+  /// Should be the [identifier] of the main net version of the currency
+  String get mainNetId;
+
+  String get ticker;
+  String get prettyName;
+  String get uriScheme;
+
   // override in subclass if the currency has tokens on it's network
   // (used for eth currently)
   bool get hasTokenSupport => false;
@@ -23,10 +36,6 @@ abstract class CryptoCurrency {
   // Override in subclass if the currency has Tor support:
   bool get torSupport => false;
 
-  // TODO: [prio=low] require these be overridden in concrete implementations to remove reliance on [coin]
-  int get fractionDigits => coin.decimals;
-  BigInt get satsPerCoin => Constants.satsPerCoin(coin);
-
   int get minConfirms;
 
   // TODO: [prio=low] could be handled differently as (at least) epiccash does not use this
@@ -35,4 +44,26 @@ abstract class CryptoCurrency {
   bool validateAddress(String address);
 
   NodeModel get defaultNode;
+
+  int get defaultSeedPhraseLength;
+  int get fractionDigits;
+  bool get hasBuySupport;
+  bool get hasMnemonicPassphraseSupport;
+  List<int> get possibleMnemonicLengths;
+  AddressType get primaryAddressType;
+  BigInt get satsPerCoin;
+  int get targetBlockTimeSeconds;
+  DerivePathType get primaryDerivePathType;
+
+  Uri defaultBlockExplorer(String txid);
+
+  @override
+  bool operator ==(Object other) {
+    return other is CryptoCurrency &&
+        other.runtimeType == runtimeType &&
+        other.network == network;
+  }
+
+  @override
+  int get hashCode => Object.hash(runtimeType, network);
 }
diff --git a/lib/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart b/lib/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart
new file mode 100644
index 000000000..69c9f33fd
--- /dev/null
+++ b/lib/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart
@@ -0,0 +1,5 @@
+import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
+
+mixin ElectrumXCurrencyInterface on Bip39HDCurrency {
+  //
+}
diff --git a/lib/wallets/crypto_currency/interfaces/paynym_currency_interface.dart b/lib/wallets/crypto_currency/interfaces/paynym_currency_interface.dart
index 6f5571009..580a1b3ed 100644
--- a/lib/wallets/crypto_currency/interfaces/paynym_currency_interface.dart
+++ b/lib/wallets/crypto_currency/interfaces/paynym_currency_interface.dart
@@ -1,7 +1,8 @@
 import 'package:stackwallet/utilities/amount/amount.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
 
-mixin PaynymCurrencyInterface on Bip39HDCurrency {
+mixin PaynymCurrencyInterface on ElectrumXCurrencyInterface, Bip39HDCurrency {
   Amount get dustLimitP2PKH => Amount(
         rawValue: BigInt.from(546),
         fractionDigits: fractionDigits,
diff --git a/lib/wallets/crypto_currency/intermediate/cryptonote_currency.dart b/lib/wallets/crypto_currency/intermediate/cryptonote_currency.dart
index 79d1f4de4..a513f84ae 100644
--- a/lib/wallets/crypto_currency/intermediate/cryptonote_currency.dart
+++ b/lib/wallets/crypto_currency/intermediate/cryptonote_currency.dart
@@ -1,3 +1,4 @@
+import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 abstract class CryptonoteCurrency extends CryptoCurrency {
@@ -7,4 +8,7 @@ abstract class CryptonoteCurrency extends CryptoCurrency {
   String get genesisHash {
     return "not used in stack's cryptonote coins";
   }
+
+  @override
+  AddressType get primaryAddressType => AddressType.cryptonote;
 }
diff --git a/lib/wallets/crypto_currency/intermediate/nano_currency.dart b/lib/wallets/crypto_currency/intermediate/nano_currency.dart
index 617f8d952..72aba78bd 100644
--- a/lib/wallets/crypto_currency/intermediate/nano_currency.dart
+++ b/lib/wallets/crypto_currency/intermediate/nano_currency.dart
@@ -8,6 +8,21 @@ abstract class NanoCurrency extends Bip39Currency {
 
   int get nanoAccountType;
 
+  @override
+  bool get hasMnemonicPassphraseSupport => false;
+
+  @override
+  int get targetBlockTimeSeconds => 1; // TODO: Verify this
+
+  @override
+  bool get hasBuySupport => false;
+
+  @override
+  int get defaultSeedPhraseLength => 24;
+
+  @override
+  List<int> get possibleMnemonicLengths => [defaultSeedPhraseLength, 12];
+
   @override
   bool validateAddress(String address) => NanoAccounts.isValid(
         nanoAccountType,
diff --git a/lib/wallets/isar/models/wallet_info.dart b/lib/wallets/isar/models/wallet_info.dart
index 0ceaa6b83..0e07b6426 100644
--- a/lib/wallets/isar/models/wallet_info.dart
+++ b/lib/wallets/isar/models/wallet_info.dart
@@ -3,7 +3,8 @@ import 'dart:convert';
 import 'package:isar/isar.dart';
 import 'package:stackwallet/models/balance.dart';
 import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/isar_id_interface.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info_meta.dart';
 import 'package:uuid/uuid.dart';
@@ -76,9 +77,10 @@ class WalletInfo implements IsarId {
   @ignore
   Balance get cachedBalanceSecondary {
     if (cachedBalanceSecondaryString == null) {
-      return Balance.zeroForCoin(coin: coin);
+      return Balance.zeroFor(currency: coin);
     } else {
-      return Balance.fromJson(cachedBalanceSecondaryString!, coin.decimals);
+      return Balance.fromJson(
+          cachedBalanceSecondaryString!, coin.fractionDigits);
     }
   }
 
@@ -86,21 +88,22 @@ class WalletInfo implements IsarId {
   @ignore
   Balance get cachedBalanceTertiary {
     if (cachedBalanceTertiaryString == null) {
-      return Balance.zeroForCoin(coin: coin);
+      return Balance.zeroFor(currency: coin);
     } else {
-      return Balance.fromJson(cachedBalanceTertiaryString!, coin.decimals);
+      return Balance.fromJson(
+          cachedBalanceTertiaryString!, coin.fractionDigits);
     }
   }
 
   @ignore
-  Coin get coin => Coin.values.byName(coinName);
+  CryptoCurrency get coin => SupportedCoins.getCryptoCurrencyFor(coinName);
 
   @ignore
   Balance get cachedBalance {
     if (cachedBalanceString == null) {
-      return Balance.zeroForCoin(coin: coin);
+      return Balance.zeroFor(currency: coin);
     } else {
-      return Balance.fromJson(cachedBalanceString!, coin.decimals);
+      return Balance.fromJson(cachedBalanceString!, coin.fractionDigits);
     }
   }
 
@@ -404,7 +407,9 @@ class WalletInfo implements IsarId {
     this.cachedBalanceTertiaryString,
     this.otherDataJsonString,
   }) : assert(
-          Coin.values.map((e) => e.name).contains(coinName),
+          SupportedCoins.cryptocurrencies
+              .map((e) => e.identifier)
+              .contains(coinName),
         );
 
   WalletInfo copyWith({
@@ -440,14 +445,14 @@ class WalletInfo implements IsarId {
   }
 
   static WalletInfo createNew({
-    required Coin coin,
+    required CryptoCurrency coin,
     required String name,
     int restoreHeight = 0,
     String? walletIdOverride,
     String? otherDataJsonString,
   }) {
     return WalletInfo(
-      coinName: coin.name,
+      coinName: coin.identifier,
       walletId: walletIdOverride ?? const Uuid().v1(),
       name: name,
       mainAddressType: coin.primaryAddressType,
@@ -461,9 +466,11 @@ class WalletInfo implements IsarId {
     Map<String, dynamic> jsonObject,
     AddressType mainAddressType,
   ) {
-    final coin = Coin.values.byName(jsonObject["coin"] as String);
+    final coin = SupportedCoins.getCryptoCurrencyFor(
+      jsonObject["coin"] as String,
+    );
     return WalletInfo(
-      coinName: coin.name,
+      coinName: coin.identifier,
       walletId: jsonObject["id"] as String,
       name: jsonObject["name"] as String,
       mainAddressType: mainAddressType,
@@ -475,7 +482,7 @@ class WalletInfo implements IsarId {
     return {
       "name": name,
       "id": walletId,
-      "coin": coin.name,
+      "coin": coin.identifier,
     };
   }
 
diff --git a/lib/wallets/isar/providers/all_wallets_info_provider.dart b/lib/wallets/isar/providers/all_wallets_info_provider.dart
index bca6f417f..a51233a0c 100644
--- a/lib/wallets/isar/providers/all_wallets_info_provider.dart
+++ b/lib/wallets/isar/providers/all_wallets_info_provider.dart
@@ -4,7 +4,8 @@ import 'package:flutter/foundation.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:isar/isar.dart';
 import 'package:stackwallet/providers/db/main_db_provider.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/supported_coins.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 
 final pAllWalletsInfo = Provider((ref) {
@@ -14,7 +15,8 @@ final pAllWalletsInfo = Provider((ref) {
 final pAllWalletsInfoByCoin = Provider((ref) {
   final infos = ref.watch(pAllWalletsInfo);
 
-  final Map<Coin, ({Coin coin, List<WalletInfo> wallets})> map = {};
+  final Map<CryptoCurrency, ({CryptoCurrency coin, List<WalletInfo> wallets})>
+      map = {};
 
   for (final info in infos) {
     if (map[info.coin] == null) {
@@ -24,8 +26,8 @@ final pAllWalletsInfoByCoin = Provider((ref) {
     map[info.coin]!.wallets.add(info);
   }
 
-  final List<({Coin coin, List<WalletInfo> wallets})> results = [];
-  for (final coin in Coin.values) {
+  final List<({CryptoCurrency coin, List<WalletInfo> wallets})> results = [];
+  for (final coin in SupportedCoins.cryptocurrencies) {
     if (map[coin] != null) {
       results.add(map[coin]!);
     }
diff --git a/lib/wallets/isar/providers/wallet_info_provider.dart b/lib/wallets/isar/providers/wallet_info_provider.dart
index b2c39ec21..a8d4ba3f3 100644
--- a/lib/wallets/isar/providers/wallet_info_provider.dart
+++ b/lib/wallets/isar/providers/wallet_info_provider.dart
@@ -2,7 +2,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:isar/isar.dart';
 import 'package:stackwallet/models/balance.dart';
 import 'package:stackwallet/providers/db/main_db_provider.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/wallets/isar/providers/util/watcher.dart';
 
@@ -27,65 +27,81 @@ final pWalletInfo = Provider.family<WalletInfo, String>(
   },
 );
 
-final pWalletCoin = Provider.family<Coin, String>(
+final pWalletCoin = Provider.family<CryptoCurrency, String>(
   (ref, walletId) {
-    return ref.watch(_wiProvider(walletId)
-        .select((value) => (value.value as WalletInfo).coin));
+    return ref.watch(
+      _wiProvider(walletId).select((value) => (value.value as WalletInfo).coin),
+    );
   },
 );
 
 final pWalletBalance = Provider.family<Balance, String>(
   (ref, walletId) {
-    return ref.watch(_wiProvider(walletId)
-        .select((value) => (value.value as WalletInfo).cachedBalance));
+    return ref.watch(
+      _wiProvider(walletId)
+          .select((value) => (value.value as WalletInfo).cachedBalance),
+    );
   },
 );
 
 final pWalletBalanceSecondary = Provider.family<Balance, String>(
   (ref, walletId) {
-    return ref.watch(_wiProvider(walletId)
-        .select((value) => (value.value as WalletInfo).cachedBalanceSecondary));
+    return ref.watch(
+      _wiProvider(walletId).select(
+          (value) => (value.value as WalletInfo).cachedBalanceSecondary),
+    );
   },
 );
 
 final pWalletBalanceTertiary = Provider.family<Balance, String>(
   (ref, walletId) {
-    return ref.watch(_wiProvider(walletId)
-        .select((value) => (value.value as WalletInfo).cachedBalanceTertiary));
+    return ref.watch(
+      _wiProvider(walletId)
+          .select((value) => (value.value as WalletInfo).cachedBalanceTertiary),
+    );
   },
 );
 
 final pWalletChainHeight = Provider.family<int, String>(
   (ref, walletId) {
-    return ref.watch(_wiProvider(walletId)
-        .select((value) => (value.value as WalletInfo).cachedChainHeight));
+    return ref.watch(
+      _wiProvider(walletId)
+          .select((value) => (value.value as WalletInfo).cachedChainHeight),
+    );
   },
 );
 
 final pWalletIsFavourite = Provider.family<bool, String>(
   (ref, walletId) {
-    return ref.watch(_wiProvider(walletId)
-        .select((value) => (value.value as WalletInfo).isFavourite));
+    return ref.watch(
+      _wiProvider(walletId)
+          .select((value) => (value.value as WalletInfo).isFavourite),
+    );
   },
 );
 
 final pWalletName = Provider.family<String, String>(
   (ref, walletId) {
-    return ref.watch(_wiProvider(walletId)
-        .select((value) => (value.value as WalletInfo).name));
+    return ref.watch(
+      _wiProvider(walletId).select((value) => (value.value as WalletInfo).name),
+    );
   },
 );
 
 final pWalletReceivingAddress = Provider.family<String, String>(
   (ref, walletId) {
-    return ref.watch(_wiProvider(walletId)
-        .select((value) => (value.value as WalletInfo).cachedReceivingAddress));
+    return ref.watch(
+      _wiProvider(walletId).select(
+          (value) => (value.value as WalletInfo).cachedReceivingAddress),
+    );
   },
 );
 
 final pWalletTokenAddresses = Provider.family<List<String>, String>(
   (ref, walletId) {
-    return ref.watch(_wiProvider(walletId)
-        .select((value) => (value.value as WalletInfo).tokenContractAddresses));
+    return ref.watch(
+      _wiProvider(walletId).select(
+          (value) => (value.value as WalletInfo).tokenContractAddresses),
+    );
   },
 );
diff --git a/lib/wallets/wallet/impl/bitcoin_frost_wallet.dart b/lib/wallets/wallet/impl/bitcoin_frost_wallet.dart
index 5d0bb3ffc..ea10a3292 100644
--- a/lib/wallets/wallet/impl/bitcoin_frost_wallet.dart
+++ b/lib/wallets/wallet/impl/bitcoin_frost_wallet.dart
@@ -351,7 +351,7 @@ class BitcoinFrostWallet<T extends FrostCurrency> extends Wallet<T> {
         final tx = await electrumXCachedClient.getTransaction(
           txHash: txHash["tx_hash"] as String,
           verbose: true,
-          coin: coin,
+          cryptoCurrency: coin,
         );
 
         if (!_duplicateTxCheck(allTransactions, tx["txid"] as String)) {
@@ -389,7 +389,7 @@ class BitcoinFrostWallet<T extends FrostCurrency> extends Wallet<T> {
 
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           final prevOutJson = Map<String, dynamic>.from(
@@ -724,7 +724,9 @@ class BitcoinFrostWallet<T extends FrostCurrency> extends Wallet<T> {
           await _updateKnownSalts(updatedKnownSalts);
         } else {
           // clear cache
-          await electrumXCachedClient.clearSharedTransactionCache(coin: coin);
+          await electrumXCachedClient.clearSharedTransactionCache(
+            cryptoCurrency: coin,
+          );
           await mainDB.deleteWalletBlockchainData(walletId);
         }
 
@@ -1082,7 +1084,7 @@ class BitcoinFrostWallet<T extends FrostCurrency> extends Wallet<T> {
   // TODO [prio=low]: Use ElectrumXInterface method.
   Future<void> _updateElectrumX() async {
     final failovers = nodeService
-        .failoverNodesFor(coin: cryptoCurrency.coin)
+        .failoverNodesFor(currency: cryptoCurrency)
         .map(
           (e) => ElectrumXNode(
             address: e.host,
@@ -1137,7 +1139,7 @@ class BitcoinFrostWallet<T extends FrostCurrency> extends Wallet<T> {
     final txn = await electrumXCachedClient.getTransaction(
       txHash: jsonUTXO["tx_hash"] as String,
       verbose: true,
-      coin: cryptoCurrency.coin,
+      cryptoCurrency: cryptoCurrency,
     );
 
     final vout = jsonUTXO["tx_pos"] as int;
diff --git a/lib/wallets/wallet/impl/bitcoincash_wallet.dart b/lib/wallets/wallet/impl/bitcoincash_wallet.dart
index 2b9355e2d..af0d1e3d6 100644
--- a/lib/wallets/wallet/impl/bitcoincash_wallet.dart
+++ b/lib/wallets/wallet/impl/bitcoincash_wallet.dart
@@ -9,29 +9,30 @@ import 'package:stackwallet/services/coins/bitcoincash/bch_utils.dart';
 import 'package:stackwallet/services/coins/bitcoincash/cashtokens.dart'
     as cash_tokens;
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/utilities/extensions/extensions.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/bcash_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
-class BitcoincashWallet extends Bip39HDWallet
+class BitcoincashWallet<T extends ElectrumXCurrencyInterface>
+    extends Bip39HDWallet<T>
     with
-        ElectrumXInterface,
-        BCashInterface,
-        CoinControlInterface,
-        CashFusionInterface {
+        ElectrumXInterface<T>,
+        BCashInterface<T>,
+        CoinControlInterface<T>,
+        CashFusionInterface<T> {
   @override
   int get isarTransactionVersion => 2;
 
   BitcoincashWallet(CryptoCurrencyNetwork network)
-      : super(Bitcoincash(network));
+      : super(Bitcoincash(network) as T);
 
   @override
   FilterOperation? get changeAddressFilterOperation => FilterGroup.and(
@@ -130,7 +131,7 @@ class BitcoincashWallet extends Bip39HDWallet
       final tx = await electrumXCachedClient.getTransaction(
         txHash: txHash["tx_hash"] as String,
         verbose: true,
-        coin: cryptoCurrency.coin,
+        cryptoCurrency: cryptoCurrency,
       );
 
       // check for duplicates before adding to list
@@ -171,7 +172,7 @@ class BitcoincashWallet extends Bip39HDWallet
 
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           try {
@@ -361,7 +362,7 @@ class BitcoincashWallet extends Bip39HDWallet
     return Amount(
       rawValue: BigInt.from(((181 * inputCount) + (34 * outputCount) + 10) *
           (feeRatePerKB / 1000).ceil()),
-      fractionDigits: info.coin.decimals,
+      fractionDigits: info.coin.fractionDigits,
     );
   }
 
diff --git a/lib/wallets/wallet/impl/dogecoin_wallet.dart b/lib/wallets/wallet/impl/dogecoin_wallet.dart
index 210ca64cd..a5f99fdbe 100644
--- a/lib/wallets/wallet/impl/dogecoin_wallet.dart
+++ b/lib/wallets/wallet/impl/dogecoin_wallet.dart
@@ -9,13 +9,14 @@ import 'package:stackwallet/utilities/extensions/extensions.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/dogecoin.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
-class DogecoinWallet extends Bip39HDWallet
-    with ElectrumXInterface, CoinControlInterface {
-  DogecoinWallet(CryptoCurrencyNetwork network) : super(Dogecoin(network));
+class DogecoinWallet<T extends ElectrumXCurrencyInterface>
+    extends Bip39HDWallet<T> with ElectrumXInterface<T>, CoinControlInterface {
+  DogecoinWallet(CryptoCurrencyNetwork network) : super(Dogecoin(network) as T);
 
   @override
   int get maximumFeerate => 2500000; // 1000x default value
@@ -89,7 +90,7 @@ class DogecoinWallet extends Bip39HDWallet
         final tx = await electrumXCachedClient.getTransaction(
           txHash: txHash["tx_hash"] as String,
           verbose: true,
-          coin: cryptoCurrency.coin,
+          cryptoCurrency: cryptoCurrency,
         );
 
         // Only tx to list once.
@@ -131,7 +132,7 @@ class DogecoinWallet extends Bip39HDWallet
 
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           final prevOutJson = Map<String, dynamic>.from(
diff --git a/lib/wallets/wallet/impl/ecash_wallet.dart b/lib/wallets/wallet/impl/ecash_wallet.dart
index 2946c6069..e17525756 100644
--- a/lib/wallets/wallet/impl/ecash_wallet.dart
+++ b/lib/wallets/wallet/impl/ecash_wallet.dart
@@ -9,28 +9,28 @@ import 'package:stackwallet/services/coins/bitcoincash/bch_utils.dart';
 import 'package:stackwallet/services/coins/bitcoincash/cashtokens.dart'
     as cash_tokens;
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/utilities/extensions/extensions.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/ecash.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/bcash_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
-class EcashWallet extends Bip39HDWallet
+class EcashWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
     with
-        ElectrumXInterface,
-        BCashInterface,
-        CoinControlInterface,
-        CashFusionInterface {
+        ElectrumXInterface<T>,
+        BCashInterface<T>,
+        CoinControlInterface<T>,
+        CashFusionInterface<T> {
   @override
   int get isarTransactionVersion => 2;
 
-  EcashWallet(CryptoCurrencyNetwork network) : super(Ecash(network));
+  EcashWallet(CryptoCurrencyNetwork network) : super(Ecash(network) as T);
 
   @override
   FilterOperation? get changeAddressFilterOperation => FilterGroup.and(
@@ -123,7 +123,7 @@ class EcashWallet extends Bip39HDWallet
         final tx = await electrumXCachedClient.getTransaction(
           txHash: txHash["tx_hash"] as String,
           verbose: true,
-          coin: cryptoCurrency.coin,
+          cryptoCurrency: cryptoCurrency,
         );
 
         // check for duplicates before adding to list
@@ -164,7 +164,7 @@ class EcashWallet extends Bip39HDWallet
 
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           final prevOutJson = Map<String, dynamic>.from(
@@ -353,7 +353,7 @@ class EcashWallet extends Bip39HDWallet
     return Amount(
       rawValue: BigInt.from(((181 * inputCount) + (34 * outputCount) + 10) *
           (feeRatePerKB / 1000).ceil()),
-      fractionDigits: info.coin.decimals,
+      fractionDigits: info.coin.fractionDigits,
     );
   }
 
diff --git a/lib/wallets/wallet/impl/epiccash_wallet.dart b/lib/wallets/wallet/impl/epiccash_wallet.dart
index b2e5ad3f1..8d9defe77 100644
--- a/lib/wallets/wallet/impl/epiccash_wallet.dart
+++ b/lib/wallets/wallet/impl/epiccash_wallet.dart
@@ -26,7 +26,6 @@ import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_
 import 'package:stackwallet/services/event_bus/global_event_bus.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/default_epicboxes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/stack_file_system.dart';
@@ -543,7 +542,7 @@ class EpiccashWallet extends Bip39Wallet {
       } else {
         try {
           Logging.instance.log(
-              "initializeExisting() ${cryptoCurrency.coin.prettyName} wallet",
+              "initializeExisting() ${cryptoCurrency.prettyName} wallet",
               level: LogLevel.Info);
 
           final config = await _getRealConfig();
@@ -774,7 +773,7 @@ class EpiccashWallet extends Bip39Wallet {
         WalletSyncStatusChangedEvent(
           WalletSyncStatus.syncing,
           walletId,
-          cryptoCurrency.coin,
+          cryptoCurrency,
         ),
       );
 
@@ -831,7 +830,7 @@ class EpiccashWallet extends Bip39Wallet {
         WalletSyncStatusChangedEvent(
           WalletSyncStatus.synced,
           walletId,
-          cryptoCurrency.coin,
+          cryptoCurrency,
         ),
       );
 
@@ -853,14 +852,14 @@ class EpiccashWallet extends Bip39Wallet {
         NodeConnectionStatusChangedEvent(
           NodeConnectionStatus.disconnected,
           walletId,
-          cryptoCurrency.coin,
+          cryptoCurrency,
         ),
       );
       GlobalEventBus.instance.fire(
         WalletSyncStatusChangedEvent(
           WalletSyncStatus.unableToSync,
           walletId,
-          cryptoCurrency.coin,
+          cryptoCurrency,
         ),
       );
       Logging.instance.log(
@@ -1072,7 +1071,7 @@ class EpiccashWallet extends Bip39Wallet {
   @override
   Future<bool> pingCheck() async {
     try {
-      final node = nodeService.getPrimaryNodeFor(coin: cryptoCurrency.coin);
+      final node = nodeService.getPrimaryNodeFor(currency: cryptoCurrency);
 
       // force unwrap optional as we want connection test to fail if wallet
       // wasn't initialized or epicbox node was set to null
diff --git a/lib/wallets/wallet/impl/ethereum_wallet.dart b/lib/wallets/wallet/impl/ethereum_wallet.dart
index a4ad1b341..38b9710e7 100644
--- a/lib/wallets/wallet/impl/ethereum_wallet.dart
+++ b/lib/wallets/wallet/impl/ethereum_wallet.dart
@@ -16,7 +16,6 @@ import 'package:stackwallet/services/ethereum/ethereum_api.dart';
 import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
 import 'package:stackwallet/services/event_bus/global_event_bus.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/eth_commons.dart';
 import 'package:stackwallet/utilities/logger.dart';
@@ -239,7 +238,7 @@ class EthereumWallet extends Bip39Wallet with PrivateKeyInterface {
 
     if (response.value == null) {
       Logging.instance.log(
-        "Failed to refresh transactions for ${cryptoCurrency.coin.prettyName} ${info.name} "
+        "Failed to refresh transactions for ${cryptoCurrency.prettyName} ${info.name} "
         "$walletId: ${response.exception}",
         level: LogLevel.Warning,
       );
@@ -349,7 +348,7 @@ class EthereumWallet extends Bip39Wallet with PrivateKeyInterface {
       await mainDB.updateOrPutTransactionV2s(txns);
     } else {
       Logging.instance.log(
-        "Failed to refresh transactions with nonces for ${cryptoCurrency.coin.prettyName} "
+        "Failed to refresh transactions with nonces for ${cryptoCurrency.prettyName} "
         "${info.name} $walletId: ${txsResponse.exception}",
         level: LogLevel.Warning,
       );
diff --git a/lib/wallets/wallet/impl/firo_wallet.dart b/lib/wallets/wallet/impl/firo_wallet.dart
index ea109fe61..d38e99287 100644
--- a/lib/wallets/wallet/impl/firo_wallet.dart
+++ b/lib/wallets/wallet/impl/firo_wallet.dart
@@ -15,6 +15,7 @@ import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/isar/models/spark_coin.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
@@ -25,12 +26,12 @@ import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/spark_interfa
 
 const sparkStartBlock = 819300; // (approx 18 Jan 2024)
 
-class FiroWallet extends Bip39HDWallet
-    with ElectrumXInterface, LelantusInterface, SparkInterface {
+class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
+    with ElectrumXInterface<T>, LelantusInterface<T>, SparkInterface<T> {
   // IMPORTANT: The order of the above mixins matters.
   // SparkInterface MUST come after LelantusInterface.
 
-  FiroWallet(CryptoCurrencyNetwork network) : super(Firo(network));
+  FiroWallet(CryptoCurrencyNetwork network) : super(Firo(network) as T);
 
   @override
   int get isarTransactionVersion => 2;
@@ -112,7 +113,7 @@ class FiroWallet extends Bip39HDWallet
       final txn = await electrumXCachedClient.getTransaction(
         txHash: tx.txid,
         verbose: true,
-        coin: info.coin,
+        cryptoCurrency: info.coin,
       );
       final height = txn["height"] as int?;
 
@@ -146,7 +147,7 @@ class FiroWallet extends Bip39HDWallet
         tx = await electrumXCachedClient.getTransaction(
           txHash: txHash["tx_hash"] as String,
           verbose: true,
-          coin: info.coin,
+          cryptoCurrency: info.coin,
         );
       } catch (_) {
         continue;
@@ -379,7 +380,7 @@ class FiroWallet extends Bip39HDWallet
         } else if (coinbase == null && txid != null && vout != null) {
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           final prevOutJson = Map<String, dynamic>.from(
@@ -603,7 +604,7 @@ class FiroWallet extends Bip39HDWallet
         if (isRescan) {
           // clear cache
           await electrumXCachedClient.clearSharedTransactionCache(
-              coin: info.coin);
+              cryptoCurrency: info.coin);
           // clear blockchain info
           await mainDB.deleteWalletBlockchainData(walletId);
         }
@@ -613,19 +614,19 @@ class FiroWallet extends Bip39HDWallet
         final setDataMapFuture = getSetDataMap(latestSetId);
         final usedSerialNumbersFuture =
             electrumXCachedClient.getUsedCoinSerials(
-          coin: info.coin,
+          cryptoCurrency: info.coin,
         );
 
         // spark
         final latestSparkCoinId = await electrumXClient.getSparkLatestCoinId();
         final sparkAnonSetFuture = electrumXCachedClient.getSparkAnonymitySet(
           groupId: latestSparkCoinId.toString(),
-          coin: info.coin,
+          cryptoCurrency: info.coin,
           useOnlyCacheIfNotEmpty: false,
         );
         final sparkUsedCoinTagsFuture =
             electrumXCachedClient.getSparkUsedCoinsTags(
-          coin: info.coin,
+          cryptoCurrency: info.coin,
         );
 
         // receiving addresses
diff --git a/lib/wallets/wallet/impl/litecoin_wallet.dart b/lib/wallets/wallet/impl/litecoin_wallet.dart
index a2c6b00c3..a8825d003 100644
--- a/lib/wallets/wallet/impl/litecoin_wallet.dart
+++ b/lib/wallets/wallet/impl/litecoin_wallet.dart
@@ -9,17 +9,19 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/litecoin.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart';
 
-class LitecoinWallet extends Bip39HDWallet
-    with ElectrumXInterface, CoinControlInterface, OrdinalsInterface {
+class LitecoinWallet<T extends ElectrumXCurrencyInterface>
+    extends Bip39HDWallet<T>
+    with ElectrumXInterface<T>, CoinControlInterface<T>, OrdinalsInterface<T> {
   @override
   int get isarTransactionVersion => 2;
 
-  LitecoinWallet(CryptoCurrencyNetwork network) : super(Litecoin(network));
+  LitecoinWallet(CryptoCurrencyNetwork network) : super(Litecoin(network) as T);
 
   @override
   FilterOperation? get changeAddressFilterOperation =>
@@ -91,7 +93,7 @@ class LitecoinWallet extends Bip39HDWallet
         final tx = await electrumXCachedClient.getTransaction(
           txHash: txHash["tx_hash"] as String,
           verbose: true,
-          coin: cryptoCurrency.coin,
+          cryptoCurrency: cryptoCurrency,
         );
 
         // Only tx to list once.
@@ -135,7 +137,7 @@ class LitecoinWallet extends Bip39HDWallet
 
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           final prevOutJson = Map<String, dynamic>.from(
diff --git a/lib/wallets/wallet/impl/namecoin_wallet.dart b/lib/wallets/wallet/impl/namecoin_wallet.dart
index c921b34b8..dee5c1d13 100644
--- a/lib/wallets/wallet/impl/namecoin_wallet.dart
+++ b/lib/wallets/wallet/impl/namecoin_wallet.dart
@@ -8,16 +8,17 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/namecoin.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
-class NamecoinWallet extends Bip39HDWallet
-    with ElectrumXInterface, CoinControlInterface {
+class NamecoinWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
+    with ElectrumXInterface<T>, CoinControlInterface<T> {
   @override
   int get isarTransactionVersion => 2;
 
-  NamecoinWallet(CryptoCurrencyNetwork network) : super(Namecoin(network));
+  NamecoinWallet(CryptoCurrencyNetwork network) : super(Namecoin(network) as T);
 
   @override
   FilterOperation? get changeAddressFilterOperation =>
@@ -117,7 +118,7 @@ class NamecoinWallet extends Bip39HDWallet
         final tx = await electrumXCachedClient.getTransaction(
           txHash: txHash["tx_hash"] as String,
           verbose: true,
-          coin: cryptoCurrency.coin,
+          cryptoCurrency: cryptoCurrency,
         );
 
         // Only tx to list once.
@@ -159,7 +160,7 @@ class NamecoinWallet extends Bip39HDWallet
 
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           final prevOutJson = Map<String, dynamic>.from(
diff --git a/lib/wallets/wallet/impl/particl_wallet.dart b/lib/wallets/wallet/impl/particl_wallet.dart
index 8c4a12a28..5b9e8f714 100644
--- a/lib/wallets/wallet/impl/particl_wallet.dart
+++ b/lib/wallets/wallet/impl/particl_wallet.dart
@@ -14,17 +14,19 @@ import 'package:stackwallet/utilities/extensions/impl/uint8_list.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/particl.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
-class ParticlWallet extends Bip39HDWallet
-    with ElectrumXInterface, CoinControlInterface {
+class ParticlWallet<T extends ElectrumXCurrencyInterface>
+    extends Bip39HDWallet<T>
+    with ElectrumXInterface<T>, CoinControlInterface<T> {
   @override
   int get isarTransactionVersion => 2;
 
-  ParticlWallet(CryptoCurrencyNetwork network) : super(Particl(network));
+  ParticlWallet(CryptoCurrencyNetwork network) : super(Particl(network) as T);
 
   // TODO: double check these filter operations are correct and do not require additional parameters
   @override
@@ -162,7 +164,7 @@ class ParticlWallet extends Bip39HDWallet
         final tx = await electrumXCachedClient.getTransaction(
           txHash: txHash["tx_hash"] as String,
           verbose: true,
-          coin: cryptoCurrency.coin,
+          cryptoCurrency: cryptoCurrency,
         );
 
         // Only tx to list once.
@@ -204,7 +206,7 @@ class ParticlWallet extends Bip39HDWallet
 
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           final prevOutJson = Map<String, dynamic>.from(
diff --git a/lib/wallets/wallet/impl/peercoin_wallet.dart b/lib/wallets/wallet/impl/peercoin_wallet.dart
index e08566f45..206b78ed3 100644
--- a/lib/wallets/wallet/impl/peercoin_wallet.dart
+++ b/lib/wallets/wallet/impl/peercoin_wallet.dart
@@ -8,16 +8,18 @@ import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/peercoin.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
-class PeercoinWallet extends Bip39HDWallet
-    with ElectrumXInterface, CoinControlInterface {
+class PeercoinWallet<T extends ElectrumXCurrencyInterface>
+    extends Bip39HDWallet<T>
+    with ElectrumXInterface<T>, CoinControlInterface<T> {
   @override
   int get isarTransactionVersion => 2;
 
-  PeercoinWallet(CryptoCurrencyNetwork network) : super(Peercoin(network));
+  PeercoinWallet(CryptoCurrencyNetwork network) : super(Peercoin(network) as T);
 
   @override
   FilterOperation? get changeAddressFilterOperation =>
@@ -123,7 +125,7 @@ class PeercoinWallet extends Bip39HDWallet
         final tx = await electrumXCachedClient.getTransaction(
           txHash: txHash["tx_hash"] as String,
           verbose: true,
-          coin: cryptoCurrency.coin,
+          cryptoCurrency: cryptoCurrency,
         );
 
         // Only tx to list once.
@@ -165,7 +167,7 @@ class PeercoinWallet extends Bip39HDWallet
 
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           final prevOutJson = Map<String, dynamic>.from(
diff --git a/lib/wallets/wallet/impl/solana_wallet.dart b/lib/wallets/wallet/impl/solana_wallet.dart
index d2f3582c9..801e7e613 100644
--- a/lib/wallets/wallet/impl/solana_wallet.dart
+++ b/lib/wallets/wallet/impl/solana_wallet.dart
@@ -16,8 +16,6 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart';
 import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/solana.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
@@ -49,7 +47,7 @@ class SolanaWallet extends Bip39Wallet<Solana> {
       publicKey: List<int>.empty(),
       derivationIndex: 0,
       derivationPath: DerivationPath()..value = _addressDerivationPath,
-      type: cryptoCurrency.coin.primaryAddressType,
+      type: cryptoCurrency.primaryAddressType,
       subType: AddressSubType.receiving,
     );
     return addressStruct;
@@ -302,19 +300,19 @@ class SolanaWallet extends Bip39Wallet<Solana> {
       final newBalance = Balance(
         total: Amount(
           rawValue: BigInt.from(balance.value),
-          fractionDigits: Coin.solana.decimals,
+          fractionDigits: cryptoCurrency.fractionDigits,
         ),
         spendable: Amount(
           rawValue: BigInt.from(spendableBalance),
-          fractionDigits: Coin.solana.decimals,
+          fractionDigits: cryptoCurrency.fractionDigits,
         ),
         blockedTotal: Amount(
           rawValue: BigInt.from(minimumRent),
-          fractionDigits: Coin.solana.decimals,
+          fractionDigits: cryptoCurrency.fractionDigits,
         ),
         pendingSpendable: Amount(
           rawValue: BigInt.zero,
-          fractionDigits: Coin.solana.decimals,
+          fractionDigits: cryptoCurrency.fractionDigits,
         ),
       );
 
@@ -358,8 +356,8 @@ class SolanaWallet extends Bip39Wallet<Solana> {
   NodeModel getCurrentNode() {
     return _solNode ??
         NodeService(secureStorageInterface: secureStorageInterface)
-            .getPrimaryNodeFor(coin: info.coin) ??
-        DefaultNodes.getNodeFor(info.coin);
+            .getPrimaryNodeFor(currency: info.coin) ??
+        info.coin.defaultNode;
   }
 
   @override
diff --git a/lib/wallets/wallet/impl/tezos_wallet.dart b/lib/wallets/wallet/impl/tezos_wallet.dart
index bdf3374a8..8506f7ba5 100644
--- a/lib/wallets/wallet/impl/tezos_wallet.dart
+++ b/lib/wallets/wallet/impl/tezos_wallet.dart
@@ -9,8 +9,6 @@ import 'package:stackwallet/models/paymint/fee_object_model.dart';
 import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/extensions/impl/string.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/api/tezos/tezos_account.dart';
@@ -108,12 +106,14 @@ class TezosWallet extends Bip39Wallet<Tezos> {
       //   print("COUNTER: $counter");
       //   print("customFee: $customFee");
       // }
-      ({InternetAddress host, int port})? proxyInfo =
+      final ({InternetAddress host, int port})? proxyInfo =
           prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null;
-      final tezartClient = tezart.TezartClient(server,
-          proxy: proxyInfo != null
-              ? "socks5://${proxyInfo.host}:${proxyInfo.port};"
-              : null);
+      final tezartClient = tezart.TezartClient(
+        server,
+        proxy: proxyInfo != null
+            ? "socks5://${proxyInfo.host}:${proxyInfo.port};"
+            : null,
+      );
 
       final opList = await tezartClient.transferOperation(
         source: sourceKeyStore,
@@ -182,7 +182,7 @@ class TezosWallet extends Bip39Wallet<Tezos> {
         throw Exception("$runtimeType prepareSend requires 1 recipient");
       }
 
-      Amount sendAmount = txData.amount!;
+      final Amount sendAmount = txData.amount!;
 
       if (sendAmount > info.cachedBalance.spendable) {
         throw Exception("Insufficient available balance");
@@ -249,7 +249,7 @@ class TezosWallet extends Bip39Wallet<Tezos> {
             amount: sendAmount,
             address: txData.recipients!.first.address,
             isChange: txData.recipients!.first.isChange,
-          )
+          ),
         ],
         // fee: fee,
         fee: Amount(
@@ -522,8 +522,8 @@ class TezosWallet extends Bip39Wallet<Tezos> {
   @override
   Future<void> updateNode() async {
     _xtzNode = NodeService(secureStorageInterface: secureStorageInterface)
-            .getPrimaryNodeFor(coin: info.coin) ??
-        DefaultNodes.getNodeFor(info.coin);
+            .getPrimaryNodeFor(currency: info.coin) ??
+        info.coin.defaultNode;
 
     await refresh();
   }
@@ -532,8 +532,8 @@ class TezosWallet extends Bip39Wallet<Tezos> {
   NodeModel getCurrentNode() {
     return _xtzNode ??
         NodeService(secureStorageInterface: secureStorageInterface)
-            .getPrimaryNodeFor(coin: info.coin) ??
-        DefaultNodes.getNodeFor(info.coin);
+            .getPrimaryNodeFor(currency: info.coin) ??
+        info.coin.defaultNode;
   }
 
   @override
@@ -547,7 +547,7 @@ class TezosWallet extends Bip39Wallet<Tezos> {
       return;
     }
 
-    List<Tuple2<Transaction, Address>> transactions = [];
+    final List<Tuple2<Transaction, Address>> transactions = [];
     for (final theTx in txs) {
       final TransactionType txType;
 
@@ -563,7 +563,7 @@ class TezosWallet extends Bip39Wallet<Tezos> {
         txType = TransactionType.unknown;
       }
 
-      var transaction = Transaction(
+      final transaction = Transaction(
         walletId: walletId,
         txid: theTx.hash,
         timestamp: theTx.timestamp,
diff --git a/lib/wallets/wallet/intermediate/bip39_hd_wallet.dart b/lib/wallets/wallet/intermediate/bip39_hd_wallet.dart
index ffb927713..230d8e8a4 100644
--- a/lib/wallets/wallet/intermediate/bip39_hd_wallet.dart
+++ b/lib/wallets/wallet/intermediate/bip39_hd_wallet.dart
@@ -66,7 +66,7 @@ abstract class Bip39HDWallet<T extends Bip39HDCurrency> extends Bip39Wallet<T>
     final address = await _generateAddress(
       chain: chain,
       index: index,
-      derivePathType: DerivePathTypeExt.primaryFor(info.coin),
+      derivePathType: info.coin.primaryDerivePathType,
     );
 
     await mainDB.updateOrPutAddresses([address]);
@@ -88,7 +88,7 @@ abstract class Bip39HDWallet<T extends Bip39HDCurrency> extends Bip39Wallet<T>
     final address = await _generateAddress(
       chain: chain,
       index: index,
-      derivePathType: DerivePathTypeExt.primaryFor(info.coin),
+      derivePathType: info.coin.primaryDerivePathType,
     );
 
     await mainDB.updateOrPutAddresses([address]);
@@ -101,7 +101,7 @@ abstract class Bip39HDWallet<T extends Bip39HDCurrency> extends Bip39Wallet<T>
       final address = await _generateAddress(
         chain: 0, // receiving
         index: 0, // initial index
-        derivePathType: DerivePathTypeExt.primaryFor(info.coin),
+        derivePathType: info.coin.primaryDerivePathType,
       );
 
       await mainDB.updateOrPutAddresses([address]);
diff --git a/lib/wallets/wallet/intermediate/bip39_wallet.dart b/lib/wallets/wallet/intermediate/bip39_wallet.dart
index 0ab794bdd..13842e0dc 100644
--- a/lib/wallets/wallet/intermediate/bip39_wallet.dart
+++ b/lib/wallets/wallet/intermediate/bip39_wallet.dart
@@ -6,7 +6,7 @@ import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_inte
 
 abstract class Bip39Wallet<T extends Bip39Currency> extends Wallet<T>
     with MnemonicInterface {
-  Bip39Wallet(T currency) : super(currency);
+  Bip39Wallet(super.currency);
 
   List<FilterOperation> get standardReceivingAddressFilters => [
         FilterCondition.equalTo(
diff --git a/lib/wallets/wallet/wallet.dart b/lib/wallets/wallet/wallet.dart
index 549bfefb2..a427de15f 100644
--- a/lib/wallets/wallet/wallet.dart
+++ b/lib/wallets/wallet/wallet.dart
@@ -15,13 +15,30 @@ import 'package:stackwallet/services/event_bus/global_event_bus.dart';
 import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/paynym_is_api.dart';
 import 'package:stackwallet/utilities/prefs.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/banano.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin_frost.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/dogecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ecash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/litecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/namecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/nano.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/particl.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/peercoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/solana.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/models/wallet_info.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
@@ -309,78 +326,63 @@ abstract class Wallet<T extends CryptoCurrency> {
   static Wallet _loadWallet({
     required WalletInfo walletInfo,
   }) {
-    switch (walletInfo.coin) {
-      case Coin.banano:
-        return BananoWallet(CryptoCurrencyNetwork.main);
+    final net = walletInfo.coin.network;
+    switch (walletInfo.coin.runtimeType) {
+      case const (Banano):
+        return BananoWallet(net);
 
-      case Coin.bitcoin:
-        return BitcoinWallet(CryptoCurrencyNetwork.main);
-      case Coin.bitcoinTestNet:
-        return BitcoinWallet(CryptoCurrencyNetwork.test);
+      case const (Bitcoin):
+        return BitcoinWallet(net);
 
-      case Coin.bitcoinFrost:
-        return BitcoinFrostWallet(CryptoCurrencyNetwork.main);
-      case Coin.bitcoinFrostTestNet:
-        return BitcoinFrostWallet(CryptoCurrencyNetwork.test);
+      case const (BitcoinFrost):
+        return BitcoinFrostWallet(net);
 
-      case Coin.bitcoincash:
-        return BitcoincashWallet(CryptoCurrencyNetwork.main);
-      case Coin.bitcoincashTestnet:
-        return BitcoincashWallet(CryptoCurrencyNetwork.test);
+      case const (Bitcoincash):
+        return BitcoincashWallet(net);
 
-      case Coin.dogecoin:
+      case const (Dogecoin):
         return DogecoinWallet(CryptoCurrencyNetwork.main);
-      case Coin.dogecoinTestNet:
-        return DogecoinWallet(CryptoCurrencyNetwork.test);
 
-      case Coin.eCash:
+      case const (Ecash):
         return EcashWallet(CryptoCurrencyNetwork.main);
 
-      case Coin.epicCash:
+      case const (Epiccash):
         return EpiccashWallet(CryptoCurrencyNetwork.main);
 
-      case Coin.ethereum:
+      case const (Ethereum):
         return EthereumWallet(CryptoCurrencyNetwork.main);
 
-      case Coin.firo:
+      case const (Firo):
         return FiroWallet(CryptoCurrencyNetwork.main);
-      case Coin.firoTestNet:
-        return FiroWallet(CryptoCurrencyNetwork.test);
 
-      case Coin.litecoin:
+      case const (Litecoin):
         return LitecoinWallet(CryptoCurrencyNetwork.main);
-      case Coin.litecoinTestNet:
-        return LitecoinWallet(CryptoCurrencyNetwork.test);
 
-      case Coin.monero:
+      case const (Monero):
         return MoneroWallet(CryptoCurrencyNetwork.main);
 
-      case Coin.namecoin:
+      case const (Namecoin):
         return NamecoinWallet(CryptoCurrencyNetwork.main);
 
-      case Coin.nano:
+      case const (Nano):
         return NanoWallet(CryptoCurrencyNetwork.main);
 
-      case Coin.particl:
+      case const (Particl):
         return ParticlWallet(CryptoCurrencyNetwork.main);
 
-      case Coin.peercoin:
+      case const (Peercoin):
         return PeercoinWallet(CryptoCurrencyNetwork.main);
-      case Coin.peercoinTestNet:
-        return PeercoinWallet(CryptoCurrencyNetwork.test);
 
-      case Coin.solana:
+      case const (Solana):
         return SolanaWallet(CryptoCurrencyNetwork.main);
 
-      case Coin.stellar:
+      case const (Stellar):
         return StellarWallet(CryptoCurrencyNetwork.main);
-      case Coin.stellarTestnet:
-        return StellarWallet(CryptoCurrencyNetwork.test);
 
-      case Coin.tezos:
+      case const (Tezos):
         return TezosWallet(CryptoCurrencyNetwork.main);
 
-      case Coin.wownero:
+      case const (Wownero):
         return WowneroWallet(CryptoCurrencyNetwork.main);
 
       default:
@@ -413,7 +415,7 @@ abstract class Wallet<T extends CryptoCurrency> {
         NodeConnectionStatusChangedEvent(
           status,
           walletId,
-          cryptoCurrency.coin,
+          cryptoCurrency,
         ),
       );
 
@@ -475,8 +477,8 @@ abstract class Wallet<T extends CryptoCurrency> {
   }
 
   NodeModel getCurrentNode() {
-    final node = nodeService.getPrimaryNodeFor(coin: cryptoCurrency.coin) ??
-        DefaultNodes.getNodeFor(cryptoCurrency.coin);
+    final node = nodeService.getPrimaryNodeFor(currency: cryptoCurrency) ??
+        cryptoCurrency.defaultNode;
 
     return node;
   }
@@ -498,7 +500,7 @@ abstract class Wallet<T extends CryptoCurrency> {
         WalletSyncStatusChangedEvent(
           WalletSyncStatus.syncing,
           walletId,
-          cryptoCurrency.coin,
+          cryptoCurrency,
         ),
       );
 
@@ -584,7 +586,7 @@ abstract class Wallet<T extends CryptoCurrency> {
         WalletSyncStatusChangedEvent(
           WalletSyncStatus.synced,
           walletId,
-          cryptoCurrency.coin,
+          cryptoCurrency,
         ),
       );
 
@@ -607,14 +609,14 @@ abstract class Wallet<T extends CryptoCurrency> {
         NodeConnectionStatusChangedEvent(
           NodeConnectionStatus.disconnected,
           walletId,
-          cryptoCurrency.coin,
+          cryptoCurrency,
         ),
       );
       GlobalEventBus.instance.fire(
         WalletSyncStatusChangedEvent(
           WalletSyncStatus.unableToSync,
           walletId,
-          cryptoCurrency.coin,
+          cryptoCurrency,
         ),
       );
       Logging.instance.log(
@@ -637,7 +639,7 @@ abstract class Wallet<T extends CryptoCurrency> {
       case SyncingType.currentWalletOnly:
       // Close the subscription for this coin's chain height.
       // NOTE: This does not work now that the subscription is shared
-      // await  (await ChainHeightServiceManager.getService(cryptoCurrency.coin))
+      // await  (await ChainHeightServiceManager.getService(cryptoCurrency))
       //     ?.cancelListen();
       case SyncingType.selectedWalletsAtStartup:
         // Close the subscription if this wallet is not in the list to be synced.
@@ -650,7 +652,7 @@ abstract class Wallet<T extends CryptoCurrency> {
                 .walletIdEqualTo(id)
                 .findFirstSync()!;
 
-            if (wallet.coin == cryptoCurrency.coin) {
+            if (wallet.coin == cryptoCurrency) {
               walletIds.add(id);
             }
           }
@@ -660,7 +662,7 @@ abstract class Wallet<T extends CryptoCurrency> {
           if (walletIds.isEmpty) {
             // NOTE: This does not work now that the subscription is shared
             // await (await ChainHeightServiceManager.getService(
-            //         cryptoCurrency.coin))
+            //         cryptoCurrency))
             //     ?.cancelListen();
           }
         }
diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/bcash_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/bcash_interface.dart
index c94fd15f9..6db46e043 100644
--- a/lib/wallets/wallet/wallet_mixin_interfaces/bcash_interface.dart
+++ b/lib/wallets/wallet/wallet_mixin_interfaces/bcash_interface.dart
@@ -8,11 +8,13 @@ import 'package:stackwallet/models/isar/models/isar_models.dart';
 import 'package:stackwallet/models/signing_data.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
-mixin BCashInterface on Bip39HDWallet, ElectrumXInterface {
+mixin BCashInterface<T extends ElectrumXCurrencyInterface>
+    on Bip39HDWallet<T>, ElectrumXInterface<T> {
   @override
   Future<TxData> buildTransaction({
     required TxData txData,
diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart
index 1a7d424a2..a4395ea7f 100644
--- a/lib/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart
+++ b/lib/wallets/wallet/wallet_mixin_interfaces/cash_fusion_interface.dart
@@ -11,16 +11,19 @@ import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'
 import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
 import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart';
 import 'package:stackwallet/services/fusion_tor_service.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/stack_file_system.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ecash.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/coin_control_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
 const String kReservedFusionAddress = "reserved_fusion_address";
 
-final kFusionServerInfoDefaults = Map<Coin, FusionInfo>.unmodifiable(const {
-  Coin.bitcoincash: FusionInfo(
+final kFusionServerInfoDefaults = Map<String, FusionInfo>.unmodifiable({
+  Bitcoincash(CryptoCurrencyNetwork.main).identifier: const FusionInfo(
     host: "fusion.servo.cash",
     port: 8789,
     ssl: true,
@@ -29,7 +32,7 @@ final kFusionServerInfoDefaults = Map<Coin, FusionInfo>.unmodifiable(const {
     // ssl: false,
     rounds: 0, // 0 is continuous
   ),
-  Coin.bitcoincashTestnet: FusionInfo(
+  Bitcoincash(CryptoCurrencyNetwork.test).identifier: const FusionInfo(
     host: "fusion.servo.cash",
     port: 8789,
     ssl: true,
@@ -38,7 +41,7 @@ final kFusionServerInfoDefaults = Map<Coin, FusionInfo>.unmodifiable(const {
     // ssl: false,
     rounds: 0, // 0 is continuous
   ),
-  Coin.eCash: FusionInfo(
+  Ecash(CryptoCurrencyNetwork.main).identifier: const FusionInfo(
     host: "fusion.tokamak.cash",
     port: 8788,
     ssl: true,
@@ -109,7 +112,8 @@ class FusionInfo {
   }
 }
 
-mixin CashFusionInterface on CoinControlInterface, ElectrumXInterface {
+mixin CashFusionInterface<T extends ElectrumXCurrencyInterface>
+    on CoinControlInterface<T>, ElectrumXInterface<T> {
   final _torService = FusionTorService.sharedInstance;
 
   // setting values on this should notify any listeners (the GUI)
@@ -307,7 +311,7 @@ mixin CashFusionInterface on CoinControlInterface, ElectrumXInterface {
     final futures = txidList.map(
       (e) => electrumXCachedClient.getTransaction(
         txHash: e,
-        coin: info.coin,
+        cryptoCurrency: info.coin,
       ),
     );
 
@@ -589,7 +593,7 @@ mixin CashFusionInterface on CoinControlInterface, ElectrumXInterface {
         checkUtxoExists: _checkUtxoExists,
         getTransactionJson: (String txid) async =>
             await electrumXCachedClient.getTransaction(
-          coin: info.coin,
+          cryptoCurrency: info.coin,
           txHash: txid,
         ),
         getPrivateKeyForPubKey: _getPrivateKeyForPubKey,
diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart
index 026e9f5fc..1ce6c7717 100644
--- a/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart
+++ b/lib/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart
@@ -14,21 +14,21 @@ import 'package:stackwallet/models/isar/models/isar_models.dart';
 import 'package:stackwallet/models/paymint/fee_object_model.dart';
 import 'package:stackwallet/models/signing_data.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/extensions/extensions.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/paynym_is_api.dart';
 import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
-import 'package:stackwallet/wallets/crypto_currency/intermediate/bip39_hd_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/impl/bitcoin_wallet.dart';
 import 'package:stackwallet/wallets/wallet/impl/peercoin_wallet.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart';
 
-mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
+mixin ElectrumXInterface<T extends ElectrumXCurrencyInterface>
+    on Bip39HDWallet<T> {
   late ElectrumXClient electrumXClient;
   late CachedElectrumXClient electrumXCachedClient;
 
@@ -43,9 +43,11 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
     }
 
     try {
-      _serverVersion ??= _parseServerVersion((await electrumXClient
-          .getServerFeatures()
-          .timeout(const Duration(seconds: 2)))["server_version"] as String);
+      _serverVersion ??= _parseServerVersion(
+        (await electrumXClient
+            .getServerFeatures()
+            .timeout(const Duration(seconds: 2)))["server_version"] as String,
+      );
     } catch (_) {
       // ignore failure as it doesn't matter
     }
@@ -133,22 +135,30 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
     // don't care about sorting if using all utxos
     if (!coinControl) {
       // sort spendable by age (oldest first)
-      spendableOutputs.sort((a, b) => (b.blockTime ?? currentChainHeight)
-          .compareTo((a.blockTime ?? currentChainHeight)));
+      spendableOutputs.sort(
+        (a, b) => (b.blockTime ?? currentChainHeight)
+            .compareTo((a.blockTime ?? currentChainHeight)),
+      );
       // Null check operator changed to null assignment in order to resolve a
       // `Null check operator used on a null value` error.  currentChainHeight
       // used in order to sort these unconfirmed outputs as the youngest, but we
       // could just as well use currentChainHeight + 1.
     }
 
-    Logging.instance.log("spendableOutputs.length: ${spendableOutputs.length}",
-        level: LogLevel.Info);
-    Logging.instance.log("availableOutputs.length: ${availableOutputs.length}",
-        level: LogLevel.Info);
+    Logging.instance.log(
+      "spendableOutputs.length: ${spendableOutputs.length}",
+      level: LogLevel.Info,
+    );
+    Logging.instance.log(
+      "availableOutputs.length: ${availableOutputs.length}",
+      level: LogLevel.Info,
+    );
     Logging.instance
         .log("spendableOutputs: $spendableOutputs", level: LogLevel.Info);
-    Logging.instance.log("spendableSatoshiValue: $spendableSatoshiValue",
-        level: LogLevel.Info);
+    Logging.instance.log(
+      "spendableSatoshiValue: $spendableSatoshiValue",
+      level: LogLevel.Info,
+    );
     Logging.instance
         .log("satoshiAmountToSend: $satoshiAmountToSend", level: LogLevel.Info);
     // If the amount the user is trying to send is smaller than the amount that they have spendable,
@@ -299,7 +309,7 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
             [recipientAddress, (await getCurrentChangeAddress())!.value],
             [
               satoshiAmountToSend,
-              max(0, satoshisBeingUsed - satoshiAmountToSend - 1)
+              max(0, satoshisBeingUsed - satoshiAmountToSend - 1),
             ],
           ),
         ),
@@ -358,13 +368,18 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
           Logging.instance.log('2 outputs in tx', level: LogLevel.Info);
           Logging.instance
               .log('Input size: $satoshisBeingUsed', level: LogLevel.Info);
-          Logging.instance.log('Recipient output size: $satoshiAmountToSend',
-              level: LogLevel.Info);
-          Logging.instance.log('Change Output Size: $changeOutputSize',
-              level: LogLevel.Info);
           Logging.instance.log(
-              'Difference (fee being paid): $feeBeingPaid sats',
-              level: LogLevel.Info);
+            'Recipient output size: $satoshiAmountToSend',
+            level: LogLevel.Info,
+          );
+          Logging.instance.log(
+            'Change Output Size: $changeOutputSize',
+            level: LogLevel.Info,
+          );
+          Logging.instance.log(
+            'Difference (fee being paid): $feeBeingPaid sats',
+            level: LogLevel.Info,
+          );
           Logging.instance
               .log('Estimated fee: $feeForTwoOutputs', level: LogLevel.Info);
 
@@ -386,19 +401,26 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
                 satoshisBeingUsed - satoshiAmountToSend - changeOutputSize;
             recipientsAmtArray.removeLast();
             recipientsAmtArray.add(changeOutputSize);
-            Logging.instance.log('Adjusted Input size: $satoshisBeingUsed',
-                level: LogLevel.Info);
             Logging.instance.log(
-                'Adjusted Recipient output size: $satoshiAmountToSend',
-                level: LogLevel.Info);
+              'Adjusted Input size: $satoshisBeingUsed',
+              level: LogLevel.Info,
+            );
             Logging.instance.log(
-                'Adjusted Change Output Size: $changeOutputSize',
-                level: LogLevel.Info);
+              'Adjusted Recipient output size: $satoshiAmountToSend',
+              level: LogLevel.Info,
+            );
             Logging.instance.log(
-                'Adjusted Difference (fee being paid): $feeBeingPaid sats',
-                level: LogLevel.Info);
-            Logging.instance.log('Adjusted Estimated fee: $feeForTwoOutputs',
-                level: LogLevel.Info);
+              'Adjusted Change Output Size: $changeOutputSize',
+              level: LogLevel.Info,
+            );
+            Logging.instance.log(
+              'Adjusted Difference (fee being paid): $feeBeingPaid sats',
+              level: LogLevel.Info,
+            );
+            Logging.instance.log(
+              'Adjusted Estimated fee: $feeForTwoOutputs',
+              level: LogLevel.Info,
+            );
             txn = await buildTransaction(
               utxoSigningData: utxoSigningData,
               txData: txData.copyWith(
@@ -423,11 +445,14 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
           Logging.instance.log('1 output in tx', level: LogLevel.Info);
           Logging.instance
               .log('Input size: $satoshisBeingUsed', level: LogLevel.Info);
-          Logging.instance.log('Recipient output size: $satoshiAmountToSend',
-              level: LogLevel.Info);
           Logging.instance.log(
-              'Difference (fee being paid): ${satoshisBeingUsed - satoshiAmountToSend} sats',
-              level: LogLevel.Info);
+            'Recipient output size: $satoshiAmountToSend',
+            level: LogLevel.Info,
+          );
+          Logging.instance.log(
+            'Difference (fee being paid): ${satoshisBeingUsed - satoshiAmountToSend} sats',
+            level: LogLevel.Info,
+          );
           Logging.instance
               .log('Estimated fee: $feeForOneOutput', level: LogLevel.Info);
           final txn = await buildTransaction(
@@ -455,11 +480,14 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
         Logging.instance.log('1 output in tx', level: LogLevel.Info);
         Logging.instance
             .log('Input size: $satoshisBeingUsed', level: LogLevel.Info);
-        Logging.instance.log('Recipient output size: $satoshiAmountToSend',
-            level: LogLevel.Info);
         Logging.instance.log(
-            'Difference (fee being paid): ${satoshisBeingUsed - satoshiAmountToSend} sats',
-            level: LogLevel.Info);
+          'Recipient output size: $satoshiAmountToSend',
+          level: LogLevel.Info,
+        );
+        Logging.instance.log(
+          'Difference (fee being paid): ${satoshisBeingUsed - satoshiAmountToSend} sats',
+          level: LogLevel.Info,
+        );
         Logging.instance
             .log('Estimated fee: $feeForOneOutput', level: LogLevel.Info);
         final txn = await buildTransaction(
@@ -487,11 +515,14 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
       Logging.instance.log('1 output in tx', level: LogLevel.Info);
       Logging.instance
           .log('Input size: $satoshisBeingUsed', level: LogLevel.Info);
-      Logging.instance.log('Recipient output size: $satoshiAmountToSend',
-          level: LogLevel.Info);
       Logging.instance.log(
-          'Fee being paid: ${satoshisBeingUsed - satoshiAmountToSend} sats',
-          level: LogLevel.Info);
+        'Recipient output size: $satoshiAmountToSend',
+        level: LogLevel.Info,
+      );
+      Logging.instance.log(
+        'Fee being paid: ${satoshisBeingUsed - satoshiAmountToSend} sats',
+        level: LogLevel.Info,
+      );
       Logging.instance
           .log('Estimated fee: $feeForOneOutput', level: LogLevel.Info);
       final txn = await buildTransaction(
@@ -515,8 +546,9 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
       // pay for the transaction fee. Ideally, at this stage, we should check if the user has any
       // additional outputs they're able to spend and then recalculate fees.
       Logging.instance.log(
-          'Cannot pay tx fee - checking for more outputs and trying again',
-          level: LogLevel.Warning);
+        'Cannot pay tx fee - checking for more outputs and trying again',
+        level: LogLevel.Warning,
+      );
       // try adding more outputs
       if (spendableOutputs.length > inputsBeingConsumed) {
         return coinSelection(
@@ -589,7 +621,8 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
 
         if (keys == null) {
           throw Exception(
-              "Failed to fetch signing data. Local db corrupt. Rescan wallet.");
+            "Failed to fetch signing data. Local db corrupt. Rescan wallet.",
+          );
         }
 
         sd.keyPair = keys;
@@ -762,8 +795,10 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
         );
       }
     } catch (e, s) {
-      Logging.instance.log("Caught exception while signing transaction: $e\n$s",
-          level: LogLevel.Error);
+      Logging.instance.log(
+        "Caught exception while signing transaction: $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
 
@@ -799,8 +834,9 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
       );
     } catch (e, s) {
       Logging.instance.log(
-          "Exception rethrown in fetchChainHeight\nError: $e\nStack trace: $s",
-          level: LogLevel.Error);
+        "Exception rethrown in fetchChainHeight\nError: $e\nStack trace: $s",
+        level: LogLevel.Error,
+      );
       // completer.completeError(e, s);
       // return Future.error(e, s);
       rethrow;
@@ -819,9 +855,10 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
   }) async {
     try {
       final response = await electrumXClient.getBatchHistory(
-          args: addresses
-              .map((e) => [cryptoCurrency.addressToScriptHash(address: e)])
-              .toList(growable: false));
+        args: addresses
+            .map((e) => [cryptoCurrency.addressToScriptHash(address: e)])
+            .toList(growable: false),
+      );
 
       final List<int> result = [];
       for (final entry in response) {
@@ -830,8 +867,9 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
       return result;
     } catch (e, s) {
       Logging.instance.log(
-          "Exception rethrown in _getBatchTxCount(address: $addresses: $e\n$s",
-          level: LogLevel.Error);
+        "Exception rethrown in _getBatchTxCount(address: $addresses: $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
   }
@@ -850,14 +888,16 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
 
   Future<void> updateElectrumX() async {
     final failovers = nodeService
-        .failoverNodesFor(coin: cryptoCurrency.coin)
-        .map((e) => ElectrumXNode(
-              address: e.host,
-              port: e.port,
-              name: e.name,
-              id: e.id,
-              useSSL: e.useSSL,
-            ))
+        .failoverNodesFor(currency: cryptoCurrency)
+        .map(
+          (e) => ElectrumXNode(
+            address: e.host,
+            port: e.port,
+            name: e.name,
+            id: e.id,
+            useSSL: e.useSSL,
+          ),
+        )
         .toList();
 
     final newNode = await _getCurrentElectrumXNode();
@@ -899,8 +939,9 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
             gapCounter < cryptoCurrency.maxUnusedAddressGap;
         index += txCountBatchSize) {
       Logging.instance.log(
-          "index: $index, \t GapCounter $chain ${type.name}: $gapCounter",
-          level: LogLevel.Info);
+        "index: $index, \t GapCounter $chain ${type.name}: $gapCounter",
+        level: LogLevel.Info,
+      );
 
       final List<String> txCountCallArgs = [];
 
@@ -979,8 +1020,9 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
             gapCounter < cryptoCurrency.maxUnusedAddressGap;
         index++) {
       Logging.instance.log(
-          "index: $index, \t GapCounter chain=$chain ${type.name}: $gapCounter",
-          level: LogLevel.Info);
+        "index: $index, \t GapCounter chain=$chain ${type.name}: $gapCounter",
+        level: LogLevel.Info,
+      );
 
       final derivePath = cryptoCurrency.constructDerivePath(
         derivePathType: type,
@@ -1107,7 +1149,7 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
     final txn = await electrumXCachedClient.getTransaction(
       txHash: jsonUTXO["tx_hash"] as String,
       verbose: true,
-      coin: cryptoCurrency.coin,
+      cryptoCurrency: cryptoCurrency,
     );
 
     final vout = jsonUTXO["tx_pos"] as int;
@@ -1194,15 +1236,15 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
         numberOfBlocksSlow: s,
         fast: Amount.fromDecimal(
           fast,
-          fractionDigits: info.coin.decimals,
+          fractionDigits: info.coin.fractionDigits,
         ).raw.toInt(),
         medium: Amount.fromDecimal(
           medium,
-          fractionDigits: info.coin.decimals,
+          fractionDigits: info.coin.fractionDigits,
         ).raw.toInt(),
         slow: Amount.fromDecimal(
           slow,
-          fractionDigits: info.coin.decimals,
+          fractionDigits: info.coin.fractionDigits,
         ).raw.toInt(),
       );
 
@@ -1235,14 +1277,14 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
 
     Amount runningBalance = Amount(
       rawValue: BigInt.zero,
-      fractionDigits: info.coin.decimals,
+      fractionDigits: info.coin.fractionDigits,
     );
     int inputCount = 0;
     for (final output in utxos) {
       if (!output.isBlocked) {
         runningBalance += Amount(
           rawValue: BigInt.from(output.value),
-          fractionDigits: info.coin.decimals,
+          fractionDigits: info.coin.fractionDigits,
         );
         inputCount++;
         if (runningBalance > amount) {
@@ -1366,7 +1408,8 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
         if (isRescan) {
           // clear cache
           await electrumXCachedClient.clearSharedTransactionCache(
-              coin: info.coin);
+            cryptoCurrency: info.coin,
+          );
           // clear blockchain info
           await mainDB.deleteWalletBlockchainData(walletId);
         }
@@ -1459,12 +1502,16 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
         }
 
         // remove extra addresses to help minimize risk of creating a large gap
-        addressesToStore.removeWhere((e) =>
-            e.subType == AddressSubType.change &&
-            e.derivationIndex > highestChangeIndexWithHistory);
-        addressesToStore.removeWhere((e) =>
-            e.subType == AddressSubType.receiving &&
-            e.derivationIndex > highestReceivingIndexWithHistory);
+        addressesToStore.removeWhere(
+          (e) =>
+              e.subType == AddressSubType.change &&
+              e.derivationIndex > highestChangeIndexWithHistory,
+        );
+        addressesToStore.removeWhere(
+          (e) =>
+              e.subType == AddressSubType.receiving &&
+              e.derivationIndex > highestReceivingIndexWithHistory,
+        );
 
         await mainDB.updateOrPutAddresses(addressesToStore);
 
@@ -1512,8 +1559,9 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
       unawaited(refresh());
     } catch (e, s) {
       Logging.instance.log(
-          "Exception rethrown from electrumx_mixin recover(): $e\n$s",
-          level: LogLevel.Info);
+        "Exception rethrown from electrumx_mixin recover(): $e\n$s",
+        level: LogLevel.Info,
+      );
 
       rethrow;
     }
@@ -1609,8 +1657,10 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
 
       return await updateSentCachedTxData(txData: txData);
     } catch (e, s) {
-      Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s",
-          level: LogLevel.Error);
+      Logging.instance.log(
+        "Exception rethrown from confirmSend(): $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
   }
@@ -1644,7 +1694,8 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
 
         if (result.fee!.raw.toInt() < result.vSize!) {
           throw Exception(
-              "Error in fee calculation: Transaction fee cannot be less than vSize");
+            "Error in fee calculation: Transaction fee cannot be less than vSize",
+          );
         }
 
         return result;
@@ -1700,8 +1751,10 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
         throw ArgumentError("Invalid fee rate argument provided!");
       }
     } catch (e, s) {
-      Logging.instance.log("Exception rethrown from prepareSend(): $e\n$s",
-          level: LogLevel.Error);
+      Logging.instance.log(
+        "Exception rethrown from prepareSend(): $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
   }
@@ -1777,7 +1830,7 @@ mixin ElectrumXInterface<T extends Bip39HDCurrency> on Bip39HDWallet<T> {
 
     return Amount(
           rawValue: available,
-          fractionDigits: info.coin.decimals,
+          fractionDigits: info.coin.fractionDigits,
         ) -
         estimatedFee;
   }
diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/lelantus_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/lelantus_interface.dart
index ce8c5064d..f182c8ca1 100644
--- a/lib/wallets/wallet/wallet_mixin_interfaces/lelantus_interface.dart
+++ b/lib/wallets/wallet/wallet_mixin_interfaces/lelantus_interface.dart
@@ -16,15 +16,17 @@ import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/api/lelantus_ffi_wrapper.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 import 'package:tuple/tuple.dart';
 
-mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
+mixin LelantusInterface<T extends ElectrumXCurrencyInterface>
+    on Bip39HDWallet<T>, ElectrumXInterface<T> {
   Future<Amount> estimateFeeForLelantus(Amount amount) async {
     final lelantusEntries = await _getLelantusEntry();
-    int spendAmount = amount.raw.toInt();
+    final int spendAmount = amount.raw.toInt();
     if (spendAmount == 0 || lelantusEntries.isEmpty) {
       return Amount(
         rawValue: BigInt.from(LelantusFeeData(0, 0, []).fee),
@@ -52,10 +54,12 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
         .filter()
         .isUsedEqualTo(false)
         .not()
-        .group((q) => q
-            .valueEqualTo("0")
-            .or()
-            .anonymitySetIdEqualTo(LelantusFfiWrapper.ANONYMITY_SET_EMPTY_ID))
+        .group(
+          (q) => q
+              .valueEqualTo("0")
+              .or()
+              .anonymitySetIdEqualTo(LelantusFfiWrapper.ANONYMITY_SET_EMPTY_ID),
+        )
         .findAll();
 
     final root = await getRootHDNode();
@@ -156,12 +160,15 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
       // fee should never be less than vSize sanity check
       if (result.fee!.raw.toInt() < result.vSize!) {
         throw Exception(
-            "Error in fee calculation: Transaction fee cannot be less than vSize");
+          "Error in fee calculation: Transaction fee cannot be less than vSize",
+        );
       }
       return result;
     } catch (e, s) {
-      Logging.instance.log("Exception rethrown in firo prepareSend(): $e\n$s",
-          level: LogLevel.Error);
+      Logging.instance.log(
+        "Exception rethrown in firo prepareSend(): $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
   }
@@ -316,17 +323,17 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
   }
 
   Future<List<Map<String, dynamic>>> fastFetch(List<String> allTxHashes) async {
-    List<Map<String, dynamic>> allTransactions = [];
+    final List<Map<String, dynamic>> allTransactions = [];
 
     const futureLimit = 30;
-    List<Future<Map<String, dynamic>>> transactionFutures = [];
+    final List<Future<Map<String, dynamic>>> transactionFutures = [];
     int currentFutureCount = 0;
     for (final txHash in allTxHashes) {
-      Future<Map<String, dynamic>> transactionFuture =
+      final Future<Map<String, dynamic>> transactionFuture =
           electrumXCachedClient.getTransaction(
         txHash: txHash,
         verbose: true,
-        coin: cryptoCurrency.coin,
+        cryptoCurrency: cryptoCurrency,
       );
       transactionFutures.add(transactionFuture);
       currentFutureCount++;
@@ -362,8 +369,8 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
     List<String> transactions,
   ) async {
     try {
-      Map<Address, Transaction> txs = {};
-      List<Map<String, dynamic>> allTransactions =
+      final Map<Address, Transaction> txs = {};
+      final List<Map<String, dynamic>> allTransactions =
           await fastFetch(transactions);
 
       for (int i = 0; i < allTransactions.length; i++) {
@@ -426,16 +433,18 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
           txs[address] = txn;
         } catch (e, s) {
           Logging.instance.log(
-              "Exception caught in getJMintTransactions(): $e\n$s",
-              level: LogLevel.Info);
+            "Exception caught in getJMintTransactions(): $e\n$s",
+            level: LogLevel.Info,
+          );
           rethrow;
         }
       }
       return txs;
     } catch (e, s) {
       Logging.instance.log(
-          "Exception rethrown in getJMintTransactions(): $e\n$s",
-          level: LogLevel.Info);
+        "Exception rethrown in getJMintTransactions(): $e\n$s",
+        level: LogLevel.Info,
+      );
       rethrow;
     }
   }
@@ -445,25 +454,26 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
       final latestSetId = await electrumXClient.getLelantusLatestCoinId();
 
       final List<Map<String, dynamic>> sets = [];
-      List<Future<Map<String, dynamic>>> anonFutures = [];
+      final List<Future<Map<String, dynamic>>> anonFutures = [];
       for (int i = 1; i <= latestSetId; i++) {
         final set = electrumXCachedClient.getAnonymitySet(
           groupId: "$i",
-          coin: info.coin,
+          cryptoCurrency: info.coin,
         );
         anonFutures.add(set);
       }
       await Future.wait(anonFutures);
       for (int i = 1; i <= latestSetId; i++) {
-        Map<String, dynamic> set = (await anonFutures[i - 1]);
+        final Map<String, dynamic> set = (await anonFutures[i - 1]);
         set["setId"] = i;
         sets.add(set);
       }
       return sets;
     } catch (e, s) {
       Logging.instance.log(
-          "Exception rethrown from refreshAnonymitySets: $e\n$s",
-          level: LogLevel.Error);
+        "Exception rethrown from refreshAnonymitySets: $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
   }
@@ -497,7 +507,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
 
     final usedSerialNumbersSet =
         (await electrumXCachedClient.getUsedCoinSerials(
-      coin: info.coin,
+      cryptoCurrency: info.coin,
     ))
             .toSet();
 
@@ -598,10 +608,10 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
 
     // TODO: [prio=high] shouldn't these be v2? If it doesn't matter than we can get rid of this logic
     // Edit the receive transactions with the mint fees.
-    List<Transaction> editedTransactions = [];
+    final List<Transaction> editedTransactions = [];
 
     for (final coin in result.lelantusCoins) {
-      String txid = coin.txid;
+      final String txid = coin.txid;
       Transaction? tx;
       try {
         tx = txns.firstWhere((e) => e.txid == txid);
@@ -614,7 +624,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
         continue;
       }
 
-      List<Transaction> inputTxns = [];
+      final List<Transaction> inputTxns = [];
       for (final input in tx.inputs) {
         Transaction? inputTx;
         try {
@@ -635,8 +645,8 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
         continue;
       }
 
-      int mintFee = tx.fee;
-      int sharedFee = mintFee ~/ inputTxns.length;
+      final int mintFee = tx.fee;
+      final int sharedFee = mintFee ~/ inputTxns.length;
       for (final inputTx in inputTxns) {
         final edited = Transaction(
           walletId: inputTx.walletId,
@@ -665,7 +675,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
     }
     // Logging.instance.log(editedTransactions, addToDebugMessagesDB: false);
 
-    Map<String, Transaction> transactionMap = {};
+    final Map<String, Transaction> transactionMap = {};
     for (final e in txns) {
       transactionMap[e.txid] = e;
     }
@@ -676,10 +686,12 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
       transactionMap[tx.txid] = tx;
     }
 
-    transactionMap.removeWhere((key, value) =>
-        result.lelantusCoins.any((element) => element.txid == key) ||
-        ((value.height == -1 || value.height == null) &&
-            !value.isConfirmed(currentHeight, cryptoCurrency.minConfirms)));
+    transactionMap.removeWhere(
+      (key, value) =>
+          result.lelantusCoins.any((element) => element.txid == key) ||
+          ((value.height == -1 || value.height == null) &&
+              !value.isConfirmed(currentHeight, cryptoCurrency.minConfirms)),
+    );
 
     try {
       await mainDB.isar.writeTxn(() async {
@@ -694,7 +706,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
       throw Exception("e=$e & s=$s");
     }
 
-    Map<String, Tuple2<Address?, Transaction>> data = {};
+    final Map<String, Tuple2<Address?, Transaction>> data = {};
 
     for (final entry in transactionMap.entries) {
       data[entry.key] = Tuple2(entry.value.address.value, entry.value);
@@ -730,9 +742,12 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
           value.item2.outputs.where((_) => true).toList(growable: false);
       final ins = value.item2.inputs.where((_) => true).toList(growable: false);
 
-      txnsData.add(Tuple2(
+      txnsData.add(
+        Tuple2(
           value.item2.copyWith(inputs: ins, outputs: outs).item1,
-          transactionAddress));
+          transactionAddress,
+        ),
+      );
     }
 
     await mainDB.addNewTransactionData(txnsData, walletId);
@@ -827,7 +842,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
 
     for (var mintsElement in txData.mintsMapLelantus!) {
       Logging.instance.log("using $mintsElement", level: LogLevel.Info);
-      Uint8List mintu8 =
+      final Uint8List mintu8 =
           Format.stringToUint8List(mintsElement['script'] as String);
       txb.addOutput(mintu8, mintsElement['value'] as int);
     }
@@ -843,12 +858,12 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
         witnessValue: signingData[i].utxo.value,
       );
     }
-    var incomplete = txb.buildIncomplete();
-    var txId = incomplete.getId();
-    var txHex = incomplete.toHex();
-    int fee = amount - incomplete.outs[0].value!;
+    final incomplete = txb.buildIncomplete();
+    final txId = incomplete.getId();
+    final txHex = incomplete.toHex();
+    final int fee = amount - incomplete.outs[0].value!;
 
-    var builtHex = txb.build();
+    final builtHex = txb.build();
 
     return txData.copyWith(
       recipients: [
@@ -859,7 +874,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
           ),
           address: "no address for lelantus mints",
           isChange: false,
-        )
+        ),
       ],
       vSize: builtHex.virtualSize(),
       txid: txId,
@@ -880,14 +895,14 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
     //   "value": amount - fee,
     //   "fees": Amount(
     //     rawValue: BigInt.from(fee),
-    //     fractionDigits: coin.decimals,
+    //     fractionDigits: coin.fractionDigits,
     //   ).decimal.toDouble(),
     //   "height": height,
     //   "txType": "Sent",
     //   "confirmed_status": false,
     //   "amount": Amount(
     //     rawValue: BigInt.from(amount),
-    //     fractionDigits: coin.decimals,
+    //     fractionDigits: coin.fractionDigits,
     //   ).decimal.toDouble(),
     //   "timestamp": DateTime.now().millisecondsSinceEpoch ~/ 1000,
     //   "subType": "mint",
@@ -908,7 +923,9 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
     // Build list of spendable outputs and totaling their satoshi amount
     for (var i = 0; i < availableOutputs.length; i++) {
       if (availableOutputs[i].isConfirmed(
-                  currentChainHeight, cryptoCurrency.minConfirms) ==
+                currentChainHeight,
+                cryptoCurrency.minConfirms,
+              ) ==
               true &&
           !(availableOutputs[i].isCoinbase &&
               availableOutputs[i].getConfirmations(currentChainHeight) <=
@@ -938,8 +955,9 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
         for (var element in value.inputs) {
           if (lelantusCoins.any((e) => e.txid == value.txid) &&
               spendableOutputs.firstWhere(
-                      (output) => output?.txid == element.txid,
-                      orElse: () => null) !=
+                    (output) => output?.txid == element.txid,
+                    orElse: () => null,
+                  ) !=
                   null) {
             spendableOutputs
                 .removeWhere((output) => output!.txid == element.txid);
@@ -954,7 +972,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
     }
 
     int satoshisBeingUsed = 0;
-    Set<UTXO> utxoObjectsToUse = {};
+    final Set<UTXO> utxoObjectsToUse = {};
 
     for (var i = 0; i < spendableOutputs.length; i++) {
       final spendable = spendableOutputs[i];
@@ -964,7 +982,7 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
       }
     }
 
-    var mintsWithoutFee = await _createMintsFromAmount(satoshisBeingUsed);
+    final mintsWithoutFee = await _createMintsFromAmount(satoshisBeingUsed);
 
     TxData txData = await buildMintTransaction(
       txData: TxData(
@@ -1005,7 +1023,8 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
   Future<List<Map<String, dynamic>>> _createMintsFromAmount(int total) async {
     if (total > LelantusFfiWrapper.MINT_LIMIT) {
       throw Exception(
-          "Lelantus mints of more than 5001 are currently disabled");
+        "Lelantus mints of more than 5001 are currently disabled",
+      );
     }
 
     int tmpTotal = total;
@@ -1075,10 +1094,11 @@ mixin LelantusInterface on Bip39HDWallet, ElectrumXInterface {
 
       if (!isUsedMintTag) {
         final mintValue = min(
-            tmpTotal,
-            (isTestnet
-                ? LelantusFfiWrapper.MINT_LIMIT_TESTNET
-                : LelantusFfiWrapper.MINT_LIMIT));
+          tmpTotal,
+          (isTestnet
+              ? LelantusFfiWrapper.MINT_LIMIT_TESTNET
+              : LelantusFfiWrapper.MINT_LIMIT),
+        );
         final mint = await LelantusFfiWrapper.getMintScript(
           amount: Amount(
             rawValue: BigInt.from(mintValue),
diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/nano_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/nano_interface.dart
index dd52da8de..f787b91f7 100644
--- a/lib/wallets/wallet/wallet_mixin_interfaces/nano_interface.dart
+++ b/lib/wallets/wallet/wallet_mixin_interfaces/nano_interface.dart
@@ -13,8 +13,6 @@ import 'package:stackwallet/services/nano_api.dart';
 import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
-import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/extensions/impl/string.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/intermediate/nano_currency.dart';
@@ -81,7 +79,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
       publicKey: publicKey.toUint8ListFromHex,
       derivationIndex: 0,
       derivationPath: null,
-      type: cryptoCurrency.coin.primaryAddressType,
+      type: cryptoCurrency.primaryAddressType,
       subType: AddressSubType.receiving,
     );
   }
@@ -138,7 +136,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
     final BigInt txAmount = BigInt.parse(amountRaw);
     final BigInt balanceAfterTx = currentBalance + txAmount;
 
-    String frontier = infoData["frontier"].toString();
+    final String frontier = infoData["frontier"].toString();
     String representative = infoData["representative"].toString();
 
     if (openBlock) {
@@ -153,7 +151,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
         NanoAccounts.createAccount(NanoAccountType.BANANO, blockHash);
 
     // construct the receive block:
-    Map<String, String> receiveBlock = {
+    final Map<String, String> receiveBlock = {
       "type": "state",
       "account": publicAddress,
       "previous": openBlock
@@ -300,8 +298,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
   @override
   Future<void> updateNode() async {
     _cachedNode = NodeService(secureStorageInterface: secureStorageInterface)
-            .getPrimaryNodeFor(coin: info.coin) ??
-        DefaultNodes.getNodeFor(info.coin);
+            .getPrimaryNodeFor(currency: info.coin) ??
+        info.coin.defaultNode;
 
     unawaited(refresh());
   }
@@ -310,8 +308,8 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
   NodeModel getCurrentNode() {
     return _cachedNode ??
         NodeService(secureStorageInterface: secureStorageInterface)
-            .getPrimaryNodeFor(coin: info.coin) ??
-        DefaultNodes.getNodeFor(info.coin);
+            .getPrimaryNodeFor(currency: info.coin) ??
+        info.coin.defaultNode;
   }
 
   @override
@@ -407,7 +405,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
       final String link = NanoAccounts.extractPublicKey(linkAsAccount);
 
       // construct the send block:
-      Map<String, String> sendBlock = {
+      final Map<String, String> sendBlock = {
         "type": "state",
         "account": publicAddress,
         "previous": frontier,
@@ -505,14 +503,15 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
       proxyInfo: prefs.useTor ? TorService.sharedInstance.getProxyInfo() : null,
     );
     final data = await jsonDecode(response.body);
-    final transactions =
-        data["history"] is List ? data["history"] as List<dynamic> : [];
+    final transactions = data["history"] is List
+        ? data["history"] as List<dynamic>
+        : <dynamic>[];
     if (transactions.isEmpty) {
       return;
     } else {
-      List<Tuple2<Transaction, Address?>> transactionList = [];
-      for (var tx in transactions) {
-        var typeString = tx["type"].toString();
+      final List<Tuple2<Transaction, Address?>> transactionList = [];
+      for (final tx in transactions) {
+        final typeString = tx["type"].toString();
         TransactionType transactionType = TransactionType.unknown;
         if (typeString == "send") {
           transactionType = TransactionType.outgoing;
@@ -524,7 +523,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
           fractionDigits: cryptoCurrency.fractionDigits,
         );
 
-        var transaction = Transaction(
+        final transaction = Transaction(
           walletId: walletId,
           txid: tx["hash"].toString(),
           timestamp: int.parse(tx["local_timestamp"].toString()),
@@ -544,7 +543,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
           numberOfMessages: null,
         );
 
-        Address address = transactionType == TransactionType.incoming
+        final Address address = transactionType == TransactionType.incoming
             ? receivingAddress
             : Address(
                 walletId: walletId,
@@ -555,7 +554,7 @@ mixin NanoInterface<T extends NanoCurrency> on Bip39Wallet<T> {
                 type: info.coin.primaryAddressType,
                 subType: AddressSubType.nonWallet,
               );
-        Tuple2<Transaction, Address> tuple = Tuple2(transaction, address);
+        final Tuple2<Transaction, Address> tuple = Tuple2(transaction, address);
         transactionList.add(tuple);
       }
 
diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart
index 5b6299f12..09fe10f52 100644
--- a/lib/wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart
+++ b/lib/wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart
@@ -4,9 +4,11 @@ import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart';
 import 'package:stackwallet/models/isar/ordinal.dart';
 import 'package:stackwallet/services/litescribe_api.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/electrumx_interface.dart';
 
-mixin OrdinalsInterface on ElectrumXInterface {
+mixin OrdinalsInterface<T extends ElectrumXCurrencyInterface>
+    on ElectrumXInterface<T> {
   final LitescribeAPI _litescribeAPI =
       LitescribeAPI(baseUrl: 'https://litescribe.io/api');
 
diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart
index 202b22943..213c9fd09 100644
--- a/lib/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart
+++ b/lib/wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart
@@ -20,11 +20,12 @@ import 'package:stackwallet/models/signing_data.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/bip32_utils.dart';
 import 'package:stackwallet/utilities/bip47_utils.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/utilities/extensions/extensions.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/logger.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/dogecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/crypto_currency/interfaces/paynym_currency_interface.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
@@ -67,7 +68,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
     final root = await _getRootNode();
     final node = root.derivePath(
       _basePaynymDerivePath(
-        testnet: info.coin.isTestNet,
+        testnet: info.coin.network == CryptoCurrencyNetwork.test,
       ),
     );
     return node;
@@ -158,7 +159,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
     final root = await _getRootNode();
     final node = root.derivePath(
       _basePaynymDerivePath(
-        testnet: info.coin.isTestNet,
+        testnet: info.coin.network == CryptoCurrencyNetwork.test,
       ),
     );
 
@@ -181,7 +182,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
       derivationPath: DerivationPath()
         ..value = _receivingPaynymAddressDerivationPath(
           index,
-          testnet: info.coin.isTestNet,
+          testnet: info.coin.network == CryptoCurrencyNetwork.test,
         ),
       type: generateSegwitAddress ? AddressType.p2wpkh : AddressType.p2pkh,
       subType: AddressSubType.paynymReceive,
@@ -218,7 +219,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
       derivationPath: DerivationPath()
         ..value = _sendPaynymAddressDerivationPath(
           index,
-          testnet: info.coin.isTestNet,
+          testnet: info.coin.network == CryptoCurrencyNetwork.test,
         ),
       type: AddressType.nonWallet,
       subType: AddressSubType.paynymSend,
@@ -275,14 +276,18 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
     final codes = await getAllPaymentCodesFromNotificationTransactions();
     final List<Future<void>> futures = [];
     for (final code in codes) {
-      futures.add(checkCurrentPaynymReceivingAddressForTransactions(
-        sender: code,
-        isSegwit: true,
-      ));
-      futures.add(checkCurrentPaynymReceivingAddressForTransactions(
-        sender: code,
-        isSegwit: false,
-      ));
+      futures.add(
+        checkCurrentPaynymReceivingAddressForTransactions(
+          sender: code,
+          isSegwit: true,
+        ),
+      );
+      futures.add(
+        checkCurrentPaynymReceivingAddressForTransactions(
+          sender: code,
+          isSegwit: false,
+        ),
+      );
     }
     await Future.wait(futures);
   }
@@ -309,7 +314,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
     final node = root
         .derivePath(
           _basePaynymDerivePath(
-            testnet: info.coin.isTestNet,
+            testnet: info.coin.network == CryptoCurrencyNetwork.test,
           ),
         )
         .derive(0);
@@ -323,7 +328,11 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
     final node = await _getRootNode();
 
     final paymentCode = PaymentCode.fromBip32Node(
-      node.derivePath(_basePaynymDerivePath(testnet: info.coin.isTestNet)),
+      node.derivePath(
+        _basePaynymDerivePath(
+          testnet: info.coin.network == CryptoCurrencyNetwork.test,
+        ),
+      ),
       networkType: networkType,
       shouldSetSegwitBit: isSegwit,
     );
@@ -333,8 +342,10 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
 
   Future<Uint8List> signWithNotificationKey(Uint8List data) async {
     final myPrivateKeyNode = await deriveNotificationBip32Node();
-    final pair = btc_dart.ECPair.fromPrivateKey(myPrivateKeyNode.privateKey!,
-        network: networkType);
+    final pair = btc_dart.ECPair.fromPrivateKey(
+      myPrivateKeyNode.privateKey!,
+      network: networkType,
+    );
     final signed = pair.sign(SHA256Digest().process(data));
     return signed;
   }
@@ -363,7 +374,8 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
 
     if (!(await hasConnected(txData.paynymAccountLite!.code.toString()))) {
       throw PaynymSendException(
-          "No notification transaction sent to $paymentCode,");
+        "No notification transaction sent to $paymentCode,",
+      );
     } else {
       final myPrivateKeyNode = await deriveNotificationBip32Node();
       final sendToAddress = await nextUnusedSendAddressFrom(
@@ -465,7 +477,9 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
       for (var i = 0; i < availableOutputs.length; i++) {
         if (availableOutputs[i].isBlocked == false &&
             availableOutputs[i].isConfirmed(
-                    await fetchChainHeight(), cryptoCurrency.minConfirms) ==
+                  await fetchChainHeight(),
+                  cryptoCurrency.minConfirms,
+                ) ==
                 true) {
           spendableOutputs.add(availableOutputs[i]);
           spendableSatoshiValue += BigInt.from(availableOutputs[i].value);
@@ -475,11 +489,13 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
       if (spendableSatoshiValue < amountToSend.raw) {
         // insufficient balance
         throw InsufficientBalanceException(
-            "Spendable balance is less than the minimum required for a notification transaction.");
+          "Spendable balance is less than the minimum required for a notification transaction.",
+        );
       } else if (spendableSatoshiValue == amountToSend.raw) {
         // insufficient balance due to missing amount to cover fee
         throw InsufficientBalanceException(
-            "Remaining balance does not cover the network fee.");
+          "Remaining balance does not cover the network fee.",
+        );
       }
 
       // sort spendable by age (oldest first)
@@ -487,7 +503,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
 
       BigInt satoshisBeingUsed = BigInt.zero;
       int outputsBeingUsed = 0;
-      List<UTXO> utxoObjectsToUse = [];
+      final List<UTXO> utxoObjectsToUse = [];
 
       for (int i = 0;
           satoshisBeingUsed < amountToSend.raw && i < spendableOutputs.length;
@@ -546,7 +562,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
         ),
       );
 
-      if (info.coin == Coin.dogecoin || info.coin == Coin.dogecoinTestNet) {
+      if (info.coin is Dogecoin) {
         if (feeForNoChange < vSizeForNoChange * BigInt.from(1000)) {
           feeForNoChange = vSizeForNoChange * BigInt.from(1000);
         }
@@ -587,21 +603,22 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
           }
 
           final txData = TxData(
-              raw: txn.item1,
-              recipients: [
-                (
-                  address: targetPaymentCodeString,
-                  amount: amountToSend,
-                  isChange: false,
-                ),
-              ],
-              fee: Amount(
-                rawValue: feeBeingPaid,
-                fractionDigits: cryptoCurrency.fractionDigits,
+            raw: txn.item1,
+            recipients: [
+              (
+                address: targetPaymentCodeString,
+                amount: amountToSend,
+                isChange: false,
               ),
-              vSize: txn.item2,
-              utxos: utxoSigningData.map((e) => e.utxo).toSet(),
-              note: "PayNym connect");
+            ],
+            fee: Amount(
+              rawValue: feeBeingPaid,
+              fractionDigits: cryptoCurrency.fractionDigits,
+            ),
+            vSize: txn.item2,
+            utxos: utxoSigningData.map((e) => e.utxo).toSet(),
+            note: "PayNym connect",
+          );
 
           return txData;
         } else {
@@ -613,24 +630,25 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
             change: BigInt.zero,
           );
 
-          BigInt feeBeingPaid = satoshisBeingUsed - amountToSend.raw;
+          final BigInt feeBeingPaid = satoshisBeingUsed - amountToSend.raw;
 
           final txData = TxData(
-              raw: txn.item1,
-              recipients: [
-                (
-                  address: targetPaymentCodeString,
-                  amount: amountToSend,
-                  isChange: false,
-                )
-              ],
-              fee: Amount(
-                rawValue: feeBeingPaid,
-                fractionDigits: cryptoCurrency.fractionDigits,
+            raw: txn.item1,
+            recipients: [
+              (
+                address: targetPaymentCodeString,
+                amount: amountToSend,
+                isChange: false,
               ),
-              vSize: txn.item2,
-              utxos: utxoSigningData.map((e) => e.utxo).toSet(),
-              note: "PayNym connect");
+            ],
+            fee: Amount(
+              rawValue: feeBeingPaid,
+              fractionDigits: cryptoCurrency.fractionDigits,
+            ),
+            vSize: txn.item2,
+            utxos: utxoSigningData.map((e) => e.utxo).toSet(),
+            note: "PayNym connect",
+          );
 
           return txData;
         }
@@ -643,24 +661,25 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
           change: BigInt.zero,
         );
 
-        BigInt feeBeingPaid = satoshisBeingUsed - amountToSend.raw;
+        final BigInt feeBeingPaid = satoshisBeingUsed - amountToSend.raw;
 
         final txData = TxData(
-            raw: txn.item1,
-            recipients: [
-              (
-                address: targetPaymentCodeString,
-                amount: amountToSend,
-                isChange: false,
-              )
-            ],
-            fee: Amount(
-              rawValue: feeBeingPaid,
-              fractionDigits: cryptoCurrency.fractionDigits,
+          raw: txn.item1,
+          recipients: [
+            (
+              address: targetPaymentCodeString,
+              amount: amountToSend,
+              isChange: false,
             ),
-            vSize: txn.item2,
-            utxos: utxoSigningData.map((e) => e.utxo).toSet(),
-            note: "PayNym connect");
+          ],
+          fee: Amount(
+            rawValue: feeBeingPaid,
+            fractionDigits: cryptoCurrency.fractionDigits,
+          ),
+          vSize: txn.item2,
+          utxos: utxoSigningData.map((e) => e.utxo).toSet(),
+          note: "PayNym connect",
+        );
 
         return txData;
       } else {
@@ -674,7 +693,8 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
           );
         } else {
           throw InsufficientBalanceException(
-              "Remaining balance does not cover the network fee.");
+            "Remaining balance does not cover the network fee.",
+          );
         }
       }
     } catch (e) {
@@ -900,8 +920,10 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
         txHash: txHash,
       );
     } catch (e, s) {
-      Logging.instance.log("Exception rethrown from confirmSend(): $e\n$s",
-          level: LogLevel.Error);
+      Logging.instance.log(
+        "Exception rethrown from confirmSend(): $e\n$s",
+        level: LogLevel.Error,
+      );
       rethrow;
     }
   }
@@ -1143,7 +1165,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
         .subTypeEqualTo(TransactionSubType.bip47Notification)
         .findAll();
 
-    List<PaymentCode> codes = [];
+    final List<PaymentCode> codes = [];
 
     for (final tx in txns) {
       // tx is sent so we can check the address's otherData for the code String
@@ -1201,7 +1223,8 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
   }
 
   Future<void> checkForNotificationTransactionsTo(
-      Set<String> otherCodeStrings) async {
+    Set<String> otherCodeStrings,
+  ) async {
     final sentNotificationTransactions = await mainDB.isar.transactionV2s
         .where()
         .walletIdEqualTo(walletId)
@@ -1214,7 +1237,8 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
     final List<PaymentCode> codes = [];
     for (final codeString in otherCodeStrings) {
       codes.add(
-          PaymentCode.fromPaymentCode(codeString, networkType: networkType));
+        PaymentCode.fromPaymentCode(codeString, networkType: networkType),
+      );
     }
 
     for (final tx in sentNotificationTransactions) {
@@ -1303,7 +1327,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
 
     final mySendBip32Node = await deriveNotificationBip32Node();
 
-    List<Address> addresses = [];
+    final List<Address> addresses = [];
     int receivingGapCounter = 0;
     int outgoingGapCounter = 0;
 
@@ -1445,7 +1469,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
       final root = await _getRootNode();
       final node = root.derivePath(
         _basePaynymDerivePath(
-          testnet: info.coin.isTestNet,
+          testnet: info.coin.network == CryptoCurrencyNetwork.test,
         ),
       );
       final paymentCode = PaymentCode.fromBip32Node(
@@ -1473,7 +1497,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
         derivationIndex: 0,
         derivationPath: DerivationPath()
           ..value = _notificationDerivationPath(
-            testnet: info.coin.isTestNet,
+            testnet: info.coin.network == CryptoCurrencyNetwork.test,
           ),
         type: AddressType.p2pkh,
         subType: AddressSubType.paynymNotification,
@@ -1559,7 +1583,8 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
   Uint8List _randomBytes(int n) {
     final Random rng = Random.secure();
     return Uint8List.fromList(
-        List<int>.generate(n, (_) => rng.nextInt(0xFF + 1)));
+      List<int>.generate(n, (_) => rng.nextInt(0xFF + 1)),
+    );
   }
 
   // ================== Overrides ==============================================
@@ -1567,18 +1592,20 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
   @override
   Future<void> updateTransactions({List<Address>? overrideAddresses}) async {
     // Get all addresses.
-    List<Address> allAddressesOld =
+    final List<Address> allAddressesOld =
         overrideAddresses ?? await fetchAddressesForElectrumXScan();
 
     // Separate receiving and change addresses.
-    Set<String> receivingAddresses = allAddressesOld
-        .where((e) =>
-            e.subType == AddressSubType.receiving ||
-            e.subType == AddressSubType.paynymNotification ||
-            e.subType == AddressSubType.paynymReceive)
+    final Set<String> receivingAddresses = allAddressesOld
+        .where(
+          (e) =>
+              e.subType == AddressSubType.receiving ||
+              e.subType == AddressSubType.paynymNotification ||
+              e.subType == AddressSubType.paynymReceive,
+        )
         .map((e) => e.value)
         .toSet();
-    Set<String> changeAddresses = allAddressesOld
+    final Set<String> changeAddresses = allAddressesOld
         .where((e) => e.subType == AddressSubType.change)
         .map((e) => e.value)
         .toSet();
@@ -1591,7 +1618,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
         await fetchHistory(allAddressesSet);
 
     // Only parse new txs (not in db yet).
-    List<Map<String, dynamic>> allTransactions = [];
+    final List<Map<String, dynamic>> allTransactions = [];
     for (final txHash in allTxHashes) {
       // Check for duplicates by searching for tx by tx_hash in db.
       // final storedTx = await mainDB.isar.transactionV2s
@@ -1606,7 +1633,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
       final tx = await electrumXCachedClient.getTransaction(
         txHash: txHash["tx_hash"] as String,
         verbose: true,
-        coin: cryptoCurrency.coin,
+        cryptoCurrency: cryptoCurrency,
       );
 
       // Only tx to list once.
@@ -1648,12 +1675,12 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
 
           final inputTx = await electrumXCachedClient.getTransaction(
             txHash: txid,
-            coin: cryptoCurrency.coin,
+            cryptoCurrency: cryptoCurrency,
           );
 
           final prevOutJson = Map<String, dynamic>.from(
-              (inputTx["vout"] as List).firstWhere((e) => e["n"] == vout)
-                  as Map);
+            (inputTx["vout"] as List).firstWhere((e) => e["n"] == vout) as Map,
+          );
 
           final prevOut = OutputV2.fromElectrumXJson(
             prevOutJson,
@@ -1726,7 +1753,8 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
       TransactionSubType subType = TransactionSubType.none;
       if (outputs.length > 1 && inputs.isNotEmpty) {
         for (int i = 0; i < outputs.length; i++) {
-          List<String>? scriptChunks = outputs[i].scriptPubKeyAsm?.split(" ");
+          final List<String>? scriptChunks =
+              outputs[i].scriptPubKeyAsm?.split(" ");
           if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") {
             final blindedPaymentCode = scriptChunks![1];
             final bytes = blindedPaymentCode.toUint8ListFromHex;
@@ -1809,7 +1837,7 @@ mixin PaynymInterface<T extends PaynymCurrencyInterface>
       final outputs = jsonTX["vout"] as List;
       for (int i = 0; i < outputs.length; i++) {
         final output = outputs[i];
-        List<String>? scriptChunks =
+        final List<String>? scriptChunks =
             (output['scriptPubKey']?['asm'] as String?)?.split(" ");
         if (scriptChunks?.length == 2 && scriptChunks?[0] == "OP_RETURN") {
           final blindedPaymentCode = scriptChunks![1];
diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart
index 7aaa1d3ed..ece37026e 100644
--- a/lib/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart
+++ b/lib/wallets/wallet/wallet_mixin_interfaces/spark_interface.dart
@@ -17,6 +17,7 @@ import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
 import 'package:stackwallet/utilities/extensions/extensions.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
+import 'package:stackwallet/wallets/crypto_currency/interfaces/electrumx_currency_interface.dart';
 import 'package:stackwallet/wallets/isar/models/spark_coin.dart';
 import 'package:stackwallet/wallets/models/tx_data.dart';
 import 'package:stackwallet/wallets/wallet/intermediate/bip39_hd_wallet.dart';
@@ -34,7 +35,8 @@ const OP_SPARKMINT = 0xd1;
 const OP_SPARKSMINT = 0xd2;
 const OP_SPARKSPEND = 0xd3;
 
-mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
+mixin SparkInterface<T extends ElectrumXCurrencyInterface>
+    on Bip39HDWallet<T>, ElectrumXInterface<T> {
   String? _sparkChangeAddressCached;
 
   /// Spark change address. Should generally not be exposed to end users.
@@ -258,7 +260,7 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
     for (int i = 1; i <= currentId; i++) {
       final set = await electrumXCachedClient.getSparkAnonymitySet(
         groupId: i.toString(),
-        coin: info.coin,
+        cryptoCurrency: info.coin,
         useOnlyCacheIfNotEmpty: true,
       );
       set["coinGroupID"] = i;
@@ -619,12 +621,12 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
 
       final anonymitySetFuture = electrumXCachedClient.getSparkAnonymitySet(
         groupId: latestSparkCoinId.toString(),
-        coin: info.coin,
+        cryptoCurrency: info.coin,
         useOnlyCacheIfNotEmpty: false,
       );
 
-      final spentCoinTagsFuture =
-          electrumXCachedClient.getSparkUsedCoinsTags(coin: info.coin);
+      final spentCoinTagsFuture = electrumXCachedClient.getSparkUsedCoinsTags(
+          cryptoCurrency: info.coin);
 
       final futureResults = await Future.wait([
         anonymitySetFuture,
@@ -1600,7 +1602,7 @@ mixin SparkInterface on Bip39HDWallet, ElectrumXInterface {
     for (final coin in coinsToCheck) {
       final tx = await electrumXCachedClient.getTransaction(
         txHash: coin.txHash,
-        coin: info.coin,
+        cryptoCurrency: info.coin,
       );
       if (tx["height"] is int) {
         updatedCoins.add(coin.copyWith(height: tx["height"] as int));
diff --git a/lib/widgets/address_book_card.dart b/lib/widgets/address_book_card.dart
index f40f4f432..8a795437f 100644
--- a/lib/widgets/address_book_card.dart
+++ b/lib/widgets/address_book_card.dart
@@ -16,13 +16,14 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/models/isar/models/contact_entry.dart';
 import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/expandable.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -69,9 +70,9 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
 
     final contact = _contact!;
 
-    final List<Coin> coins = [];
+    final List<CryptoCurrency> coins = [];
 
-    for (final coin in Coin.values) {
+    for (final coin in SupportedCoins.cryptocurrencies) {
       if (contact.addresses.where((e) => e.coin == coin).isNotEmpty) {
         coins.add(coin);
       }
diff --git a/lib/widgets/choose_coin_view.dart b/lib/widgets/choose_coin_view.dart
index 52ff990f2..862585786 100644
--- a/lib/widgets/choose_coin_view.dart
+++ b/lib/widgets/choose_coin_view.dart
@@ -14,11 +14,13 @@ import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/providers/providers.dart';
+import 'package:stackwallet/supported_coins.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/background.dart';
 import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
@@ -33,11 +35,11 @@ import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class ChooseCoinView extends ConsumerStatefulWidget {
   const ChooseCoinView({
-    Key? key,
+    super.key,
     required this.title,
     required this.coinAdditional,
     required this.nextRouteName,
-  }) : super(key: key);
+  });
 
   static const String routeName = "/chooseCoin";
 
@@ -50,12 +52,14 @@ class ChooseCoinView extends ConsumerStatefulWidget {
 }
 
 class _ChooseCoinViewState extends ConsumerState<ChooseCoinView> {
-  List<Coin> _coins = [...Coin.values];
+  List<CryptoCurrency> _coins = [...SupportedCoins.cryptocurrencies];
 
   @override
   void initState() {
     _coins = _coins.toList();
-    _coins.remove(Coin.firoTestNet);
+    _coins.removeWhere(
+      (e) => e.identifier == Firo(CryptoCurrencyNetwork.test).identifier,
+    );
     super.initState();
   }
 
@@ -66,12 +70,17 @@ class _ChooseCoinViewState extends ConsumerState<ChooseCoinView> {
 
   @override
   Widget build(BuildContext context) {
-    bool showTestNet = ref.watch(
+    final bool showTestNet = ref.watch(
       prefsChangeNotifierProvider.select((value) => value.showTestNetCoins),
     );
 
-    List<Coin> coins =
-        showTestNet ? _coins : _coins.where((e) => !e.isTestNet).toList();
+    final List<CryptoCurrency> coins = showTestNet
+        ? _coins
+        : _coins
+            .where(
+              (e) => e.network == CryptoCurrencyNetwork.main,
+            )
+            .toList();
 
     return Background(
       child: Scaffold(
diff --git a/lib/widgets/crypto_notifications.dart b/lib/widgets/crypto_notifications.dart
index b570ae4f9..52c5b3fc5 100644
--- a/lib/widgets/crypto_notifications.dart
+++ b/lib/widgets/crypto_notifications.dart
@@ -16,7 +16,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/notifications_api.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 abstract class CryptoNotificationsEventBus {
   static final instance = EventBus();
@@ -28,7 +28,7 @@ class CryptoNotificationEvent {
   final String walletName;
   final DateTime date;
   final bool shouldWatchForUpdates;
-  final Coin coin;
+  final CryptoCurrency coin;
   final String? txid;
   final int? confirmations;
   final int? requiredConfirmations;
@@ -52,9 +52,9 @@ class CryptoNotificationEvent {
 
 class CryptoNotifications extends ConsumerStatefulWidget {
   const CryptoNotifications({
-    Key? key,
+    super.key,
     required this.child,
-  }) : super(key: key);
+  });
 
   final Widget child;
 
@@ -74,7 +74,7 @@ class _CryptoNotificationsState extends ConsumerState<CryptoNotifications> {
       iconAssetName: ref.read(coinIconProvider(event.coin)),
       date: event.date,
       shouldWatchForUpdates: event.shouldWatchForUpdates,
-      coinName: event.coin.name,
+      coinName: event.coin.identifier,
       txid: event.txid,
       confirmations: event.confirmations,
       requiredConfirmations: event.requiredConfirmations,
diff --git a/lib/widgets/desktop/desktop_fee_dialog.dart b/lib/widgets/desktop/desktop_fee_dialog.dart
index a4a5a9abc..237c2bf8d 100644
--- a/lib/widgets/desktop/desktop_fee_dialog.dart
+++ b/lib/widgets/desktop/desktop_fee_dialog.dart
@@ -9,10 +9,13 @@ import 'package:stackwallet/providers/wallet/public_private_balance_state_provid
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
-import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/wownero.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/wallets/isar/providers/eth/current_token_wallet_provider.dart';
 import 'package:stackwallet/wallets/wallet/impl/firo_wallet.dart';
 import 'package:stackwallet/widgets/animated_text.dart';
@@ -22,10 +25,10 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
 
 class DesktopFeeDialog extends ConsumerStatefulWidget {
   const DesktopFeeDialog({
-    Key? key,
+    super.key,
     required this.walletId,
     this.isToken = false,
-  }) : super(key: key);
+  });
 
   final String walletId;
   final bool isToken;
@@ -44,24 +47,28 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
     required Amount amount,
     required FeeRateType feeRateType,
     required int feeRate,
-    required Coin coin,
+    required CryptoCurrency coin,
   }) async {
     switch (feeRateType) {
       case FeeRateType.fast:
         if (ref
-                .read(widget.isToken
-                    ? tokenFeeSessionCacheProvider
-                    : feeSheetSessionCacheProvider)
+                .read(
+                  widget.isToken
+                      ? tokenFeeSessionCacheProvider
+                      : feeSheetSessionCacheProvider,
+                )
                 .fast[amount] ==
             null) {
           if (widget.isToken == false) {
             final wallet = ref.read(pWallets).getWallet(walletId);
 
-            if (coin == Coin.monero || coin == Coin.wownero) {
+            if (coin is Monero || coin is Wownero) {
               final fee = await wallet.estimateFeeFor(
-                  amount, MoneroTransactionPriority.fast.raw!);
+                amount,
+                MoneroTransactionPriority.fast.raw!,
+              );
               ref.read(feeSheetSessionCacheProvider).fast[amount] = fee;
-            } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+            } else if (coin is Firo) {
               final Amount fee;
               switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
                 case FiroType.spark:
@@ -86,26 +93,32 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
           }
         }
         return ref
-            .read(widget.isToken
-                ? tokenFeeSessionCacheProvider
-                : feeSheetSessionCacheProvider)
+            .read(
+              widget.isToken
+                  ? tokenFeeSessionCacheProvider
+                  : feeSheetSessionCacheProvider,
+            )
             .fast[amount]!;
 
       case FeeRateType.average:
         if (ref
-                .read(widget.isToken
-                    ? tokenFeeSessionCacheProvider
-                    : feeSheetSessionCacheProvider)
+                .read(
+                  widget.isToken
+                      ? tokenFeeSessionCacheProvider
+                      : feeSheetSessionCacheProvider,
+                )
                 .average[amount] ==
             null) {
           if (widget.isToken == false) {
             final wallet = ref.read(pWallets).getWallet(walletId);
 
-            if (coin == Coin.monero || coin == Coin.wownero) {
+            if (coin is Monero || coin is Wownero) {
               final fee = await wallet.estimateFeeFor(
-                  amount, MoneroTransactionPriority.regular.raw!);
+                amount,
+                MoneroTransactionPriority.regular.raw!,
+              );
               ref.read(feeSheetSessionCacheProvider).average[amount] = fee;
-            } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+            } else if (coin is Firo) {
               final Amount fee;
               switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
                 case FiroType.spark:
@@ -130,26 +143,32 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
           }
         }
         return ref
-            .read(widget.isToken
-                ? tokenFeeSessionCacheProvider
-                : feeSheetSessionCacheProvider)
+            .read(
+              widget.isToken
+                  ? tokenFeeSessionCacheProvider
+                  : feeSheetSessionCacheProvider,
+            )
             .average[amount]!;
 
       case FeeRateType.slow:
         if (ref
-                .read(widget.isToken
-                    ? tokenFeeSessionCacheProvider
-                    : feeSheetSessionCacheProvider)
+                .read(
+                  widget.isToken
+                      ? tokenFeeSessionCacheProvider
+                      : feeSheetSessionCacheProvider,
+                )
                 .slow[amount] ==
             null) {
           if (widget.isToken == false) {
             final wallet = ref.read(pWallets).getWallet(walletId);
 
-            if (coin == Coin.monero || coin == Coin.wownero) {
+            if (coin is Monero || coin is Wownero) {
               final fee = await wallet.estimateFeeFor(
-                  amount, MoneroTransactionPriority.slow.raw!);
+                amount,
+                MoneroTransactionPriority.slow.raw!,
+              );
               ref.read(feeSheetSessionCacheProvider).slow[amount] = fee;
-            } else if (coin == Coin.firo || coin == Coin.firoTestNet) {
+            } else if (coin is Firo) {
               final Amount fee;
               switch (ref.read(publicPrivateBalanceStateProvider.state).state) {
                 case FiroType.spark:
@@ -174,9 +193,11 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
           }
         }
         return ref
-            .read(widget.isToken
-                ? tokenFeeSessionCacheProvider
-                : feeSheetSessionCacheProvider)
+            .read(
+              widget.isToken
+                  ? tokenFeeSessionCacheProvider
+                  : feeSheetSessionCacheProvider,
+            )
             .slow[amount]!;
       default:
         return Amount.zero;
@@ -250,14 +271,14 @@ class _DesktopFeeDialogState extends ConsumerState<DesktopFeeDialog> {
 
 class DesktopFeeItem extends ConsumerStatefulWidget {
   const DesktopFeeItem({
-    Key? key,
+    super.key,
     required this.feeObject,
     required this.feeRateType,
     required this.walletId,
     required this.feeFor,
     required this.isSelected,
     this.isButton = true,
-  }) : super(key: key);
+  });
 
   final FeeObject? feeObject;
   final FeeRateType feeRateType;
@@ -266,7 +287,7 @@ class DesktopFeeItem extends ConsumerStatefulWidget {
     required Amount amount,
     required FeeRateType feeRateType,
     required int feeRate,
-    required Coin coin,
+    required CryptoCurrency coin,
   }) feeFor;
   final bool isSelected;
   final bool isButton;
@@ -287,7 +308,9 @@ class _DesktopFeeItemState extends ConsumerState<DesktopFeeItem> {
   ];
 
   String estimatedTimeToBeIncludedInNextBlock(
-      int targetBlockTime, int estimatedNumberOfBlocks) {
+    int targetBlockTime,
+    int estimatedNumberOfBlocks,
+  ) {
     int time = targetBlockTime * estimatedNumberOfBlocks;
 
     int hours = (time / 3600).floor();
@@ -338,14 +361,14 @@ class _DesktopFeeItemState extends ConsumerState<DesktopFeeItem> {
                 (value) => value.getWallet(widget.walletId).info.coin,
               ),
             );
-            if ((coin == Coin.firo || coin == Coin.firoTestNet) &&
+            if ((coin is Firo) &&
                 ref.watch(publicPrivateBalanceStateProvider.state).state ==
                     "Private") {
               return Text(
                 "~${ref.watch(pAmountFormatter(coin)).format(
                       Amount(
                         rawValue: BigInt.parse("3794"),
-                        fractionDigits: coin.decimals,
+                        fractionDigits: coin.fractionDigits,
                       ),
                       indicatePrecisionLoss: false,
                     )}",
@@ -378,7 +401,8 @@ class _DesktopFeeItemState extends ConsumerState<DesktopFeeItem> {
           }
 
           final wallet = ref.watch(
-              pWallets.select((value) => value.getWallet(widget.walletId)));
+            pWallets.select((value) => value.getWallet(widget.walletId)),
+          );
 
           if (widget.feeObject == null) {
             return AnimatedText(
@@ -410,10 +434,10 @@ class _DesktopFeeItemState extends ConsumerState<DesktopFeeItem> {
                             indicatePrecisionLoss: false,
                           )})";
 
-                  timeString = wallet.info.coin == Coin.ethereum
+                  timeString = wallet.info.coin is Ethereum
                       ? ""
                       : estimatedTimeToBeIncludedInNextBlock(
-                          Constants.targetBlockTimeInSeconds(wallet.info.coin),
+                          wallet.info.coin.targetBlockTimeSeconds,
                           widget.feeRateType == FeeRateType.fast
                               ? widget.feeObject!.numberOfBlocksFast
                               : widget.feeRateType == FeeRateType.slow
diff --git a/lib/widgets/dialogs/tor_warning_dialog.dart b/lib/widgets/dialogs/tor_warning_dialog.dart
index d4bd7dc81..7f4bd7cae 100644
--- a/lib/widgets/dialogs/tor_warning_dialog.dart
+++ b/lib/widgets/dialogs/tor_warning_dialog.dart
@@ -1,20 +1,20 @@
 import 'package:flutter/cupertino.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/desktop/primary_button.dart';
 import 'package:stackwallet/widgets/desktop/secondary_button.dart';
 import 'package:stackwallet/widgets/dialogs/basic_dialog.dart';
 
 class TorWarningDialog extends StatelessWidget {
-  final Coin coin;
+  final CryptoCurrency coin;
   final VoidCallback? onContinue;
   final VoidCallback? onCancel;
 
-  TorWarningDialog({
-    Key? key,
+  const TorWarningDialog({
+    super.key,
     required this.coin,
     this.onContinue,
     this.onCancel,
-  }) : super(key: key);
+  });
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/widgets/fee_slider.dart b/lib/widgets/fee_slider.dart
index 64e3af12b..b2cdc87e6 100644
--- a/lib/widgets/fee_slider.dart
+++ b/lib/widgets/fee_slider.dart
@@ -1,8 +1,9 @@
 import 'dart:math';
 
 import 'package:flutter/material.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/dogecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class FeeSlider extends StatefulWidget {
   const FeeSlider({
@@ -12,7 +13,7 @@ class FeeSlider extends StatefulWidget {
     this.showWU = false,
   });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final bool showWU;
   final void Function(int) onSatVByteChanged;
 
@@ -51,12 +52,10 @@ class _FeeSliderState extends State<FeeSlider> {
             setState(() {
               sliderValue = value;
               final number = pow(sliderValue * (max - min) + min, 4).toDouble();
-              switch (widget.coin) {
-                case Coin.dogecoin:
-                case Coin.dogecoinTestNet:
-                  rate = (number * 1000).toInt();
-                default:
-                  rate = number.toInt();
+              if (widget.coin is Dogecoin) {
+                rate = (number * 1000).toInt();
+              } else {
+                rate = number.toInt();
               }
             });
             widget.onSatVByteChanged(rate);
diff --git a/lib/widgets/icon_widgets/eth_token_icon.dart b/lib/widgets/icon_widgets/eth_token_icon.dart
index dbc2d6794..0cd730690 100644
--- a/lib/widgets/icon_widgets/eth_token_icon.dart
+++ b/lib/widgets/icon_widgets/eth_token_icon.dart
@@ -15,14 +15,15 @@ import 'package:isar/isar.dart';
 import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
 import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class EthTokenIcon extends ConsumerStatefulWidget {
   const EthTokenIcon({
-    Key? key,
+    super.key,
     required this.contractAddress,
     this.size = 22,
-  }) : super(key: key);
+  });
 
   final String contractAddress;
   final double size;
@@ -49,7 +50,7 @@ class _EthTokenIconState extends ConsumerState<EthTokenIcon> {
   Widget build(BuildContext context) {
     if (imageUrl == null || imageUrl!.isEmpty) {
       return SvgPicture.asset(
-        ref.watch(coinIconProvider(Coin.ethereum)),
+        ref.watch(coinIconProvider(Ethereum(CryptoCurrencyNetwork.main))),
         width: widget.size,
         height: widget.size,
       );
diff --git a/lib/widgets/managed_favorite.dart b/lib/widgets/managed_favorite.dart
index b5266ea2a..5ab0800d5 100644
--- a/lib/widgets/managed_favorite.dart
+++ b/lib/widgets/managed_favorite.dart
@@ -16,21 +16,22 @@ import 'package:flutter_svg/svg.dart';
 import 'package:stackwallet/providers/db/main_db_provider.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
+import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
 import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart';
 import 'package:stackwallet/widgets/custom_buttons/favorite_toggle.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 
 class ManagedFavorite extends ConsumerStatefulWidget {
   const ManagedFavorite({
-    Key? key,
+    super.key,
     required this.walletId,
-  }) : super(key: key);
+  });
 
   final String walletId;
 
@@ -50,7 +51,7 @@ class _ManagedFavoriteCardState extends ConsumerState<ManagedFavorite> {
     final coin = ref.watch(pWalletCoin(walletId));
 
     Amount total = ref.watch(pWalletBalance(walletId)).total;
-    if (coin == Coin.firo || coin == Coin.firoTestNet) {
+    if (coin is Firo) {
       final balancePrivate =
           ref.watch(pWalletBalanceSecondary(walletId)).total +
               ref.watch(pWalletBalanceTertiary(walletId)).total;
@@ -85,10 +86,7 @@ class _ManagedFavoriteCardState extends ConsumerState<ManagedFavorite> {
             children: [
               Container(
                 decoration: BoxDecoration(
-                  color: Theme.of(context)
-                      .extension<StackColors>()!
-                      .colorForCoin(coin)
-                      .withOpacity(0.5),
+                  color: ref.watch(pCoinColor(coin)).withOpacity(0.5),
                   borderRadius: BorderRadius.circular(
                     Constants.size.circularBorderRadius,
                   ),
@@ -141,7 +139,7 @@ class _ManagedFavoriteCardState extends ConsumerState<ManagedFavorite> {
                                   .extension<StackColors>()!
                                   .buttonTextBorderless,
                         ),
-                      )
+                      ),
                     ],
                   ),
                 ),
diff --git a/lib/widgets/node_card.dart b/lib/widgets/node_card.dart
index a6ac18302..65bf02fb4 100644
--- a/lib/widgets/node_card.dart
+++ b/lib/widgets/node_card.dart
@@ -13,29 +13,21 @@ import 'dart:async';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:solana/solana.dart';
-import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/notifications/show_flush_bar.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart';
 import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/node_details_view.dart';
 import 'package:stackwallet/providers/global/active_wallet_provider.dart';
+import 'package:stackwallet/providers/global/secure_store_provider.dart';
 import 'package:stackwallet/providers/providers.dart';
-import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/connection_check/electrum_connection_check.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
-import 'package:stackwallet/utilities/logger.dart';
-import 'package:stackwallet/utilities/test_epic_box_connection.dart';
-import 'package:stackwallet/utilities/test_eth_node_connection.dart';
-import 'package:stackwallet/utilities/test_monero_node_connection.dart';
-import 'package:stackwallet/utilities/test_stellar_node_connection.dart';
+import 'package:stackwallet/utilities/test_node_connection.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
-import 'package:stackwallet/wallets/api/tezos/tezos_rpc_api.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/conditional_parent.dart';
 import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
 import 'package:stackwallet/widgets/expandable.dart';
@@ -45,13 +37,13 @@ import 'package:tuple/tuple.dart';
 
 class NodeCard extends ConsumerStatefulWidget {
   const NodeCard({
-    Key? key,
+    super.key,
     required this.nodeId,
     required this.coin,
     required this.popBackToRoute,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final String nodeId;
   final String popBackToRoute;
 
@@ -97,161 +89,6 @@ class _NodeCardState extends ConsumerState<NodeCard> {
     }
   }
 
-  Future<bool> _testConnection(
-    NodeModel node,
-    BuildContext context,
-    WidgetRef ref,
-  ) async {
-    bool testPassed = false;
-
-    switch (widget.coin) {
-      case Coin.epicCash:
-        try {
-          testPassed = await testEpicNodeConnection(
-                NodeFormData()
-                  ..host = node.host
-                  ..useSSL = node.useSSL
-                  ..port = node.port,
-              ) !=
-              null;
-        } catch (e, s) {
-          Logging.instance.log("$e\n$s", level: LogLevel.Warning);
-        }
-        break;
-
-      case Coin.monero:
-      case Coin.wownero:
-        try {
-          final uri = Uri.parse(node.host);
-          if (uri.scheme.startsWith("http")) {
-            final String path = uri.path.isEmpty ? "/json_rpc" : uri.path;
-
-            String uriString = "${uri.scheme}://${uri.host}:${node.port}$path";
-
-            final response = await testMoneroNodeConnection(
-              Uri.parse(uriString),
-              false,
-            );
-
-            if (response.cert != null) {
-              if (mounted) {
-                final shouldAllowBadCert = await showBadX509CertificateDialog(
-                  response.cert!,
-                  response.url!,
-                  response.port!,
-                  context,
-                );
-
-                if (shouldAllowBadCert) {
-                  final response = await testMoneroNodeConnection(
-                      Uri.parse(uriString), true);
-                  testPassed = response.success;
-                }
-              }
-            } else {
-              testPassed = response.success;
-            }
-          }
-        } catch (e, s) {
-          Logging.instance.log("$e\n$s", level: LogLevel.Warning);
-        }
-
-        break;
-
-      case Coin.bitcoin:
-      case Coin.litecoin:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.particl:
-      case Coin.bitcoinTestNet:
-      case Coin.firoTestNet:
-      case Coin.dogecoinTestNet:
-      case Coin.bitcoincash:
-      case Coin.litecoinTestNet:
-      case Coin.namecoin:
-      case Coin.bitcoincashTestnet:
-      case Coin.eCash:
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
-        try {
-          testPassed = await checkElectrumServer(
-            host: node.host,
-            port: node.port,
-            useSSL: node.useSSL,
-            overridePrefs: ref.read(prefsChangeNotifierProvider),
-            overrideTorService: ref.read(pTorService),
-          );
-        } catch (_) {
-          testPassed = false;
-        }
-
-        break;
-
-      case Coin.ethereum:
-        try {
-          testPassed = await testEthNodeConnection(node.host);
-        } catch (_) {
-          testPassed = false;
-        }
-        break;
-
-      case Coin.nano:
-      case Coin.banano:
-        throw UnimplementedError();
-      //TODO: check network/node
-      case Coin.tezos:
-        try {
-          testPassed = await TezosRpcAPI.testNetworkConnection(
-            nodeInfo: (host: node.host, port: node.port),
-          );
-        } catch (_) {}
-        break;
-      case Coin.stellar:
-      case Coin.stellarTestnet:
-        try {
-          testPassed = await testStellarNodeConnection(node.host, node.port);
-        } catch (_) {
-          testPassed = false;
-        }
-        break;
-
-      case Coin.solana:
-        try {
-          RpcClient rpcClient;
-          if (node.host.startsWith("http") || node.host.startsWith("https")) {
-            rpcClient = RpcClient("${node.host}:${node.port}");
-          } else {
-            rpcClient = RpcClient("http://${node.host}:${node.port}");
-          }
-          await rpcClient.getEpochInfo().then((value) => testPassed = true);
-        } catch (_) {
-          testPassed = false;
-        }
-        break;
-    }
-
-    if (testPassed) {
-      // showFloatingFlushBar(
-      //   type: FlushBarType.success,
-      //   message: "Server ping success",
-      //   context: context,
-      // );
-    } else {
-      unawaited(
-        showFloatingFlushBar(
-          type: FlushBarType.warning,
-          iconAsset: Assets.svg.circleAlert,
-          message: "Could not connect to node",
-          context: context,
-        ),
-      );
-    }
-
-    return testPassed;
-  }
-
   @override
   void initState() {
     nodeId = widget.nodeId;
@@ -260,10 +97,14 @@ class _NodeCardState extends ConsumerState<NodeCard> {
 
   @override
   Widget build(BuildContext context) {
-    final node = ref.watch(nodeServiceChangeNotifierProvider
-        .select((value) => value.getPrimaryNodeFor(coin: widget.coin)));
-    final _node = ref.watch(nodeServiceChangeNotifierProvider
-        .select((value) => value.getNodeById(id: nodeId)))!;
+    final node = ref.watch(
+      nodeServiceChangeNotifierProvider
+          .select((value) => value.getPrimaryNodeFor(currency: widget.coin)),
+    );
+    final _node = ref.watch(
+      nodeServiceChangeNotifierProvider
+          .select((value) => value.getNodeById(id: nodeId)),
+    )!;
 
     if (node?.name == _node.name) {
       _status = "Connected";
@@ -324,21 +165,50 @@ class _NodeCardState extends ConsumerState<NodeCard> {
                       text: "Connect",
                       enabled: _status == "Disconnected",
                       onTap: () async {
-                        final canConnect =
-                            await _testConnection(_node, context, ref);
-                        if (!canConnect) {
-                          return;
+                        final nodeFormData = NodeFormData()
+                          ..useSSL = _node.useSSL
+                          ..trusted = _node.trusted
+                          ..name = _node.name
+                          ..host = _node.host
+                          ..login = _node.loginName
+                          ..port = _node.port
+                          ..isFailover = _node.isFailover;
+                        nodeFormData.password = await _node.getPassword(
+                          ref.read(secureStoreProvider),
+                        );
+
+                        if (context.mounted) {
+                          final canConnect = await testNodeConnection(
+                            context: context,
+                            nodeFormData: nodeFormData,
+                            cryptoCurrency: widget.coin,
+                            ref: ref,
+                          );
+
+                          if (!canConnect) {
+                            if (context.mounted) {
+                              unawaited(
+                                showFloatingFlushBar(
+                                  type: FlushBarType.warning,
+                                  iconAsset: Assets.svg.circleAlert,
+                                  message: "Could not connect to node",
+                                  context: context,
+                                ),
+                              );
+                            }
+                            return;
+                          }
+
+                          await ref
+                              .read(nodeServiceChangeNotifierProvider)
+                              .setPrimaryNodeFor(
+                                coin: widget.coin,
+                                node: _node,
+                                shouldNotifyListeners: true,
+                              );
+
+                          await _notifyWalletsOfUpdatedNode(ref);
                         }
-
-                        await ref
-                            .read(nodeServiceChangeNotifierProvider)
-                            .setPrimaryNodeFor(
-                              coin: widget.coin,
-                              node: _node,
-                              shouldNotifyListeners: true,
-                            );
-
-                        await _notifyWalletsOfUpdatedNode(ref);
                       },
                     ),
                     const SizedBox(
diff --git a/lib/widgets/node_options_sheet.dart b/lib/widgets/node_options_sheet.dart
index 31bdec456..7002f7fa5 100644
--- a/lib/widgets/node_options_sheet.dart
+++ b/lib/widgets/node_options_sheet.dart
@@ -11,6 +11,7 @@
 import 'dart:async';
 
 import 'package:flutter/material.dart';
+import 'package:flutter_libmonero/wownero/wownero.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
 import 'package:solana/solana.dart';
@@ -26,13 +27,31 @@ import 'package:stackwallet/utilities/assets.dart';
 import 'package:stackwallet/utilities/connection_check/electrum_connection_check.dart';
 import 'package:stackwallet/utilities/constants.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/enums/sync_type_enum.dart';
 import 'package:stackwallet/utilities/logger.dart';
 import 'package:stackwallet/utilities/test_epic_box_connection.dart';
 import 'package:stackwallet/utilities/test_eth_node_connection.dart';
 import 'package:stackwallet/utilities/test_monero_node_connection.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/banano.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoin_frost.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/bitcoincash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/dogecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ecash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/firo.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/litecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/monero.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/namecoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/nano.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/particl.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/peercoin.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/solana.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/stellar.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/tezos.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
 import 'package:tuple/tuple.dart';
 
@@ -45,7 +64,7 @@ class NodeOptionsSheet extends ConsumerWidget {
   }) : super(key: key);
 
   final String nodeId;
-  final Coin coin;
+  final CryptoCurrency coin;
   final String popBackToRoute;
 
   Future<void> _notifyWalletsOfUpdatedNode(WidgetRef ref) async {
@@ -85,8 +104,8 @@ class NodeOptionsSheet extends ConsumerWidget {
       NodeModel node, BuildContext context, WidgetRef ref) async {
     bool testPassed = false;
 
-    switch (coin) {
-      case Coin.epicCash:
+    switch (coin.runtimeType) {
+      case const (Epiccash):
         try {
           testPassed = await testEpicNodeConnection(
                 NodeFormData()
@@ -100,14 +119,15 @@ class NodeOptionsSheet extends ConsumerWidget {
         }
         break;
 
-      case Coin.monero:
-      case Coin.wownero:
+      case const (Monero):
+      case const (Wownero):
         try {
           final uri = Uri.parse(node.host);
           if (uri.scheme.startsWith("http")) {
             final String path = uri.path.isEmpty ? "/json_rpc" : uri.path;
 
-            String uriString = "${uri.scheme}://${uri.host}:${node.port}$path";
+            final String uriString =
+                "${uri.scheme}://${uri.host}:${node.port}$path";
 
             final response = await testMoneroNodeConnection(
               Uri.parse(uriString),
@@ -139,23 +159,16 @@ class NodeOptionsSheet extends ConsumerWidget {
 
         break;
 
-      case Coin.bitcoin:
-      case Coin.litecoin:
-      case Coin.dogecoin:
-      case Coin.firo:
-      case Coin.particl:
-      case Coin.bitcoinTestNet:
-      case Coin.firoTestNet:
-      case Coin.dogecoinTestNet:
-      case Coin.bitcoincash:
-      case Coin.litecoinTestNet:
-      case Coin.namecoin:
-      case Coin.bitcoincashTestnet:
-      case Coin.eCash:
-      case Coin.bitcoinFrost:
-      case Coin.bitcoinFrostTestNet:
-      case Coin.peercoin:
-      case Coin.peercoinTestNet:
+      case const (Bitcoin):
+      case const (Litecoin):
+      case const (Dogecoin):
+      case const (Firo):
+      case const (Particl):
+      case const (Bitcoincash):
+      case const (Namecoin):
+      case const (Ecash):
+      case const (BitcoinFrost):
+      case const (Peercoin):
         try {
           testPassed = await checkElectrumServer(
             host: node.host,
@@ -170,7 +183,7 @@ class NodeOptionsSheet extends ConsumerWidget {
 
         break;
 
-      case Coin.ethereum:
+      case (Ethereum):
         try {
           testPassed = await testEthNodeConnection(node.host);
         } catch (_) {
@@ -178,15 +191,14 @@ class NodeOptionsSheet extends ConsumerWidget {
         }
         break;
 
-      case Coin.nano:
-      case Coin.banano:
-      case Coin.tezos:
-      case Coin.stellar:
-      case Coin.stellarTestnet:
+      case const (Nano):
+      case const (Banano):
+      case const (Tezos):
+      case const (Stellar):
         throw UnimplementedError();
       //TODO: check network/node
 
-      case Coin.solana:
+      case const (Solana):
         try {
           RpcClient rpcClient;
           if (node.host.startsWith("http") || node.host.startsWith("https")) {
@@ -227,7 +239,7 @@ class NodeOptionsSheet extends ConsumerWidget {
 
     final status = ref
                 .watch(nodeServiceChangeNotifierProvider
-                    .select((value) => value.getPrimaryNodeFor(coin: coin)))
+                    .select((value) => value.getPrimaryNodeFor(currency: coin)))
                 ?.id !=
             nodeId
         ? "Disconnected"
diff --git a/lib/widgets/transaction_card.dart b/lib/widgets/transaction_card.dart
index 6f3995002..30ab94579 100644
--- a/lib/widgets/transaction_card.dart
+++ b/lib/widgets/transaction_card.dart
@@ -22,10 +22,12 @@ import 'package:stackwallet/themes/stack_colors.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_formatter.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/utilities/util.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/epiccash.dart';
+import 'package:stackwallet/wallets/crypto_currency/coins/ethereum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
 import 'package:tuple/tuple.dart';
 
@@ -49,16 +51,16 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
   late final bool isTokenTx;
   late final String prefix;
   late final String unit;
-  late final Coin coin;
+  late final CryptoCurrency coin;
   late final EthContract? tokenContract;
   late final int minConfirms;
 
   String whatIsIt(
     TransactionType type,
-    Coin coin,
+    CryptoCurrency coin,
     int currentHeight,
   ) {
-    if (coin == Coin.epicCash && _transaction.slateId == null) {
+    if (coin is Epiccash && _transaction.slateId == null) {
       return "Restored Funds";
     }
 
@@ -169,7 +171,7 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
             ),
           ),
           onPressed: () async {
-            if (coin == Coin.epicCash && _transaction.slateId == null) {
+            if (coin is Epiccash && _transaction.slateId == null) {
               unawaited(showFloatingFlushBar(
                 context: context,
                 message:
@@ -230,7 +232,7 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
                               fit: BoxFit.scaleDown,
                               child: Text(
                                 _transaction.isCancelled
-                                    ? coin == Coin.ethereum
+                                    ? coin is Ethereum
                                         ? "Failed"
                                         : "Cancelled"
                                     : whatIsIt(
diff --git a/lib/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart b/lib/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart
index 1da53d402..2424f57a8 100644
--- a/lib/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart
+++ b/lib/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart
@@ -18,19 +18,19 @@ import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
 import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
 import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
 import 'package:stackwallet/themes/coin_icon_provider.dart';
-import 'package:stackwallet/themes/stack_colors.dart';
+import 'package:stackwallet/themes/theme_providers.dart';
 import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/wallets/crypto_currency/crypto_currency.dart';
 
 class WalletInfoCoinIcon extends ConsumerWidget {
   const WalletInfoCoinIcon({
-    Key? key,
+    super.key,
     required this.coin,
     this.size = 32,
     this.contractAddress,
-  }) : super(key: key);
+  });
 
-  final Coin coin;
+  final CryptoCurrency coin;
   final String? contractAddress;
   final double size;
 
@@ -55,10 +55,7 @@ class WalletInfoCoinIcon extends ConsumerWidget {
       width: size,
       height: size,
       decoration: BoxDecoration(
-        color: Theme.of(context)
-            .extension<StackColors>()!
-            .colorForCoin(coin)
-            .withOpacity(0.4),
+        color: ref.watch(pCoinColor(coin)).withOpacity(0.4),
         borderRadius: BorderRadius.circular(
           Constants.size.circularBorderRadius,
         ),
diff --git a/test/address_utils_test.dart b/test/address_utils_test.dart
index f1dcf1260..81bafbd9d 100644
--- a/test/address_utils_test.dart
+++ b/test/address_utils_test.dart
@@ -1,6 +1,5 @@
 import 'package:flutter_test/flutter_test.dart';
 import 'package:stackwallet/utilities/address_utils.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 void main() {
   const String firoAddress = "a6ESWKz7szru5syLtYAPRhHLdKvMq3Yt1j";
diff --git a/test/cached_electrumx_test.dart b/test/cached_electrumx_test.dart
index 46466163b..13c4bd3f9 100644
--- a/test/cached_electrumx_test.dart
+++ b/test/cached_electrumx_test.dart
@@ -4,7 +4,7 @@ import 'package:mockito/annotations.dart';
 import 'package:mockito/mockito.dart';
 import 'package:stackwallet/electrumx_rpc/cached_electrumx_client.dart';
 import 'package:stackwallet/electrumx_rpc/electrumx_client.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+
 import 'package:stackwallet/utilities/prefs.dart';
 
 import 'cached_electrumx_test.mocks.dart';
diff --git a/test/global_events_test.dart b/test/global_events_test.dart
index b5bb10a22..b45f08035 100644
--- a/test/global_events_test.dart
+++ b/test/global_events_test.dart
@@ -4,7 +4,6 @@ import 'package:stackwallet/services/event_bus/events/global/refresh_percent_cha
 import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart';
 import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
 import 'package:stackwallet/services/event_bus/global_event_bus.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 void main() {
   test("NodeConnectionStatusChangedEvent", () async {
diff --git a/test/services/node_service_test.dart b/test/services/node_service_test.dart
index 2bd889b6e..57eaebcd6 100644
--- a/test/services/node_service_test.dart
+++ b/test/services/node_service_test.dart
@@ -5,7 +5,7 @@ import 'package:stackwallet/db/hive/db.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+
 import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
 
 void main() {
diff --git a/test/utilities/amount/amount_unit_test.dart b/test/utilities/amount/amount_unit_test.dart
index 7591473b5..e3edee615 100644
--- a/test/utilities/amount/amount_unit_test.dart
+++ b/test/utilities/amount/amount_unit_test.dart
@@ -2,7 +2,6 @@ import 'package:decimal/decimal.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:stackwallet/utilities/amount/amount.dart';
 import 'package:stackwallet/utilities/amount/amount_unit.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
 
 void main() {
   test("displayAmount BTC", () {
diff --git a/test/widget_tests/address_book_card_test.dart b/test/widget_tests/address_book_card_test.dart
index 1d38e6c95..581d56529 100644
--- a/test/widget_tests/address_book_card_test.dart
+++ b/test/widget_tests/address_book_card_test.dart
@@ -11,7 +11,7 @@ import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart
 import 'package:stackwallet/providers/global/address_book_service_provider.dart';
 import 'package:stackwallet/services/address_book_service.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/address_book_card.dart';
 
diff --git a/test/widget_tests/node_card_test.dart b/test/widget_tests/node_card_test.dart
index b8e126696..faa1361f1 100644
--- a/test/widget_tests/node_card_test.dart
+++ b/test/widget_tests/node_card_test.dart
@@ -9,7 +9,7 @@ import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/providers/providers.dart';
 import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+
 import 'package:stackwallet/utilities/util.dart';
 import 'package:stackwallet/widgets/node_card.dart';
 import 'package:stackwallet/widgets/node_options_sheet.dart';
diff --git a/test/widget_tests/node_options_sheet_test.dart b/test/widget_tests/node_options_sheet_test.dart
index a0d5690d3..3379742ea 100644
--- a/test/widget_tests/node_options_sheet_test.dart
+++ b/test/widget_tests/node_options_sheet_test.dart
@@ -11,7 +11,7 @@ import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/services/tor_service.dart';
 import 'package:stackwallet/services/wallets.dart';
 import 'package:stackwallet/themes/stack_colors.dart';
-import 'package:stackwallet/utilities/enums/coin_enum.dart';
+
 import 'package:stackwallet/utilities/prefs.dart';
 import 'package:stackwallet/widgets/node_options_sheet.dart';