v4.25.0 Release Candidate (#2153)

* v4.25.0 Release Candidate * update rest of platforms version [skip ci] * replace macos icons [skip ci] * fix: incorrect balance reporting (#2155) * fix: monero frozen coins, call updateSendingBalance, display "ALL" balance properly * fix: decred formatting on send page --------- Co-authored-by: cyan <cyjan@mrcyjanek.net>

Omar Hatem committed Apr 4, 2025 at 00:49 UTC 24ec5fa7fd3bc4b08dbf769e6005e5e1e3054707
21 files changed +99 -79
assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_1024.png
Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_1024.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_1024.png differ
assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_128.png
Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_128.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_128.png differ
assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_16.png
Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_16.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_16.png differ
assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_256.png
Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_256.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_256.png differ
assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_32.png
Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_32.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_32.png differ
assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_512.png
Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_512.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_512.png differ
assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_64.png
Binary files a/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_64.png and b/assets/images/macos_icons/cakewallet_macos_icons/cakewallet_macos_64.png differ
assets/text/Monerocom_Release_Notes.txt
+2 -4
@@ -1,5 +1,3 @@
1 -Add background sync to Monero
2 -Enhance Backup files
3 -Improve app usability and user experience
4 -User interface enhancements
1 +UI/UX enhancements
2 +Performance improvements
3 Bug fixes
\ No newline at end of file
assets/text/Release_Notes.txt
+3 -7
@@ -1,8 +1,4 @@
1 -Add background sync to Monero
2 -Add Decred Wallet
3 -Remove Haven Wallet
4 -Fix and Improve Solana Wallet
5 -Enhance Backup files
6 -Improve app usability and user experience
7 -User interface enhancements
1 +New App Logo
2 +UI/UX enhancements
3 +Performance improvements
4 Bug fixes
\ No newline at end of file
cw_decred/lib/wallet.dart
+4
@@ -4,6 +4,7 @@ import 'dart:io';
4 import 'package:cw_core/exceptions.dart';
5 import 'package:cw_core/transaction_direction.dart';
6 import 'package:cw_core/utils/print_verbose.dart';
7 +import 'package:cw_decred/amount_format.dart';
8 import 'package:cw_decred/pending_transaction.dart';
9 import 'package:cw_decred/transaction_credentials.dart';
10 import 'package:flutter/foundation.dart';
@@ -122,6 +123,9 @@ abstract class DecredWalletBase
123 return _pubkey;
124 }
125
126 + @override
127 + String formatCryptoAmount(String amount) => decredAmountToString(amount: int.parse(amount));
128 +
129 Future<void> init() async {
130 final getSeed = () async {
131 if (!watchingOnly) {
cw_monero/lib/monero_unspent.dart
+18 -7
@@ -4,21 +4,32 @@ import 'package:cw_monero/api/coins_info.dart';
4 import 'package:monero/monero.dart' as monero;
5
6 class MoneroUnspent extends Unspent {
7 + static Future<MoneroUnspent> fromUnspent(String address, String hash, String keyImage, int value, bool isFrozen, bool isUnlocked) async {
8 + return MoneroUnspent(
9 + address: address,
10 + hash: hash,
11 + keyImage: keyImage,
12 + value: value,
13 + isFrozen: isFrozen,
14 + isUnlocked: isUnlocked);
15 + }
16 +
17 MoneroUnspent(
8 - String address, String hash, String keyImage, int value, bool isFrozen, this.isUnlocked)
18 + {required String address,
19 + required String hash,
20 + required String keyImage,
21 + required int value,
22 + required bool isFrozen,
23 + required this.isUnlocked})
24 : super(address, hash, value, 0, keyImage) {
10 - getCoinByKeyImage(keyImage).then((coinId) {
11 - if (coinId == null) return;
12 - getCoin(coinId).then((coin) {
13 - _frozen = monero.CoinsInfo_frozen(coin);
14 - });
15 - });
25 + _frozen = isFrozen;
26 }
27
28 bool _frozen = false;
29
30 @override
31 set isFrozen(bool freeze) {
32 + _frozen = freeze;
33 printV("set isFrozen: $freeze ($keyImage): $freeze");
34 getCoinByKeyImage(keyImage!).then((coinId) async {
35 if (coinId == null) return;
cw_monero/lib/monero_wallet.dart
+1 -1
@@ -592,7 +592,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
592 final coin = await getCoin(i);
593 final coinSpent = monero.CoinsInfo_spent(coin);
594 if (coinSpent == false && monero.CoinsInfo_subaddrAccount(coin) == walletAddresses.account!.id) {
595 - final unspent = MoneroUnspent(
595 + final unspent = await MoneroUnspent.fromUnspent(
596 monero.CoinsInfo_address(coin),
597 monero.CoinsInfo_hash(coin),
598 monero.CoinsInfo_keyImage(coin),
lib/src/screens/dashboard/pages/transactions_page.dart
+11 -15
@@ -45,20 +45,17 @@ class TransactionsPage extends StatelessWidget {
45 Observer(builder: (_) {
46 final status = dashboardViewModel.status;
47 if (status is SyncingSyncStatus) {
48 - return Padding(
49 - padding: const EdgeInsets.fromLTRB(24, 0, 24, 8),
50 - child: DashBoardRoundedCardWidget(
51 - key: ValueKey('transactions_page_syncing_alert_card_key'),
52 - onTap: () {
53 - try {
54 - final uri = Uri.parse(
55 - "https://docs.cakewallet.com/faq/funds-not-appearing");
56 - launchUrl(uri, mode: LaunchMode.externalApplication);
57 - } catch (_) {}
58 - },
59 - title: S.of(context).syncing_wallet_alert_title,
60 - subTitle: S.of(context).syncing_wallet_alert_content,
61 - ),
48 + return DashBoardRoundedCardWidget(
49 + key: ValueKey('transactions_page_syncing_alert_card_key'),
50 + onTap: () {
51 + try {
52 + final uri = Uri.parse(
53 + "https://docs.cakewallet.com/faq/funds-not-appearing");
54 + launchUrl(uri, mode: LaunchMode.externalApplication);
55 + } catch (_) {}
56 + },
57 + title: S.of(context).syncing_wallet_alert_title,
58 + subTitle: S.of(context).syncing_wallet_alert_content,
59 );
60 } else {
61 return Container();
@@ -72,7 +69,6 @@ class TransactionsPage extends StatelessWidget {
69 child: Observer(
70 builder: (_) {
71 final items = dashboardViewModel.items;
75 - final amount = items.length + 1;
72 return items.isNotEmpty
73 ? ListView.builder(
74 key: ValueKey('transactions_page_list_view_builder_key'),
lib/src/screens/send/widgets/send_card.dart
+38 -26
@@ -94,6 +94,9 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
94 @override
95 void initState() {
96 super.initState();
97 + WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
98 + sendViewModel.updateSendingBalance();
99 + });
100
101 /// if the current wallet doesn't match the one in the qr code
102 if (initialPaymentRequest != null &&
@@ -244,38 +247,47 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
247 currencyValueValidator: output.sendAll
248 ? sendViewModel.allAmountValidator
249 : sendViewModel.amountValidator,
247 - allAmountCallback: () async => output.setSendAll(sendViewModel.sendingBalance)),
250 + allAmountCallback: () async => output.setSendAll(await sendViewModel.sendingBalance)),
251 Divider(
252 height: 1,
253 color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
254 Observer(
252 - builder: (_) => Padding(
253 - padding: EdgeInsets.only(top: 10),
254 - child: Row(
255 - mainAxisSize: MainAxisSize.max,
256 - mainAxisAlignment: MainAxisAlignment.spaceBetween,
257 - children: <Widget>[
258 - Expanded(
259 - child: Text(
260 - S.of(context).available_balance + ':',
261 - style: TextStyle(
255 + builder: (_) {
256 + // force rebuild on mobx
257 + final _ = sendViewModel.coinTypeToSpendFrom;
258 + return Padding(
259 + padding: EdgeInsets.only(top: 10),
260 + child: Row(
261 + mainAxisSize: MainAxisSize.max,
262 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
263 + children: <Widget>[
264 + Expanded(
265 + child: Text(
266 + S.of(context).available_balance + ':',
267 + style: TextStyle(
268 + fontSize: 12,
269 + fontWeight: FontWeight.w600,
270 + color:
271 + Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
272 + ),
273 + ),
274 + FutureBuilder<String>(
275 + future: sendViewModel.sendingBalance,
276 + builder: (context, snapshot) {
277 + return Text(
278 + snapshot.data ?? sendViewModel.balance, // default to balance while loading
279 + style: TextStyle(
280 fontSize: 12,
281 fontWeight: FontWeight.w600,
282 color:
283 Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
266 - ),
267 - ),
268 - Text(
269 - sendViewModel.sendingBalance,
270 - style: TextStyle(
271 - fontSize: 12,
272 - fontWeight: FontWeight.w600,
273 - color:
274 - Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
275 - )
276 - ],
277 - ),
278 - ),
284 + );
285 + },
286 + )
287 + ],
288 + ),
289 + );
290 + },
291 ),
292 if (!sendViewModel.isFiatDisabled)
293 CurrencyAmountTextField(
@@ -509,9 +521,9 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
521 }
522 });
523
512 - reaction((_) => sendViewModel.selectedCryptoCurrency, (Currency currency) {
524 + reaction((_) => sendViewModel.selectedCryptoCurrency, (Currency currency) async {
525 if (output.sendAll) {
514 - output.setSendAll(sendViewModel.sendingBalance);
526 + output.setSendAll(await sendViewModel.sendingBalance);
527 }
528
529 output.setCryptoAmount(cryptoAmountController.text);
lib/view_model/send/send_view_model.dart
+2 -2
@@ -245,7 +245,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
245 }
246
247 @computed
248 - String get sendingBalance {
248 + Future<String> get sendingBalance async {
249 // only for electrum, monero, wownero, decred wallets atm:
250 switch (wallet.type) {
251 case WalletType.bitcoin:
@@ -255,7 +255,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
255 case WalletType.wownero:
256 case WalletType.decred:
257 return wallet.formatCryptoAmount(
258 - unspentCoinsListViewModel.getSendingBalance(coinTypeToSpendFrom).toString());
258 + (await unspentCoinsListViewModel.getSendingBalance(coinTypeToSpendFrom)).toString());
259 default:
260 return balance;
261 }
lib/view_model/unspent_coins/unspent_coins_list_view_model.dart
+5 -2
@@ -149,12 +149,15 @@ abstract class UnspentCoinsListViewModelBase with Store {
149 }
150
151 @action
152 - int getSendingBalance(UnspentCoinType overrideCoinTypeToSpendFrom) {
152 + Future<int> getSendingBalance(UnspentCoinType overrideCoinTypeToSpendFrom) async {
153 // return items.where((element) => element.isSending).fold(0, (previousValue, element) => previousValue + element.value);
154 // go through all unspent coins and add up the value minus frozen and non sending:
155 int total = 0;
156 -
156 + await _updateUnspents();
157 + Set<String> seen = {};
158 for (final item in _getSpecificUnspents(overrideCoinTypeToSpendFrom)) {
159 + if (seen.contains(item.hash)) continue;
160 + seen.add(item.hash);
161 if (item.isFrozen || !item.isSending) continue;
162 total += item.value;
163 }
scripts/android/app_env.sh
+4 -4
@@ -14,15 +14,15 @@ TYPES=($MONERO_COM $CAKEWALLET)
14 APP_ANDROID_TYPE=$1
15
16 MONERO_COM_NAME="Monero.com"
17 -MONERO_COM_VERSION="1.21.0"
18 -MONERO_COM_BUILD_NUMBER=116
17 +MONERO_COM_VERSION="4.25.0"
18 +MONERO_COM_BUILD_NUMBER=118
19 MONERO_COM_BUNDLE_ID="com.monero.app"
20 MONERO_COM_PACKAGE="com.monero.app"
21 MONERO_COM_SCHEME="monero.com"
22
23 CAKEWALLET_NAME="Cake Wallet"
24 -CAKEWALLET_VERSION="5.0.0"
25 -CAKEWALLET_BUILD_NUMBER=254
24 +CAKEWALLET_VERSION="4.25.0"
25 +CAKEWALLET_BUILD_NUMBER=255
26 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
27 CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
28 CAKEWALLET_SCHEME="cakewallet"
scripts/ios/app_env.sh
+4 -4
@@ -12,13 +12,13 @@ TYPES=($MONERO_COM $CAKEWALLET)
12 APP_IOS_TYPE=$1
13
14 MONERO_COM_NAME="Monero.com"
15 -MONERO_COM_VERSION="1.21.0"
16 -MONERO_COM_BUILD_NUMBER=114
15 +MONERO_COM_VERSION="4.25.0"
16 +MONERO_COM_BUILD_NUMBER=115
17 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
18
19 CAKEWALLET_NAME="Cake Wallet"
20 -CAKEWALLET_VERSION="5.0.0"
21 -CAKEWALLET_BUILD_NUMBER=308
20 +CAKEWALLET_VERSION="4.25.0"
21 +CAKEWALLET_BUILD_NUMBER=309
22 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
23
24
scripts/linux/app_env.sh
+2 -2
@@ -14,8 +14,8 @@ if [ -n "$1" ]; then
14 fi
15
16 CAKEWALLET_NAME="Cake Wallet"
17 -CAKEWALLET_VERSION="1.14.0"
18 -CAKEWALLET_BUILD_NUMBER=50
17 +CAKEWALLET_VERSION="4.25.0"
18 +CAKEWALLET_BUILD_NUMBER=51
19
20 if ! [[ " ${TYPES[*]} " =~ " ${APP_LINUX_TYPE} " ]]; then
21 echo "Wrong app type."
scripts/macos/app_env.sh
+4 -4
@@ -16,13 +16,13 @@ if [ -n "$1" ]; then
16 fi
17
18 MONERO_COM_NAME="Monero.com"
19 -MONERO_COM_VERSION="1.11.0"
20 -MONERO_COM_BUILD_NUMBER=46
19 +MONERO_COM_VERSION="4.25.0"
20 +MONERO_COM_BUILD_NUMBER=47
21 MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
22
23 CAKEWALLET_NAME="Cake Wallet"
24 -CAKEWALLET_VERSION="1.17.0"
25 -CAKEWALLET_BUILD_NUMBER=108
24 +CAKEWALLET_VERSION="4.25.0"
25 +CAKEWALLET_BUILD_NUMBER=109
26 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
27
28 if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
scripts/windows/build_exe_installer.iss
+1 -1
@@ -1,5 +1,5 @@
1 #define MyAppName "Cake Wallet"
2 -#define MyAppVersion "0.5.0"
2 +#define MyAppVersion "4.25.0"
3 #define MyAppPublisher "Cake Labs LLC"
4 #define MyAppURL "https://cakewallet.com/"
5 #define MyAppExeName "CakeWallet.exe"