diff --git a/git-authors.toml b/git-authors.toml
new file mode 100644
index 0000000..85f4b7e
--- /dev/null
+++ b/git-authors.toml
@@ -0,0 +1,7 @@
+[authors.mtk]
+name = "Mikkel Troels Kongsted"
+email = "mtkongsted@gmail.com"
+
+[authors.sfj]
+name = "SFJ"
+email = "simonfromjakobsen@gmail.com"
\ No newline at end of file
diff --git a/mobile/lib/controllers/cart.dart b/mobile/lib/controllers/cart.dart
index 1baa3c1..2cfa3cf 100644
--- a/mobile/lib/controllers/cart.dart
+++ b/mobile/lib/controllers/cart.dart
@@ -119,9 +119,9 @@ class CartControllerMemory extends CartController {
   Future<Result<Null, String>> purchase(String token) async {
     final res = await server.purchaseCart(token, cart);
     switch (res) {
-      case Success<Null>():
+      case Ok<Null, String>():
         return const Ok(null);
-      case Error<Null>(message: final message):
+      case Err<Null, String>(value: final message):
         return Err(message);
     }
   }
diff --git a/mobile/lib/controllers/product.dart b/mobile/lib/controllers/product.dart
index a555c94..caa06a1 100644
--- a/mobile/lib/controllers/product.dart
+++ b/mobile/lib/controllers/product.dart
@@ -15,10 +15,10 @@ class ProductController extends ChangeNotifier {
   Future<void> fetchProductsFromServer() async {
     final res = await server.allProducts();
     switch (res) {
-      case Success<List<Product>>(data: final data):
+      case Ok<List<Product>, String>(value: final data):
         products = data;
         notifyListeners();
-      case Error<List<Product>>():
+      case Err<List<Product>, String>():
         return;
     }
   }
diff --git a/mobile/lib/controllers/session.dart b/mobile/lib/controllers/session.dart
new file mode 100644
index 0000000..c3cba2d
--- /dev/null
+++ b/mobile/lib/controllers/session.dart
@@ -0,0 +1,163 @@
+import 'package:flutter/material.dart';
+import 'package:mobile/models/user.dart';
+import 'package:mobile/results.dart';
+import 'package:mobile/server/server.dart';
+
+class SessionController {
+  final Server server;
+
+  String? _sessionToken;
+  User? _sessionUser;
+
+  final List<_ChangeListener> _sessionChangeListeners = [];
+  final List<_ChangeListener> _userChangeListeners = [];
+
+  SessionController({required this.server});
+
+  Future<Result<Null, String>> loginUser(String email, String password) async {
+    final loginResult = await server.login(email, password);
+    switch (loginResult) {
+      case Ok<String, String>(value: final sessionToken):
+        _sessionToken = sessionToken;
+        notifySessionChangeListeners();
+        return const Ok(null);
+      case Err<String, String>(value: final message):
+        return Err(message);
+    }
+  }
+
+  Future<Result<Null, Null>> loadUser() async {
+    // TODO: retrieve session from cache, if exists
+    return _loadCurrentUser();
+  }
+
+  Future<Result<Null, Null>> _loadCurrentUser() async {
+    final sessionUserResult = await _requestWithSession<User>(
+        (server, sessionToken) => server.sessionUser(sessionToken));
+    switch (sessionUserResult) {
+      case Ok<User, String>(value: final sessionUser):
+        _sessionUser = sessionUser;
+        notifyUserChangeListeners();
+
+        // The mechanism for checking that a user is logged in, only listens on
+        // the session provider. There we also notify sessions listeners, to
+        // account for this one specific case. Is this smart? idk.
+        notifySessionChangeListeners();
+
+        return const Ok(null);
+      case Err<User, String>():
+        return const Err(null);
+    }
+  }
+
+  Future<Null> logout() async {
+    final sessionToken = _sessionToken;
+    if (sessionToken == null) {
+      return;
+    }
+    await server.logout(sessionToken);
+    _sessionToken = null;
+    notifySessionChangeListeners();
+  }
+
+  User get user {
+    final user = _sessionUser;
+    if (user == null) {
+      throw NoUser();
+    }
+    return user;
+  }
+
+  bool get hasUser {
+    return _sessionUser != null;
+  }
+
+  Future<Result<Null, String>> addBalance() async {
+    final addBalanceResult = await _requestWithSession(
+        (server, sessionToken) => server.addBalance(sessionToken));
+    if (addBalanceResult case Err<Null, String>(value: final message)) {
+      return Err(message);
+    }
+    if (await _loadCurrentUser() case Err<Null, Null>()) {
+      return const Err("could not fetch user");
+    }
+    return const Ok(null);
+  }
+
+  /// Package private.
+  Future<Result<T, String>> _requestWithSession<T>(
+      Future<Result<T, String>> Function(Server server, String sessionToken)
+          func) async {
+    final sessionToken = _sessionToken;
+    if (sessionToken == null) {
+      return const Err("unathorized");
+    }
+    final result = await func(server, sessionToken);
+    if (result case Err<T, String>(value: final message)) {
+      if (message == "unauthorized") {
+        _sessionToken = null;
+        _sessionUser = null;
+        notifySessionChangeListeners();
+        notifyUserChangeListeners();
+        return const Err("unathorized");
+      }
+    }
+    return result;
+  }
+
+  /// Package private.
+  void _addSessionChangeListener(_ChangeListener listener) {
+    _sessionChangeListeners.add(listener);
+  }
+
+  /// Package private.
+  void _addUserChangeListener(_ChangeListener listener) {
+    _userChangeListeners.add(listener);
+  }
+
+  /// Class private.
+  void notifySessionChangeListeners() {
+    for (final listener in _sessionChangeListeners) {
+      listener.notify();
+    }
+  }
+
+  /// Class private.
+  void notifyUserChangeListeners() {
+    for (final listener in _userChangeListeners) {
+      listener.notify();
+    }
+  }
+}
+
+abstract class _ChangeListener {
+  void notify();
+}
+
+class NoUser implements Exception {}
+
+class SessionProvider extends ChangeNotifier implements _ChangeListener {
+  final SessionController controller;
+
+  SessionProvider({required this.controller}) {
+    controller._addSessionChangeListener(this);
+  }
+
+  @override
+  void notify() {
+    notifyListeners();
+  }
+}
+
+class CurrentUserProvider extends ChangeNotifier implements _ChangeListener {
+  final SessionController controller;
+
+  CurrentUserProvider({required this.controller}) {
+    controller._addUserChangeListener(this);
+  }
+
+  @override
+  void notify() {
+    notifyListeners();
+  }
+}
diff --git a/mobile/lib/controllers/user.dart b/mobile/lib/controllers/user.dart
deleted file mode 100644
index 6a81b1d..0000000
--- a/mobile/lib/controllers/user.dart
+++ /dev/null
@@ -1,132 +0,0 @@
-import 'package:flutter/material.dart';
-import 'package:mobile/models/user.dart';
-import 'package:mobile/results.dart';
-import 'package:mobile/server/server.dart';
-
-class UserController extends ChangeNotifier {
-  final Server server;
-  String? _sessionToken;
-  User? _user;
-
-  Future<Result<User, Null>> userLoad = Future.error(Null);
-
-  UserController({required this.server});
-
-  /// Make sure a user exists before calling using `.loadUser()`.
-  User get user {
-    final user = _user;
-    if (user == null) {
-      throw NoUserExcept();
-    }
-    return user;
-  }
-
-  Future<Result<Null, Null>> loadUser() async {
-    if (_sessionToken == null) {
-      return const Err(null);
-    }
-
-    final userResult = await server.sessionUser(_sessionToken!);
-    switch (userResult) {
-      case Success<User>(data: final user):
-        _user = user;
-        return const Ok(null);
-      case Error<User>():
-        return const Err(null);
-    }
-  }
-
-  Future<Result<Null, Null>> loadedUser() async {
-    throw Exception();
-  }
-
-  Future<Result<Null, String>> login(String email, String password) async {
-    switch (await server.login(email, password)) {
-      case Success<String>(data: final token):
-        _sessionToken = token;
-        notifyListeners();
-        return const Ok(null);
-      case Error<String>(message: final message):
-        notifyListeners();
-        return Err(message);
-    }
-  }
-
-  Future<void> _validateToken() async {
-    final token = _sessionToken;
-    if (token == null) {
-      return;
-    }
-    final res = await server.sessionUser(token);
-    switch (res) {
-      case Success<User>():
-        return;
-      case Error<User>():
-        _sessionToken = null;
-        return;
-    }
-  }
-
-  @Deprecated("Use 'user' instead.")
-  User? get userOld {
-    loadUserOld();
-    return _user;
-  }
-
-  Future<void> _notifyIfTokenChanged() async {
-    final prev = _sessionToken;
-    _validateToken();
-    if (prev != _sessionToken) {
-      notifyListeners();
-    }
-  }
-
-  @Deprecated("Use 'loadUser' instead.")
-  Future<void> loadUserOld() async {
-    final token = _sessionToken;
-    if (token == null) {
-      _user = null;
-      return;
-    }
-    final res = await server.sessionUser(token);
-    switch (res) {
-      case Success<User>(data: final user):
-        _user = user;
-        return;
-      case Error<User>():
-        _user = null;
-        return;
-    }
-  }
-
-  String? get sessionToken {
-    _notifyIfTokenChanged();
-    return _sessionToken;
-  }
-
-  Future<void> logout() async {
-    final token = _sessionToken;
-    if (token != null) {
-      await server.logout(token);
-      _sessionToken = null;
-    }
-    notifyListeners();
-  }
-
-  Future<Result<Null, String>> addBalance() async {
-    final token = _sessionToken;
-    if (token == null) {
-      return const Err("No token");
-    }
-    final res = await server.addBalance(token);
-    notifyListeners();
-    switch (res) {
-      case Success<Null>():
-        return const Ok(null);
-      case Error<Null>(message: final message):
-        return Err(message);
-    }
-  }
-}
-
-class NoUserExcept implements Exception {}
diff --git a/mobile/lib/controllers/users.dart b/mobile/lib/controllers/users.dart
index 847078e..15fd89e 100644
--- a/mobile/lib/controllers/users.dart
+++ b/mobile/lib/controllers/users.dart
@@ -10,9 +10,9 @@ class UsersController {
       String name, String email, String password) async {
     final res = await server.register(name, email, password);
     switch (res) {
-      case Success<Null>():
+      case Ok<Null, String>():
         return const Ok(null);
-      case Error<Null>(message: final message):
+      case Err<Null, String>(value: final message):
         return Err(message);
     }
   }
diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart
index 9406f0e..4a1fb12 100644
--- a/mobile/lib/main.dart
+++ b/mobile/lib/main.dart
@@ -1,6 +1,6 @@
 import 'package:flutter/material.dart';
 import 'package:google_fonts/google_fonts.dart';
-import 'package:mobile/controllers/user.dart';
+import 'package:mobile/controllers/session.dart';
 import 'package:mobile/pages/dashboard.dart';
 import 'package:mobile/pages/log_in_page.dart';
 import 'package:mobile/controllers/add_to_cart_state.dart';
@@ -10,6 +10,7 @@ import 'package:mobile/controllers/paying_state.dart';
 import 'package:mobile/controllers/product.dart';
 import 'package:mobile/controllers/receipt.dart';
 import 'package:mobile/controllers/users.dart';
+import 'package:mobile/results.dart';
 import 'package:mobile/server/backend_server.dart';
 import 'package:mobile/server/server.dart';
 import 'package:provider/provider.dart';
@@ -17,29 +18,38 @@ import 'package:mobile/controllers/routing.dart';
 
 void main() {
   final server = BackendServer();
-  final users = UsersController(server: server);
+  final usersController = UsersController(server: server);
+  final sessionController = SessionController(server: server);
 
-  final user = UserController(server: server);
-  user.loadUser().ignore();
+  sessionController.loadUser();
 
   runApp(MyApp(
-    users: users,
+    usersController: usersController,
+    sessionController: sessionController,
     server: server,
   ));
 }
 
 class MyApp extends StatelessWidget {
-  final UsersController users;
+  final UsersController usersController;
+  final SessionController sessionController;
 
   final Server server;
 
-  const MyApp({super.key, required this.users, required this.server});
+  const MyApp(
+      {super.key,
+      required this.usersController,
+      required this.sessionController,
+      required this.server});
 
   @override
   Widget build(BuildContext context) {
     return MultiProvider(
       providers: [
-        ChangeNotifierProvider(create: (_) => UserController(server: server)),
+        ChangeNotifierProvider(
+            create: (_) => SessionProvider(controller: sessionController)),
+        ChangeNotifierProvider(
+            create: (_) => CurrentUserProvider(controller: sessionController)),
         ChangeNotifierProvider(create: (_) => RoutingController()),
         ChangeNotifierProvider(
             create: (_) => ProductController(server: server)),
@@ -49,7 +59,7 @@ class MyApp extends StatelessWidget {
         ChangeNotifierProvider(create: (_) => PayingStateController()),
         ChangeNotifierProvider(create: (_) => AddToCartStateController()),
         ChangeNotifierProvider(create: (_) => LocationImageController()),
-        Provider(create: (_) => users),
+        Provider(create: (_) => usersController),
       ],
       child: MaterialApp(
           title: 'Fresh Plaza',
@@ -61,12 +71,24 @@ class MyApp extends StatelessWidget {
                 GoogleFonts.merriweatherTextTheme(Theme.of(context).textTheme),
             useMaterial3: true,
           ),
-          home: Consumer<UserController>(
-            builder: (_, sessionController, __) {
-              if (sessionController.sessionToken is String) {
+          home: Consumer<SessionProvider>(
+            builder: (_, provider, ___) {
+              if (provider.controller.hasUser) {
                 return Dashboard();
               }
-              return const LogInPage();
+              return FutureBuilder(
+                  future: provider.controller.loadUser(),
+                  builder: (_, snapshot) {
+                    final error = snapshot.error;
+                    if (error != null) {
+                      throw error;
+                    }
+                    if (snapshot.data != null &&
+                        snapshot.data is Err<Null, Null>) {
+                      return const LoginPage();
+                    }
+                    return const Scaffold(body: CircularProgressIndicator());
+                  });
             },
           )),
     );
diff --git a/mobile/lib/pages/finish_shopping_page.dart b/mobile/lib/pages/finish_shopping_page.dart
index 392c9a8..1e08115 100644
--- a/mobile/lib/pages/finish_shopping_page.dart
+++ b/mobile/lib/pages/finish_shopping_page.dart
@@ -3,7 +3,7 @@ import 'package:mobile/controllers/routing.dart';
 import 'package:mobile/controllers/cart.dart';
 import 'package:mobile/controllers/paying_state.dart';
 import 'package:mobile/controllers/receipt.dart';
-import 'package:mobile/controllers/user.dart';
+import 'package:mobile/controllers/session.dart';
 import 'package:mobile/results.dart';
 import 'package:mobile/utils/price.dart';
 import 'package:mobile/widgets/primary_button.dart';
@@ -57,42 +57,42 @@ class FinishShoppingPage extends StatelessWidget {
                   child: Center(
                       child: PrimaryButton(
                           onPressed: () async {
-                            final session = context.read<UserController>();
-                            payingStateRepo.next();
-                            await Future.delayed(const Duration(seconds: 1));
-                            if (cartController.purchase(session.sessionToken!)
-                                is Err) {
-                              if (context.mounted) {
-                                showDialog<String>(
-                                  context: context,
-                                  builder: (BuildContext context) =>
-                                      AlertDialog(
-                                    content: const Text(
-                                        'Du har desværre ikke råd til at købe dette'),
-                                    actions: <Widget>[
-                                      TextButton(
-                                        onPressed: () =>
-                                            Navigator.pop(context, 'OK'),
-                                        child: const Text('OK'),
-                                      ),
-                                    ],
-                                  ),
-                                );
-                              }
-                              payingStateRepo.reset();
-                              return;
-                            }
-                            receiptRepo.createReceipt(cart);
-                            payingStateRepo.next();
-                            await Future.delayed(const Duration(seconds: 1));
-                            cartController.clearCart();
-                            payingStateRepo.reset();
-                            if (context.mounted) {
-                              Navigator.pop(context);
-                              final RoutingController routing =
-                                  context.read<RoutingController>();
-                              routing.routeTo(PageSelector.homePage);
-                            }
+                            // final session = context.read<SessionController>();
+                            // payingStateRepo.next();
+                            // await Future.delayed(const Duration(seconds: 1));
+                            // if (cartController.purchase(session.sessionToken!)
+                            //     is Err) {
+                            //   if (context.mounted) {
+                            //     showDialog<String>(
+                            //       context: context,
+                            //       builder: (BuildContext context) =>
+                            //           AlertDialog(
+                            //         content: const Text(
+                            //             'Du har desværre ikke råd til at købe dette'),
+                            //         actions: <Widget>[
+                            //           TextButton(
+                            //             onPressed: () =>
+                            //                 Navigator.pop(context, 'OK'),
+                            //             child: const Text('OK'),
+                            //           ),
+                            //         ],
+                            //       ),
+                            //     );
+                            //   }
+                            //   payingStateRepo.reset();
+                            //   return;
+                            // }
+                            // receiptRepo.createReceipt(cart);
+                            // payingStateRepo.next();
+                            // await Future.delayed(const Duration(seconds: 1));
+                            // cartController.clearCart();
+                            // payingStateRepo.reset();
+                            // if (context.mounted) {
+                            //   Navigator.pop(context);
+                            //   final RoutingController routing =
+                            //       context.read<RoutingController>();
+                            //   routing.routeTo(PageSelector.homePage);
+                            // }
                           },
                           child: const Text("Betal"))),
                 ),
diff --git a/mobile/lib/pages/home_page.dart b/mobile/lib/pages/home_page.dart
index 4e6f063..f58c057 100644
--- a/mobile/lib/pages/home_page.dart
+++ b/mobile/lib/pages/home_page.dart
@@ -1,7 +1,6 @@
 import 'package:flutter/material.dart';
-import 'package:mobile/controllers/user.dart';
+import 'package:mobile/controllers/session.dart';
 import 'package:mobile/pages/settings_page.dart';
-import 'package:mobile/utils/build_if_session_exists.dart';
 import 'package:mobile/utils/price.dart';
 import 'package:provider/provider.dart';
 
@@ -10,8 +9,6 @@ class HomePage extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    final userController = context.watch<UserController>();
-
     return Column(
       children: [
         Row(
@@ -30,29 +27,33 @@ class HomePage extends StatelessWidget {
         ),
         Card(
           child: Container(
-              decoration: const BoxDecoration(
-                borderRadius: BorderRadius.all(Radius.circular(10)),
-                color: Color(0xFFFFFFFF),
-              ),
-              padding: const EdgeInsets.all(10),
-              child: BuildIfSessionUserExists(
-                  sessionController: userController,
-                  placeholder: const CircularProgressIndicator(),
-                  builder: (context, user) => Text(
-                      "Saldo: ${formatDkkCents(user.balanceDkkCents)}",
-                      style: Theme.of(context).textTheme.headlineSmall))),
+            decoration: const BoxDecoration(
+              borderRadius: BorderRadius.all(Radius.circular(10)),
+              color: Colors.white,
+            ),
+            padding: const EdgeInsets.all(10),
+            child: Consumer<CurrentUserProvider>(
+              builder: (_, provider, ___) {
+                final user = provider.controller.user;
+                return Text("Saldo: ${formatDkkCents(user.balanceDkkCents)}",
+                    style: Theme.of(context).textTheme.headlineSmall);
+              },
+            ),
+          ),
         ),
         Expanded(
           child: Column(
             mainAxisAlignment: MainAxisAlignment.center,
             children: [
-              BuildIfSessionUserExists(
-                  sessionController: userController,
-                  placeholder: const CircularProgressIndicator(),
-                  builder: (context, user) => Text(
-                        "Velkommen ${user.name}",
-                        style: Theme.of(context).textTheme.headlineMedium,
-                      ))
+              Consumer<CurrentUserProvider>(
+                builder: (_, provider, ___) {
+                  final user = provider.controller.user;
+                  return Text(
+                    "Velkommen ${user.name}",
+                    style: Theme.of(context).textTheme.headlineMedium,
+                  );
+                },
+              )
             ],
           ),
         ),
diff --git a/mobile/lib/pages/log_in_page.dart b/mobile/lib/pages/log_in_page.dart
index ccb9454..d5a8c32 100644
--- a/mobile/lib/pages/log_in_page.dart
+++ b/mobile/lib/pages/log_in_page.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:mobile/controllers/user.dart';
+import 'package:mobile/controllers/session.dart';
 import 'package:mobile/pages/register_page.dart';
 import 'package:mobile/results.dart';
 import 'package:mobile/widgets/error_box.dart';
@@ -7,30 +7,30 @@ import 'package:mobile/widgets/primary_button.dart';
 import 'package:mobile/widgets/primary_input.dart';
 import 'package:provider/provider.dart';
 
-class LogInPage extends StatelessWidget {
-  const LogInPage({super.key});
+class LoginPage extends StatelessWidget {
+  const LoginPage({super.key});
 
   @override
   Widget build(BuildContext context) {
     return const Scaffold(
         body: Row(
             mainAxisAlignment: MainAxisAlignment.center,
-            children: [LogInForm()]));
+            children: [LoginForm()]));
   }
 }
 
-class LogInForm extends StatefulWidget {
-  const LogInForm({super.key});
+class LoginForm extends StatefulWidget {
+  const LoginForm({super.key});
 
   @override
-  State<StatefulWidget> createState() => LogInFormState();
+  State<StatefulWidget> createState() => LoginFormState();
 }
 
-class LogInFormState extends State<LogInForm> {
+class LoginFormState extends State<LoginForm> {
   bool loginError = false;
   @override
   Widget build(BuildContext context) {
-    final userController = context.read<UserController>();
+    final sessionProvider = context.read<SessionProvider>();
 
     final mailController = TextEditingController();
     final passwordController = TextEditingController();
@@ -63,8 +63,8 @@ class LogInFormState extends State<LogInForm> {
         ),
         PrimaryButton(
             onPressed: () async {
-              final loginResult = await userController.login(
-                  mailController.text, passwordController.text);
+              final loginResult = await sessionProvider.controller
+                  .loginUser(mailController.text, passwordController.text);
               switch (loginResult) {
                 case Ok<Null, String>():
                   setState(() => loginError = false);
diff --git a/mobile/lib/pages/settings_page.dart b/mobile/lib/pages/settings_page.dart
index 68553c2..1b814c8 100644
--- a/mobile/lib/pages/settings_page.dart
+++ b/mobile/lib/pages/settings_page.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:mobile/controllers/user.dart';
+import 'package:mobile/controllers/session.dart';
 import 'package:mobile/pages/settings_pages/saldo.dart';
 import 'package:provider/provider.dart';
 
@@ -30,9 +30,11 @@ class SettingsPage extends StatelessWidget {
         icon: Icons.door_back_door,
         title: "Log ud",
         action: (context) async {
-          final sessionsController = context.read<UserController>();
-          Navigator.pop(context);
-          await sessionsController.logout();
+          final sessionProvider = context.read<SessionProvider>();
+          await sessionProvider.controller.logout();
+          if (context.mounted) {
+            Navigator.pop(context);
+          }
         }),
   ];
 
diff --git a/mobile/lib/pages/settings_pages/saldo.dart b/mobile/lib/pages/settings_pages/saldo.dart
index 5de59d5..88d96db 100644
--- a/mobile/lib/pages/settings_pages/saldo.dart
+++ b/mobile/lib/pages/settings_pages/saldo.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:mobile/controllers/user.dart';
+import 'package:mobile/controllers/session.dart';
 import 'package:mobile/results.dart';
 import 'package:mobile/utils/build_if_session_exists.dart';
 import 'package:mobile/utils/price.dart';
@@ -10,7 +10,6 @@ class SaldoSettingsPage extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    final sessionController = context.watch<UserController>();
     return Scaffold(
       backgroundColor: Colors.white,
       body: SafeArea(
@@ -26,22 +25,30 @@ class SaldoSettingsPage extends StatelessWidget {
                 ),
               ],
             ),
-            BuildIfSessionUserExists(
-                sessionController: sessionController,
-                placeholder: const CircularProgressIndicator(),
-                builder: (context, user) {
-                  return Text(
-                      "Nuværende saldo: ${formatDkkCents(user.balanceDkkCents)}",
-                      style: Theme.of(context).textTheme.bodyLarge);
-                }),
+            Consumer<CurrentUserProvider>(builder: (_, provider, ___) {
+              final user = provider.controller.user;
+              return Text(
+                  "Nuværende saldo: ${formatDkkCents(user.balanceDkkCents)}",
+                  style: Theme.of(context).textTheme.bodyLarge);
+            }),
             ElevatedButton.icon(
               onPressed: () async {
-                final res = await sessionController.addBalance();
-                switch (res) {
-                  case Ok<Null, String>():
-                    print("yay");
-                  case Err<Null, String>(value: final message):
-                    print("Womp womp fejled er: $message");
+                final currentUserProvider = context.read<CurrentUserProvider>();
+                final res = await currentUserProvider.controller.addBalance();
+                if (res case Err<Null, String>(value: final message)) {
+                  if (context.mounted) {
+                    showDialog(
+                        context: context,
+                        builder: (context) => AlertDialog(
+                              content: Text('Serverfejl: $message'),
+                              actions: <Widget>[
+                                TextButton(
+                                  onPressed: () => Navigator.pop(context, 'OK'),
+                                  child: const Text('OK'),
+                                ),
+                              ],
+                            ));
+                  }
                 }
               },
               icon: const Icon(Icons.add),
diff --git a/mobile/lib/server/backend_server.dart b/mobile/lib/server/backend_server.dart
index 4082d90..b24f319 100644
--- a/mobile/lib/server/backend_server.dart
+++ b/mobile/lib/server/backend_server.dart
@@ -4,6 +4,7 @@ import 'package:http/http.dart' as http;
 import 'package:mobile/models/cart_item.dart';
 import 'package:mobile/models/product.dart';
 import 'package:mobile/models/user.dart';
+import 'package:mobile/results.dart';
 import 'package:mobile/server/server.dart';
 
 class BackendServer implements Server {
@@ -21,24 +22,23 @@ class BackendServer implements Server {
   }
 
   @override
-  Future<Response<List<Product>>> allProducts() async {
+  Future<Result<List<Product>, String>> allProducts() async {
     final res = await http
         .get(
           Uri.parse("$_apiUrl/products/all"),
         )
         .then((res) => json.decode(res.body));
     if (res["ok"]) {
-      return Success(
-          data: (res["products"] as List<dynamic>)
-              .map(((product) => Product.fromJson(product)))
-              .toList());
+      return Ok((res["products"] as List<dynamic>)
+          .map(((product) => Product.fromJson(product)))
+          .toList());
     } else {
-      return Error(message: res["msg"]);
+      return Err(res["msg"]);
     }
   }
 
   @override
-  Future<Response<Null>> register(
+  Future<Result<Null, String>> register(
     String name,
     String email,
     String password,
@@ -49,14 +49,14 @@ class BackendServer implements Server {
     ).then((res) => json.decode(res.body));
 
     if (res["ok"]) {
-      return Success(data: null);
+      return Ok(null);
     } else {
-      return Error(message: res["msg"]);
+      return Err(res["msg"]);
     }
   }
 
   @override
-  Future<Response<String>> login(
+  Future<Result<String, String>> login(
     String email,
     String password,
   ) async {
@@ -66,41 +66,41 @@ class BackendServer implements Server {
     ).then((res) => json.decode(res.body));
 
     if (res["ok"]) {
-      return Success(data: res["token"]);
+      return Ok(res["token"]);
     } else {
-      return Error(message: res["msg"]);
+      return Err(res["msg"]);
     }
   }
 
   @override
-  Future<Response<Null>> logout(String token) async {
+  Future<Result<Null, String>> logout(String token) async {
     final res = await _post(
       endpoint: "sessions/logout",
     ).then((res) => json.decode(res.body));
 
     if (res["ok"]) {
-      return Success(data: null);
+      return Ok(null);
     } else {
-      return Error(message: res["msg"]);
+      return Err(res["msg"]);
     }
   }
 
   @override
-  Future<Response<User>> sessionUser(String token) async {
+  Future<Result<User, String>> sessionUser(String token) async {
     ("sending request fr with token $token");
     final res = await http.get(
       Uri.parse("$_apiUrl/sessions/user"),
       headers: {"Session-Token": token},
     ).then((res) => json.decode(res.body));
     if (res["ok"]) {
-      return Success(data: User.fromJson(res["user"]));
+      return Ok(User.fromJson(res["user"]));
     } else {
-      return Error(message: res["msg"]);
+      return Err(res["msg"]);
     }
   }
 
   @override
-  Future<Response<Null>> purchaseCart(
+  Future<Result<Null, String>> purchaseCart(
       String token, List<CartItem> cartItems) async {
     final res = await http.post(Uri.parse("$_apiUrl/carts/purchase"), headers: {
       "Content-Type": "application/json",
@@ -113,14 +113,14 @@ class BackendServer implements Server {
     }).then((res) => json.decode(res.body));
 
     if (res["ok"]) {
-      return Success(data: null);
+      return Ok(null);
     } else {
-      return Error(message: res["msg"]);
+      return Err(res["msg"]);
     }
   }
 
   @override
-  Future<Response<Null>> addBalance(String token) async {
+  Future<Result<Null, String>> addBalance(String token) async {
     print("$_apiUrl/api/users/balance/add");
     final res = await http.post(
       Uri.parse("$_apiUrl/users/balance/add"),
@@ -132,9 +132,9 @@ class BackendServer implements Server {
     ).then((res) => json.decode(res.body));
 
     if (res["ok"]) {
-      return Success(data: null);
+      return Ok(null);
     } else {
-      return Error(message: res["msg"]);
+      return Err(res["msg"]);
     }
   }
 }
diff --git a/mobile/lib/server/mock_server.dart b/mobile/lib/server/mock_server.dart
index 0500231..33ad079 100644
--- a/mobile/lib/server/mock_server.dart
+++ b/mobile/lib/server/mock_server.dart
@@ -2,13 +2,14 @@ import 'package:mobile/models/cart_item.dart';
 import 'package:mobile/models/coordinate.dart';
 import 'package:mobile/models/product.dart';
 import 'package:mobile/models/user.dart';
+import 'package:mobile/results.dart';
 import 'package:mobile/server/server.dart';
 
 class MockServer implements Server {
   @override
-  Future<Response<List<Product>>> allProducts() async {
+  Future<Result<List<Product>, String>> allProducts() async {
     var nextId = 0;
-    return Success(data: <Product>[
+    return Ok(<Product>[
       Product(
           id: nextId++,
           name: "Minimælk",
@@ -91,45 +92,44 @@ class MockServer implements Server {
   }
 
   @override
-  Future<Response<Null>> register(
+  Future<Result<Null, String>> register(
     String name,
     String email,
     String password,
   ) async {
-    return Success(data: null);
+    return Ok(null);
   }
 
   @override
-  Future<Response<String>> login(
+  Future<Result<String, String>> login(
     String email,
     String password,
   ) async {
-    return Success(data: "asdsadasdsad");
+    return Ok("asdsadasdsad");
   }
 
   @override
-  Future<Response<Null>> logout(String token) async {
-    return Success(data: null);
+  Future<Result<Null, String>> logout(String token) async {
+    return Ok(null);
   }
 
   @override
-  Future<Response<User>> sessionUser(String token) async {
-    return Success(
-        data: User(
-            id: 0,
-            email: "test@test.com",
-            name: "testuser",
-            balanceDkkCents: 10000));
+  Future<Result<User, String>> sessionUser(String token) async {
+    return Ok(User(
+        id: 0,
+        email: "test@test.com",
+        name: "testuser",
+        balanceDkkCents: 10000));
   }
 
   @override
-  Future<Response<Null>> purchaseCart(
+  Future<Result<Null, String>> purchaseCart(
       String token, List<CartItem> cartItems) async {
-    return Success(data: null);
+    return Ok(null);
   }
 
   @override
-  Future<Response<Null>> addBalance(String token) async {
-    return Success(data: null);
+  Future<Result<Null, String>> addBalance(String token) async {
+    return Ok(null);
   }
 }
diff --git a/mobile/lib/server/server.dart b/mobile/lib/server/server.dart
index c224055..cd3ba7d 100644
--- a/mobile/lib/server/server.dart
+++ b/mobile/lib/server/server.dart
@@ -1,37 +1,27 @@
 import 'package:mobile/models/cart_item.dart';
 import 'package:mobile/models/product.dart';
 import 'package:mobile/models/user.dart';
+import 'package:mobile/results.dart';
 
 abstract class Server {
-  Future<Response<List<Product>>> allProducts();
+  Future<Result<List<Product>, String>> allProducts();
 
-  Future<Response<Null>> register(
+  Future<Result<Null, String>> register(
     String name,
     String email,
     String password,
   );
 
-  Future<Response<String>> login(
+  Future<Result<String, String>> login(
     String email,
     String password,
   );
-  Future<Response<Null>> logout(String token);
+  Future<Result<Null, String>> logout(String token);
 
-  Future<Response<User>> sessionUser(String token);
+  Future<Result<User, String>> sessionUser(String token);
 
-  Future<Response<Null>> purchaseCart(String token, List<CartItem> cartItems);
+  Future<Result<Null, String>> purchaseCart(
+      String token, List<CartItem> cartItems);
 
-  Future<Response<Null>> addBalance(String token);
-}
-
-sealed class Response<Data> {}
-
-class Success<Data> extends Response<Data> {
-  Data data;
-  Success({required this.data});
-}
-
-class Error<Data> extends Response<Data> {
-  String message;
-  Error({required this.message});
+  Future<Result<Null, String>> addBalance(String token);
 }
diff --git a/mobile/lib/utils/build_if_session_exists.dart b/mobile/lib/utils/build_if_session_exists.dart
index ec8524f..4282fc3 100644
--- a/mobile/lib/utils/build_if_session_exists.dart
+++ b/mobile/lib/utils/build_if_session_exists.dart
@@ -1,28 +1,3 @@
 import 'package:flutter/material.dart';
-import 'package:mobile/controllers/user.dart';
+import 'package:mobile/controllers/session.dart';
 import 'package:mobile/models/user.dart';
-
-class BuildIfSessionUserExists extends StatelessWidget {
-  final UserController sessionController;
-  final Widget placeholder;
-  final Widget Function(BuildContext, User) builder;
-
-  const BuildIfSessionUserExists(
-      {super.key,
-      required this.sessionController,
-      required this.placeholder,
-      required this.builder});
-
-  @override
-  Widget build(BuildContext context) {
-    return FutureBuilder(
-        future: sessionController.loadUserOld(),
-        builder: (context, snapshot) {
-          final user = sessionController.userOld;
-          if (user == null) {
-            return placeholder;
-          }
-          return builder(context, user);
-        });
-  }
-}
diff --git a/mobile/test/widget_test.dart b/mobile/test/widget_test.dart
deleted file mode 100644
index a6b7d51..0000000
--- a/mobile/test/widget_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// This is a basic Flutter widget test.
-//
-// To perform an interaction with a widget in your test, use the WidgetTester
-// utility in the flutter_test package. For example, you can send tap and scroll
-// gestures. You can also use WidgetTester to find child widgets in the widget
-// tree, read text, and verify that the values of widget properties are correct.
-
-import 'package:flutter/material.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'package:mobile/main.dart';
-
-void main() {
-  testWidgets('Counter increments smoke test', (WidgetTester tester) async {
-    // Build our app and trigger a frame.
-    await tester.pumpWidget(const MyApp());
-
-    // Verify that our counter starts at 0.
-    expect(find.text('0'), findsOneWidget);
-    expect(find.text('1'), findsNothing);
-
-    // Tap the '+' icon and trigger a frame.
-    await tester.tap(find.byIcon(Icons.add));
-    await tester.pump();
-
-    // Verify that our counter has incremented.
-    expect(find.text('0'), findsNothing);
-    expect(find.text('1'), findsOneWidget);
-  });
-}