diff --git a/README.md b/README.md
index 6d025032..9830906d 100644
--- a/README.md
+++ b/README.md
@@ -81,12 +81,24 @@ You can add accounts to a wallet by:
### 4. Vault Import & Export
- Vault files contain **encrypted wallets and keys** for backup/migration
- Encrypted with **AES-256** using a password provided by the user
-- **Minimum password length:** 8 characters (no recovery possible if forgotten)
+- **Minimum password length:** 12 characters (no recovery possible if forgotten)
- When exporting, the vault password can be the same as or different from the wallet password
- Vaults can also be imported into the **[Qubic Web Wallet](https://qubic.wallet.org)**
---
+### 5. App Message
+- Displays static messages fetched from the backend to inform users about maintenance periods, updates, or other announcements.
+- The message can be of two types:
+ - Blocking: Shows a maintenance screen that prevents app use until the period ends.
+ - Non-blocking: Shows a one-time informational dialog that can be dismissed.
+- Each message includes metadata such as:
+ - Target platform (ios, android, macos, or all)
+ - Validity period (startDate, endDate)
+ - Blocking flag (true or false)
+
+---
+
## RPC Communication
Qubic Wallet interacts with the network using the following RPC endpoints:
diff --git a/assets/icons/maintenance.svg b/assets/icons/maintenance.svg
new file mode 100644
index 00000000..bbff9a08
--- /dev/null
+++ b/assets/icons/maintenance.svg
@@ -0,0 +1,21 @@
+
+
+
\ No newline at end of file
diff --git a/lib/config.dart b/lib/config.dart
index 94b41980..fd75ea05 100644
--- a/lib/config.dart
+++ b/lib/config.dart
@@ -35,9 +35,12 @@ abstract class Config {
static const useNativeSnackbar = false;
static const URL_WebExplorer = "https://explorer.qubic.org";
-
static const networkQubicMainnet = "Qubic Mainnet";
+ static const qubicStaticApiUrl =
+ "https://raw.githubusercontent.com/ahmed-tarek-salem/qubic-appcast-test/refs/heads/main";
+ static const qubicStaticMessages = "/message.json";
+
//Qubic Helper Utilities
static final qubicHelper = QubicHelperConfig(
win64: QubicHelperConfigEntry(
diff --git a/lib/di.dart b/lib/di.dart
index 1b978909..26f9250c 100644
--- a/lib/di.dart
+++ b/lib/di.dart
@@ -1,24 +1,26 @@
import 'package:app_links/app_links.dart';
import 'package:get_it/get_it.dart';
-import 'package:qubic_wallet/services/screenshot_service.dart';
-import 'package:qubic_wallet/services/qr_scanner_service.dart';
import 'package:qubic_wallet/helpers/global_snack_bar.dart';
import 'package:qubic_wallet/models/wallet_connect/wallet_connect_modals_controller.dart';
import 'package:qubic_wallet/resources/apis/archive/qubic_archive_api.dart';
import 'package:qubic_wallet/resources/apis/live/qubic_live_api.dart';
+import 'package:qubic_wallet/resources/apis/qubic_helpers_api.dart';
+import 'package:qubic_wallet/resources/apis/static/qubic_static_api.dart';
import 'package:qubic_wallet/resources/apis/stats/qubic_stats_api.dart';
import 'package:qubic_wallet/resources/hive_storage.dart';
import 'package:qubic_wallet/resources/qubic_cmd.dart';
import 'package:qubic_wallet/resources/secure_storage.dart';
import 'package:qubic_wallet/services/biometric_service.dart';
+import 'package:qubic_wallet/services/qr_scanner_service.dart';
+import 'package:qubic_wallet/services/screenshot_service.dart';
import 'package:qubic_wallet/services/wallet_connect_service.dart';
+import 'package:qubic_wallet/stores/app_message_store.dart';
import 'package:qubic_wallet/stores/application_store.dart';
+import 'package:qubic_wallet/stores/dapp_store.dart';
import 'package:qubic_wallet/stores/network_store.dart';
import 'package:qubic_wallet/stores/root_jailbreak_flag_store.dart';
import 'package:qubic_wallet/stores/settings_store.dart';
-import 'package:qubic_wallet/stores/dapp_store.dart';
import 'package:qubic_wallet/timed_controller.dart';
-import 'package:qubic_wallet/resources/apis/qubic_helpers_api.dart';
final GetIt getIt = GetIt.instance;
@@ -31,11 +33,14 @@ Future setupDI() async {
QubicArchiveApi(getIt()));
getIt.registerSingleton(QubicStatsApi(getIt()));
getIt.registerSingleton(QubicHelpersApi());
+ getIt.registerSingleton(QubicStaticApi());
//Stores
getIt.registerSingleton(ApplicationStore());
getIt.registerSingleton(SettingsStore());
getIt.registerSingleton(DappStore());
+ getIt.registerSingleton(AppMessageStore());
+
getIt.registerSingleton(SecureStorage());
await getIt().initialize();
getIt.registerSingleton(HiveStorage());
diff --git a/lib/dtos/app_message_dto.dart b/lib/dtos/app_message_dto.dart
new file mode 100644
index 00000000..16c20893
--- /dev/null
+++ b/lib/dtos/app_message_dto.dart
@@ -0,0 +1,63 @@
+class AppMessageDto {
+ final String? id;
+ final String title;
+ final String message;
+ final bool blocking;
+ final String platform; // e.g. "all", "ios", "android"
+ final DateTime? startDate;
+ final DateTime? endDate;
+ final bool disabled;
+
+ AppMessageDto({
+ required this.id,
+ required this.title,
+ required this.message,
+ required this.blocking,
+ required this.platform,
+ this.startDate,
+ this.endDate,
+ this.disabled = false,
+ });
+
+ factory AppMessageDto.fromJson(Map json) {
+ return AppMessageDto(
+ id: json['id'],
+ title: json['title'] ?? '',
+ message: json['message'] ?? '',
+ blocking: json['blocking'] ?? false,
+ platform: json['platform'] ?? 'all',
+ startDate:
+ json['startDate'] == null ? null : _parseDate(json['startDate']),
+ endDate: json['endDate'] == null ? null : _parseDate(json['endDate']),
+ disabled: json['disabled'] ?? false,
+ );
+ }
+
+ /// Check if the message is currently active
+ bool get isActive {
+ final now = DateTime.now().toUtc();
+ if (startDate != null && now.isBefore(startDate!)) return false;
+ if (endDate != null && now.isAfter(endDate!)) return false;
+ return true;
+ }
+
+ /// Check if message applies to current platform
+ bool appliesToPlatform(String currentPlatform) {
+ final lowerPlatform = platform.toLowerCase();
+ return lowerPlatform == 'all' ||
+ lowerPlatform == currentPlatform.toLowerCase();
+ }
+
+ bool isValid(String currentPlatform) {
+ return isActive && appliesToPlatform(currentPlatform) && !disabled;
+ }
+
+ static DateTime? _parseDate(dynamic value) {
+ if (value == null) return null;
+ try {
+ return DateTime.parse(value).toUtc();
+ } catch (_) {
+ return null;
+ }
+ }
+}
diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb
index 8a745be9..a51196f2 100644
--- a/lib/l10n/app_de.arb
+++ b/lib/l10n/app_de.arb
@@ -838,5 +838,6 @@
"revealSeedCopiedToClipboardMessage": "Privater Seed wurde vorübergehend in die Zwischenablage kopiert (für 1 Minute gespeichert)",
"revealSeedWarningTitle": "Teile deinen privaten Seed nicht!",
"revealSeedWarningDescription": "Wenn jemand deinen privaten Seed hat, hat er vollständige Kontrolle über dein Konto",
- "blockedScreenshotWarning": "Screenshot geschützt — dieser Bildschirm bleibt privat."
+ "blockedScreenshotWarning": "Screenshot geschützt — dieser Bildschirm bleibt privat.",
+ "maintenanceRefreshButton": "Aktualisieren"
}
\ No newline at end of file
diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb
index 69ad16db..6925168f 100644
--- a/lib/l10n/app_en.arb
+++ b/lib/l10n/app_en.arb
@@ -901,5 +901,6 @@
"revealSeedCopiedToClipboardMessage": "Private seed temporarily copied to clipboard (stored for 1 minute)",
"revealSeedWarningTitle": "Do not share your Private Seed!",
"revealSeedWarningDescription": "If someone has your private seed, they will have full control of your account",
- "blockedScreenshotWarning": "Screenshot protected — this screen is private."
+ "blockedScreenshotWarning": "Screenshot protected — this screen is private.",
+ "maintenanceRefreshButton": "Refresh"
}
\ No newline at end of file
diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb
index 0af02916..86d7c9db 100644
--- a/lib/l10n/app_es.arb
+++ b/lib/l10n/app_es.arb
@@ -837,5 +837,6 @@
"revealSeedCopiedToClipboardMessage": "La semilla privada se copió temporalmente (por 1 minuto) al portapapeles",
"revealSeedWarningTitle": "¡No compartas tu semilla privada!",
"revealSeedWarningDescription": "Si alguien tiene tu semilla privada, tendrá control total de tu cuenta",
- "blockedScreenshotWarning": "Captura protegida: esta pantalla es privada."
+ "blockedScreenshotWarning": "Captura protegida: esta pantalla es privada.",
+ "maintenanceRefreshButton": "Actualizar"
}
\ No newline at end of file
diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb
index d8302427..b6c041c0 100644
--- a/lib/l10n/app_fr.arb
+++ b/lib/l10n/app_fr.arb
@@ -843,5 +843,6 @@
"revealSeedCopiedToClipboardMessage": "La phrase secrète a été copiée temporairement (pendant 1 minute) dans le presse-papiers ",
"revealSeedWarningTitle": "Ne partagez pas votre phrase secrète!",
"revealSeedWarningDescription": "Si quelqu’un possède votre phrase secrète, il aura un contrôle total sur votre compte",
- "blockedScreenshotWarning": "Capture protégée — cet écran reste privé."
+ "blockedScreenshotWarning": "Capture protégée — cet écran reste privé.",
+ "maintenanceRefreshButton": "Rafraîchir"
}
\ No newline at end of file
diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb
index 792e0269..0421b338 100644
--- a/lib/l10n/app_ru.arb
+++ b/lib/l10n/app_ru.arb
@@ -838,5 +838,6 @@
"revealSeedCopiedToClipboardMessage": "Приватная сид-фраза временно скопирована в буфер обмена (хранится 1 минуту)",
"revealSeedWarningTitle": "Никогда не делитесь своей приватной сид-фразой!",
"revealSeedWarningDescription": "Если кто-то получит вашу приватную сид-фразу, он получит полный доступ к вашему аккаунту",
- "blockedScreenshotWarning": "Скриншот защищён — экран остаётся приватным."
+ "blockedScreenshotWarning": "Скриншот защищён — экран остаётся приватным.",
+ "maintenanceRefreshButton": "Обновить"
}
\ No newline at end of file
diff --git a/lib/l10n/app_tr.arb b/lib/l10n/app_tr.arb
index d7b41baf..e8a57603 100644
--- a/lib/l10n/app_tr.arb
+++ b/lib/l10n/app_tr.arb
@@ -838,5 +838,6 @@
"revealSeedCopiedToClipboardMessage": "Özel anahtar geçici olarak panoya kopyalandı (1 dakika saklanır)",
"revealSeedWarningTitle": "Özel Anahtarınızı Paylaşmayın!",
"revealSeedWarningDescription": "Birisi özel anahtarınıza sahipse, hesabınız üzerinde tam kontrol sahibi olur",
- "blockedScreenshotWarning": "Ekran görüntüsü korundu — bu ekran gizli kalır."
+ "blockedScreenshotWarning": "Ekran görüntüsü korundu — bu ekran gizli kalır.",
+ "maintenanceRefreshButton": "Yenile"
}
\ No newline at end of file
diff --git a/lib/l10n/app_vi.arb b/lib/l10n/app_vi.arb
index 19a81756..70b13fdc 100644
--- a/lib/l10n/app_vi.arb
+++ b/lib/l10n/app_vi.arb
@@ -901,5 +901,6 @@
"revealSeedCopiedToClipboardMessage": "Seed riêng tư đã được sao chép tạm thời vào clipboard (được lưu trong 1 phút)",
"revealSeedWarningTitle": "Đừng chia sẻ seed riêng tư của bạn!",
"revealSeedWarningDescription": "Nếu ai đó có seed riêng tư của bạn, họ sẽ có toàn quyền kiểm soát tài khoản của bạn",
- "blockedScreenshotWarning": "Chụp màn hình được bảo vệ — màn hình này là riêng tư."
-}
+ "blockedScreenshotWarning": "Chụp màn hình được bảo vệ — màn hình này là riêng tư.",
+ "maintenanceRefreshButton": "Làm mới"
+}
\ No newline at end of file
diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb
index 8ca8cff8..75f1aafd 100644
--- a/lib/l10n/app_zh.arb
+++ b/lib/l10n/app_zh.arb
@@ -838,5 +838,6 @@
"revealSeedCopiedToClipboardMessage": "私密助记词已临时复制到剪贴板(保存 1 分钟)",
"revealSeedWarningTitle": "请勿泄露您的私密助记词!",
"revealSeedWarningDescription": "如果他人获取了您的私密助记词,他们将完全控制您的账户",
- "blockedScreenshotWarning": "螢幕截圖已保護,此畫面保持隱私。"
+ "blockedScreenshotWarning": "螢幕截圖已保護,此畫面保持隱私。",
+ "maintenanceRefreshButton": "重新整理"
}
\ No newline at end of file
diff --git a/lib/pages/main/maintenance_screen.dart b/lib/pages/main/maintenance_screen.dart
new file mode 100644
index 00000000..639bacd9
--- /dev/null
+++ b/lib/pages/main/maintenance_screen.dart
@@ -0,0 +1,71 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_mobx/flutter_mobx.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:qubic_wallet/di.dart';
+import 'package:qubic_wallet/dtos/app_message_dto.dart';
+import 'package:qubic_wallet/flutter_flow/theme_paddings.dart';
+import 'package:qubic_wallet/l10n/l10n.dart';
+import 'package:qubic_wallet/stores/app_message_store.dart';
+import 'package:qubic_wallet/styles/app_icons.dart';
+import 'package:qubic_wallet/styles/text_styles.dart';
+import 'package:qubic_wallet/styles/themed_controls.dart';
+
+class MaintenanceScreen extends StatelessWidget {
+ final AppMessageDto? appMessage;
+ const MaintenanceScreen({super.key, this.appMessage});
+
+ @override
+ Widget build(BuildContext context) {
+ final l10n = l10nOf(context);
+ return PopScope(
+ canPop: false,
+ child: Scaffold(
+ body: Center(
+ child: Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: ThemePaddings.normalPadding),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ SvgPicture.asset(
+ AppIcons.maintenance,
+ height: 100,
+ colorFilter: const ColorFilter.mode(
+ LightThemeColors.primary40, BlendMode.srcIn),
+ ),
+ ThemedControls.spacerVerticalNormal(),
+ Text(appMessage?.title ?? "",
+ style: TextStyles.alertHeader, textAlign: TextAlign.center),
+ ThemedControls.spacerVerticalSmall(),
+ Text(appMessage?.message ?? "",
+ style: TextStyles.alertText, textAlign: TextAlign.center),
+ ThemedControls.spacerVerticalNormal(),
+ Observer(builder: (context) {
+ bool isLoading = getIt().isLoading;
+ return ThemedControls.primaryButtonSmall(
+ onPressed: () async {
+ final navigator = Navigator.of(context);
+ final message =
+ await getIt().getAppMessage();
+ if (message == null) {
+ navigator.pop();
+ }
+ },
+ text: isLoading ? "" : l10n.maintenanceRefreshButton,
+ icon: isLoading
+ ? const SizedBox(
+ height: 20,
+ width: 20,
+ child: CircularProgressIndicator(
+ strokeWidth: 2,
+ color: LightThemeColors.background),
+ )
+ : null);
+ }),
+ ],
+ ),
+ )),
+ ),
+ );
+ }
+}
diff --git a/lib/pages/main/tab_wallet_contents.dart b/lib/pages/main/tab_wallet_contents.dart
index ff9d001a..4f6626f8 100644
--- a/lib/pages/main/tab_wallet_contents.dart
+++ b/lib/pages/main/tab_wallet_contents.dart
@@ -18,8 +18,10 @@ import 'package:qubic_wallet/flutter_flow/theme_paddings.dart';
import 'package:qubic_wallet/helpers/app_logger.dart';
import 'package:qubic_wallet/helpers/show_alert_dialog.dart';
import 'package:qubic_wallet/l10n/l10n.dart';
+import 'package:qubic_wallet/pages/main/maintenance_screen.dart';
import 'package:qubic_wallet/pages/main/wallet_contents/add_account_modal_bottom_sheet.dart';
import 'package:qubic_wallet/pages/main/wallet_contents/add_wallet_connect/add_wallet_connect.dart';
+import 'package:qubic_wallet/stores/app_message_store.dart';
import 'package:qubic_wallet/stores/application_store.dart';
import 'package:qubic_wallet/stores/network_store.dart';
import 'package:qubic_wallet/stores/root_jailbreak_flag_store.dart';
@@ -67,6 +69,7 @@ class _TabWalletContentsState extends State {
}
}
});
+ checkAppMessage();
_scrollController.addListener(() {
if (_scrollController.offset > sliverExpanded) {
@@ -150,6 +153,30 @@ class _TabWalletContentsState extends State {
appStore.triggerAddAccountModal();
}
+ void checkAppMessage() async {
+ final message = await getIt().getAppMessage();
+ if (message == null || !mounted) return;
+ if (message.blocking) {
+ Future.delayed(const Duration(seconds: 1), () {
+ if (mounted) {
+ pushScreenWithoutNavBar(
+ context, MaintenanceScreen(appMessage: message));
+ }
+ });
+ } else {
+ showDialog(
+ context: context,
+ builder: (context) {
+ return getAlertDialog(
+ message.title,
+ message.message,
+ primaryButtonLabel: l10nWrapper.l10n!.generalButtonOK,
+ primaryButtonFunction: () => Navigator.of(context).pop(),
+ );
+ });
+ }
+ }
+
@override
Widget build(BuildContext context) {
final l10n = l10nOf(context);
@@ -159,6 +186,7 @@ class _TabWalletContentsState extends State {
edgeOffset: kToolbarHeight,
onRefresh: () async {
await _timedController.interruptFetchTimer();
+ checkAppMessage();
},
backgroundColor: LightThemeColors.refreshIndicatorBackground,
child: Container(
diff --git a/lib/resources/apis/static/qubic_static_api.dart b/lib/resources/apis/static/qubic_static_api.dart
new file mode 100644
index 00000000..5dc9e5c3
--- /dev/null
+++ b/lib/resources/apis/static/qubic_static_api.dart
@@ -0,0 +1,27 @@
+import 'dart:convert';
+
+import 'package:dio/dio.dart';
+import 'package:qubic_wallet/config.dart';
+import 'package:qubic_wallet/dtos/app_message_dto.dart';
+import 'package:qubic_wallet/models/app_error.dart';
+import 'package:qubic_wallet/services/dio_client.dart';
+
+class QubicStaticApi {
+ late Dio _dio;
+
+ QubicStaticApi() {
+ _dio = DioClient.getDio(baseUrl: Config.qubicStaticApiUrl);
+ }
+
+ Future getAppMessage() async {
+ try {
+ final response = await _dio.get(Config.qubicStaticMessages);
+ final decodedResponse = json.decode(response.data);
+ return decodedResponse["id"] == null
+ ? null
+ : AppMessageDto.fromJson(decodedResponse);
+ } catch (error) {
+ throw ErrorHandler.handleError(error);
+ }
+ }
+}
diff --git a/lib/stores/app_message_store.dart b/lib/stores/app_message_store.dart
new file mode 100644
index 00000000..3b422100
--- /dev/null
+++ b/lib/stores/app_message_store.dart
@@ -0,0 +1,34 @@
+import 'package:mobx/mobx.dart';
+import 'package:qubic_wallet/di.dart';
+import 'package:qubic_wallet/dtos/app_message_dto.dart';
+import 'package:qubic_wallet/helpers/app_logger.dart';
+import 'package:qubic_wallet/resources/apis/static/qubic_static_api.dart';
+import 'package:universal_platform/universal_platform.dart';
+
+part 'app_message_store.g.dart';
+
+// ignore: library_private_types_in_public_api
+class AppMessageStore = _AppMessageStore with _$AppMessageStore;
+
+abstract class _AppMessageStore with Store {
+ @observable
+ bool isLoading = false;
+
+ @action
+ Future getAppMessage() async {
+ isLoading = true;
+ try {
+ final message = await getIt().getAppMessage();
+ if (message != null &&
+ message.isValid(UniversalPlatform.operatingSystem)) {
+ return message;
+ }
+ return null;
+ } catch (e) {
+ appLogger.e(e);
+ return null;
+ } finally {
+ isLoading = false;
+ }
+ }
+}
diff --git a/lib/stores/app_message_store.g.dart b/lib/stores/app_message_store.g.dart
new file mode 100644
index 00000000..58d31f5a
--- /dev/null
+++ b/lib/stores/app_message_store.g.dart
@@ -0,0 +1,42 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'app_message_store.dart';
+
+// **************************************************************************
+// StoreGenerator
+// **************************************************************************
+
+// ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic, no_leading_underscores_for_local_identifiers
+
+mixin _$AppMessageStore on _AppMessageStore, Store {
+ late final _$isLoadingAtom =
+ Atom(name: '_AppMessageStore.isLoading', context: context);
+
+ @override
+ bool get isLoading {
+ _$isLoadingAtom.reportRead();
+ return super.isLoading;
+ }
+
+ @override
+ set isLoading(bool value) {
+ _$isLoadingAtom.reportWrite(value, super.isLoading, () {
+ super.isLoading = value;
+ });
+ }
+
+ late final _$getAppMessageAsyncAction =
+ AsyncAction('_AppMessageStore.getAppMessage', context: context);
+
+ @override
+ Future getAppMessage() {
+ return _$getAppMessageAsyncAction.run(() => super.getAppMessage());
+ }
+
+ @override
+ String toString() {
+ return '''
+isLoading: ${isLoading}
+ ''';
+ }
+}
diff --git a/lib/stores/settings_store.dart b/lib/stores/settings_store.dart
index bbb7c2f8..738ef953 100644
--- a/lib/stores/settings_store.dart
+++ b/lib/stores/settings_store.dart
@@ -64,20 +64,6 @@ abstract class _SettingsStore with Store {
await secureStorage.setWalletSettings(settings);
}
- @action
- Future setTOTPKey(String key) async {
- settings.TOTPKey = key;
- settings = Settings.clone(settings);
- await secureStorage.setWalletSettings(settings);
- }
-
- @action
- Future clearTOTPKey() async {
- settings.TOTPKey = null;
- settings = Settings.clone(settings);
- await secureStorage.setWalletSettings(settings);
- }
-
@action
Future setAutoLockTimeout(int value) async {
settings.autoLockTimeout = value;
diff --git a/lib/stores/settings_store.g.dart b/lib/stores/settings_store.g.dart
index bc4c7426..b553117f 100644
--- a/lib/stores/settings_store.g.dart
+++ b/lib/stores/settings_store.g.dart
@@ -108,22 +108,6 @@ mixin _$SettingsStore on _SettingsStore, Store {
return _$setBiometricsAsyncAction.run(() => super.setBiometrics(value));
}
- late final _$setTOTPKeyAsyncAction =
- AsyncAction('_SettingsStore.setTOTPKey', context: context);
-
- @override
- Future setTOTPKey(String key) {
- return _$setTOTPKeyAsyncAction.run(() => super.setTOTPKey(key));
- }
-
- late final _$clearTOTPKeyAsyncAction =
- AsyncAction('_SettingsStore.clearTOTPKey', context: context);
-
- @override
- Future clearTOTPKey() {
- return _$clearTOTPKeyAsyncAction.run(() => super.clearTOTPKey());
- }
-
late final _$setAutoLockTimeoutAsyncAction =
AsyncAction('_SettingsStore.setAutoLockTimeout', context: context);
diff --git a/lib/styles/app_icons.dart b/lib/styles/app_icons.dart
index b437162f..436e6000 100644
--- a/lib/styles/app_icons.dart
+++ b/lib/styles/app_icons.dart
@@ -35,4 +35,5 @@ abstract class AppIcons {
static const String support = '${_path}support.svg';
static const String google = '${_path}google.svg';
static const String pendingAndFailedTrx = '${_path}clock-alert-outline.svg';
+ static const String maintenance = '${_path}maintenance.svg';
}