v5.1.0 Release Candidate (#2332)

* v5.1.0 Release Candidate

* update app versions [skip ci]

* separate secrets for Monero.com [skip ci]

* fix: amount getting wiped when pasting address

* update Trocador Monero api key [skip ci]

* move fiat api key to headers [skip ci]

* latest Release candidate
This commit is contained in:
Omar Hatem 2025-06-27 22:20:18 +03:00 committed by GitHub
parent 5aeb6b7522
commit c2cca1ff37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 95 additions and 70 deletions

View file

@ -6,6 +6,7 @@ import 'package:cake_wallet/anonpay/anonpay_status_response.dart';
import 'package:cake_wallet/core/fiat_conversion_service.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/exchange/limits.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/crypto_currency.dart';
@ -27,7 +28,7 @@ class AnonPayApi {
static const anonPayPath = '/anonpay';
static const anonPayStatus = '/anonpay/status';
static const coinPath = 'api/coin';
static const apiKey = secrets.trocadorApiKey;
static final apiKey = isMoneroOnly ? secrets.trocadorMoneroApiKey : secrets.trocadorApiKey;
Future<AnonpayStatusResponse> paymentStatus(String id) async {
final response = await ProxyWrapper().get(

View file

@ -14,7 +14,6 @@ Future<double> _fetchPrice(String crypto, String fiat, bool torOnly) async {
'interval_count': '1',
'base': crypto.split(".").first,
'quote': fiat,
'key': secrets.fiatApiKey,
};
num price = 0.0;
@ -26,6 +25,9 @@ Future<double> _fetchPrice(String crypto, String fiat, bool torOnly) async {
final response = await ProxyWrapper().get(
onionUri: onionUri,
clearnetUri: torOnly ? onionUri : clearnetUri,
headers: {
"x-api-key": secrets.fiatApiKey,
}
);

View file

@ -11,13 +11,12 @@ import 'package:cake_wallet/exchange/trade_request.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/distribution_info.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
class ChangeNowExchangeProvider extends ExchangeProvider {
ChangeNowExchangeProvider({required SettingsStore settingsStore})
: _settingsStore = settingsStore,
@ -30,7 +29,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
];
static final apiKey =
DeviceInfo.instance.isMobile ? secrets.changeNowApiKey : secrets.changeNowApiKeyDesktop;
isMoneroOnly ? secrets.changeNowMoneroApiKey : secrets.changeNowCakeWalletApiKey;
static const apiAuthority = 'api.changenow.io';
static const createTradePath = '/v2/exchange';
static const findTradeByIdPath = '/v2/exchange/by-id';
@ -74,7 +73,6 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
};
final uri = Uri.https(apiAuthority, rangePath, params);
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
if (response.statusCode == 400) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@ -120,7 +118,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
final uri = Uri.https(apiAuthority, estimatedAmountPath, params);
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final fromAmount = double.parse(responseJSON['fromAmount'].toString());
final toAmount = double.parse(responseJSON['toAmount'].toString());
@ -184,7 +182,6 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
headers: headers,
body: json.encode(body),
);
if (response.statusCode == 400) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@ -228,7 +225,6 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
final params = <String, String>{'id': id};
final uri = Uri.https(apiAuthority, findTradeByIdPath, params);
final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers);
if (response.statusCode == 404) throw TradeNotFoundException(id, provider: description);

View file

@ -9,6 +9,7 @@ import 'package:cake_wallet/exchange/trade_not_found_exception.dart';
import 'package:cake_wallet/exchange/trade_request.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
@ -16,7 +17,7 @@ import 'package:cw_core/utils/print_verbose.dart';
class ExolixExchangeProvider extends ExchangeProvider {
ExolixExchangeProvider() : super(pairList: supportedPairs(_notSupported));
static final apiKey = secrets.exolixApiKey;
static final apiKey = isMoneroOnly ? secrets.exolixMoneroApiKey : secrets.exolixCakeWalletApiKey;
static const apiBaseUrl = 'exolix.com';
static const transactionsPath = '/api/v2/transactions';
static const ratePath = '/api/v2/rate';

View file

@ -8,6 +8,7 @@ import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/exchange/trade_request.dart';
import 'package:cake_wallet/exchange/trade_state.dart';
import 'package:cake_wallet/exchange/utils/currency_pairs_utils.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
@ -51,7 +52,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
CryptoCurrency.zaddr,
];
static const apiKey = secrets.trocadorApiKey;
static final apiKey = isMoneroOnly ? secrets.trocadorMoneroApiKey : secrets.trocadorApiKey;
static const clearNetAuthority = 'api.trocador.app';
static const onionApiAuthority = clearNetAuthority;
// static const onionApiAuthority = 'trocadorfyhlu27aefre5u7zri66gudtzdyelymftvr4yjwcxhfaqsid.onion';

View file

@ -10,11 +10,11 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:url_launcher/url_launcher.dart';
class CakeFeaturesPage extends StatelessWidget {
CakeFeaturesPage(
{required this.dashboardViewModel, required this.cakeFeaturesViewModel});
CakeFeaturesPage({required this.dashboardViewModel, required this.cakeFeaturesViewModel});
final DashboardViewModel dashboardViewModel;
final CakeFeaturesViewModel cakeFeaturesViewModel;
@ -59,23 +59,26 @@ class CakeFeaturesPage extends StatelessWidget {
fit: BoxFit.cover,
),
),
if (dashboardViewModel.type == WalletType.ethereum) ...[
DashBoardRoundedCardWidget(
isDarkTheme: dashboardViewModel.isDarkTheme,
shadowBlur: dashboardViewModel.getShadowBlur(),
shadowSpread: dashboardViewModel.getShadowSpread(),
onTap: () =>
Navigator.of(context).pushNamed(Routes.dEuroSavings),
title: S.of(context).deuro_savings,
subTitle: S.of(context).deuro_savings_subtitle,
image: Image.asset(
'assets/images/deuro_icon.png',
height: 80,
width: 80,
fit: BoxFit.cover,
),
),
],
Observer(builder: (_) {
if (dashboardViewModel.type == WalletType.ethereum) {
return DashBoardRoundedCardWidget(
isDarkTheme: dashboardViewModel.isDarkTheme,
shadowBlur: dashboardViewModel.getShadowBlur(),
shadowSpread: dashboardViewModel.getShadowSpread(),
onTap: () => Navigator.of(context).pushNamed(Routes.dEuroSavings),
title: S.of(context).deuro_savings,
subTitle: S.of(context).deuro_savings_subtitle,
image: Image.asset(
'assets/images/deuro_icon.png',
height: 80,
width: 80,
fit: BoxFit.cover,
),
);
}
return const SizedBox();
}),
DashBoardRoundedCardWidget(
isDarkTheme: dashboardViewModel.isDarkTheme,
shadowBlur: dashboardViewModel.getShadowBlur(),

View file

@ -302,7 +302,8 @@ class ExchangeCardState<T extends Currency> extends State<ExchangeCard<T>> {
final paymentRequest = PaymentRequest.fromUri(uri);
addressController.text = paymentRequest.address;
if (amountController.text.isNotEmpty) {
if (amountController.text.isNotEmpty &&
paymentRequest.amount.isNotEmpty) {
_showAmountPopup(context, paymentRequest);
return;
}

View file

@ -263,11 +263,17 @@ class AddressTextField<T extends Currency> extends StatelessWidget {
final address = clipboard?.text ?? '';
if (address.isNotEmpty) {
try {
final uri = Uri.parse(address);
controller?.text = uri.path;
onURIScanned?.call(uri);
} catch (_) {
// if it has query parameters then it's a valid uri
// added because Uri.parse(address) can parse a normal address string and would still be valid
if (address.contains("=")) {
try {
final uri = Uri.parse(address);
controller?.text = uri.path;
onURIScanned?.call(uri);
} catch (_) {
controller?.text = address;
}
} else {
controller?.text = address;
}
}