diff --git a/android/fastlane/metadata/android/en-US/changelogs/148.txt b/android/fastlane/metadata/android/en-US/changelogs/148.txt
new file mode 100644
index 0000000000..29e78c6890
--- /dev/null
+++ b/android/fastlane/metadata/android/en-US/changelogs/148.txt
@@ -0,0 +1 @@
+- Asynchronous background fetching of AR and tIO balances with improved loading and error handling.
diff --git a/lib/authentication/ardrive_auth.dart b/lib/authentication/ardrive_auth.dart
index d7c9dfa138..4266983045 100644
--- a/lib/authentication/ardrive_auth.dart
+++ b/lib/authentication/ardrive_auth.dart
@@ -171,6 +171,8 @@ class ArDriveAuthImpl implements ArDriveAuth {
 
       currentUser = await _userRepository.getUser(password);
 
+      _updateBalance();
+
       if (await _biometricAuthentication.isEnabled()) {
         logger.i('Saving password in secure storage');
 
@@ -308,11 +310,33 @@ class ArDriveAuthImpl implements ArDriveAuth {
 
     currentUser = await _userRepository.getUser(password);
 
+    _updateBalance();
+
     _userStreamController.add(_currentUser);
 
     return currentUser;
   }
 
+  void _updateBalance() {
+    _userRepository.getIOTokens(currentUser.wallet).then((value) {
+      _currentUser = _currentUser!.copyWith(
+        ioTokens: value,
+        errorFetchingIOTokens: false,
+      );
+      _userStreamController.add(_currentUser);
+    }).catchError((e) {
+      _currentUser = _currentUser!.copyWith(
+        errorFetchingIOTokens: true,
+      );
+      _userStreamController.add(_currentUser);
+      return Future.value(null);
+    });
+    _userRepository.getBalance(currentUser.wallet).then((value) {
+      _currentUser = _currentUser!.copyWith(walletBalance: value);
+      _userStreamController.add(_currentUser);
+    });
+  }
+
   Future<void> _saveUser(
     String password,
     ProfileType profileType,
@@ -364,11 +388,13 @@ class ArDriveAuthImpl implements ArDriveAuth {
 
   @override
   Future<void> refreshBalance() async {
-    final balance = await _userRepository.getBalance(currentUser.wallet);
-
-    currentUser = currentUser.copyWith(walletBalance: balance);
+    _currentUser = _currentUser!.copyWith(
+      errorFetchingIOTokens: false,
+    );
 
     _userStreamController.add(_currentUser);
+
+    _updateBalance();
   }
 }
 
diff --git a/lib/blocs/profile/profile_cubit.dart b/lib/blocs/profile/profile_cubit.dart
index 56536d7e60..6ebbf79e80 100644
--- a/lib/blocs/profile/profile_cubit.dart
+++ b/lib/blocs/profile/profile_cubit.dart
@@ -36,6 +36,13 @@ class ProfileCubit extends Cubit<ProfileState> {
         _arDriveAuth = arDriveAuth,
         super(ProfileCheckingAvailability()) {
     promptToAuthenticate();
+
+    _arDriveAuth.onAuthStateChanged().listen((user) {
+      if (user != null) {
+        emit(ProfileLoggedIn(
+            user: user, useTurbo: _turboUploadService.useTurboUpload));
+      }
+    });
   }
 
   Future<bool> isCurrentProfileArConnect() async {
diff --git a/lib/blocs/profile/profile_state.dart b/lib/blocs/profile/profile_state.dart
index 0195106608..2c55c2bbfd 100644
--- a/lib/blocs/profile/profile_state.dart
+++ b/lib/blocs/profile/profile_state.dart
@@ -49,7 +49,7 @@ class ProfileLoggedIn extends ProfileAvailable {
       useTurbo;
 
   @override
-  List<Object?> get props => [user];
+  List<Object?> get props => [user, useTurbo];
 }
 
 class ProfilePromptAdd extends ProfileUnavailable {}
diff --git a/lib/components/profile_card.dart b/lib/components/profile_card.dart
index d084cb8d8d..3d03d69210 100644
--- a/lib/components/profile_card.dart
+++ b/lib/components/profile_card.dart
@@ -15,6 +15,7 @@ import 'package:ardrive/services/config/config.dart';
 import 'package:ardrive/turbo/services/payment_service.dart';
 import 'package:ardrive/turbo/topup/components/turbo_balance_widget.dart';
 import 'package:ardrive/turbo/utils/utils.dart';
+import 'package:ardrive/user/balance/user_balance_bloc.dart';
 import 'package:ardrive/user/download_wallet/download_wallet_modal.dart';
 import 'package:ardrive/utils/app_localizations_wrapper.dart';
 import 'package:ardrive/utils/open_url.dart';
@@ -477,36 +478,70 @@ class _ProfileCardState extends State<ProfileCard> {
 
     final ioTokens = state.user.ioTokens;
 
-    return Padding(
-      padding: const EdgeInsets.symmetric(horizontal: 16.0),
-      child: Column(
-        mainAxisAlignment: MainAxisAlignment.center,
-        crossAxisAlignment: CrossAxisAlignment.start,
-        children: [
-          Text(
-            'tIO Tokens',
-            style: typography.paragraphNormal(
-              fontWeight: ArFontWeight.semiBold,
-              color: colorTokens.textHigh,
-            ),
-          ),
-          if (ioTokens != null)
-            Text(
-              ioTokens,
-              style: typography.paragraphNormal(
-                color: colorTokens.textLow,
-                fontWeight: ArFontWeight.semiBold,
-              ),
-            ),
-          if (ioTokens == null)
-            Text(
-              'An error occurred while fetching IO tokens',
-              style: typography.paragraphNormal(
-                color: colorTokens.textLow,
-                fontWeight: ArFontWeight.semiBold,
+    return BlocProvider(
+      create: (context) => UserBalanceBloc(auth: context.read<ArDriveAuth>())
+        ..add(GetUserBalance()),
+      child: BlocBuilder<UserBalanceBloc, UserBalanceState>(
+        builder: (context, state) {
+          if (state is UserBalanceLoaded) {
+            return Padding(
+              padding: const EdgeInsets.symmetric(horizontal: 16.0),
+              child: Column(
+                mainAxisAlignment: MainAxisAlignment.center,
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Text(
+                    'tIO Tokens',
+                    style: typography.paragraphNormal(
+                      fontWeight: ArFontWeight.semiBold,
+                      color: colorTokens.textHigh,
+                    ),
+                  ),
+                  if (state is UserBalanceLoadingIOTokens &&
+                      !state.errorFetchingIOTokens)
+                    const Padding(
+                      padding: EdgeInsets.only(top: 8),
+                      child: LinearProgressIndicator(),
+                    ),
+                  if (ioTokens != null)
+                    Text(
+                      ioTokens,
+                      style: typography.paragraphNormal(
+                        color: colorTokens.textLow,
+                        fontWeight: ArFontWeight.semiBold,
+                      ),
+                    ),
+                  if (state.errorFetchingIOTokens) ...[
+                    Row(
+                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
+                      children: [
+                        Text(
+                          'Error fetching tIO balance',
+                          style: typography.paragraphNormal(
+                            fontWeight: ArFontWeight.semiBold,
+                            color: ArDriveTheme.of(context)
+                                .themeData
+                                .colors
+                                .themeErrorDefault,
+                          ),
+                        ),
+                        ArDriveIconButton(
+                          icon: ArDriveIcons.refresh(),
+                          onPressed: () {
+                            context
+                                .read<UserBalanceBloc>()
+                                .add(RefreshUserBalance());
+                          },
+                        )
+                      ],
+                    ),
+                  ]
+                ],
               ),
-            ),
-        ],
+            );
+          }
+          return const SizedBox.shrink();
+        },
       ),
     );
   }
diff --git a/lib/main.dart b/lib/main.dart
index 9b8873c46e..3b968f7d0b 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -394,6 +394,7 @@ class AppState extends State<App> {
           create: (context) => UserRepository(
             context.read<ProfileDao>(),
             context.read<ArweaveService>(),
+            ArioSDKFactory().create(),
           ),
         ),
         RepositoryProvider(
diff --git a/lib/user/balance/user_balance_bloc.dart b/lib/user/balance/user_balance_bloc.dart
new file mode 100644
index 0000000000..54a990dad5
--- /dev/null
+++ b/lib/user/balance/user_balance_bloc.dart
@@ -0,0 +1,93 @@
+import 'dart:async';
+
+import 'package:ardrive/authentication/ardrive_auth.dart';
+import 'package:ardrive/user/user.dart';
+import 'package:equatable/equatable.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+
+part 'user_balance_event.dart';
+part 'user_balance_state.dart';
+
+class UserBalanceBloc extends Bloc<UserBalanceEvent, UserBalanceState> {
+  final ArDriveAuth _auth;
+  StreamSubscription<User?>? _userSubscription;
+
+  UserBalanceBloc({required ArDriveAuth auth})
+      : _auth = auth,
+        super(UserBalanceInitial()) {
+    on<GetUserBalance>(_onGetUserBalance);
+    on<RefreshUserBalance>(_onRefreshUserBalance);
+  }
+
+  Future<void> _onGetUserBalance(
+      GetUserBalance event, Emitter<UserBalanceState> emit) async {
+    await _cancelSubscription();
+
+    final user = _auth.currentUser;
+    _emitUserBalanceState(user, emit);
+
+    _userSubscription = _auth.onAuthStateChanged().listen((user) {
+      if (isClosed) return;
+      _emitUserBalanceState(user, emit);
+      if (user?.ioTokens != null) {
+        _cancelSubscription();
+      }
+    });
+
+    await _userSubscription?.asFuture();
+  }
+
+  Future<void> _onRefreshUserBalance(
+      RefreshUserBalance event, Emitter<UserBalanceState> emit) async {
+    if (isClosed) return;
+
+    await _cancelSubscription();
+
+    emit(UserBalanceLoadingIOTokens(
+      arBalance: _auth.currentUser.walletBalance,
+      errorFetchingIOTokens: false,
+    ));
+
+    _auth.refreshBalance();
+
+    _userSubscription = _auth.onAuthStateChanged().listen((user) {
+      if (isClosed) return;
+      _emitUserBalanceState(user, emit);
+      if (user?.ioTokens != null) {
+        _cancelSubscription();
+      }
+    });
+
+    await _userSubscription?.asFuture();
+  }
+
+  Future<void> _cancelSubscription() async {
+    if (_userSubscription != null) {
+      await _userSubscription!.cancel();
+      _userSubscription = null;
+    }
+  }
+
+  void _emitUserBalanceState(User? user, Emitter<UserBalanceState> emit) {
+    if (user == null) return;
+
+    if (user.ioTokens == null && !user.errorFetchingIOTokens) {
+      emit(UserBalanceLoadingIOTokens(
+        arBalance: user.walletBalance,
+        errorFetchingIOTokens: user.errorFetchingIOTokens,
+      ));
+    } else {
+      emit(UserBalanceLoaded(
+        arBalance: user.walletBalance,
+        ioTokens: user.ioTokens,
+        errorFetchingIOTokens: user.errorFetchingIOTokens,
+      ));
+    }
+  }
+
+  @override
+  Future<void> close() async {
+    await _cancelSubscription();
+    return super.close();
+  }
+}
diff --git a/lib/user/balance/user_balance_event.dart b/lib/user/balance/user_balance_event.dart
new file mode 100644
index 0000000000..9d2e0b4f45
--- /dev/null
+++ b/lib/user/balance/user_balance_event.dart
@@ -0,0 +1,12 @@
+part of 'user_balance_bloc.dart';
+
+sealed class UserBalanceEvent extends Equatable {
+  const UserBalanceEvent();
+
+  @override
+  List<Object> get props => [];
+}
+
+final class GetUserBalance extends UserBalanceEvent {}
+
+final class RefreshUserBalance extends UserBalanceEvent {}
diff --git a/lib/user/balance/user_balance_state.dart b/lib/user/balance/user_balance_state.dart
new file mode 100644
index 0000000000..185e120bde
--- /dev/null
+++ b/lib/user/balance/user_balance_state.dart
@@ -0,0 +1,30 @@
+part of 'user_balance_bloc.dart';
+
+sealed class UserBalanceState extends Equatable {
+  const UserBalanceState();
+
+  @override
+  List<Object> get props => [];
+}
+
+final class UserBalanceInitial extends UserBalanceState {}
+
+final class UserBalanceLoaded extends UserBalanceState {
+  final BigInt arBalance;
+  final String? ioTokens;
+  final bool errorFetchingIOTokens;
+
+  const UserBalanceLoaded({
+    required this.arBalance,
+    required this.ioTokens,
+    required this.errorFetchingIOTokens,
+  });
+}
+
+final class UserBalanceLoadingIOTokens extends UserBalanceLoaded {
+  const UserBalanceLoadingIOTokens({
+    required super.arBalance,
+    super.ioTokens,
+    super.errorFetchingIOTokens = false,
+  });
+}
diff --git a/lib/user/repositories/user_repository.dart b/lib/user/repositories/user_repository.dart
index 9384757c5d..789a10e2a7 100644
--- a/lib/user/repositories/user_repository.dart
+++ b/lib/user/repositories/user_repository.dart
@@ -17,23 +17,29 @@ abstract class UserRepository {
   Future<void> deleteUser();
   Future<String?> getOwnerOfDefaultProfile();
   Future<BigInt> getBalance(Wallet wallet);
+  Future<String?> getIOTokens(Wallet wallet);
 
-  factory UserRepository(ProfileDao profileDao, ArweaveService arweave) =>
+  factory UserRepository(
+          ProfileDao profileDao, ArweaveService arweave, ArioSDK arioSDK) =>
       _UserRepository(
         profileDao: profileDao,
         arweave: arweave,
+        arioSDK: arioSDK,
       );
 }
 
 class _UserRepository implements UserRepository {
   final ProfileDao _profileDao;
   final ArweaveService _arweave;
+  final ArioSDK _arioSDK;
 
   _UserRepository({
     required ProfileDao profileDao,
     required ArweaveService arweave,
+    required ArioSDK arioSDK,
   })  : _profileDao = profileDao,
-        _arweave = arweave;
+        _arweave = arweave,
+        _arioSDK = arioSDK;
 
   // TODO: Check ProfileDAO to implement only one source for user data
 
@@ -48,8 +54,6 @@ class _UserRepository implements UserRepository {
 
     final profileDetails = await _profileDao.loadDefaultProfile(password);
 
-    final ioTokens = await _getIOTokens(profileDetails: profileDetails);
-
     final user = User(
       profileType: ProfileType.values[profileDetails.details.profileType],
       wallet: profileDetails.wallet,
@@ -59,7 +63,7 @@ class _UserRepository implements UserRepository {
       walletBalance: await _arweave.getWalletBalance(
         await profileDetails.wallet.getAddress(),
       ),
-      ioTokens: ioTokens,
+      errorFetchingIOTokens: false,
     );
 
     logger.d('Loaded user');
@@ -107,23 +111,18 @@ class _UserRepository implements UserRepository {
     return profile.walletPublicKey;
   }
 
-  Future<String?> _getIOTokens({
-    required ProfileLoadDetails profileDetails,
-  }) async {
-    try {
-      String? ioTokens;
+  @override
+  Future<String?> getIOTokens(Wallet wallet) async {
+    String? ioTokens;
 
-      if (isArioSDKSupportedOnPlatform()) {
-        ioTokens = await ArioSDKFactory()
-            .create()
-            .getIOTokens(await profileDetails.wallet.getAddress());
+    if (isArioSDKSupportedOnPlatform()) {
+      ioTokens = await _arioSDK.getIOTokens(await wallet.getAddress());
+      if (ioTokens == 'null') {
+        throw Exception('Error fetching IOTokens');
       }
-
-      return ioTokens;
-    } catch (e, stacktrace) {
-      logger.e('Failed to get IO tokens', e, stacktrace);
-      return null;
     }
+
+    return ioTokens;
   }
 
   @override
diff --git a/lib/user/user.dart b/lib/user/user.dart
index 713abdd93e..3366c7d8be 100644
--- a/lib/user/user.dart
+++ b/lib/user/user.dart
@@ -13,6 +13,7 @@ abstract class User with EquatableMixin {
   late final SecretKey cipherKey;
   late final ProfileType profileType;
   abstract final String? ioTokens;
+  abstract final bool errorFetchingIOTokens;
 
   factory User({
     required String password,
@@ -22,6 +23,7 @@ abstract class User with EquatableMixin {
     required SecretKey cipherKey,
     required ProfileType profileType,
     String? ioTokens,
+    required bool errorFetchingIOTokens,
   }) =>
       _User(
         password: password,
@@ -31,6 +33,7 @@ abstract class User with EquatableMixin {
         cipherKey: cipherKey,
         profileType: profileType,
         ioTokens: ioTokens,
+        errorFetchingIOTokens: errorFetchingIOTokens,
       );
 
   User copyWith({
@@ -41,6 +44,7 @@ abstract class User with EquatableMixin {
     SecretKey? cipherKey,
     ProfileType? profileType,
     String? ioTokens,
+    bool? errorFetchingIOTokens,
   });
 }
 
@@ -59,6 +63,8 @@ class _User implements User {
   late final ProfileType profileType;
   @override
   final String? ioTokens;
+  @override
+  final bool errorFetchingIOTokens;
 
   _User({
     required this.password,
@@ -68,16 +74,18 @@ class _User implements User {
     required this.cipherKey,
     required this.profileType,
     this.ioTokens,
+    required this.errorFetchingIOTokens,
   });
 
   @override
-  List<Object> get props => [
+  List<Object?> get props => [
         password,
         walletAddress,
         walletBalance,
         cipherKey,
         profileType,
         wallet,
+        ioTokens,
       ];
 
   @override
@@ -95,6 +103,7 @@ class _User implements User {
     SecretKey? cipherKey,
     ProfileType? profileType,
     String? ioTokens,
+    bool? errorFetchingIOTokens,
   }) {
     return _User(
       password: password ?? this.password,
@@ -104,6 +113,8 @@ class _User implements User {
       cipherKey: cipherKey ?? this.cipherKey,
       profileType: profileType ?? this.profileType,
       ioTokens: ioTokens ?? this.ioTokens,
+      errorFetchingIOTokens:
+          errorFetchingIOTokens ?? this.errorFetchingIOTokens,
     );
   }
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index 118826237d..e272479beb 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: Secure, permanent storage
 
 publish_to: 'none'
 
-version: 2.52.0
+version: 2.53.0
 
 environment:
   sdk: '>=3.2.0 <4.0.0'
diff --git a/test/authentication/ardrive_auth_test.dart b/test/authentication/ardrive_auth_test.dart
index 00716e5ecf..2650bc383e 100644
--- a/test/authentication/ardrive_auth_test.dart
+++ b/test/authentication/ardrive_auth_test.dart
@@ -133,6 +133,7 @@ void main() {
           walletBalance: BigInt.one,
           cipherKey: SecretKey([]),
           profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
         );
         test(
             'should return the user when has private drives and login with sucess. ',
@@ -140,7 +141,10 @@ void main() {
           when(() => mockArweaveService.getFirstPrivateDriveTxId(wallet,
                   maxRetries: any(named: 'maxRetries')))
               .thenAnswer((_) async => 'some_id');
-
+          when(() => mockUserRepository.getIOTokens(wallet))
+              .thenAnswer((_) async => '0.4');
+          when(() => mockUserRepository.getBalance(wallet))
+              .thenAnswer((_) async => BigInt.one);
           when(() => mockBiometricAuthentication.isEnabled())
               .thenAnswer((_) async => false);
 
@@ -222,6 +226,10 @@ void main() {
 
           when(() => mockUserRepository.hasUser())
               .thenAnswer((invocation) => Future.value(true));
+          when(() => mockUserRepository.getIOTokens(wallet))
+              .thenAnswer((_) async => '0.4');
+          when(() => mockUserRepository.getBalance(wallet))
+              .thenAnswer((_) async => BigInt.one);
 
           when(
             () => mockArweaveService.getLatestDriveEntityWithId(
@@ -277,6 +285,11 @@ void main() {
           when(() => mockUserRepository.hasUser())
               .thenAnswer((invocation) => Future.value(true));
 
+          when(() => mockUserRepository.getIOTokens(wallet))
+              .thenAnswer((_) async => '0.4');
+          when(() => mockUserRepository.getBalance(wallet))
+              .thenAnswer((_) async => BigInt.one);
+
           when(() => mockUserRepository.deleteUser())
               .thenAnswer((invocation) async {});
 
@@ -321,6 +334,11 @@ void main() {
           when(() => mockUserRepository.deleteUser())
               .thenAnswer((invocation) async {});
 
+          when(() => mockUserRepository.getIOTokens(wallet))
+              .thenAnswer((_) async => '0.4');
+          when(() => mockUserRepository.getBalance(wallet))
+              .thenAnswer((_) async => BigInt.one);
+
           when(() => mockUserRepository.saveUser(
                   'password', ProfileType.json, wallet))
               .thenAnswer((invocation) => Future.value(null));
@@ -372,6 +390,7 @@ void main() {
           walletBalance: BigInt.one,
           cipherKey: SecretKey([]),
           profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
         );
 
         test(
@@ -390,6 +409,11 @@ void main() {
           when(() => mockUserRepository.hasUser())
               .thenAnswer((_) async => true);
 
+          when(() => mockUserRepository.getIOTokens(wallet))
+              .thenAnswer((_) async => '0.4');
+          when(() => mockUserRepository.getBalance(wallet))
+              .thenAnswer((_) async => BigInt.one);
+
           when(() => mockUserRepository.getUser('password123'))
               .thenAnswer((invocation) => Future.value(loggedUser));
 
@@ -484,6 +508,7 @@ void main() {
         walletBalance: BigInt.one,
         cipherKey: SecretKey([]),
         profileType: ProfileType.json,
+        errorFetchingIOTokens: false,
       );
 
       test('should return the user when password is correct', () async {
@@ -491,6 +516,10 @@ void main() {
             .thenAnswer((_) async => false);
         when(() => mockUserRepository.getUser('password'))
             .thenAnswer((invocation) async => unlockedUser);
+        when(() => mockUserRepository.getIOTokens(wallet))
+            .thenAnswer((_) async => '0.4');
+        when(() => mockUserRepository.getBalance(wallet))
+            .thenAnswer((_) async => BigInt.one);
 
         when(() => mockBiometricAuthentication.isEnabled())
             .thenAnswer((_) async => false);
@@ -523,6 +552,7 @@ void main() {
         walletBalance: BigInt.one,
         cipherKey: SecretKey([]),
         profileType: ProfileType.json,
+        errorFetchingIOTokens: false,
       );
 
       test(
@@ -532,6 +562,11 @@ void main() {
             .thenAnswer((_) async => false);
         when(() => mockUserRepository.hasUser())
             .thenAnswer((invocation) => Future.value(true));
+        when(() => mockUserRepository.getIOTokens(wallet))
+            .thenAnswer((_) async => '0.4');
+        when(() => mockUserRepository.getBalance(wallet))
+            .thenAnswer((_) async => BigInt.one);
+
         when(() => mockUserRepository.getUser('password'))
             .thenAnswer((invocation) async => unlockedUser);
         when(() => mockBiometricAuthentication.isEnabled())
@@ -588,6 +623,7 @@ void main() {
           walletBalance: BigInt.one,
           cipherKey: SecretKey([]),
           profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
         );
         when(
           () => mockArweaveService.getFirstPrivateDriveTxId(
@@ -597,6 +633,11 @@ void main() {
         ).thenAnswer((_) async => 'some_id');
         when(() => mockBiometricAuthentication.isEnabled())
             .thenAnswer((_) async => false);
+        when(() => mockUserRepository.getIOTokens(wallet))
+            .thenAnswer((_) async => '0.4');
+        when(() => mockUserRepository.getBalance(wallet))
+            .thenAnswer((_) async => BigInt.one);
+
         when(
           () => mockArDriveCrypto.deriveDriveKey(
             wallet,
@@ -659,6 +700,7 @@ void main() {
           walletBalance: BigInt.one,
           cipherKey: SecretKey([]),
           profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
         );
         when(() => mockBiometricAuthentication.isEnabled())
             .thenAnswer((_) async => false);
@@ -674,6 +716,11 @@ void main() {
         ).thenAnswer((invocation) => Future.value(SecretKey([])));
         when(() => mockUserRepository.hasUser())
             .thenAnswer((invocation) => Future.value(true));
+        when(() => mockUserRepository.getIOTokens(wallet))
+            .thenAnswer((_) async => '0.4');
+        when(() => mockUserRepository.getBalance(wallet))
+            .thenAnswer((_) async => BigInt.one);
+
         when(
           () => mockArweaveService.getLatestDriveEntityWithId(
             any(),
@@ -708,6 +755,7 @@ void main() {
           walletBalance: BigInt.one,
           cipherKey: SecretKey([]),
           profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
         );
 
         arDriveAuth.onAuthStateChanged().listen((user) {
@@ -774,5 +822,44 @@ void main() {
 
       expect(walletAddress, null);
     });
+
+    group('refreshBalance method', () {
+      test('should update current user balance and notify listeners', () async {
+        // Arrange
+        final initialBalance = BigInt.one;
+        final updatedBalance = BigInt.two;
+        final initialUser = User(
+          password: 'password',
+          wallet: wallet,
+          walletAddress: 'walletAddress',
+          walletBalance: initialBalance,
+          cipherKey: SecretKey([]),
+          profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
+        );
+        // Updated user with new balance
+        final updatedUser = initialUser.copyWith(walletBalance: updatedBalance);
+
+        arDriveAuth.currentUser = initialUser;
+
+        when(() => mockUserRepository.getBalance(wallet))
+            .thenAnswer((_) async => updatedBalance);
+        when(() => mockUserRepository.getIOTokens(wallet))
+            .thenAnswer((_) async => '0.4');
+
+        // Act
+        await arDriveAuth.refreshBalance();
+
+        // Assert
+        expect(arDriveAuth.currentUser.walletBalance, equals(updatedBalance));
+        expect(arDriveAuth.currentUser.errorFetchingIOTokens, false);
+        verify(() => mockUserRepository.getBalance(wallet)).called(1);
+
+        // Verify that listeners are notified
+        arDriveAuth.onAuthStateChanged().listen((user) {
+          expect(user, equals(updatedUser));
+        });
+      });
+    });
   });
 }
diff --git a/test/authentication/login/blocs/login_bloc_test.dart b/test/authentication/login/blocs/login_bloc_test.dart
index 0fae361e90..9c256a8a24 100644
--- a/test/authentication/login/blocs/login_bloc_test.dart
+++ b/test/authentication/login/blocs/login_bloc_test.dart
@@ -186,6 +186,7 @@ void main() {
       walletBalance: BigInt.one,
       cipherKey: SecretKey([]),
       profileType: ProfileType.json,
+      errorFetchingIOTokens: false,
     );
     blocTest(
       'should emit the event to show onboarding when user is not an existing one',
@@ -355,6 +356,7 @@ void main() {
               walletBalance: BigInt.one,
               cipherKey: SecretKey([]),
               profileType: ProfileType.json,
+              errorFetchingIOTokens: false,
             ));
       },
       act: (bloc) async {
@@ -422,6 +424,7 @@ void main() {
       walletBalance: BigInt.one,
       cipherKey: SecretKey([]),
       profileType: ProfileType.json,
+      errorFetchingIOTokens: false,
     );
 
     blocTest(
@@ -486,6 +489,7 @@ void main() {
       walletBalance: BigInt.one,
       cipherKey: SecretKey([]),
       profileType: ProfileType.json,
+      errorFetchingIOTokens: false,
     );
 
     blocTest(
@@ -809,6 +813,7 @@ void main() {
             walletBalance: BigInt.one,
             cipherKey: SecretKey([]),
             profileType: ProfileType.json,
+            errorFetchingIOTokens: false,
           ),
         );
       },
@@ -833,6 +838,7 @@ void main() {
       walletBalance: BigInt.one,
       cipherKey: SecretKey([]),
       profileType: ProfileType.json,
+      errorFetchingIOTokens: false,
     );
 
     blocTest(
diff --git a/test/blocs/create_snapshot_cubit_test.dart b/test/blocs/create_snapshot_cubit_test.dart
index 90ed376fca..c3c5b60254 100644
--- a/test/blocs/create_snapshot_cubit_test.dart
+++ b/test/blocs/create_snapshot_cubit_test.dart
@@ -160,6 +160,7 @@ void main() {
               ),
               profileType: ProfileType.json,
               ioTokens: 'ioTokens',
+              errorFetchingIOTokens: false,
             ),
             useTurbo: false,
           ),
@@ -214,6 +215,7 @@ void main() {
               walletBalance: BigInt.one,
               cipherKey: cipher,
               profileType: ProfileType.json,
+              errorFetchingIOTokens: false,
             ));
 
         when(() => appConfig.allowedDataItemSizeForTurbo)
diff --git a/test/blocs/drive_create_cubit_test.dart b/test/blocs/drive_create_cubit_test.dart
index f6a2dca3a8..cafdf2a799 100644
--- a/test/blocs/drive_create_cubit_test.dart
+++ b/test/blocs/drive_create_cubit_test.dart
@@ -72,6 +72,7 @@ void main() {
               cipherKey: SecretKey(keyBytes),
               profileType: ProfileType.json,
               ioTokens: 'ioTokens',
+              errorFetchingIOTokens: false,
             ),
             useTurbo: turboUploadService.useTurboUpload,
           ),
diff --git a/test/blocs/fs_entry_license_bloc_test.dart b/test/blocs/fs_entry_license_bloc_test.dart
index efa6a209da..0340f6a2e1 100644
--- a/test/blocs/fs_entry_license_bloc_test.dart
+++ b/test/blocs/fs_entry_license_bloc_test.dart
@@ -271,6 +271,7 @@ void main() {
             walletBalance: BigInt.one,
             profileType: ProfileType.json,
             ioTokens: 'ioTokens',
+            errorFetchingIOTokens: false,
           ),
           useTurbo: false,
         ),
diff --git a/test/blocs/fs_entry_move_bloc_test.dart b/test/blocs/fs_entry_move_bloc_test.dart
index 7ccfa7b7f9..75d2658a12 100644
--- a/test/blocs/fs_entry_move_bloc_test.dart
+++ b/test/blocs/fs_entry_move_bloc_test.dart
@@ -273,6 +273,7 @@ void main() {
             walletBalance: BigInt.one,
             profileType: ProfileType.json,
             ioTokens: 'ioTokens',
+            errorFetchingIOTokens: false,
           ),
           useTurbo: false,
         ),
diff --git a/test/blocs/prompt_to_snapshot_bloc_test.dart b/test/blocs/prompt_to_snapshot_bloc_test.dart
index b2701bd4e1..8edba0e6b7 100644
--- a/test/blocs/prompt_to_snapshot_bloc_test.dart
+++ b/test/blocs/prompt_to_snapshot_bloc_test.dart
@@ -59,6 +59,7 @@ void main() {
           walletBalance: BigInt.one,
           cipherKey: SecretKey(List.generate(32, (index) => index)),
           profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
         ),
         useTurbo: false,
       ));
@@ -240,6 +241,7 @@ void main() {
             walletBalance: BigInt.one,
             cipherKey: SecretKey(List.generate(32, (index) => index)),
             profileType: ProfileType.json,
+            errorFetchingIOTokens: false,
           ),
           useTurbo: false,
         ));
diff --git a/test/blocs/upload_cubit_test.dart b/test/blocs/upload_cubit_test.dart
index e2a9fb6558..513ed451a2 100644
--- a/test/blocs/upload_cubit_test.dart
+++ b/test/blocs/upload_cubit_test.dart
@@ -308,6 +308,7 @@ void main() {
             walletBalance: BigInt.one,
             cipherKey: SecretKey(tKeyBytes),
             profileType: ProfileType.json,
+            errorFetchingIOTokens: false,
           ),
           useTurbo: false,
         ),
@@ -335,6 +336,7 @@ void main() {
           walletBalance: BigInt.one,
           cipherKey: SecretKey([]),
           profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
         ),
       );
 
@@ -418,6 +420,7 @@ void main() {
               walletBalance: BigInt.one,
               cipherKey: SecretKey(tKeyBytes),
               profileType: ProfileType.json,
+              errorFetchingIOTokens: false,
             ),
           ),
         );
@@ -523,6 +526,7 @@ void main() {
             walletBalance: BigInt.one,
             cipherKey: SecretKey(tKeyBytes),
             profileType: ProfileType.json,
+            errorFetchingIOTokens: false,
           ),
           useTurbo: false,
         ),
diff --git a/test/core/upload/uploader_test.dart b/test/core/upload/uploader_test.dart
index f25a266686..e06dfa5b94 100644
--- a/test/core/upload/uploader_test.dart
+++ b/test/core/upload/uploader_test.dart
@@ -1016,7 +1016,9 @@ User getFakeUser() => User(
     walletAddress: 'walletAddress',
     walletBalance: BigInt.one,
     cipherKey: SecretKey([]),
-    profileType: ProfileType.arConnect);
+    profileType: ProfileType.arConnect,
+      errorFetchingIOTokens: false,
+    );
 
 FolderEntry getFakeFolder() => FolderEntry(
       id: 'id',
diff --git a/test/test_utils/fake_user.dart b/test/test_utils/fake_user.dart
index a6f5c837fe..73fb04b395 100644
--- a/test/test_utils/fake_user.dart
+++ b/test/test_utils/fake_user.dart
@@ -11,6 +11,7 @@ final fakeUserJson = User(
   walletBalance: BigInt.zero,
   cipherKey: SecretKey([1, 2, 3]),
   profileType: ProfileType.json,
+  errorFetchingIOTokens: false,
 );
 
 final fakeUserArConnect = User(
@@ -20,4 +21,6 @@ final fakeUserArConnect = User(
   walletBalance: BigInt.zero,
   cipherKey: SecretKey([1, 2, 3]),
   profileType: ProfileType.arConnect,
+  errorFetchingIOTokens: false,
+
 );
diff --git a/test/user/repositories/user_repository_test.dart b/test/user/repositories/user_repository_test.dart
index 2d8512e943..0f76329911 100644
--- a/test/user/repositories/user_repository_test.dart
+++ b/test/user/repositories/user_repository_test.dart
@@ -3,6 +3,8 @@ import 'package:ardrive/models/models.dart';
 import 'package:ardrive/services/arweave/arweave.dart';
 import 'package:ardrive/user/repositories/user_repository.dart';
 import 'package:ardrive/user/user.dart';
+import 'package:ardrive_utils/ardrive_utils.dart';
+import 'package:ario_sdk/ario_sdk.dart';
 import 'package:cryptography/cryptography.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter_test/flutter_test.dart';
@@ -12,10 +14,13 @@ import '../../test_utils/utils.dart';
 
 class MockTransaction extends Mock implements TransactionCommonMixin {}
 
+class MockArioSDK extends Mock implements ArioSDK {}
+
 void main() {
   late UserRepository userRepository;
   late ArweaveService mockArweaveService;
   late ProfileDao mockProfileDao;
+  late MockArioSDK mockArioSDK;
 
   const rightPassword = 'right-password';
 
@@ -27,10 +32,12 @@ void main() {
   setUp(() {
     mockArweaveService = MockArweaveService();
     mockProfileDao = MockProfileDao();
+    mockArioSDK = MockArioSDK();
 
     userRepository = UserRepository(
       mockProfileDao,
       mockArweaveService,
+      mockArioSDK,
     );
 
     // register fallback values
@@ -80,6 +87,7 @@ void main() {
           walletBalance: BigInt.zero,
           cipherKey: SecretKey([1, 2, 3]),
           profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
         );
 
         expect(result, isNotNull);
@@ -146,6 +154,7 @@ void main() {
           walletBalance: BigInt.zero,
           cipherKey: SecretKey([1, 2, 3]),
           profileType: ProfileType.json,
+          errorFetchingIOTokens: false,
         );
 
         when(() => mockProfileDao.addProfile(
@@ -233,5 +242,89 @@ void main() {
         verify(() => mockProfileDao.getDefaultProfile()).called(1);
       });
     });
+
+    group('getIOTokens method', () {
+      test('should return IO tokens when ArioSDK is supported', () async {
+        final wallet = getTestWallet();
+        const expectedIOTokens = '100';
+        final walletAddress = await wallet.getAddress();
+
+        AppPlatform.setMockPlatform(platform: SystemPlatform.Web);
+
+        when(() => mockArioSDK.getIOTokens(walletAddress))
+            .thenAnswer((_) async => expectedIOTokens);
+
+        final result = await userRepository.getIOTokens(wallet);
+
+        expect(result, expectedIOTokens);
+        verify(() => mockArioSDK.getIOTokens(walletAddress)).called(1);
+      });
+
+      test('should return null when ArioSDK is not supported', () async {
+        final wallet = getTestWallet();
+
+        AppPlatform.setMockPlatform(platform: SystemPlatform.Android);
+
+        final result = await userRepository.getIOTokens(wallet);
+
+        expect(result, isNull);
+
+        verifyNever(() => mockArioSDK.getIOTokens(any()));
+      });
+
+      test('should return null when ArioSDK is not supported', () async {
+        final wallet = getTestWallet();
+
+        AppPlatform.setMockPlatform(platform: SystemPlatform.iOS);
+
+        final result = await userRepository.getIOTokens(wallet);
+
+        expect(result, isNull);
+
+        verifyNever(() => mockArioSDK.getIOTokens(any()));
+      });
+    });
+
+    group('getBalance method', () {
+      test('should return the correct balance', () async {
+        final wallet = getTestWallet();
+        final expectedBalance = BigInt.from(100);
+        final walletAddress = await wallet.getAddress();
+
+        when(() => mockArweaveService.getWalletBalance(walletAddress))
+            .thenAnswer((_) async => expectedBalance);
+        when(() => mockArweaveService.getPendingTxFees(walletAddress))
+            .thenAnswer((_) async => BigInt.from(0));
+
+        final result = await userRepository.getBalance(wallet);
+
+        expect(result, expectedBalance);
+        verify(() => mockArweaveService.getWalletBalance(walletAddress))
+            .called(1);
+        verify(() => mockArweaveService.getPendingTxFees(walletAddress))
+            .called(1);
+      });
+
+      test('should return the correct balance when has pending transactions',
+          () async {
+        final wallet = getTestWallet();
+        final expectedBalance = BigInt.from(100);
+        final expectedPendingTxFees = BigInt.from(10);
+        final walletAddress = await wallet.getAddress();
+
+        when(() => mockArweaveService.getWalletBalance(walletAddress))
+            .thenAnswer((_) async => expectedBalance);
+        when(() => mockArweaveService.getPendingTxFees(walletAddress))
+            .thenAnswer((_) async => expectedPendingTxFees);
+
+        final result = await userRepository.getBalance(wallet);
+
+        expect(result, expectedBalance - expectedPendingTxFees);
+        verify(() => mockArweaveService.getWalletBalance(walletAddress))
+            .called(1);
+        verify(() => mockArweaveService.getPendingTxFees(walletAddress))
+            .called(1);
+      });
+    });
   });
 }
diff --git a/test/utils/user_utils.dart b/test/utils/user_utils.dart
index cd0fd68a99..05a08e8c87 100644
--- a/test/utils/user_utils.dart
+++ b/test/utils/user_utils.dart
@@ -23,6 +23,7 @@ void main() {
         walletBalance: BigInt.zero,
         cipherKey: SecretKey([1, 2, 3]),
         profileType: ProfileType.json,
+        errorFetchingIOTokens: false,
       );
       // arrange
       when(() => auth.currentUser).thenReturn(user);
@@ -46,6 +47,7 @@ void main() {
         walletBalance: BigInt.zero,
         cipherKey: SecretKey([1, 2, 3]),
         profileType: ProfileType.json,
+        errorFetchingIOTokens: false,
       );
       // arrange
       when(() => auth.currentUser).thenReturn(user);