diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml
index 4df215e13..282941365 100644
--- a/.github/workflows/pr_test_build.yml
+++ b/.github/workflows/pr_test_build.yml
@@ -16,6 +16,7 @@ jobs:
env:
STORE_PASS: test@cake_wallet
KEY_PASS: test@cake_wallet
+ PR_NUMBER: ${{ github.event.number }}
steps:
- name: is pr
@@ -150,10 +151,7 @@ jobs:
- name: Rename app
run: |
- hash=`sha512sum <<<"${{ env.BRANCH_NAME }}"`
- substring=${hash:0:15}
- echo substring
- echo -e "id=com.cakewallet.test_$(substring)\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
+ echo -e "id=com.cakewallet.test_${{ env.PR_NUMBER }}\nname=${{ env.BRANCH_NAME }}" > /opt/android/cake_wallet/android/app.properties
- name: Build
run: |
diff --git a/assets/images/notification_icon.svg b/assets/images/notification_icon.svg
new file mode 100644
index 000000000..099039e67
--- /dev/null
+++ b/assets/images/notification_icon.svg
@@ -0,0 +1,69 @@
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/status_website_image.png b/assets/images/status_website_image.png
new file mode 100644
index 000000000..017bb64e1
Binary files /dev/null and b/assets/images/status_website_image.png differ
diff --git a/assets/text/Monerocom_Release_Notes.txt b/assets/text/Monerocom_Release_Notes.txt
index 732e58a18..05f78b809 100644
--- a/assets/text/Monerocom_Release_Notes.txt
+++ b/assets/text/Monerocom_Release_Notes.txt
@@ -1,2 +1,2 @@
-New themes
+In-App live status page for the app services
Bug fixes and enhancements
\ No newline at end of file
diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt
index 1c2ec154c..05f78b809 100644
--- a/assets/text/Release_Notes.txt
+++ b/assets/text/Release_Notes.txt
@@ -1,6 +1,2 @@
-Add Solana wallet
-Support ALL Bitcoin address types (Legacy, Segwit (both variants), Taproot)
-Enhance Sending/Receiving flow for Bitcoin
-Improve fee calculations in Bitcoin
-New themes
+In-App live status page for the app services
Bug fixes and enhancements
\ No newline at end of file
diff --git a/cw_core/lib/crypto_currency.dart b/cw_core/lib/crypto_currency.dart
index ce509015c..9cebce10a 100644
--- a/cw_core/lib/crypto_currency.dart
+++ b/cw_core/lib/crypto_currency.dart
@@ -216,7 +216,7 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen
static const usdcEPoly = CryptoCurrency(title: 'USDC.E', tag: 'POLY', fullName: 'USD Coin (PoS)', raw: 88, name: 'usdcepoly', iconPath: 'assets/images/usdc_icon.png', decimals: 6);
static const kaspa = CryptoCurrency(title: 'KAS', fullName: 'Kaspa', raw: 89, name: 'kas', iconPath: 'assets/images/kaspa_icon.png', decimals: 8);
static const digibyte = CryptoCurrency(title: 'DGB', fullName: 'DigiByte', raw: 90, name: 'dgb', iconPath: 'assets/images/digibyte.png', decimals: 8);
- static const usdtSol = CryptoCurrency(title: 'USDT', tag: 'SOL', fullName: 'USDT Tether', raw: 90, name: 'usdtsol', iconPath: 'assets/images/usdt_icon.png', decimals: 6);
+ static const usdtSol = CryptoCurrency(title: 'USDT', tag: 'SOL', fullName: 'USDT Tether', raw: 91, name: 'usdtsol', iconPath: 'assets/images/usdt_icon.png', decimals: 6);
static final Map _rawCurrencyMap =
diff --git a/cw_core/lib/monero_transaction_priority.dart b/cw_core/lib/monero_transaction_priority.dart
index f5c00ecc7..81058f336 100644
--- a/cw_core/lib/monero_transaction_priority.dart
+++ b/cw_core/lib/monero_transaction_priority.dart
@@ -1,7 +1,4 @@
import 'package:cw_core/transaction_priority.dart';
-import 'package:cw_core/wallet_type.dart';
-//import 'package:cake_wallet/generated/i18n.dart';
-import 'package:cw_core/enumerable_item.dart';
class MoneroTransactionPriority extends TransactionPriority {
const MoneroTransactionPriority({required String title, required int raw})
@@ -12,21 +9,20 @@ class MoneroTransactionPriority extends TransactionPriority {
MoneroTransactionPriority.automatic,
MoneroTransactionPriority.medium,
MoneroTransactionPriority.fast,
- MoneroTransactionPriority.fastest
+ MoneroTransactionPriority.fastest,
];
- static const slow = MoneroTransactionPriority(title: 'Slow', raw: 0);
- static const automatic = MoneroTransactionPriority(title: 'Automatic', raw: 1);
+ static const automatic = MoneroTransactionPriority(title: 'Automatic', raw: 0);
+ static const slow = MoneroTransactionPriority(title: 'Slow', raw: 1);
static const medium = MoneroTransactionPriority(title: 'Medium', raw: 2);
static const fast = MoneroTransactionPriority(title: 'Fast', raw: 3);
static const fastest = MoneroTransactionPriority(title: 'Fastest', raw: 4);
- static const standard = slow;
static MoneroTransactionPriority deserialize({required int raw}) {
switch (raw) {
case 0:
- return slow;
- case 1:
return automatic;
+ case 1:
+ return slow;
case 2:
return medium;
case 3:
diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart
index a3c665277..db386837c 100644
--- a/cw_monero/lib/monero_wallet.dart
+++ b/cw_monero/lib/monero_wallet.dart
@@ -191,13 +191,8 @@ abstract class MoneroWalletBase extends WalletBase setup({
yatStore: getIt.get(),
ordersStore: getIt.get(),
anonpayTransactionsStore: getIt.get(),
+ sharedPreferences: getIt.get(),
keyService: getIt.get()));
getIt.registerFactory(
diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart
index 59b8d5d5b..c3ebde94c 100644
--- a/lib/entities/default_settings_migration.dart
+++ b/lib/entities/default_settings_migration.dart
@@ -201,6 +201,9 @@ Future defaultSettingsMigration(
await changeSolanaCurrentNodeToDefault(
sharedPreferences: sharedPreferences, nodes: nodes);
break;
+ case 28:
+ await _updateMoneroPriority(sharedPreferences);
+ break;
default:
break;
}
@@ -215,6 +218,18 @@ Future defaultSettingsMigration(
await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version);
}
+Future _updateMoneroPriority(SharedPreferences sharedPreferences) async {
+ final currentPriority =
+ await sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority) ??
+ monero!.getDefaultTransactionPriority().serialize();
+
+ // was set to automatic but automatic should be 0
+ if (currentPriority == 1) {
+ sharedPreferences.setInt(PreferencesKey.moneroTransactionPriority,
+ monero!.getDefaultTransactionPriority().serialize()); // 0
+ }
+}
+
Future _validateWalletInfoBoxData(Box walletInfoSource) async {
try {
final root = await getAppDir();
diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart
index 0dd251aaa..1808be97c 100644
--- a/lib/entities/preferences_key.dart
+++ b/lib/entities/preferences_key.dart
@@ -72,4 +72,5 @@ class PreferencesKey {
static const lastSeenAppVersion = 'last_seen_app_version';
static const shouldShowMarketPlaceInDashboard = 'should_show_marketplace_in_dashboard';
static const isNewInstall = 'is_new_install';
+ static const serviceStatusShaKey = 'service_status_sha_key';
}
diff --git a/lib/entities/service_status.dart b/lib/entities/service_status.dart
new file mode 100644
index 000000000..392c8072d
--- /dev/null
+++ b/lib/entities/service_status.dart
@@ -0,0 +1,41 @@
+class ServiceStatus {
+ final String title;
+ final String description;
+ final String? image;
+ final String? status;
+ final DateTime date;
+
+ ServiceStatus(
+ {required this.title,
+ required this.description,
+ required this.date,
+ this.image,
+ this.status});
+
+ factory ServiceStatus.fromJson(Map json) => ServiceStatus(
+ title: json['title'] as String? ?? '',
+ description: json['description'] as String? ?? '',
+ date: DateTime.tryParse(json['date'] as String? ?? '') ?? DateTime.now(),
+ image: json['image'] as String?,
+ status: json['status'] as String?,
+ );
+}
+
+class ServicesResponse {
+ final List servicesStatus;
+ final bool hasUpdates;
+ final String currentSha;
+
+ ServicesResponse(this.servicesStatus, this.hasUpdates, this.currentSha);
+
+ factory ServicesResponse.fromJson(
+ Map json, bool hasUpdates, String currentSha) {
+ return ServicesResponse(
+ (json['notices'] as List? ?? [])
+ .map((e) => ServiceStatus.fromJson(e as Map))
+ .toList(),
+ hasUpdates,
+ currentSha,
+ );
+ }
+}
diff --git a/lib/main.dart b/lib/main.dart
index 0bd6b472d..bdcb1e7d3 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -165,7 +165,7 @@ Future initializeAppConfigs() async {
transactionDescriptions: transactionDescriptions,
secureStorage: secureStorage,
anonpayInvoiceInfo: anonpayInvoiceInfo,
- initialMigrationVersion: 27);
+ initialMigrationVersion: 28);
}
Future initialSetup(
diff --git a/lib/solana/cw_solana.dart b/lib/solana/cw_solana.dart
index cdbf5bca3..7b805c1d5 100644
--- a/lib/solana/cw_solana.dart
+++ b/lib/solana/cw_solana.dart
@@ -111,7 +111,7 @@ class CWSolana extends Solana {
@override
List? getValidationLength(CryptoCurrency type) {
if (type is SPLToken) {
- return [44];
+ return [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44];
}
return null;
diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart
index 61e7d6176..3806dff91 100644
--- a/lib/src/screens/dashboard/dashboard_page.dart
+++ b/lib/src/screens/dashboard/dashboard_page.dart
@@ -7,6 +7,7 @@ import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sideba
import 'package:cake_wallet/src/screens/dashboard/pages/market_place_page.dart';
import 'package:cake_wallet/src/screens/wallet_connect/widgets/modals/bottom_sheet_listener.dart';
import 'package:cake_wallet/src/widgets/gradient_background.dart';
+import 'package:cake_wallet/src/widgets/services_updates_widget.dart';
import 'package:cake_wallet/src/widgets/vulnerable_seeds_popup.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/utils/device_info.dart';
@@ -101,6 +102,9 @@ class _DashboardPageView extends BasePage {
@override
Widget get endDrawer => MenuWidget(dashboardViewModel);
+ @override
+ Widget leading(BuildContext context) => ServicesUpdatesWidget(dashboardViewModel.getServicesStatus());
+
@override
Widget middle(BuildContext context) {
return SyncIndicator(
diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart
index 8119e9fd4..940ab54ca 100644
--- a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart
+++ b/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu_item.dart
@@ -7,13 +7,15 @@ class SideMenuItem extends StatelessWidget {
required this.onTap,
this.imagePath,
this.icon,
+ this.widget,
this.isSelected = false,
- }) : assert((icon != null && imagePath == null) || (icon == null && imagePath != null));
+ }) : assert(widget != null || icon != null || imagePath != null);
final void Function() onTap;
final String? imagePath;
final IconData? icon;
final bool isSelected;
+ final Widget? widget;
Color _setColor(BuildContext context) {
if (isSelected) {
@@ -28,18 +30,7 @@ class SideMenuItem extends StatelessWidget {
return InkWell(
child: Padding(
padding: EdgeInsets.all(20),
- child: icon != null
- ? Icon(
- icon,
- color: _setColor(context),
- )
- : Image.asset(
- imagePath ?? '',
- fit: BoxFit.cover,
- height: 30,
- width: 30,
- color: _setColor(context),
- ),
+ child: widget ?? _getIcon(context),
),
onTap: () => onTap.call(),
highlightColor: Colors.transparent,
@@ -48,4 +39,19 @@ class SideMenuItem extends StatelessWidget {
splashColor: Colors.transparent,
);
}
+
+ Widget _getIcon(BuildContext context) {
+ return icon != null
+ ? Icon(
+ icon,
+ color: _setColor(context),
+ )
+ : Image.asset(
+ imagePath ?? '',
+ fit: BoxFit.cover,
+ height: 30,
+ width: 30,
+ color: _setColor(context),
+ );
+ }
}
diff --git a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart b/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart
index f73570048..d0ddb19e6 100644
--- a/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart
+++ b/lib/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart
@@ -9,6 +9,7 @@ import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sideba
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator.dart';
import 'package:cake_wallet/src/screens/wallet_connect/widgets/modals/bottom_sheet_listener.dart';
+import 'package:cake_wallet/src/widgets/services_updates_widget.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
import 'package:flutter/cupertino.dart';
@@ -105,12 +106,18 @@ class DesktopSidebarWrapper extends BasePage {
? selectedIconPath
: unselectedIconPath,
),
+ SideMenuItem(
+ widget: ServicesUpdatesWidget(dashboardViewModel.getServicesStatus()),
+ isSelected: desktopSidebarViewModel.currentPage == SidebarItem.status,
+ onTap: () {},
+ ),
],
bottomItems: [
SideMenuItem(
- imagePath: 'assets/images/support_icon.png',
- isSelected: desktopSidebarViewModel.currentPage == SidebarItem.support,
- onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.support)),
+ imagePath: 'assets/images/support_icon.png',
+ isSelected: desktopSidebarViewModel.currentPage == SidebarItem.support,
+ onTap: () => desktopSidebarViewModel.onPageChange(SidebarItem.support),
+ ),
SideMenuItem(
imagePath: 'assets/images/settings_outline.png',
isSelected: desktopSidebarViewModel.currentPage == SidebarItem.settings,
diff --git a/lib/src/widgets/base_alert_dialog.dart b/lib/src/widgets/base_alert_dialog.dart
index b251e4b45..5c1111740 100644
--- a/lib/src/widgets/base_alert_dialog.dart
+++ b/lib/src/widgets/base_alert_dialog.dart
@@ -179,7 +179,7 @@ class BaseAlertDialog extends StatelessWidget {
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
- if (headerText != null) headerTitle(context),
+ if (headerText?.isNotEmpty ?? false) headerTitle(context),
Padding(
padding: EdgeInsets.fromLTRB(24, 20, 24, 0),
child: title(context),
diff --git a/lib/src/widgets/service_status_tile.dart b/lib/src/widgets/service_status_tile.dart
new file mode 100644
index 000000000..f2a079841
--- /dev/null
+++ b/lib/src/widgets/service_status_tile.dart
@@ -0,0 +1,71 @@
+import 'package:auto_size_text/auto_size_text.dart';
+import 'package:cake_wallet/entities/service_status.dart';
+import 'package:flutter/material.dart';
+import 'package:intl/intl.dart';
+
+class ServiceStatusTile extends StatelessWidget {
+ final ServiceStatus status;
+
+ const ServiceStatusTile(this.status, {super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return ListTile(
+ contentPadding: const EdgeInsets.all(8),
+ title: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 8),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Expanded(
+ child: AutoSizeText(
+ "${status.title}${status.status != null ? " - ${status.status}" : ""}",
+ style: TextStyle(
+ fontSize: 16,
+ fontFamily: 'Lato',
+ fontWeight: FontWeight.w800,
+ height: 1,
+ ),
+ maxLines: 1,
+ textAlign: TextAlign.start,
+ ),
+ ),
+ Text(
+ _getTimeString(status.date),
+ style: TextStyle(fontSize: 12),
+ ),
+ ],
+ ),
+ ),
+ leading: RotatedBox(
+ child: Icon(
+ Icons.info,
+ color: status.status == "resolved" ? Colors.green : Colors.red,
+ ),
+ quarterTurns: 2,
+ ),
+ subtitle: Row(
+ children: [
+ Expanded(child: Text(status.description)),
+ if (status.image != null)
+ SizedBox(
+ height: 50,
+ width: 50,
+ child: Image.network(status.image!),
+ ),
+ ],
+ ),
+ );
+ }
+
+ String _getTimeString(DateTime date) {
+ int difference = DateTime.now().difference(date).inHours;
+ if (difference == 0) {
+ return "few minutes ago";
+ }
+ if (difference < 24) {
+ return DateFormat('h:mm a').format(date);
+ }
+ return DateFormat('d-MM-yyyy').format(date);
+ }
+}
diff --git a/lib/src/widgets/services_updates_widget.dart b/lib/src/widgets/services_updates_widget.dart
new file mode 100644
index 000000000..9557ff6b9
--- /dev/null
+++ b/lib/src/widgets/services_updates_widget.dart
@@ -0,0 +1,122 @@
+import 'package:cake_wallet/di.dart';
+import 'package:cake_wallet/entities/preferences_key.dart';
+import 'package:cake_wallet/entities/service_status.dart';
+import 'package:cake_wallet/src/widgets/primary_button.dart';
+import 'package:cake_wallet/src/widgets/service_status_tile.dart';
+import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
+import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+class ServicesUpdatesWidget extends StatelessWidget {
+ final Future servicesResponse;
+
+ const ServicesUpdatesWidget(this.servicesResponse, {super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: FutureBuilder(
+ future: servicesResponse,
+ builder: (context, state) {
+ return InkWell(
+ onTap: state.hasData
+ ? () {
+ // save currentSha when the user see the status
+ getIt
+ .get()
+ .setString(PreferencesKey.serviceStatusShaKey, state.data!.currentSha);
+
+ showModalBottomSheet(
+ context: context,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(50),
+ topRight: Radius.circular(50),
+ ),
+ ),
+ constraints: BoxConstraints(
+ maxHeight: MediaQuery.of(context).size.height / 2,
+ minHeight: MediaQuery.of(context).size.height / 4,
+ ),
+ builder: (context) {
+ Widget body;
+ if (state.data!.servicesStatus.isEmpty) {
+ body = Center(
+ child: Text("Everything is up and running as expected"),
+ );
+ } else {
+ body = SingleChildScrollView(
+ child: Column(
+ children: state.data!.servicesStatus
+ .map((status) => ServiceStatusTile(status))
+ .toList()),
+ );
+ }
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 20),
+ child: Stack(
+ children: [
+ body,
+ Align(
+ alignment: Alignment.bottomCenter,
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ horizontal: MediaQuery.of(context).size.width / 8),
+ child: PrimaryImageButton(
+ onPressed: () {
+ try {
+ launchUrl(Uri.parse("https://status.cakewallet.com/"));
+ } catch (_) {}
+ },
+ image: Image.asset(
+ "assets/images/status_website_image.png",
+ color: Theme.of(context).brightness == Brightness.light
+ ? Colors.white
+ : null,
+ ),
+ text: "Status Website",
+ color: Theme.of(context)
+ .extension()!
+ .createNewWalletButtonBackgroundColor,
+ textColor: Theme.of(context)
+ .extension()!
+ .restoreWalletButtonTextColor,
+ ),
+ ),
+ )
+ ],
+ ),
+ );
+ },
+ );
+ }
+ : null,
+ child: Stack(
+ children: [
+ SvgPicture.asset(
+ "assets/images/notification_icon.svg",
+ color: Theme.of(context).extension()!.pageTitleTextColor,
+ width: 30,
+ ),
+ if (state.hasData && state.data!.hasUpdates)
+ Container(
+ height: 7,
+ width: 7,
+ margin: EdgeInsetsDirectional.only(start: 15),
+ decoration: BoxDecoration(
+ color: Colors.red,
+ shape: BoxShape.circle,
+ ),
+ ),
+ ],
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart
index da5eb0373..b02c09f82 100644
--- a/lib/view_model/dashboard/dashboard_view_model.dart
+++ b/lib/view_model/dashboard/dashboard_view_model.dart
@@ -4,8 +4,10 @@ import 'package:cake_wallet/buy/buy_provider.dart';
import 'package:cake_wallet/core/key_service.dart';
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
import 'package:cake_wallet/entities/balance_display_mode.dart';
+import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart';
+import 'package:cake_wallet/entities/service_status.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/monero/monero.dart';
@@ -42,7 +44,8 @@ import 'package:cw_core/wallet_type.dart';
import 'package:eth_sig_util/util/utils.dart';
import 'package:flutter/services.dart';
import 'package:mobx/mobx.dart';
-import 'package:cake_wallet/entities/provider_types.dart';
+import 'package:http/http.dart' as http;
+import 'package:shared_preferences/shared_preferences.dart';
part 'dashboard_view_model.g.dart';
@@ -59,6 +62,7 @@ abstract class DashboardViewModelBase with Store {
required this.yatStore,
required this.ordersStore,
required this.anonpayTransactionsStore,
+ required this.sharedPreferences,
required this.keyService})
: hasSellAction = false,
hasBuyAction = false,
@@ -280,6 +284,7 @@ abstract class DashboardViewModelBase with Store {
bool get hasRescan => wallet.type == WalletType.monero || wallet.type == WalletType.haven;
final KeyService keyService;
+ final SharedPreferences sharedPreferences;
BalanceViewModel balanceViewModel;
@@ -339,15 +344,13 @@ abstract class DashboardViewModelBase with Store {
bool hasExchangeAction;
@computed
- bool get isEnabledBuyAction =>
- !settingsStore.disableBuy && availableBuyProviders.isNotEmpty;
+ bool get isEnabledBuyAction => !settingsStore.disableBuy && availableBuyProviders.isNotEmpty;
@observable
bool hasBuyAction;
@computed
- bool get isEnabledSellAction =>
- !settingsStore.disableSell && availableSellProviders.isNotEmpty;
+ bool get isEnabledSellAction => !settingsStore.disableSell && availableSellProviders.isNotEmpty;
@observable
bool hasSellAction;
@@ -472,7 +475,8 @@ abstract class DashboardViewModelBase with Store {
Future> checkAffectedWallets() async {
// await load file
- final vulnerableSeedsString = await rootBundle.loadString('assets/text/cakewallet_weak_bitcoin_seeds_hashed_sorted_version1.txt');
+ final vulnerableSeedsString = await rootBundle
+ .loadString('assets/text/cakewallet_weak_bitcoin_seeds_hashed_sorted_version1.txt');
final vulnerableSeeds = vulnerableSeedsString.split("\n");
final walletInfoSource = await CakeHive.openBox(WalletInfo.boxName);
@@ -497,4 +501,29 @@ abstract class DashboardViewModelBase with Store {
return affectedWallets;
}
+
+ Future getServicesStatus() async {
+ try {
+ final res = await http.get(Uri.parse("https://service-api.cakewallet.com/v1/active-notices"));
+
+ if (res.statusCode < 200 || res.statusCode >= 300) {
+ throw res.body;
+ }
+
+ final oldSha = sharedPreferences.getString(PreferencesKey.serviceStatusShaKey);
+
+ final hash = await Cryptography.instance.sha256().hash(utf8.encode(res.body));
+ final currentSha = bytesToHex(hash.bytes);
+
+ final hasUpdates = oldSha != currentSha;
+
+ return ServicesResponse.fromJson(
+ json.decode(res.body) as Map,
+ hasUpdates,
+ currentSha,
+ );
+ } catch (_) {
+ return ServicesResponse([], false, '');
+ }
+ }
}
diff --git a/lib/view_model/dashboard/desktop_sidebar_view_model.dart b/lib/view_model/dashboard/desktop_sidebar_view_model.dart
index 543b44b35..52a6dc49b 100644
--- a/lib/view_model/dashboard/desktop_sidebar_view_model.dart
+++ b/lib/view_model/dashboard/desktop_sidebar_view_model.dart
@@ -5,6 +5,7 @@ part 'desktop_sidebar_view_model.g.dart';
enum SidebarItem {
dashboard,
transactions,
+ status,
support,
settings,
}
diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart
index 772150368..507ed14cc 100644
--- a/lib/view_model/send/send_view_model.dart
+++ b/lib/view_model/send/send_view_model.dart
@@ -427,9 +427,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
) {
if (walletType == WalletType.ethereum ||
walletType == WalletType.polygon ||
+ walletType == WalletType.solana ||
walletType == WalletType.haven) {
if (error.contains('gas required exceeds allowance') ||
- error.contains('insufficient funds for')) {
+ error.contains('insufficient funds')) {
return S.current.do_not_have_enough_gas_asset(currency.toString());
}
diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh
index fa3701fa7..eb1aaaacc 100644
--- a/scripts/android/app_env.sh
+++ b/scripts/android/app_env.sh
@@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.11.0"
-MONERO_COM_BUILD_NUMBER=77
+MONERO_COM_VERSION="1.11.1"
+MONERO_COM_BUILD_NUMBER=78
MONERO_COM_BUNDLE_ID="com.monero.app"
MONERO_COM_PACKAGE="com.monero.app"
MONERO_COM_SCHEME="monero.com"
CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.14.0"
-CAKEWALLET_BUILD_NUMBER=196
+CAKEWALLET_VERSION="4.14.1"
+CAKEWALLET_BUILD_NUMBER=197
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
CAKEWALLET_SCHEME="cakewallet"
diff --git a/scripts/android/build_monero.sh b/scripts/android/build_monero.sh
index e0010b351..fb596e452 100755
--- a/scripts/android/build_monero.sh
+++ b/scripts/android/build_monero.sh
@@ -1,13 +1,12 @@
#!/bin/sh
. ./config.sh
-MONERO_BRANCH=release-v0.18.2.2-android
+MONERO_BRANCH=release-v0.18.3.2-android
MONERO_SRC_DIR=${WORKDIR}/monero
git clone https://github.com/cake-tech/monero.git ${MONERO_SRC_DIR} --branch ${MONERO_BRANCH}
cd $MONERO_SRC_DIR
-git submodule init
-git submodule update
+git submodule update --init --force
for arch in "aarch" "aarch64" "i686" "x86_64"
do
@@ -59,7 +58,7 @@ cd $MONERO_SRC_DIR
rm -rf ./build/release
mkdir -p ./build/release
cd ./build/release
-CC=${CLANG} CXX=${CXXLANG} cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH=${ARCH} -D STATIC=ON -D BUILD_64=${BUILD_64} -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG=${TAG} -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARCH_ABI=${ARCH_ABI} $FLAGS ../..
+CC=${CLANG} CXX=${CXXLANG} cmake -D USE_DEVICE_TREZOR=OFF -D BUILD_GUI_DEPS=1 -D BUILD_TESTS=OFF -D ARCH=${ARCH} -D STATIC=ON -D BUILD_64=${BUILD_64} -D CMAKE_BUILD_TYPE=release -D ANDROID=true -D INSTALL_VENDORED_LIBUNBOUND=ON -D BUILD_TAG=${TAG} -D CMAKE_SYSTEM_NAME="Android" -D CMAKE_ANDROID_STANDALONE_TOOLCHAIN="${ANDROID_STANDALONE_TOOLCHAIN_PATH}" -D CMAKE_ANDROID_ARCH_ABI=${ARCH_ABI} -D MANUAL_SUBMODULES=1 $FLAGS ../..
make wallet_api -j$THREADS
find . -path ./lib -prune -o -name '*.a' -exec cp '{}' lib \;
diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh
index 31f0b9548..1c778063d 100644
--- a/scripts/ios/app_env.sh
+++ b/scripts/ios/app_env.sh
@@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_IOS_TYPE=$1
MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.11.0"
-MONERO_COM_BUILD_NUMBER=75
+MONERO_COM_VERSION="1.11.1"
+MONERO_COM_BUILD_NUMBER=76
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="4.14.0"
-CAKEWALLET_BUILD_NUMBER=215
+CAKEWALLET_VERSION="4.14.1"
+CAKEWALLET_BUILD_NUMBER=216
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
HAVEN_NAME="Haven"
diff --git a/scripts/ios/build_monero.sh b/scripts/ios/build_monero.sh
index 54dda546f..6f06f22c1 100755
--- a/scripts/ios/build_monero.sh
+++ b/scripts/ios/build_monero.sh
@@ -4,7 +4,7 @@
MONERO_URL="https://github.com/cake-tech/monero.git"
MONERO_DIR_PATH="${EXTERNAL_IOS_SOURCE_DIR}/monero"
-MONERO_VERSION=release-v0.18.2.2
+MONERO_VERSION=release-v0.18.3.2
BUILD_TYPE=release
PREFIX=${EXTERNAL_IOS_DIR}
DEST_LIB_DIR=${EXTERNAL_IOS_LIB_DIR}/monero
@@ -52,6 +52,7 @@ cmake -D IOS=ON \
-DUNBOUND_INCLUDE_DIR=${EXTERNAL_IOS_INCLUDE_DIR} \
-DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \
-DUSE_DEVICE_TREZOR=OFF \
+ -DMANUAL_SUBMODULES=1 \
../..
make wallet_api -j4
find . -path ./lib -prune -o -name '*.a' -exec cp '{}' lib \;
diff --git a/scripts/ios/build_sodium.sh b/scripts/ios/build_sodium.sh
index 66f383fb4..5632719ad 100755
--- a/scripts/ios/build_sodium.sh
+++ b/scripts/ios/build_sodium.sh
@@ -8,9 +8,10 @@ SODIUM_URL="https://github.com/jedisct1/libsodium.git"
echo "============================ SODIUM ============================"
echo "Cloning SODIUM from - $SODIUM_URL"
-git clone $SODIUM_URL $SODIUM_PATH --branch stable
+git clone $SODIUM_URL $SODIUM_PATH
cd $SODIUM_PATH
-./dist-build/ios.sh
+git checkout 443617d7507498f7477703f0b51cb596d4539262
+./dist-build/apple-xcframework.sh
-mv ${SODIUM_PATH}/libsodium-ios/include/* $EXTERNAL_IOS_INCLUDE_DIR
-mv ${SODIUM_PATH}/libsodium-ios/lib/* $EXTERNAL_IOS_LIB_DIR
\ No newline at end of file
+mv ${SODIUM_PATH}/libsodium-apple/ios/include/* $EXTERNAL_IOS_INCLUDE_DIR
+mv ${SODIUM_PATH}/libsodium-apple/ios/lib/* $EXTERNAL_IOS_LIB_DIR
\ No newline at end of file
diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh
index 4dec47f40..4c84832e6 100755
--- a/scripts/macos/app_env.sh
+++ b/scripts/macos/app_env.sh
@@ -16,13 +16,13 @@ if [ -n "$1" ]; then
fi
MONERO_COM_NAME="Monero.com"
-MONERO_COM_VERSION="1.1.0"
-MONERO_COM_BUILD_NUMBER=7
+MONERO_COM_VERSION="1.1.1"
+MONERO_COM_BUILD_NUMBER=9
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet"
-CAKEWALLET_VERSION="1.7.0"
-CAKEWALLET_BUILD_NUMBER=55
+CAKEWALLET_VERSION="1.7.1"
+CAKEWALLET_BUILD_NUMBER=56
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
diff --git a/scripts/macos/build_monero.sh b/scripts/macos/build_monero.sh
index c1ee0e5d3..1af7ae0e3 100755
--- a/scripts/macos/build_monero.sh
+++ b/scripts/macos/build_monero.sh
@@ -4,7 +4,7 @@
MONERO_URL="https://github.com/cake-tech/monero.git"
MONERO_DIR_PATH="${EXTERNAL_MACOS_SOURCE_DIR}/monero"
-MONERO_VERSION=release-v0.18.2.2
+MONERO_VERSION=release-v0.18.3.2
BUILD_TYPE=release
PREFIX=${EXTERNAL_MACOS_DIR}
DEST_LIB_DIR=${EXTERNAL_MACOS_LIB_DIR}/monero
@@ -46,6 +46,7 @@ cmake -DARCH=${ARCH} \
-DUNBOUND_INCLUDE_DIR=${EXTERNAL_MACOS_INCLUDE_DIR} \
-DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \
-DUSE_DEVICE_TREZOR=OFF \
+ -DMANUAL_SUBMODULES=1 \
../..
make wallet_api -j4
find . -path ./lib -prune -o -name '*.a' -exec cp '{}' lib \;