Fix issues from code review

This commit is contained in:
Godwin Asuquo 2023-03-01 23:44:15 +02:00
parent dbfbadffda
commit b0175719b9
11 changed files with 165 additions and 83 deletions

View file

@ -78,14 +78,6 @@ jobs:
cd /opt/android/cake_wallet
flutter packages pub run tool/generate_localization.dart
- name: Upgrade flutter packages
run: |
cd /opt/android/cake_wallet
cd cw_core && flutter pub upgrade && cd ..
cd cw_monero && flutter pub upgrade && cd ..
cd cw_bitcoin && flutter pub upgrade && cd ..
cd cw_haven && flutter pub upgrade && cd ..
- name: Build generated code
run: |
cd /opt/android/cake_wallet

View file

@ -1,10 +1,12 @@
import 'dart:io' show File, Platform;
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
import 'package:share_plus/share_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cw_core/wallet_type.dart';
@ -142,7 +144,9 @@ Future defaultSettingsMigration(
case 19:
await validateBitcoinSavedTransactionPriority(sharedPreferences);
break;
case 20:
await migrateExchangeStatus(sharedPreferences);
break;
default:
break;
}
@ -501,3 +505,13 @@ Future<void> changeDefaultHavenNode(
await node.save();
});
}
Future<void> migrateExchangeStatus(SharedPreferences sharedPreferences) async {
final isExchangeDisabled = sharedPreferences.getBool(PreferencesKey.disableExchangeKey);
if (isExchangeDisabled == null) {
return;
}
await sharedPreferences.setInt(PreferencesKey.exchangeStatusKey, isExchangeDisabled
? ExchangeApiMode.disabled.raw : ExchangeApiMode.enabled.raw);
}

View file

@ -0,0 +1,39 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cw_core/enumerable_item.dart';
class ExchangeApiMode extends EnumerableItem<int> with Serializable<int> {
const ExchangeApiMode({required String title, required int raw}) : super(title: title, raw: raw);
static const all = [ExchangeApiMode.enabled, ExchangeApiMode.torOnly, ExchangeApiMode.disabled];
static const enabled = ExchangeApiMode(raw: 0, title: 'Enabled');
static const torOnly = ExchangeApiMode(raw: 1, title: 'Tor only');
static const disabled = ExchangeApiMode(raw: 2, title: 'Disabled');
static ExchangeApiMode deserialize({required int raw}) {
switch (raw) {
case 0:
return enabled;
case 1:
return torOnly;
case 2:
return disabled;
default:
throw Exception('Unexpected token: $raw for ExchangeApiMode deserialize');
}
}
@override
String toString() {
switch (this) {
case ExchangeApiMode.enabled:
return S.current.enabled;
case ExchangeApiMode.torOnly:
return S.current.tor_only;
case ExchangeApiMode.disabled:
return S.current.disabled;
default:
return '';
}
}
}

View file

@ -14,7 +14,7 @@ abstract class ExchangeProvider {
bool get isAvailable;
bool get isEnabled;
bool get supportsFixedRate;
bool get shouldUseOnionAddress => false;
bool get supportsOnionAddress => false;
@override
String toString() => title;

View file

@ -13,10 +13,12 @@ import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:http/http.dart';
class TrocadorExchangeProvider extends ExchangeProvider {
TrocadorExchangeProvider()
TrocadorExchangeProvider({this.useTorOnly = false})
: _lastUsedRateId = '',
super(pairList: _supportedPairs());
bool useTorOnly;
static const List<CryptoCurrency> _notSupported = [
CryptoCurrency.scrt,
CryptoCurrency.stx,
@ -83,7 +85,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
params['id'] = _lastUsedRateId;
}
final String apiAuthority = shouldUseOnionAddress ? await _getAuthority() : clearNetAuthority;
final String apiAuthority = await _getAuthority();
final uri = Uri.https(apiAuthority, createTradePath, params);
final response = await get(uri);
@ -142,7 +144,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
'name': from.name,
};
final String apiAuthority = shouldUseOnionAddress ? await _getAuthority() : clearNetAuthority;
final String apiAuthority = await _getAuthority();
final uri = Uri.https(apiAuthority, coinPath, params);
final response = await get(uri);
@ -178,7 +180,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
return 0.0;
}
final String apiAuthority = shouldUseOnionAddress ? await _getAuthority() : clearNetAuthority;
final String apiAuthority = await _getAuthority();
final params = <String, String>{
'api_key': apiKey,
@ -214,7 +216,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
@override
Future<Trade> findTradeById({required String id}) async {
final String apiAuthority = shouldUseOnionAddress ? await _getAuthority() : clearNetAuthority;
final String apiAuthority = await _getAuthority();
final uri = Uri.https(apiAuthority, tradePath, {'api_key': apiKey, 'id': id});
return get(uri).then((response) {
if (response.statusCode != 200) {
@ -265,7 +267,7 @@ class TrocadorExchangeProvider extends ExchangeProvider {
bool get supportsFixedRate => true;
@override
bool get shouldUseOnionAddress => true;
bool get supportsOnionAddress => true;
@override
String get title => 'Trocador';
@ -297,11 +299,21 @@ class TrocadorExchangeProvider extends ExchangeProvider {
}
Future<String> _getAuthority() async {
if(!supportsOnionAddress){
return clearNetAuthority;
}
try {
if (useTorOnly) {
return onionApiAuthority;
}
final uri = Uri.https(onionApiAuthority, '/api/trade');
await get(uri);
return onionApiAuthority;
} catch (e) {
return clearNetAuthority;
}
}

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
@ -48,28 +49,36 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
padding: EdgeInsets.only(top: 24),
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Observer(
builder: (_) => Column(
content: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SettingsChoicesCell(
ChoicesListItem<FiatApiMode>(
title: S.current.fiat_api,
items: FiatApiMode.all,
selectedItem: widget.privacySettingsViewModel.fiatApi,
onItemSelected: (FiatApiMode mode) =>
widget.privacySettingsViewModel.setFiatMode(mode),
Observer(
builder: (_) {
return SettingsSwitcherCell(
title: S.current.disable_fiat,
value: widget.privacySettingsViewModel.fiatApi == FiatApiMode.disabled,
onValueChange: (BuildContext context, bool value) {
widget.privacySettingsViewModel.setFiatMode(value);
});
}
),
),
SettingsChoicesCell(
ChoicesListItem<FiatApiMode>(
Observer(
builder: (_) {
return SettingsChoicesCell(
ChoicesListItem<ExchangeApiMode>(
title: S.current.exchange,
items: FiatApiMode.all,
items: ExchangeApiMode.all,
selectedItem: widget.privacySettingsViewModel.exchangeStatus,
onItemSelected: (FiatApiMode mode) =>
onItemSelected: (ExchangeApiMode mode) =>
widget.privacySettingsViewModel.setEnableExchange(mode),
),
);
}
),
Observer(
builder: (_) {
return Column(
children: [
SettingsSwitcherCell(
title: S.current.add_custom_node,
value: widget.privacySettingsViewModel.addCustomNode,
@ -84,7 +93,11 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
),
)
],
);
}
),
],
),
bottomSectionPadding: EdgeInsets.all(24),
bottomSection: Column(

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
@ -24,20 +25,18 @@ class PrivacyPage extends BasePage {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
SettingsSwitcherCell(
title: S.current.disable_fiat,
value: _privacySettingsViewModel.isFiatDisabled,
onValueChange: (BuildContext context, bool value) {
_privacySettingsViewModel.setFiatMode(value);
}),
SettingsChoicesCell(
ChoicesListItem<FiatApiMode>(
title: S.current.fiat_api,
items: FiatApiMode.all,
selectedItem: _privacySettingsViewModel.fiatApi,
onItemSelected: (FiatApiMode mode) => _privacySettingsViewModel.setFiatMode(mode),
),
),
SettingsChoicesCell(
ChoicesListItem<FiatApiMode>(
ChoicesListItem<ExchangeApiMode>(
title: S.current.exchange,
items: FiatApiMode.all,
items: ExchangeApiMode.all,
selectedItem: _privacySettingsViewModel.exchangeStatus,
onItemSelected: (FiatApiMode mode) => _privacySettingsViewModel.setEnableExchange(mode),
onItemSelected: (ExchangeApiMode mode) => _privacySettingsViewModel.setEnableExchange(mode),
),
),
SettingsSwitcherCell(

View file

@ -1,4 +1,5 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/pin_code_required_duration.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cw_core/transaction_priority.dart';
@ -31,7 +32,7 @@ abstract class SettingsStoreBase with Store {
required bool initialSaveRecipientAddress,
required FiatApiMode initialFiatMode,
required bool initialAllowBiometricalAuthentication,
required FiatApiMode initialExchangeStatus,
required ExchangeApiMode initialExchangeStatus,
required ThemeBase initialTheme,
required int initialPinLength,
required String initialLanguageCode,
@ -154,7 +155,7 @@ abstract class SettingsStoreBase with Store {
reaction(
(_) => exchangeStatus,
(FiatApiMode mode) => sharedPreferences.setInt(
(ExchangeApiMode mode) => sharedPreferences.setInt(
PreferencesKey.exchangeStatusKey, mode.serialize()));
this
@ -192,7 +193,7 @@ abstract class SettingsStoreBase with Store {
bool allowBiometricalAuthentication;
@observable
FiatApiMode exchangeStatus;
ExchangeApiMode exchangeStatus;
@observable
ThemeBase currentTheme;
@ -284,9 +285,9 @@ abstract class SettingsStoreBase with Store {
final allowBiometricalAuthentication = sharedPreferences
.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ??
false;
final exchangeStatus = FiatApiMode.deserialize(
final exchangeStatus = ExchangeApiMode.deserialize(
raw: sharedPreferences
.getInt(PreferencesKey.exchangeStatusKey) ?? FiatApiMode.enabled.raw);
.getInt(PreferencesKey.exchangeStatusKey) ?? ExchangeApiMode.enabled.raw);
final legacyTheme =
(sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy) ?? false)
? ThemeType.dark.index
@ -401,9 +402,9 @@ abstract class SettingsStoreBase with Store {
allowBiometricalAuthentication = sharedPreferences
.getBool(PreferencesKey.allowBiometricalAuthenticationKey) ??
allowBiometricalAuthentication;
exchangeStatus = FiatApiMode.deserialize(
exchangeStatus = ExchangeApiMode.deserialize(
raw: sharedPreferences
.getInt(PreferencesKey.exchangeStatusKey) ?? FiatApiMode.enabled.raw);
.getInt(PreferencesKey.exchangeStatusKey) ?? ExchangeApiMode.enabled.raw);
final legacyTheme =
(sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy) ?? false)
? ThemeType.dark.index

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cw_core/wallet_type.dart';
@ -12,7 +13,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
AdvancedPrivacySettingsViewModelBase(this.type, this._settingsStore) : _addCustomNode = false;
@computed
FiatApiMode get exchangeStatus => _settingsStore.exchangeStatus;
ExchangeApiMode get exchangeStatus => _settingsStore.exchangeStatus;
@computed
FiatApiMode get fiatApi => _settingsStore.fiatApiMode;
@ -28,12 +29,16 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
bool get addCustomNode => _addCustomNode;
@action
void setFiatMode(FiatApiMode value) {
_settingsStore.fiatApiMode = value;
void setFiatMode(bool value) {
if (value) {
_settingsStore.fiatApiMode = FiatApiMode.disabled;
return;
}
_settingsStore.fiatApiMode = FiatApiMode.enabled;
}
@action
void setEnableExchange(FiatApiMode value) {
void setEnableExchange(ExchangeApiMode value) {
_settingsStore.exchangeStatus = value;
}

View file

@ -56,6 +56,7 @@ abstract class ExchangeViewModelBase with Store {
isDepositAddressEnabled = false,
isReceiveAddressEnabled = false,
isReceiveAmountEditable = false,
_providerUseTorOnly = false,
receiveCurrencies = <CryptoCurrency>[],
depositCurrencies = <CryptoCurrency>[],
limits = Limits(min: 0, max: 0),
@ -65,6 +66,7 @@ abstract class ExchangeViewModelBase with Store {
depositCurrency = wallet.currency,
providerList = [],
selectedProviders = ObservableList<ExchangeProvider>() {
_providerUseTorOnly = _settingsStore.exchangeStatus == FiatApiMode.torOnly;
_setProviders();
const excludeDepositCurrencies = [CryptoCurrency.btt, CryptoCurrency.nano];
const excludeReceiveCurrencies = [CryptoCurrency.xlm, CryptoCurrency.xrp,
@ -121,18 +123,18 @@ abstract class ExchangeViewModelBase with Store {
_calculateBestRate();
});
}
bool _providerUseTorOnly;
final WalletBase wallet;
final Box<Trade> trades;
final ExchangeTemplateStore _exchangeTemplateStore;
final TradesStore tradesStore;
final SharedPreferences sharedPreferences;
final _allProviders = [
List<ExchangeProvider> get _allProviders => [
ChangeNowExchangeProvider(),
SideShiftExchangeProvider(),
SimpleSwapExchangeProvider(),
TrocadorExchangeProvider(),
TrocadorExchangeProvider(useTorOnly: _providerUseTorOnly),
];
@observable
@ -695,7 +697,7 @@ abstract class ExchangeViewModelBase with Store {
void _setProviders(){
if (_settingsStore.exchangeStatus == FiatApiMode.torOnly) {
providerList = _allProviders.where((provider) => provider.shouldUseOnionAddress).toList();
providerList = _allProviders.where((provider) => provider.supportsOnionAddress).toList();
} else {
providerList = _allProviders;
}

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
@ -12,23 +13,27 @@ abstract class PrivacySettingsViewModelBase with Store {
final SettingsStore _settingsStore;
@computed
FiatApiMode get exchangeStatus => _settingsStore.exchangeStatus;
ExchangeApiMode get exchangeStatus => _settingsStore.exchangeStatus;
@computed
bool get shouldSaveRecipientAddress => _settingsStore.shouldSaveRecipientAddress;
@computed
FiatApiMode get fiatApi => _settingsStore.fiatApiMode;
bool get isFiatDisabled => _settingsStore.fiatApiMode == FiatApiMode.disabled;
@action
void setShouldSaveRecipientAddress(bool value) => _settingsStore.shouldSaveRecipientAddress = value;
@action
void setEnableExchange(FiatApiMode value) => _settingsStore.exchangeStatus = value;
void setEnableExchange(ExchangeApiMode value) => _settingsStore.exchangeStatus = value;
@action
void setFiatMode(FiatApiMode value) {
_settingsStore.fiatApiMode = value;
void setFiatMode(bool value) {
if (value) {
_settingsStore.fiatApiMode = FiatApiMode.disabled;
return;
}
_settingsStore.fiatApiMode = FiatApiMode.enabled;
}
}