diff --git a/lib/models/token_balance.dart b/lib/models/token_balance.dart
new file mode 100644
index 000000000..632a5ade5
--- /dev/null
+++ b/lib/models/token_balance.dart
@@ -0,0 +1,71 @@
+import 'dart:convert';
+
+import 'package:decimal/decimal.dart';
+import 'package:stackwallet/models/balance.dart';
+import 'package:stackwallet/utilities/enums/coin_enum.dart';
+import 'package:stackwallet/utilities/format.dart';
+
+class TokenBalance extends Balance {
+  TokenBalance({
+    required this.contractAddress,
+    required this.decimalPlaces,
+    required super.total,
+    required super.spendable,
+    required super.blockedTotal,
+    required super.pendingSpendable,
+    super.coin = Coin.ethereum,
+  });
+
+  final String contractAddress;
+  final int decimalPlaces;
+
+  @override
+  Decimal getTotal({bool includeBlocked = false}) =>
+      Format.satoshisToEthTokenAmount(
+        includeBlocked ? total : total - blockedTotal,
+        decimalPlaces,
+      );
+
+  @override
+  Decimal getSpendable() => Format.satoshisToEthTokenAmount(
+        spendable,
+        decimalPlaces,
+      );
+
+  @override
+  Decimal getPending() => Format.satoshisToEthTokenAmount(
+        pendingSpendable,
+        decimalPlaces,
+      );
+
+  @override
+  Decimal getBlocked() => Format.satoshisToEthTokenAmount(
+        blockedTotal,
+        decimalPlaces,
+      );
+
+  @override
+  String toJsonIgnoreCoin() => jsonEncode({
+        "decimalPlaces": decimalPlaces,
+        "total": total,
+        "spendable": spendable,
+        "blockedTotal": blockedTotal,
+        "pendingSpendable": pendingSpendable,
+      });
+
+  factory TokenBalance.fromJson(
+    String json,
+    String contractAddress,
+    int decimalPlaces,
+  ) {
+    final decoded = jsonDecode(json);
+    return TokenBalance(
+      contractAddress: contractAddress,
+      decimalPlaces: decoded["decimalPlaces"] as int,
+      total: decoded["total"] as int,
+      spendable: decoded["spendable"] as int,
+      blockedTotal: decoded["blockedTotal"] as int,
+      pendingSpendable: decoded["pendingSpendable"] as int,
+    );
+  }
+}
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 c7bfeb25a..3d021f30e 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
@@ -15,7 +15,6 @@ import 'package:stackwallet/utilities/format.dart';
 import 'package:stackwallet/utilities/show_loading.dart';
 import 'package:stackwallet/utilities/text_styles.dart';
 import 'package:stackwallet/widgets/rounded_white_container.dart';
-import 'package:tuple/tuple.dart';
 
 class MyTokenSelectItem extends ConsumerWidget {
   const MyTokenSelectItem(
@@ -51,27 +50,25 @@ class MyTokenSelectItem extends ConsumerWidget {
               BorderRadius.circular(Constants.size.circularBorderRadius),
         ),
         onPressed: () async {
-          final tokenService = EthereumTokenService(
+          ref.read(tokenServiceStateProvider.state).state =
+              EthereumTokenService(
             token: token,
             secureStore: ref.read(secureStoreProvider),
             ethWallet: ref.read(managerProvider).wallet as EthereumWallet,
             tracker: TransactionNotificationTracker(
-                walletId: ref.read(managerProvider).walletId),
+              walletId: ref.read(managerProvider).walletId,
+            ),
           );
 
           await showLoading<void>(
-            whileFuture: tokenService.initializeExisting(),
+            whileFuture: ref.read(tokenServiceProvider)!.initializeExisting(),
             context: context,
             message: "Loading ${token.name}",
           );
 
           await Navigator.of(context).pushNamed(
             TokenView.routeName,
-            arguments: Tuple3(
-              walletId,
-              token,
-              tokenService,
-            ),
+            arguments: walletId,
           );
         },
 
diff --git a/lib/pages/token_view/sub_widgets/token_summary.dart b/lib/pages/token_view/sub_widgets/token_summary.dart
index bac284bb0..28abdda8a 100644
--- a/lib/pages/token_view/sub_widgets/token_summary.dart
+++ b/lib/pages/token_view/sub_widgets/token_summary.dart
@@ -1,127 +1,50 @@
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
-import 'package:flutter_svg/flutter_svg.dart';
-import 'package:stackwallet/pages/token_view/sub_widgets/token_summary_info.dart';
-import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_summary_info.dart';
-import 'package:stackwallet/services/coins/manager.dart';
-import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
-import 'package:stackwallet/utilities/assets.dart';
-import 'package:stackwallet/utilities/constants.dart';
-import 'package:stackwallet/utilities/theme/stack_colors.dart';
+import 'package:stackwallet/pages/token_view/token_view.dart';
+import 'package:stackwallet/providers/global/wallets_provider.dart';
+import 'package:stackwallet/utilities/text_styles.dart';
+import 'package:stackwallet/widgets/rounded_container.dart';
 
-class TokenSummary extends StatelessWidget {
+class TokenSummary extends ConsumerWidget {
   const TokenSummary({
     Key? key,
     required this.walletId,
-    required this.managerProvider,
-    required this.initialSyncStatus,
-    this.aspectRatio = 2.0,
-    this.minHeight = 100.0,
-    this.minWidth = 200.0,
-    this.maxHeight = 250.0,
-    this.maxWidth = 400.0,
   }) : super(key: key);
 
   final String walletId;
-  final ChangeNotifierProvider<Manager> managerProvider;
-  final WalletSyncStatus initialSyncStatus;
-
-  final double aspectRatio;
-  final double minHeight;
-  final double minWidth;
-  final double maxHeight;
-  final double maxWidth;
 
   @override
-  Widget build(BuildContext context) {
-    return AspectRatio(
-      aspectRatio: aspectRatio,
-      child: ConstrainedBox(
-        constraints: BoxConstraints(
-          minHeight: minHeight,
-          minWidth: minWidth,
-          maxHeight: maxHeight,
-          maxWidth: minWidth,
-        ),
-        child: Stack(
-          children: [
-            Consumer(
-              builder: (_, ref, __) {
-                return Container(
-                  decoration: BoxDecoration(
-                    color: Theme.of(context)
-                        .extension<StackColors>()!
-                        .colorForCoin(ref.watch(
-                            managerProvider.select((value) => value.coin))),
-                    borderRadius: BorderRadius.circular(
-                      Constants.size.circularBorderRadius,
-                    ),
-                  ),
-                );
-              },
-            ),
-            Positioned.fill(
-              child: Row(
-                crossAxisAlignment: CrossAxisAlignment.start,
-                children: [
-                  const Spacer(
-                    flex: 5,
-                  ),
-                  Expanded(
-                    flex: 6,
-                    child: SvgPicture.asset(
-                      Assets.svg.ellipse1,
-                      // fit: BoxFit.fitWidth,
-                      // clipBehavior: Clip.none,
-                    ),
-                  ),
-                  const SizedBox(
-                    width: 25,
-                  ),
-                ],
+  Widget build(BuildContext context, WidgetRef ref) {
+    return RoundedContainer(
+      color: const Color(0xFFE9EAFF), // todo: fix color
+      // color: Theme.of(context).extension<StackColors>()!.,
+
+      child: Column(
+        children: [
+          Text(
+            ref.watch(
+              walletsChangeNotifierProvider.select(
+                (value) => value.getManager(walletId).walletName,
               ),
             ),
-            // Positioned.fill(
-            //   child:
-            // Column(
-            //   mainAxisAlignment: MainAxisAlignment.end,
-            //   children: [
-            Align(
-              alignment: Alignment.bottomCenter,
-              child: Row(
-                children: [
-                  const Spacer(
-                    flex: 1,
-                  ),
-                  Expanded(
-                    flex: 3,
-                    child: SvgPicture.asset(
-                      Assets.svg.ellipse2,
-                      // fit: BoxFit.f,
-                      // clipBehavior: Clip.none,
-                    ),
-                  ),
-                  const SizedBox(
-                    width: 13,
-                  ),
-                ],
+            style: STextStyles.label(context),
+          ),
+          Text(
+            ref.watch(tokenServiceProvider.select((value) => value!.balance
+                .getTotal()
+                .toStringAsFixed(ref.watch(tokenServiceProvider
+                    .select((value) => value!.token.decimals))))),
+            style: STextStyles.label(context),
+          ),
+          Text(
+            ref.watch(
+              walletsChangeNotifierProvider.select(
+                (value) => value.getManager(walletId).walletName,
               ),
             ),
-            //   ],
-            // ),
-            // ),
-            Positioned.fill(
-              child: Padding(
-                padding: const EdgeInsets.all(16.0),
-                child: TokenSummaryInfo(
-                  walletId: walletId,
-                  managerProvider: managerProvider,
-                  initialSyncStatus: initialSyncStatus,
-                ),
-              ),
-            ),
-          ],
-        ),
+            style: STextStyles.label(context),
+          ),
+        ],
       ),
     );
   }
diff --git a/lib/pages/token_view/token_view.dart b/lib/pages/token_view/token_view.dart
index 41357ff37..4160650bf 100644
--- a/lib/pages/token_view/token_view.dart
+++ b/lib/pages/token_view/token_view.dart
@@ -2,7 +2,6 @@ import 'package:event_bus/event_bus.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:flutter_svg/svg.dart';
-import 'package:stackwallet/models/ethereum/eth_token.dart';
 import 'package:stackwallet/pages/token_view/sub_widgets/token_transaction_list_widget.dart';
 import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart';
 import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
@@ -15,13 +14,16 @@ 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';
 
+final tokenServiceStateProvider =
+    StateProvider<EthereumTokenService?>((ref) => null);
+final tokenServiceProvider = ChangeNotifierProvider<EthereumTokenService?>(
+    (ref) => ref.watch(tokenServiceStateProvider));
+
 /// [eventBus] should only be set during testing
 class TokenView extends ConsumerStatefulWidget {
   const TokenView({
     Key? key,
     required this.walletId,
-    required this.token,
-    required this.tokenService,
     this.eventBus,
   }) : super(key: key);
 
@@ -29,8 +31,6 @@ class TokenView extends ConsumerStatefulWidget {
   static const double navBarHeight = 65.0;
 
   final String walletId;
-  final EthToken token;
-  final EthereumTokenService tokenService;
   final EventBus? eventBus;
 
   @override
@@ -51,7 +51,6 @@ class _TokenViewState extends ConsumerState<TokenView> {
   @override
   Widget build(BuildContext context) {
     debugPrint("BUILD: $runtimeType");
-    // print("MY TOTAL BALANCE IS ${widget.token.totalBalance}");
 
     return Background(
       child: Scaffold(
@@ -67,7 +66,6 @@ class _TokenViewState extends ConsumerState<TokenView> {
             children: [
               SvgPicture.asset(
                 Assets.svg.iconFor(coin: Coin.ethereum),
-                // color: Theme.of(context).extension<StackColors>()!.accentColorDark
                 width: 24,
                 height: 24,
               ),
@@ -76,14 +74,16 @@ class _TokenViewState extends ConsumerState<TokenView> {
               ),
               Expanded(
                 child: Text(
-                  widget.token.name,
+                  ref.watch(tokenServiceProvider
+                      .select((value) => value!.token.name)),
                   style: STextStyles.navBarTitle(context),
                   overflow: TextOverflow.ellipsis,
                 ),
               ),
               Expanded(
                 child: Text(
-                  widget.token.symbol,
+                  ref.watch(tokenServiceProvider
+                      .select((value) => value!.token.symbol)),
                   style: STextStyles.navBarTitle(context),
                   overflow: TextOverflow.ellipsis,
                 ),
@@ -167,7 +167,8 @@ class _TokenViewState extends ConsumerState<TokenView> {
                         children: [
                           Expanded(
                             child: TokenTransactionsList(
-                              tokenService: widget.tokenService,
+                              tokenService: ref.watch(tokenServiceProvider
+                                  .select((value) => value!)),
                               walletId: widget.walletId,
                             ),
                           ),
diff --git a/lib/route_generator.dart b/lib/route_generator.dart
index 37d7ccefa..1b3c5b9ab 100644
--- a/lib/route_generator.dart
+++ b/lib/route_generator.dart
@@ -128,7 +128,6 @@ import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/nodes_
 import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/security_settings.dart';
 import 'package:stackwallet/pages_desktop_specific/settings/settings_menu/syncing_preferences_settings.dart';
 import 'package:stackwallet/services/coins/manager.dart';
-import 'package:stackwallet/services/ethereum/ethereum_token_service.dart';
 import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
 import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
 import 'package:stackwallet/utilities/enums/add_wallet_type_enum.dart';
@@ -1461,14 +1460,11 @@ class RouteGenerator {
       //   }
 
       case TokenView.routeName:
-        if (args is Tuple3<String, EthToken,
-            EthereumTokenService>) {
+        if (args is String) {
           return getRoute(
             shouldUseMaterialRoute: useMaterialPageRoute,
             builder: (_) => TokenView(
-              walletId: args.item1,
-              token: args.item2,
-              tokenService: args.item3,
+              walletId: args,
             ),
             settings: RouteSettings(
               name: settings.name,
diff --git a/lib/services/ethereum/ethereum_token_service.dart b/lib/services/ethereum/ethereum_token_service.dart
index bae28dba9..ca26fbecd 100644
--- a/lib/services/ethereum/ethereum_token_service.dart
+++ b/lib/services/ethereum/ethereum_token_service.dart
@@ -2,6 +2,7 @@ import 'dart:async';
 
 import 'package:decimal/decimal.dart';
 import 'package:ethereum_addresses/ethereum_addresses.dart';
+import 'package:flutter/widgets.dart';
 import 'package:http/http.dart';
 import 'package:isar/isar.dart';
 import 'package:stackwallet/models/ethereum/eth_token.dart';
@@ -9,10 +10,12 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart';
 import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
 import 'package:stackwallet/models/node_model.dart';
 import 'package:stackwallet/models/paymint/fee_object_model.dart';
+import 'package:stackwallet/models/token_balance.dart';
 import 'package:stackwallet/services/coins/ethereum/ethereum_wallet.dart';
 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/services/mixins/eth_token_cache.dart';
 import 'package:stackwallet/services/node_service.dart';
 import 'package:stackwallet/services/transaction_notification_tracker.dart';
 import 'package:stackwallet/utilities/default_nodes.dart';
@@ -25,7 +28,7 @@ import 'package:stackwallet/utilities/logger.dart';
 import 'package:tuple/tuple.dart';
 import 'package:web3dart/web3dart.dart' as web3dart;
 
-class EthereumTokenService {
+class EthereumTokenService extends ChangeNotifier with EthTokenCache {
   final EthToken token;
   final EthereumWallet ethWallet;
   final TransactionNotificationTracker tracker;
@@ -48,11 +51,11 @@ class EthereumTokenService {
     required this.tracker,
   }) : _secureStore = secureStore {
     _contractAddress = web3dart.EthereumAddress.fromHex(token.contractAddress);
+    initCache(ethWallet.walletId, token);
   }
 
-  Future<Decimal> get availableBalance async {
-    return await totalBalance;
-  }
+  TokenBalance get balance => _balance ??= getCachedBalance();
+  TokenBalance? _balance;
 
   Coin get coin => Coin.ethereum;
 
@@ -177,18 +180,6 @@ class EthereumTokenService {
 
     final feeEstimate = await estimateFeeFor(satoshiAmount, fee);
 
-    bool isSendAll = false;
-    final balance =
-        Format.decimalAmountToSatoshis(await availableBalance, coin);
-    if (satoshiAmount == balance) {
-      isSendAll = true;
-    }
-
-    if (isSendAll) {
-      //Send the full balance
-      satoshiAmount = balance;
-    }
-
     Map<String, dynamic> txData = {
       "fee": feeEstimate,
       "feeInWei": fee,
@@ -205,6 +196,7 @@ class EthereumTokenService {
     if (!_refreshLock) {
       _refreshLock = true;
       try {
+        await refreshCachedBalance();
         await _refreshTransactions();
       } catch (e, s) {
         Logging.instance.log(
@@ -213,22 +205,33 @@ class EthereumTokenService {
         );
       } finally {
         _refreshLock = false;
+        notifyListeners();
       }
     }
   }
 
-  Future<Decimal> get totalBalance async {
+  Future<void> refreshCachedBalance() async {
     final balanceRequest = await _client.call(
         contract: _contract,
         function: _balanceFunction,
         params: [_credentials.address]);
 
-    String balance = balanceRequest.first.toString();
-    final balanceInDecimal = Format.satoshisToEthTokenAmount(
-      int.parse(balance),
-      token.decimals,
+    print("==========================================");
+    print("balanceRequest: $balanceRequest");
+    print("==========================================");
+
+    String _balance = balanceRequest.first.toString();
+
+    final newBalance = TokenBalance(
+      contractAddress: token.contractAddress,
+      total: int.parse(_balance),
+      spendable: int.parse(_balance),
+      blockedTotal: 0,
+      pendingSpendable: 0,
+      decimalPlaces: token.decimals,
     );
-    return Decimal.parse(balanceInDecimal.toString());
+    await updateCachedBalance(newBalance);
+    notifyListeners();
   }
 
   Future<List<Transaction>> get transactions => ethWallet.db
diff --git a/lib/services/mixins/eth_token_cache.dart b/lib/services/mixins/eth_token_cache.dart
new file mode 100644
index 000000000..b490e849c
--- /dev/null
+++ b/lib/services/mixins/eth_token_cache.dart
@@ -0,0 +1,50 @@
+import 'package:stackwallet/hive/db.dart';
+import 'package:stackwallet/models/ethereum/eth_token.dart';
+import 'package:stackwallet/models/token_balance.dart';
+
+abstract class _Keys {
+  static String tokenBalance(String contractAddress) {
+    return "tokenBalanceCache_$contractAddress";
+  }
+}
+
+mixin EthTokenCache {
+  late final String _walletId;
+  late final EthToken _token;
+
+  void initCache(String walletId, EthToken token) {
+    _walletId = walletId;
+    _token = token;
+  }
+
+  // token balance cache
+  TokenBalance getCachedBalance() {
+    final jsonString = DB.instance.get<dynamic>(
+      boxName: _walletId,
+      key: _Keys.tokenBalance(_token.contractAddress),
+    ) as String?;
+    if (jsonString == null) {
+      return TokenBalance(
+        contractAddress: _token.contractAddress,
+        decimalPlaces: _token.decimals,
+        total: 0,
+        spendable: 0,
+        blockedTotal: 0,
+        pendingSpendable: 0,
+      );
+    }
+    return TokenBalance.fromJson(
+      jsonString,
+      _token.contractAddress,
+      _token.decimals,
+    );
+  }
+
+  Future<void> updateCachedBalance(TokenBalance balance) async {
+    await DB.instance.put<dynamic>(
+      boxName: _walletId,
+      key: _Keys.tokenBalance(_token.contractAddress),
+      value: balance.toJsonIgnoreCoin(),
+    );
+  }
+}