diff --git a/assets/node_list.yml b/assets/node_list.yml index 09fb72383..fccc968cf 100644 --- a/assets/node_list.yml +++ b/assets/node_list.yml @@ -1,31 +1,24 @@ - - uri: xmr-node-uk.cakewallet.com:18081 + uri: xmr-node.cakewallet.com:18081 is_default: true - - uri: xmr-node-eu.cakewallet.com:18081 + uri: cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081 is_default: false - - uri: xmr-node-usa-east.cakewallet.com:18081 + uri: node.sethforprivacy.com:18089 + is_default: false +- + uri: nodes.hashvault.pro:18081 + is_default: false +- + uri: node.c3pool.com:18081 + is_default: false +- + uri: node.supportxmr.com:18081 + is_default: false +- + uri: node.community.rino.io:18081 is_default: false - uri: node.moneroworld.com:18089 is_default: false -- - uri: node.xmr.pt:18081 - is_default: false -- - uri: node.monero.net:18081 - is_default: false -- - uri: opennode.xmr-tw.org:18089 - is_default: false -- - uri: node.imonero.org:18081 - is_default: false - - uri: node.c3pool.com:18081 - is_default: false - - uri: xmr.prprpr.icu:18081 - is_default: false - diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 7abed8c07..fad546d90 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -129,7 +129,7 @@ abstract class ElectrumWalletBase extends WalletBase startSync() async { try { - syncStatus = StartingSyncStatus(); + syncStatus = AttemptingSyncStatus(); await walletAddresses.discoverAddresses(); await updateTransactions(); _subscribeForUpdates(); diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart index 886add3cd..ff1d6b051 100644 --- a/cw_core/lib/node.dart +++ b/cw_core/lib/node.dart @@ -17,6 +17,7 @@ class Node extends HiveObject with Keyable { {this.login, this.password, this.useSSL, + this.trusted = false, String? uri, WalletType? type,}) { if (uri != null) { @@ -31,7 +32,8 @@ class Node extends HiveObject with Keyable { : uriRaw = map['uri'] as String? ?? '', login = map['login'] as String?, password = map['password'] as String?, - useSSL = map['useSSL'] as bool?; + useSSL = map['useSSL'] as bool?, + trusted = map['trusted'] as bool? ?? false; static const typeId = 1; static const boxName = 'Nodes'; @@ -51,6 +53,9 @@ class Node extends HiveObject with Keyable { @HiveField(4) bool? useSSL; + @HiveField(5) + bool trusted; + bool get isSSL => useSSL ?? false; Uri get uri { @@ -104,28 +109,28 @@ class Node extends HiveObject with Keyable { final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path); final realm = 'monero-rpc'; final body = { - 'jsonrpc': '2.0', - 'id': '0', + 'jsonrpc': '2.0', + 'id': '0', 'method': 'get_info' }; try { final authenticatingClient = HttpClient(); - + authenticatingClient.addCredentials( rpcUri, - realm, + realm, HttpClientDigestCredentials(login ?? '', password ?? ''), ); - + final http.Client client = ioc.IOClient(authenticatingClient); - + final response = await client.post( rpcUri, headers: {'Content-Type': 'application/json'}, body: json.encode(body), ); - + client.close(); final resBody = json.decode(response.body) as Map; diff --git a/cw_core/lib/sync_status.dart b/cw_core/lib/sync_status.dart index fabec67c8..4983967d0 100644 --- a/cw_core/lib/sync_status.dart +++ b/cw_core/lib/sync_status.dart @@ -28,7 +28,7 @@ class NotConnectedSyncStatus extends SyncStatus { double progress() => 0.0; } -class StartingSyncStatus extends SyncStatus { +class AttemptingSyncStatus extends SyncStatus { @override double progress() => 0.0; } diff --git a/cw_haven/ios/Classes/haven_api.cpp b/cw_haven/ios/Classes/haven_api.cpp index c1013bf87..aecaf0016 100644 --- a/cw_haven/ios/Classes/haven_api.cpp +++ b/cw_haven/ios/Classes/haven_api.cpp @@ -927,6 +927,16 @@ extern "C" return static_cast(rates.size()); } + void set_trusted_daemon(bool arg) + { + m_wallet->setTrustedDaemon(arg); + } + + bool trusted_daemon() + { + return m_wallet->trustedDaemon(); + } + #ifdef __cplusplus } #endif diff --git a/cw_haven/lib/api/signatures.dart b/cw_haven/lib/api/signatures.dart index 774a303d7..31c911edc 100644 --- a/cw_haven/lib/api/signatures.dart +++ b/cw_haven/lib/api/signatures.dart @@ -137,4 +137,8 @@ typedef get_rate = Pointer Function(); typedef size_of_rate = Int32 Function(); -typedef update_rate = Void Function(); \ No newline at end of file +typedef update_rate = Void Function(); + +typedef set_trusted_daemon = Void Function(Int8 trusted); + +typedef trusted_daemon = Int8 Function(); \ No newline at end of file diff --git a/cw_haven/lib/api/types.dart b/cw_haven/lib/api/types.dart index f1dc0e26b..de9ff74a0 100644 --- a/cw_haven/lib/api/types.dart +++ b/cw_haven/lib/api/types.dart @@ -135,4 +135,8 @@ typedef GetRate = Pointer Function(); typedef SizeOfRate = int Function(); -typedef UpdateRate = void Function(); \ No newline at end of file +typedef UpdateRate = void Function(); + +typedef SetTrustedDaemon = void Function(int); + +typedef TrustedDaemon = int Function(); \ No newline at end of file diff --git a/cw_haven/lib/api/wallet.dart b/cw_haven/lib/api/wallet.dart index 2b85f60e2..bdf6a1af7 100644 --- a/cw_haven/lib/api/wallet.dart +++ b/cw_haven/lib/api/wallet.dart @@ -116,6 +116,14 @@ final rescanBlockchainAsyncNative = havenApi .lookup>('rescan_blockchain') .asFunction(); +final setTrustedDaemonNative = havenApi + .lookup>('set_trusted_daemon') + .asFunction(); + +final trustedDaemonNative = havenApi + .lookup>('trusted_daemon') + .asFunction(); + int getSyncingHeight() => getSyncingHeightNative(); bool isNeededToRefresh() => isNeededToRefreshNative() != 0; @@ -351,3 +359,7 @@ Future isConnected() => compute(_isConnected, 0); Future getNodeHeight() => compute(_getNodeHeight, 0); void rescanBlockchainAsync() => rescanBlockchainAsyncNative(); + +Future setTrustedDaemon(bool trusted) async => setTrustedDaemonNative(_boolToInt(trusted)); + +Future trustedDaemon() async => trustedDaemonNative() != 0; diff --git a/cw_haven/lib/haven_wallet.dart b/cw_haven/lib/haven_wallet.dart index 4f360bdff..a4b949d8f 100644 --- a/cw_haven/lib/haven_wallet.dart +++ b/cw_haven/lib/haven_wallet.dart @@ -121,6 +121,8 @@ abstract class HavenWalletBase extends WalletBasegetSubaddressLabel(accountIndex, addressIndex).c_str()); } + void set_trusted_daemon(bool arg) + { + m_wallet->setTrustedDaemon(arg); + } + + bool trusted_daemon() + { + return m_wallet->trustedDaemon(); + } + #ifdef __cplusplus } #endif diff --git a/cw_monero/ios/Classes/monero_api.h b/cw_monero/ios/Classes/monero_api.h index 3e2ebcff2..74258ba4c 100644 --- a/cw_monero/ios/Classes/monero_api.h +++ b/cw_monero/ios/Classes/monero_api.h @@ -30,6 +30,9 @@ void set_refresh_from_block_height(uint64_t height); void set_recovering_from_seed(bool is_recovery); void store(char *path); +void set_trusted_daemon(bool arg); +bool trusted_daemon(); + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/cw_monero/lib/api/signatures.dart b/cw_monero/lib/api/signatures.dart index f9e88153e..0b14fd557 100644 --- a/cw_monero/lib/api/signatures.dart +++ b/cw_monero/lib/api/signatures.dart @@ -125,4 +125,8 @@ typedef rescan_blockchain = Void Function(); typedef get_subaddress_label = Pointer Function( Int32 accountIndex, - Int32 addressIndex); \ No newline at end of file + Int32 addressIndex); + +typedef set_trusted_daemon = Void Function(Int8 trusted); + +typedef trusted_daemon = Int8 Function(); \ No newline at end of file diff --git a/cw_monero/lib/api/types.dart b/cw_monero/lib/api/types.dart index 468ce93e2..c5918c12a 100644 --- a/cw_monero/lib/api/types.dart +++ b/cw_monero/lib/api/types.dart @@ -123,4 +123,8 @@ typedef RescanBlockchainAsync = void Function(); typedef GetSubaddressLabel = Pointer Function( int accountIndex, - int addressIndex); \ No newline at end of file + int addressIndex); + +typedef SetTrustedDaemon = void Function(int); + +typedef TrustedDaemon = int Function(); \ No newline at end of file diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart index 5c2f1bd27..7ddbf29dc 100644 --- a/cw_monero/lib/api/wallet.dart +++ b/cw_monero/lib/api/wallet.dart @@ -120,6 +120,14 @@ final getSubaddressLabelNative = moneroApi .lookup>('get_subaddress_label') .asFunction(); +final setTrustedDaemonNative = moneroApi + .lookup>('set_trusted_daemon') + .asFunction(); + +final trustedDaemonNative = moneroApi + .lookup>('trusted_daemon') + .asFunction(); + int getSyncingHeight() => getSyncingHeightNative(); bool isNeededToRefresh() => isNeededToRefreshNative() != 0; @@ -359,4 +367,8 @@ void rescanBlockchainAsync() => rescanBlockchainAsyncNative(); String getSubaddressLabel(int accountIndex, int addressIndex) { return convertUTF8ToString(pointer: getSubaddressLabelNative(accountIndex, addressIndex)); -} \ No newline at end of file +} + +Future setTrustedDaemon(bool trusted) async => setTrustedDaemonNative(_boolToInt(trusted)); + +Future trustedDaemon() async => trustedDaemonNative() != 0; \ No newline at end of file diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart index 404d8bad0..a9d708c05 100644 --- a/cw_monero/lib/monero_wallet.dart +++ b/cw_monero/lib/monero_wallet.dart @@ -136,6 +136,8 @@ abstract class MoneroWalletBase extends WalletBase( - () => SharedPreferences.getInstance()); + getIt.registerSingletonAsync(() => SharedPreferences.getInstance()); } final isBitcoinBuyEnabled = (secrets.wyreSecretKey?.isNotEmpty ?? false) && @@ -219,73 +220,64 @@ Future setup( walletList: getIt.get(), settingsStore: getIt.get(), nodeListStore: getIt.get())); - getIt.registerSingleton(TradesStore( - tradesSource: _tradesSource, settingsStore: getIt.get())); - getIt.registerSingleton(OrdersStore( - ordersSource: _ordersSource, settingsStore: getIt.get())); + getIt.registerSingleton( + TradesStore(tradesSource: _tradesSource, settingsStore: getIt.get())); + getIt.registerSingleton( + OrdersStore(ordersSource: _ordersSource, settingsStore: getIt.get())); getIt.registerSingleton(TradeFilterStore()); getIt.registerSingleton(TransactionFilterStore()); getIt.registerSingleton(FiatConversionStore()); - getIt.registerSingleton( - SendTemplateStore(templateSource: _templates)); + getIt.registerSingleton(SendTemplateStore(templateSource: _templates)); getIt.registerSingleton( ExchangeTemplateStore(templateSource: _exchangeTemplates)); - getIt.registerSingleton(YatStore( - appStore: getIt.get(), - secureStorage: getIt.get()) - ..init()); + getIt.registerSingleton( + YatStore(appStore: getIt.get(), secureStorage: getIt.get()) + ..init()); - final secretStore = - await SecretStoreBase.load(getIt.get()); + final secretStore = await SecretStoreBase.load(getIt.get()); getIt.registerSingleton(secretStore); - getIt.registerFactory( - () => KeyService(getIt.get())); + getIt.registerFactory(() => KeyService(getIt.get())); - getIt.registerFactoryParam( - (type, _) => WalletCreationService( + getIt.registerFactoryParam((type, _) => + WalletCreationService( initialType: type, keyService: getIt.get(), secureStorage: getIt.get(), sharedPreferences: getIt.get(), walletInfoSource: _walletInfoSource)); - getIt.registerFactory( - () => WalletLoadingService( + getIt.registerFactory(() => WalletLoadingService( getIt.get(), getIt.get(), (WalletType type) => getIt.get(param1: type))); - getIt.registerFactoryParam((type, _) => - WalletNewVM(getIt.get(), - getIt.get(param1: type), _walletInfoSource, - type: type)); + getIt.registerFactoryParam((type, _) => WalletNewVM( + getIt.get(), getIt.get(param1: type), _walletInfoSource, + type: type)); - getIt - .registerFactoryParam((args, _) { + getIt.registerFactoryParam((args, _) { final type = args.first as WalletType; final language = args[1] as String; final mnemonic = args[2] as String; - return WalletRestorationFromSeedVM(getIt.get(), - getIt.get(param1: type), _walletInfoSource, + return WalletRestorationFromSeedVM( + getIt.get(), getIt.get(param1: type), _walletInfoSource, type: type, language: language, seed: mnemonic); }); - getIt - .registerFactoryParam((args, _) { + getIt.registerFactoryParam((args, _) { final type = args.first as WalletType; final language = args[1] as String; - return WalletRestorationFromKeysVM(getIt.get(), - getIt.get(param1: type), _walletInfoSource, + return WalletRestorationFromKeysVM( + getIt.get(), getIt.get(param1: type), _walletInfoSource, type: type, language: language); }); getIt.registerFactory(() => - WalletAddressListViewModel( - appStore: getIt.get(), yatStore: getIt.get())); + WalletAddressListViewModel(appStore: getIt.get(), yatStore: getIt.get())); getIt.registerFactory(() => BalanceViewModel( appStore: getIt.get(), @@ -306,15 +298,12 @@ Future setup( secureStorage: getIt.get(), sharedPreferences: getIt.get())); - getIt.registerFactory(() => AuthViewModel( - getIt.get(), - getIt.get(), - getIt.get(), - BiometricAuth())); + getIt.registerFactory(() => AuthViewModel(getIt.get(), + getIt.get(), getIt.get(), BiometricAuth())); getIt.registerFactory( - () => AuthPage(getIt.get(), onAuthenticationFinished: - (isAuthenticated, AuthPageState authPageState) { + () => AuthPage(getIt.get(), + onAuthenticationFinished: (isAuthenticated, AuthPageState authPageState) { if (!isAuthenticated) { return; } @@ -329,8 +318,7 @@ Future setup( authPageState.changeProcessText('Loading the wallet'); if (loginError != null) { - authPageState - .changeProcessText('ERROR: ${loginError.toString()}'); + authPageState.changeProcessText('ERROR: ${loginError.toString()}'); } ReactionDisposer? _reaction; @@ -341,28 +329,29 @@ Future setup( }, closable: false), instanceName: 'login'); - getIt - .registerFactoryParam( - (onAuthFinished, closable) => AuthPage(getIt.get(), - onAuthenticationFinished: onAuthFinished, - closable: closable ?? false)); + getIt.registerFactoryParam( + (onAuthFinished, closable) => AuthPage(getIt.get(), + onAuthenticationFinished: onAuthFinished, closable: closable ?? false)); - getIt.registerFactory(() => - BalancePage(dashboardViewModel: getIt.get(), settingsStore: getIt.get())); + getIt.registerFactory(() => BalancePage( + dashboardViewModel: getIt.get(), + settingsStore: getIt.get())); - getIt.registerFactory(() => DashboardPage( balancePage: getIt.get(), walletViewModel: getIt.get(), addressListViewModel: getIt.get())); - getIt.registerFactory(() => ReceivePage( + getIt.registerFactory(() => DashboardPage( + balancePage: getIt.get(), + walletViewModel: getIt.get(), addressListViewModel: getIt.get())); + getIt.registerFactory( + () => ReceivePage(addressListViewModel: getIt.get())); getIt.registerFactory(() => AddressPage( addressListViewModel: getIt.get(), walletViewModel: getIt.get())); - getIt.registerFactoryParam( - (dynamic item, _) => WalletAddressEditOrCreateViewModel( - wallet: getIt.get().wallet!, item: item)); + getIt.registerFactoryParam((dynamic item, _) => + WalletAddressEditOrCreateViewModel(wallet: getIt.get().wallet!, item: item)); - getIt.registerFactoryParam( - (dynamic item, _) => AddressEditOrCreatePage( + getIt.registerFactoryParam((dynamic item, _) => + AddressEditOrCreatePage( addressEditOrCreateViewModel: getIt.get(param1: item))); @@ -380,20 +369,16 @@ Future setup( getIt.get(), _transactionDescriptionBox)); - getIt.registerFactory( - () => SendPage(sendViewModel: getIt.get(), - settingsViewModel: getIt.get())); + getIt.registerFactory(() => SendPage(sendViewModel: getIt.get())); - getIt.registerFactory(() => SendTemplatePage( - sendTemplateViewModel: getIt.get())); + getIt.registerFactory( + () => SendTemplatePage(sendTemplateViewModel: getIt.get())); getIt.registerFactory(() => WalletListViewModel( - _walletInfoSource, - getIt.get(), - getIt.get())); + _walletInfoSource, getIt.get(), getIt.get())); - getIt.registerFactory(() => - WalletListPage(walletListViewModel: getIt.get())); + getIt + .registerFactory(() => WalletListPage(walletListViewModel: getIt.get())); getIt.registerFactory(() { final wallet = getIt.get().wallet!; @@ -402,11 +387,12 @@ Future setup( return MoneroAccountListViewModel(wallet); } - throw Exception('Unexpected wallet type: ${wallet.type} for generate MoneroAccountListViewModel'); + throw Exception( + 'Unexpected wallet type: ${wallet.type} for generate MoneroAccountListViewModel'); }); - getIt.registerFactory(() => MoneroAccountListPage( - accountListViewModel: getIt.get())); + getIt.registerFactory( + () => MoneroAccountListPage(accountListViewModel: getIt.get())); /*getIt.registerFactory(() { final wallet = getIt.get().wallet; @@ -423,92 +409,86 @@ Future setup( moneroAccountCreationViewModel: getIt.get()));*/ - getIt.registerFactoryParam( + getIt.registerFactoryParam( (AccountListItem? account, _) => MoneroAccountEditOrCreateViewModel( monero!.getAccountList(getIt.get().wallet!), haven?.getAccountList(getIt.get().wallet!), wallet: getIt.get().wallet!, accountListItem: account)); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (AccountListItem? account, _) => MoneroAccountEditOrCreatePage( moneroAccountCreationViewModel: getIt.get(param1: account))); getIt.registerFactory(() { - final appStore = getIt.get(); - final yatStore = getIt.get(); - final authService = getIt.get(); - return SettingsViewModel(appStore.settingsStore, yatStore, authService, appStore.wallet!); + return DisplaySettingsViewModel(getIt.get()); }); - getIt - .registerFactory(() => WalletSeedViewModel(getIt.get().wallet!)); + getIt.registerFactory(() { + return PrivacySettingsViewModel(getIt.get()); + }); - getIt.registerFactoryParam( - (bool isWalletCreated, _) => WalletSeedPage( - getIt.get(), - isNewWalletCreated: isWalletCreated)); + getIt.registerFactory(() { + return OtherSettingsViewModel(getIt.get(), getIt.get().wallet!); + }); - getIt - .registerFactory(() => WalletKeysViewModel(getIt.get().wallet!)); + getIt.registerFactory(() { + return SecuritySettingsViewModel(getIt.get()); + }); + + getIt.registerFactory(() => WalletSeedViewModel(getIt.get().wallet!)); + + getIt.registerFactoryParam((bool isWalletCreated, _) => + WalletSeedPage(getIt.get(), isNewWalletCreated: isWalletCreated)); + + getIt.registerFactory(() => WalletKeysViewModel(getIt.get().wallet!)); getIt.registerFactory(() => WalletKeysPage(getIt.get())); getIt.registerFactoryParam( - (ContactRecord? contact, _) => - ContactViewModel(_contactSource, contact: contact)); + (ContactRecord? contact, _) => ContactViewModel(_contactSource, contact: contact)); - getIt.registerFactory( - () => ContactListViewModel(_contactSource, _walletInfoSource)); + getIt.registerFactory(() => ContactListViewModel(_contactSource, _walletInfoSource)); - getIt.registerFactoryParam( - (bool isEditable, _) => ContactListPage(getIt.get(), - isEditable: isEditable)); + getIt.registerFactoryParam((bool isEditable, _) => + ContactListPage(getIt.get(), isEditable: isEditable)); getIt.registerFactoryParam( - (ContactRecord? contact, _) => - ContactPage(getIt.get(param1: contact))); + (ContactRecord? contact, _) => ContactPage(getIt.get(param1: contact))); getIt.registerFactory(() { final appStore = getIt.get(); - return NodeListViewModel( - _nodeSource, appStore.wallet!, appStore.settingsStore); + return NodeListViewModel(_nodeSource, appStore.wallet!, appStore.settingsStore); }); - getIt.registerFactory(() => NodeListPage(getIt.get())); - - getIt.registerFactory(() => ConnectionSyncPage(getIt.get(), getIt.get())); - - getIt.registerFactory(() => SecurityBackupPage(getIt.get())); - - getIt.registerFactory(() => PrivacyPage(getIt.get())); - - getIt.registerFactory(() => DisplaySettingsPage(getIt.get())); - - getIt.registerFactory(() => OtherSettingsPage(getIt.get())); - - getIt.registerFactory(() => - NodeCreateOrEditViewModel(_nodeSource, getIt.get().wallet!)); - getIt.registerFactory( - () => NodeCreateOrEditPage(getIt.get())); + () => ConnectionSyncPage(getIt.get(), getIt.get())); + + getIt.registerFactory(() => SecurityBackupPage(getIt.get())); + + getIt.registerFactory(() => PrivacyPage(getIt.get())); + + getIt.registerFactory(() => DisplaySettingsPage(getIt.get())); + + getIt.registerFactory(() => OtherSettingsPage(getIt.get())); + + getIt + .registerFactory(() => NodeCreateOrEditViewModel(_nodeSource, getIt.get().wallet!)); + + getIt.registerFactory(() => NodeCreateOrEditPage(getIt.get())); getIt.registerFactory(() => OnRamperPage( - settingsStore: getIt.get().settingsStore, - wallet: getIt.get().wallet!)); + settingsStore: getIt.get().settingsStore, wallet: getIt.get().wallet!)); getIt.registerFactory(() => ExchangeViewModel( - getIt.get().wallet!, - _tradesSource, - getIt.get(), - getIt.get(), - getIt.get().settingsStore, - getIt.get(), - getIt.get(), - )); + getIt.get().wallet!, + _tradesSource, + getIt.get(), + getIt.get(), + getIt.get().settingsStore, + getIt.get(), + )); getIt.registerFactory(() => ExchangeTradeViewModel( wallet: getIt.get().wallet!, @@ -518,40 +498,34 @@ Future setup( getIt.registerFactory(() => ExchangePage(getIt.get())); - getIt.registerFactory( - () => ExchangeConfirmPage(tradesStore: getIt.get())); - - getIt.registerFactory(() => ExchangeTradePage( - exchangeTradeViewModel: getIt.get())); + getIt.registerFactory(() => ExchangeConfirmPage(tradesStore: getIt.get())); getIt.registerFactory( - () => ExchangeTemplatePage(getIt.get())); + () => ExchangeTradePage(exchangeTradeViewModel: getIt.get())); - getIt.registerFactoryParam( - (WalletType param1, __) { + getIt.registerFactory(() => ExchangeTemplatePage(getIt.get())); + + getIt.registerFactoryParam((WalletType param1, __) { switch (param1) { case WalletType.haven: return haven!.createHavenWalletService(_walletInfoSource); case WalletType.monero: return monero!.createMoneroWalletService(_walletInfoSource); case WalletType.bitcoin: - return bitcoin!.createBitcoinWalletService( - _walletInfoSource, _unspentCoinsInfoSource!); + return bitcoin!.createBitcoinWalletService(_walletInfoSource, _unspentCoinsInfoSource!); case WalletType.litecoin: - return bitcoin!.createLitecoinWalletService( - _walletInfoSource, _unspentCoinsInfoSource!); + return bitcoin!.createLitecoinWalletService(_walletInfoSource, _unspentCoinsInfoSource!); default: throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService'); } }); - getIt.registerFactory(() => SetupPinCodeViewModel( - getIt.get(), getIt.get())); + getIt.registerFactory( + () => SetupPinCodeViewModel(getIt.get(), getIt.get())); - getIt.registerFactoryParam, String), void>( - (onSuccessfulPinSetup, _) => SetupPinCodePage( - getIt.get(), + getIt.registerFactoryParam, String), + void>( + (onSuccessfulPinSetup, _) => SetupPinCodePage(getIt.get(), onSuccessfulPinSetup: onSuccessfulPinSetup)); getIt.registerFactory(() => RescanViewModel(getIt.get().wallet!)); @@ -560,17 +534,16 @@ Future setup( getIt.registerFactory(() => FaqPage(getIt.get())); - getIt.registerFactoryParam( - (type, _) => WalletRestoreViewModel(getIt.get(), - getIt.get(param1: type), _walletInfoSource, + getIt.registerFactoryParam((type, _) => + WalletRestoreViewModel( + getIt.get(), getIt.get(param1: type), _walletInfoSource, type: type)); - getIt.registerFactoryParam((type, _) => - WalletRestorePage(getIt.get(param1: type))); + getIt.registerFactoryParam( + (type, _) => WalletRestorePage(getIt.get(param1: type))); - getIt - .registerFactoryParam( - (TransactionInfo transactionInfo, _) { + getIt.registerFactoryParam( + (TransactionInfo transactionInfo, _) { final wallet = getIt.get().wallet!; return TransactionDetailsViewModel( transactionInfo: transactionInfo, @@ -584,52 +557,47 @@ Future setup( transactionDetailsViewModel: getIt.get(param1: transactionInfo))); - getIt.registerFactoryParam( + getIt.registerFactoryParam( (param1, _) => NewWalletTypePage(onTypeSelected: param1)); getIt.registerFactoryParam( (WalletType type, _) => PreSeedPage(type)); getIt.registerFactoryParam((trade, _) => - TradeDetailsViewModel(tradeForDetails: trade, trades: _tradesSource, + TradeDetailsViewModel( + tradeForDetails: trade, + trades: _tradesSource, settingsStore: getIt.get())); - getIt.registerFactory(() => BackupService( - getIt.get(), - _walletInfoSource, - getIt.get(), - getIt.get())); + getIt.registerFactory(() => BackupService(getIt.get(), _walletInfoSource, + getIt.get(), getIt.get())); - getIt.registerFactory(() => BackupViewModel(getIt.get(), - getIt.get(), getIt.get())); + getIt.registerFactory(() => BackupViewModel( + getIt.get(), getIt.get(), getIt.get())); getIt.registerFactory(() => BackupPage(getIt.get())); - getIt.registerFactory( - () => EditBackupPasswordViewModel(getIt.get(), getIt.get())); + getIt.registerFactory(() => + EditBackupPasswordViewModel(getIt.get(), getIt.get())); - getIt.registerFactory( - () => EditBackupPasswordPage(getIt.get())); + getIt.registerFactory(() => EditBackupPasswordPage(getIt.get())); getIt.registerFactory(() => RestoreOptionsPage()); - getIt.registerFactory( - () => RestoreFromBackupViewModel(getIt.get())); + getIt.registerFactory(() => RestoreFromBackupViewModel(getIt.get())); - getIt.registerFactory( - () => RestoreFromBackupPage(getIt.get())); + getIt.registerFactory(() => RestoreFromBackupPage(getIt.get())); - getIt.registerFactoryParam((Trade trade, _) => - TradeDetailsPage(getIt.get(param1: trade))); + getIt.registerFactoryParam( + (Trade trade, _) => TradeDetailsPage(getIt.get(param1: trade))); getIt.registerFactory(() => BuyAmountViewModel()); getIt.registerFactory(() { final wallet = getIt.get().wallet; - return BuyViewModel(_ordersSource, getIt.get(), - getIt.get(), getIt.get(), + return BuyViewModel(_ordersSource, getIt.get(), getIt.get(), + getIt.get(), wallet: wallet!); }); @@ -641,7 +609,8 @@ Future setup( final url = args.first as String; final buyViewModel = args[1] as BuyViewModel; - return BuyWebViewPage(buyViewModel: buyViewModel, ordersStore: getIt.get(), url: url); + return BuyWebViewPage( + buyViewModel: buyViewModel, ordersStore: getIt.get(), url: url); }); getIt.registerFactoryParam((order, _) { @@ -650,8 +619,8 @@ Future setup( return OrderDetailsViewModel(wallet: wallet!, orderForDetails: order); }); - getIt.registerFactoryParam((Order order, _) => - OrderDetailsPage(getIt.get(param1: order))); + getIt.registerFactoryParam( + (Order order, _) => OrderDetailsPage(getIt.get(param1: order))); getIt.registerFactory(() => SupportViewModel()); @@ -660,20 +629,18 @@ Future setup( getIt.registerFactory(() { final wallet = getIt.get().wallet; - return UnspentCoinsListViewModel( - wallet: wallet!, unspentCoinsInfo: _unspentCoinsInfoSource!); + return UnspentCoinsListViewModel(wallet: wallet!, unspentCoinsInfo: _unspentCoinsInfoSource!); }); - getIt.registerFactory(() => UnspentCoinsListPage( - unspentCoinsListViewModel: getIt.get())); + getIt.registerFactory(() => + UnspentCoinsListPage(unspentCoinsListViewModel: getIt.get())); getIt.registerFactoryParam( - (item, model) => UnspentCoinsDetailsViewModel( - unspentCoinsItem: item, unspentCoinsListViewModel: model)); + (item, model) => + UnspentCoinsDetailsViewModel(unspentCoinsItem: item, unspentCoinsListViewModel: model)); - getIt.registerFactoryParam( - (List args, _) { + getIt.registerFactoryParam((List args, _) { final item = args.first as UnspentCoinsItem; final unspentCoinsListViewModel = args[1] as UnspentCoinsListViewModel; @@ -686,12 +653,15 @@ Future setup( getIt.registerFactory(() => YatService()); - getIt.registerFactory(() => AddressResolver(yatService: getIt.get(), - walletType: getIt.get().wallet!.type)); + getIt.registerFactory(() => AddressResolver( + yatService: getIt.get(), walletType: getIt.get().wallet!.type)); getIt.registerFactoryParam( - (String qrData, bool isLight) => FullscreenQRPage(qrData: qrData, isLight: isLight,)); - + (String qrData, bool isLight) => FullscreenQRPage( + qrData: qrData, + isLight: isLight, + )); + getIt.registerFactory(() => IoniaApi()); getIt.registerFactory(() => AnyPayApi()); @@ -699,26 +669,24 @@ Future setup( getIt.registerFactory( () => IoniaService(getIt.get(), getIt.get())); - getIt.registerFactory( - () => IoniaAnyPay( - getIt.get(), - getIt.get(), - getIt.get().wallet!)); + getIt.registerFactory(() => IoniaAnyPay( + getIt.get(), getIt.get(), getIt.get().wallet!)); getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get())); getIt.registerFactory(() => IoniaAuthViewModel(ioniaService: getIt.get())); - getIt.registerFactoryParam((double amount, merchant) { + getIt.registerFactoryParam( + (double amount, merchant) { return IoniaMerchPurchaseViewModel( - ioniaAnyPayService: getIt.get(), - amount: amount, - ioniaMerchant: merchant, - sendViewModel: getIt.get() - ); + ioniaAnyPayService: getIt.get(), + amount: amount, + ioniaMerchant: merchant, + sendViewModel: getIt.get()); }); - getIt.registerFactoryParam((IoniaMerchant merchant, _) { + getIt.registerFactoryParam( + (IoniaMerchant merchant, _) { return IoniaBuyCardViewModel(ioniaMerchant: merchant); }); @@ -746,41 +714,43 @@ Future setup( getIt.registerFactoryParam((List args, _) { final amount = args.first as double; final merchant = args.last as IoniaMerchant; - return IoniaBuyGiftCardDetailPage(getIt.get(param1: amount, param2: merchant)); + return IoniaBuyGiftCardDetailPage( + getIt.get(param1: amount, param2: merchant)); }); - getIt.registerFactoryParam((IoniaGiftCard giftCard, _) { - return IoniaGiftCardDetailsViewModel( - ioniaService: getIt.get(), - giftCard: giftCard); - }); - - getIt.registerFactoryParam((List args, _) { - final amount = args[0] as double; - final merchant = args[1] as IoniaMerchant; - final tip = args[2] as IoniaTip; - - return IoniaCustomTipViewModel(amount: amount, tip: tip, ioniaMerchant: merchant); - }); - - getIt.registerFactoryParam((IoniaGiftCard giftCard, _) { - return IoniaGiftCardDetailPage(getIt.get(param1: giftCard)); + getIt.registerFactoryParam( + (IoniaGiftCard giftCard, _) { + return IoniaGiftCardDetailsViewModel( + ioniaService: getIt.get(), giftCard: giftCard); }); - getIt.registerFactoryParam((List args, _){ + getIt.registerFactoryParam((List args, _) { + final amount = args[0] as double; + final merchant = args[1] as IoniaMerchant; + final tip = args[2] as IoniaTip; + + return IoniaCustomTipViewModel(amount: amount, tip: tip, ioniaMerchant: merchant); + }); + + getIt.registerFactoryParam( + (IoniaGiftCard giftCard, _) { + return IoniaGiftCardDetailPage(getIt.get(param1: giftCard)); + }); + + getIt.registerFactoryParam((List args, _) { final giftCard = args.first as IoniaGiftCard; - - return IoniaMoreOptionsPage(giftCard); + + return IoniaMoreOptionsPage(giftCard); }); - getIt.registerFactoryParam((IoniaGiftCard giftCard, _) => IoniaCustomRedeemViewModel(giftCard)); + getIt.registerFactoryParam( + (IoniaGiftCard giftCard, _) => IoniaCustomRedeemViewModel(giftCard)); - getIt.registerFactoryParam((List args, _){ + getIt.registerFactoryParam((List args, _) { final giftCard = args.first as IoniaGiftCard; - - return IoniaCustomRedeemPage(getIt.get(param1: giftCard) ); - }); + return IoniaCustomRedeemPage(getIt.get(param1: giftCard)); + }); getIt.registerFactoryParam((List args, _) { return IoniaCustomTipPage(getIt.get(param1: args)); @@ -796,16 +766,17 @@ Future setup( getIt.registerFactory(() => IoniaAccountCardsPage(getIt.get())); - getIt.registerFactoryParam( - (IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo) - => IoniaPaymentStatusViewModel( - getIt.get(), - paymentInfo: paymentInfo, - committedInfo: committedInfo)); + getIt.registerFactoryParam( + (IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo) => + IoniaPaymentStatusViewModel(getIt.get(), + paymentInfo: paymentInfo, committedInfo: committedInfo)); - getIt.registerFactoryParam( - (IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo) - => IoniaPaymentStatusPage(getIt.get(param1: paymentInfo, param2: committedInfo))); + getIt.registerFactoryParam( + (IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo) => + IoniaPaymentStatusPage( + getIt.get(param1: paymentInfo, param2: committedInfo))); _isSetupFinished = true; } diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index b2036c3f6..9aff05500 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -69,6 +69,8 @@ Future defaultSettingsMigration( sharedPreferences: sharedPreferences, nodes: nodes); await changeLitecoinCurrentElectrumServerToDefault( sharedPreferences: sharedPreferences, nodes: nodes); + await changeHavenCurrentNodeToDefault( + sharedPreferences: sharedPreferences, nodes: nodes); break; case 2: @@ -133,19 +135,32 @@ Future defaultSettingsMigration( await changeDefaultHavenNode(nodes); break; + case 18: + await addOnionNode(nodes); + break; + default: break; } await sharedPreferences.setInt( - 'current_default_settings_migration_version', version); + PreferencesKey.currentDefaultSettingsMigrationVersion, version); } catch (e) { print('Migration error: ${e.toString()}'); } }); await sharedPreferences.setInt( - 'current_default_settings_migration_version', version); + PreferencesKey.currentDefaultSettingsMigrationVersion, version); +} + +Future addOnionNode(Box nodes) async { + final onionNodeUri = "cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081"; + + // check if the user has this node before (added it manually) + if (nodes.values.firstWhereOrNull((element) => element.uriRaw == onionNodeUri) == null) { + await nodes.add(Node(uri: onionNodeUri, type: WalletType.monero)); + } } Future replaceNodesMigration({required Box nodes}) async { @@ -176,7 +191,7 @@ Future changeMoneroCurrentNodeToDefault( final node = getMoneroDefaultNode(nodes: nodes); final nodeId = node?.key as int ?? 0; // 0 - England - await sharedPreferences.setInt('current_node_id', nodeId); + await sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, nodeId); } Node? getBitcoinDefaultElectrumServer({required Box nodes}) { @@ -223,7 +238,7 @@ Future changeBitcoinCurrentElectrumServerToDefault( final server = getBitcoinDefaultElectrumServer(nodes: nodes); final serverId = server?.key as int ?? 0; - await sharedPreferences.setInt('current_node_id_btc', serverId); + await sharedPreferences.setInt(PreferencesKey.currentBitcoinElectrumSererIdKey, serverId); } Future changeLitecoinCurrentElectrumServerToDefault( @@ -232,7 +247,7 @@ Future changeLitecoinCurrentElectrumServerToDefault( final server = getLitecoinDefaultElectrumServer(nodes: nodes); final serverId = server?.key as int ?? 0; - await sharedPreferences.setInt('current_node_id_ltc', serverId); + await sharedPreferences.setInt(PreferencesKey.currentLitecoinElectrumSererIdKey, serverId); } Future changeHavenCurrentNodeToDefault( @@ -252,7 +267,7 @@ Future replaceDefaultNode( 'eu-node.cakewallet.io:18081', 'node.cakewallet.io:18081' ]; - final currentNodeId = sharedPreferences.getInt('current_node_id'); + final currentNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey); final currentNode = nodes.values.firstWhereOrNull((Node node) => node.key == currentNodeId); final needToReplace = @@ -277,17 +292,29 @@ Future updateNodeTypes({required Box nodes}) async { Future addBitcoinElectrumServerList({required Box nodes}) async { final serverList = await loadBitcoinElectrumServerList(); - await nodes.addAll(serverList); + for (var node in serverList) { + if (nodes.values.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) { + await nodes.add(node); + } + } } Future addLitecoinElectrumServerList({required Box nodes}) async { final serverList = await loadLitecoinElectrumServerList(); - await nodes.addAll(serverList); + for (var node in serverList) { + if (nodes.values.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) { + await nodes.add(node); + } + } } Future addHavenNodeList({required Box nodes}) async { final nodeList = await loadDefaultHavenNodes(); - await nodes.addAll(nodeList); + for (var node in nodeList) { + if (nodes.values.firstWhereOrNull((element) => element.uriRaw == node.uriRaw) == null) { + await nodes.add(node); + } + } } Future addAddressesForMoneroWallets( @@ -431,7 +458,7 @@ Future resetBitcoinElectrumServer( final oldElectrumServer = nodeSource.values.firstWhereOrNull( (node) => node.uri.toString().contains('electrumx.cakewallet.com')); var cakeWalletNode = nodeSource.values.firstWhereOrNull( - (node) => node.uri.toString() == cakeWalletBitcoinElectrumUri); + (node) => node.uriRaw.toString() == cakeWalletBitcoinElectrumUri); if (cakeWalletNode == null) { cakeWalletNode = diff --git a/lib/entities/priority_for_wallet_type.dart b/lib/entities/priority_for_wallet_type.dart new file mode 100644 index 000000000..927ab8803 --- /dev/null +++ b/lib/entities/priority_for_wallet_type.dart @@ -0,0 +1,21 @@ +import 'package:cake_wallet/bitcoin/bitcoin.dart'; +import 'package:cake_wallet/haven/haven.dart'; +import 'package:cake_wallet/monero/monero.dart'; +import 'package:cw_core/transaction_priority.dart'; +import 'package:cw_core/wallet_type.dart'; + +List priorityForWalletType(WalletType type) { + switch (type) { + case WalletType.monero: + return monero!.getTransactionPriorities(); + case WalletType.bitcoin: + return bitcoin!.getTransactionPriorities(); + case WalletType.litecoin: + return bitcoin!.getLitecoinTransactionPriorities(); + case WalletType.haven: + return haven!.getTransactionPriorities(); + default: + return []; + } +} + diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart index 20f529733..96b6142e6 100644 --- a/lib/exchange/changenow/changenow_exchange_provider.dart +++ b/lib/exchange/changenow/changenow_exchange_provider.dart @@ -114,7 +114,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider { final uri = Uri.https(apiAuthority, createTradePath); final response = await post(uri, headers: headers, body: json.encode(body)); - + if (response.statusCode == 400) { final responseJSON = json.decode(response.body) as Map; final error = responseJSON['error'] as String; @@ -130,7 +130,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider { final id = responseJSON['id'] as String; final inputAddress = responseJSON['payinAddress'] as String; final refundAddress = responseJSON['refundAddress'] as String; - final extraId = responseJSON['payinExtraId'] as String; + final extraId = responseJSON['payinExtraId'] as String?; return Trade( id: id, diff --git a/lib/main.dart b/lib/main.dart index 3cd5679b3..e1fade7b4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -128,7 +128,7 @@ Future main() async { exchangeTemplates: exchangeTemplates, transactionDescriptions: transactionDescriptions, secureStorage: secureStorage, - initialMigrationVersion: 17); + initialMigrationVersion: 18); runApp(App()); } catch (e, stacktrace) { runApp(MaterialApp( diff --git a/lib/router.dart b/lib/router.dart index 7818cc52f..4d3d61f5f 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -41,7 +41,6 @@ import 'package:cake_wallet/src/screens/dashboard/dashboard_page.dart'; import 'package:cake_wallet/src/screens/seed/wallet_seed_page.dart'; import 'package:cake_wallet/src/screens/auth/auth_page.dart'; import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart'; -import 'package:cake_wallet/src/screens/nodes/nodes_list_page.dart'; import 'package:cake_wallet/src/screens/receive/receive_page.dart'; import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart'; @@ -278,10 +277,6 @@ Route createRoute(RouteSettings settings) { param2: false), onWillPop: () async => false)); - case Routes.nodeList: - return CupertinoPageRoute( - builder: (_) => getIt.get()); - case Routes.connectionSync: return CupertinoPageRoute( builder: (_) => getIt.get()); diff --git a/lib/routes.dart b/lib/routes.dart index 04642ba34..d738b13e8 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -21,7 +21,6 @@ class Routes { static const seedLanguage = '/seed_language'; static const walletList = '/view_model.wallet_list'; static const auth = '/auth'; - static const nodeList = '/node_list'; static const newNode = '/new_node_list'; static const login = '/login'; static const splash = '/splash'; diff --git a/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart b/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart index 2fbb1d57d..1c13f7a88 100644 --- a/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart +++ b/lib/src/screens/ionia/cards/ionia_manage_cards_page.dart @@ -118,7 +118,7 @@ class IoniaManageCardsPage extends BasePage { width: 32, padding: EdgeInsets.all(8), decoration: BoxDecoration( - color: Colors.white.withOpacity(0.15), + color: Theme.of(context).textTheme!.headline6!.backgroundColor!, border: Border.all( color: Colors.white.withOpacity(0.2), ), diff --git a/lib/src/screens/ionia/widgets/ionia_filter_modal.dart b/lib/src/screens/ionia/widgets/ionia_filter_modal.dart index ec6e84cc0..2b885f736 100644 --- a/lib/src/screens/ionia/widgets/ionia_filter_modal.dart +++ b/lib/src/screens/ionia/widgets/ionia_filter_modal.dart @@ -20,7 +20,7 @@ class IoniaFilterModal extends StatelessWidget { padding: EdgeInsets.all(10), child: Image.asset( 'assets/images/mini_search_icon.png', - color: Theme.of(context).accentColor, + color: Theme.of(context).textTheme.subtitle2!.color!, ), ); return Scaffold( @@ -53,7 +53,7 @@ class IoniaFilterModal extends StatelessWidget { prefixIcon: searchIcon, hintText: S.of(context).search_category, contentPadding: EdgeInsets.only(bottom: 5), - fillColor: Theme.of(context).textTheme!.subtitle1!.backgroundColor!, + fillColor: Theme.of(context).primaryTextTheme!.caption!.decorationColor!.withOpacity(0.5), border: OutlineInputBorder( borderSide: BorderSide.none, borderRadius: BorderRadius.circular(8), diff --git a/lib/src/screens/nodes/node_create_or_edit_page.dart b/lib/src/screens/nodes/node_create_or_edit_page.dart index bd8153226..e84b6bdad 100644 --- a/lib/src/screens/nodes/node_create_or_edit_page.dart +++ b/lib/src/screens/nodes/node_create_or_edit_page.dart @@ -174,7 +174,22 @@ class NodeCreateOrEditPage extends BasePage { caption: S.of(context).use_ssl, )) ], - )) + )), + Padding( + padding: EdgeInsets.only(top: 20), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Observer( + builder: (_) => StandardCheckbox( + value: nodeCreateOrEditViewModel.trusted, + onChanged: (value) => + nodeCreateOrEditViewModel.trusted = value, + caption: S.of(context).trusted, + )) + ], + )), ] ], )), diff --git a/lib/src/screens/nodes/nodes_list_page.dart b/lib/src/screens/nodes/nodes_list_page.dart deleted file mode 100644 index 556a0fd06..000000000 --- a/lib/src/screens/nodes/nodes_list_page.dart +++ /dev/null @@ -1,166 +0,0 @@ -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:cw_core/node.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/palette.dart'; -import 'package:cake_wallet/generated/i18n.dart'; -import 'package:cake_wallet/src/screens/base_page.dart'; -import 'package:cake_wallet/src/screens/nodes/widgets/node_list_row.dart'; -import 'package:cake_wallet/src/widgets/standard_list.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; -import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; - -class NodeListPage extends BasePage { - NodeListPage(this.nodeListViewModel); - - @override - String get title => S.current.nodes; - - final NodeListViewModel nodeListViewModel; - - @override - Widget trailing(context) { - return Container( - height: 32, - decoration: BoxDecoration( - borderRadius: BorderRadius.all(Radius.circular(16)), - color: Theme.of(context).accentTextTheme.caption!.color!), - child: ButtonTheme( - minWidth: double.minPositive, - child: TextButton( - onPressed: () async { - await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithTwoActions( - alertTitle: S.of(context).node_reset_settings_title, - alertContent: - S.of(context).nodes_list_reset_to_default_message, - rightButtonText: S.of(context).reset, - leftButtonText: S.of(context).cancel, - actionRightButton: () async { - Navigator.of(context).pop(); - await nodeListViewModel.reset(); - }, - actionLeftButton: () => Navigator.of(context).pop()); - }); - }, - child: Text( - S.of(context).reset, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 14.0, - fontWeight: FontWeight.w600, - color: Palette.blueCraiola), - )), - ), - ); - } - - @override - Widget body(BuildContext context) { - return Container( - padding: EdgeInsets.only(top: 10), - child: Observer( - builder: (BuildContext context) { - return SectionStandardList( - sectionCount: 2, - context: context, - itemCounter: (int sectionIndex) { - if (sectionIndex == 0) { - return 1; - } - - return nodeListViewModel.nodes.length; - }, - itemBuilder: (_, sectionIndex, index) { - if (sectionIndex == 0) { - return NodeHeaderListRow( - title: S.of(context).add_new_node, - onTap: (_) async => await Navigator.of(context) - .pushNamed(Routes.newNode)); - } - - final node = nodeListViewModel.nodes[index]; - final isSelected = - node.keyIndex == nodeListViewModel.currentNode.keyIndex; - final nodeListRow = NodeListRow( - title: node.uriRaw, - isSelected: isSelected, - isAlive: node.requestNode(), - onTap: (_) async { - if (isSelected) { - return; - } - - await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithTwoActions( - alertTitle: - S.of(context).change_current_node_title, - alertContent: S - .of(context) - .change_current_node(node.uriRaw), - leftButtonText: S.of(context).cancel, - rightButtonText: S.of(context).change, - actionLeftButton: () => - Navigator.of(context).pop(), - actionRightButton: () async { - await nodeListViewModel.setAsCurrent(node); - Navigator.of(context).pop(); - }); - }); - }); - - final dismissibleRow = Slidable( - key: Key('${node.keyIndex}'), - startActionPane: _actionPane(context, node), - endActionPane: _actionPane(context, node), - child: nodeListRow, - ); - - return isSelected ? nodeListRow : dismissibleRow; - }); - }, - ), - ); - } - - ActionPane _actionPane(BuildContext context, Node node) => ActionPane( - motion: const ScrollMotion(), - extentRatio: 0.3, - children: [ - SlidableAction( - onPressed: (context) async { - final confirmed = await showPopUp( - context: context, - builder: (BuildContext context) { - return AlertWithTwoActions( - alertTitle: S.of(context).remove_node, - alertContent: - S.of(context).remove_node_message, - rightButtonText: S.of(context).remove, - leftButtonText: S.of(context).cancel, - actionRightButton: () => - Navigator.pop(context, true), - actionLeftButton: () => - Navigator.pop(context, false)); - }) ?? - false; - - if (confirmed) { - await nodeListViewModel.delete(node); - } - }, - backgroundColor: Colors.red, - foregroundColor: Colors.white, - icon: CupertinoIcons.delete, - label: S.of(context).delete, - ), - ], - ); -} diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index e0cfff517..b051a3afb 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -1,4 +1,3 @@ -import 'dart:ui'; import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart'; import 'package:cake_wallet/src/screens/send/widgets/send_card.dart'; @@ -6,8 +5,6 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/picker.dart'; import 'package:cake_wallet/src/widgets/template_tile.dart'; import 'package:cake_wallet/view_model/send/output.dart'; -import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:mobx/mobx.dart'; @@ -28,13 +25,11 @@ import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'package:cw_core/crypto_currency.dart'; class SendPage extends BasePage { - SendPage({required this.sendViewModel,required this.settingsViewModel }) : _formKey = GlobalKey(),fiatFromSettings = settingsViewModel.fiatCurrency; + SendPage({required this.sendViewModel}) : _formKey = GlobalKey(); final SendViewModel sendViewModel; - final SettingsViewModel settingsViewModel; final GlobalKey _formKey; final controller = PageController(initialPage: 0); - final FiatCurrency fiatFromSettings ; bool _effectsInstalled = false; @@ -55,7 +50,7 @@ class SendPage extends BasePage { @override void onClose(BuildContext context) { - settingsViewModel.setFiatCurrency(fiatFromSettings); + sendViewModel.onClose(); Navigator.of(context).pop(); } @@ -236,7 +231,7 @@ class SendPage extends BasePage { if(template.isCurrencySelected){ output.setCryptoAmount(template.amount); }else{ - settingsViewModel.setFiatCurrency(fiatFromTemplate); + sendViewModel.setFiatCurrency(fiatFromTemplate); output.setFiatAmount(template.amountFiat); } output.resetParsedAddress(); diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index dc589923f..d5775e2b5 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -1,11 +1,10 @@ -import 'dart:ui'; +import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cw_core/transaction_priority.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/picker.dart'; import 'package:cake_wallet/view_model/send/output.dart'; -import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; diff --git a/lib/src/screens/settings/display_settings_page.dart b/lib/src/screens/settings/display_settings_page.dart index 0c18ce09a..cd413ff45 100644 --- a/lib/src/screens/settings/display_settings_page.dart +++ b/lib/src/screens/settings/display_settings_page.dart @@ -8,18 +8,18 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell. import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_list.dart'; import 'package:cake_wallet/view_model/settings/choices_list_item.dart'; -import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; +import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart'; import 'package:cake_wallet/wallet_type_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; class DisplaySettingsPage extends BasePage { - DisplaySettingsPage(this.settingsViewModel); + DisplaySettingsPage(this._displaySettingsViewModel); @override String get title => S.current.display_settings; - final SettingsViewModel settingsViewModel; + final DisplaySettingsViewModel _displaySettingsViewModel; @override Widget body(BuildContext context) { @@ -30,17 +30,17 @@ class DisplaySettingsPage extends BasePage { children: [ SettingsSwitcherCell( title: S.current.settings_display_balance, - value: settingsViewModel.shouldDisplayBalance, + value: _displaySettingsViewModel.shouldDisplayBalance, onValueChange: (_, bool value) { - settingsViewModel.setShouldDisplayBalance(value); + _displaySettingsViewModel.setShouldDisplayBalance(value); }), if (!isHaven) SettingsPickerCell( title: S.current.settings_currency, searchHintText: S.current.search_currency, items: FiatCurrency.all, - selectedItem: settingsViewModel.fiatCurrency, - onItemSelected: (FiatCurrency currency) => settingsViewModel.setFiatCurrency(currency), + selectedItem: _displaySettingsViewModel.fiatCurrency, + onItemSelected: (FiatCurrency currency) => _displaySettingsViewModel.setFiatCurrency(currency), images: FiatCurrency.all.map((e) => Image.asset("assets/images/flags/${e.countryCode}.png")).toList(), isGridView: true, matchingCriteria: (FiatCurrency currency, String searchText) { @@ -55,8 +55,8 @@ class DisplaySettingsPage extends BasePage { displayItem: (dynamic code) { return LanguageService.list[code] ?? ''; }, - selectedItem: settingsViewModel.languageCode, - onItemSelected: settingsViewModel.onLanguageSelected, + selectedItem: _displaySettingsViewModel.languageCode, + onItemSelected: _displaySettingsViewModel.onLanguageSelected, images: LanguageService.list.keys .map((e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png")) .toList(), @@ -68,8 +68,8 @@ class DisplaySettingsPage extends BasePage { ChoicesListItem( title: S.current.color_theme, items: ThemeList.all, - selectedItem: settingsViewModel.theme, - onItemSelected: (ThemeBase theme) => settingsViewModel.setTheme(theme), + selectedItem: _displaySettingsViewModel.theme, + onItemSelected: (ThemeBase theme) => _displaySettingsViewModel.setTheme(theme), ), ), ], diff --git a/lib/src/screens/settings/other_settings_page.dart b/lib/src/screens/settings/other_settings_page.dart index 65d976708..e055e2e8e 100644 --- a/lib/src/screens/settings/other_settings_page.dart +++ b/lib/src/screens/settings/other_settings_page.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; @@ -5,18 +6,17 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arro import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_version_cell.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; -import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; -import 'package:cw_core/transaction_priority.dart'; +import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; class OtherSettingsPage extends BasePage { - OtherSettingsPage(this._settingsViewModel); + OtherSettingsPage(this._otherSettingsViewModel); @override String get title => S.current.other_settings; - final SettingsViewModel _settingsViewModel; + final OtherSettingsViewModel _otherSettingsViewModel; @override Widget body(BuildContext context) { @@ -26,10 +26,10 @@ class OtherSettingsPage extends BasePage { child: Column(children: [ SettingsPickerCell( title: S.current.settings_fee_priority, - items: priorityForWalletType(_settingsViewModel.walletType), - displayItem: _settingsViewModel.getDisplayPriority, - selectedItem: _settingsViewModel.transactionPriority, - onItemSelected: _settingsViewModel.onDisplayPrioritySelected, + items: priorityForWalletType(_otherSettingsViewModel.walletType), + displayItem: _otherSettingsViewModel.getDisplayPriority, + selectedItem: _otherSettingsViewModel.transactionPriority, + onItemSelected: _otherSettingsViewModel.onDisplayPrioritySelected, ), SettingsCellWithArrow( title: S.current.settings_terms_and_conditions, @@ -37,7 +37,7 @@ class OtherSettingsPage extends BasePage { ), StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)), Spacer(), - SettingsVersionCell(title: S.of(context).version(_settingsViewModel.currentVersion)) + SettingsVersionCell(title: S.of(context).version(_otherSettingsViewModel.currentVersion)) ]), ); }); diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart index d8518ce3b..128d864f4 100644 --- a/lib/src/screens/settings/privacy_page.dart +++ b/lib/src/screens/settings/privacy_page.dart @@ -1,29 +1,42 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; -import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; +import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; class PrivacyPage extends BasePage { - PrivacyPage(this.settingsViewModel); + PrivacyPage(this._privacySettingsViewModel); @override String get title => S.current.privacy_settings; - final SettingsViewModel settingsViewModel; + final PrivacySettingsViewModel _privacySettingsViewModel; @override Widget body(BuildContext context) { return Container( padding: EdgeInsets.only(top: 10), child: Observer(builder: (_) { - return SettingsSwitcherCell( - title: S.current.settings_save_recipient_address, - value: settingsViewModel.shouldSaveRecipientAddress, - onValueChange: (BuildContext _, bool value) { - settingsViewModel.setShouldSaveRecipientAddress(value); - }); + return Observer(builder: (_) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + SettingsSwitcherCell( + title: S.current.disable_exchange, + value: _privacySettingsViewModel.disableExchange, + onValueChange: (BuildContext context, bool value) { + _privacySettingsViewModel.setEnableExchange(value); + }), + SettingsSwitcherCell( + title: S.current.settings_save_recipient_address, + value: _privacySettingsViewModel.shouldSaveRecipientAddress, + onValueChange: (BuildContext _, bool value) { + _privacySettingsViewModel.setShouldSaveRecipientAddress(value); + }) + ], + ); + }); }), ); } diff --git a/lib/src/screens/settings/security_backup_page.dart b/lib/src/screens/settings/security_backup_page.dart index a3babb0bb..7040816d9 100644 --- a/lib/src/screens/settings/security_backup_page.dart +++ b/lib/src/screens/settings/security_backup_page.dart @@ -8,42 +8,45 @@ import 'package:cake_wallet/src/screens/settings/widgets/settings_cell_with_arro import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; import 'package:cake_wallet/src/widgets/standard_list.dart'; -import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; +import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; class SecurityBackupPage extends BasePage { - SecurityBackupPage(this.settingsViewModel); + SecurityBackupPage(this._securitySettingsViewModel); @override String get title => S.current.security_and_backup; - final SettingsViewModel settingsViewModel; + final SecuritySettingsViewModel _securitySettingsViewModel; @override Widget body(BuildContext context) { - return Container( padding: EdgeInsets.only(top: 10), child: Column(mainAxisSize: MainAxisSize.min, children: [ SettingsCellWithArrow( title: S.current.show_keys, - handler: (_) => settingsViewModel.checkPinCodeRiquired() ? Navigator.of(context).pushNamed(Routes.auth, - arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) { - if (isAuthenticatedSuccessfully) { - auth.close(route: Routes.showKeys); - } - }) : Navigator.of(context).pushNamed(Routes.showKeys), + handler: (_) => _securitySettingsViewModel.checkPinCodeRiquired() + ? Navigator.of(context).pushNamed(Routes.auth, + arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) { + if (isAuthenticatedSuccessfully) { + auth.close(route: Routes.showKeys); + } + }) + : Navigator.of(context).pushNamed(Routes.showKeys), ), StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)), SettingsCellWithArrow( title: S.current.create_backup, - handler: (_) => settingsViewModel.checkPinCodeRiquired() ? Navigator.of(context).pushNamed(Routes.auth, - arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) { - if (isAuthenticatedSuccessfully) { - auth.close(route: Routes.backup); - } - }) : Navigator.of(context).pushNamed(Routes.backup), + handler: (_) => _securitySettingsViewModel.checkPinCodeRiquired() + ? Navigator.of(context).pushNamed(Routes.auth, + arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) { + if (isAuthenticatedSuccessfully) { + auth.close(route: Routes.backup); + } + }) + : Navigator.of(context).pushNamed(Routes.backup), ), StandardListSeparator(padding: EdgeInsets.symmetric(horizontal: 24)), SettingsCellWithArrow( @@ -63,37 +66,38 @@ class SecurityBackupPage extends BasePage { children: [ SettingsSwitcherCell( title: S.current.settings_allow_biometrical_authentication, - value: settingsViewModel.allowBiometricalAuthentication, + value: _securitySettingsViewModel.allowBiometricalAuthentication, onValueChange: (BuildContext context, bool value) { if (value) { Navigator.of(context).pushNamed(Routes.auth, arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) async { if (isAuthenticatedSuccessfully) { - if (await settingsViewModel.biometricAuthenticated()) { - settingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully); + if (await _securitySettingsViewModel.biometricAuthenticated()) { + _securitySettingsViewModel + .setAllowBiometricalAuthentication(isAuthenticatedSuccessfully); } } else { - settingsViewModel.setAllowBiometricalAuthentication(isAuthenticatedSuccessfully); + _securitySettingsViewModel + .setAllowBiometricalAuthentication(isAuthenticatedSuccessfully); } auth.close(); }); } else { - settingsViewModel.setAllowBiometricalAuthentication(value); + _securitySettingsViewModel.setAllowBiometricalAuthentication(value); } }), - SettingsPickerCell( + SettingsPickerCell( title: S.current.require_pin_after, items: PinCodeRequiredDuration.values, - selectedItem: settingsViewModel.pinCodeRequiredDuration, + selectedItem: _securitySettingsViewModel.pinCodeRequiredDuration, onItemSelected: (PinCodeRequiredDuration code) { - settingsViewModel.setPinCodeRequiredDuration(code); + _securitySettingsViewModel.setPinCodeRequiredDuration(code); }, ), ], ); }), - ]), ); } diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index 725208324..b19434166 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -6,8 +6,8 @@ import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/exchange/sideshift/sideshift_exchange_provider.dart'; import 'package:cake_wallet/exchange/sideshift/sideshift_request.dart'; import 'package:cake_wallet/exchange/simpleswap/simpleswap_exchange_provider.dart'; -import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; import 'package:cake_wallet/exchange/simpleswap/simpleswap_request.dart'; +import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/sync_status.dart'; @@ -42,7 +42,7 @@ class ExchangeViewModel = ExchangeViewModelBase with _$ExchangeViewModel; abstract class ExchangeViewModelBase with Store { ExchangeViewModelBase(this.wallet, this.trades, this._exchangeTemplateStore, - this.tradesStore, this._settingsStore, this.sharedPreferences, this._settingsViewModel) + this.tradesStore, this._settingsStore, this.sharedPreferences) : _cryptoNumberFormat = NumberFormat(), isReverse = false, isFixedRateMode = false, @@ -189,6 +189,19 @@ abstract class ExchangeViewModelBase with Store { ObservableList get templates => _exchangeTemplateStore.templates; + + @computed + TransactionPriority get transactionPriority { + final priority = _settingsStore.priority[wallet.type]; + + if (priority == null) { + throw Exception('Unexpected type ${wallet.type.toString()}'); + } + + return priority; + } + + bool get hasAllAmount => wallet.type == WalletType.bitcoin && depositCurrency == wallet.currency; @@ -198,11 +211,11 @@ abstract class ExchangeViewModelBase with Store { switch (wallet.type) { case WalletType.monero: case WalletType.haven: - return _settingsViewModel.transactionPriority == monero!.getMoneroTransactionPrioritySlow(); + return transactionPriority == monero!.getMoneroTransactionPrioritySlow(); case WalletType.bitcoin: - return _settingsViewModel.transactionPriority == bitcoin!.getBitcoinTransactionPrioritySlow(); + return transactionPriority == bitcoin!.getBitcoinTransactionPrioritySlow(); case WalletType.litecoin: - return _settingsViewModel.transactionPriority == bitcoin!.getLitecoinTransactionPrioritySlow(); + return transactionPriority == bitcoin!.getLitecoinTransactionPrioritySlow(); default: return false; } @@ -220,8 +233,6 @@ abstract class ExchangeViewModelBase with Store { final SettingsStore _settingsStore; - final SettingsViewModel _settingsViewModel; - double _bestRate = 0.0; late Timer bestRateSync; @@ -296,12 +307,14 @@ abstract class ExchangeViewModelBase with Store { } Future _calculateBestRate() async { + final amount = double.tryParse(isFixedRateMode ? receiveAmount : depositAmount) ?? 1; + final result = await Future.wait( _tradeAvailableProviders .map((element) => element.calculateAmount( from: depositCurrency, to: receiveCurrency, - amount: 1, + amount: amount, isFixedRateMode: isFixedRateMode, isReceiveAmount: false)) ); @@ -311,7 +324,7 @@ abstract class ExchangeViewModelBase with Store { for (int i=0;i highestMax) { highestMax = tempLimits.max; @@ -360,7 +373,7 @@ abstract class ExchangeViewModelBase with Store { } } - if (lowestMin < double.maxFinite) { + if (lowestMin != double.maxFinite) { limits = Limits(min: lowestMin, max: highestMax); limitsState = LimitsLoadedSuccessfully(limits: limits); diff --git a/lib/view_model/node_list/node_create_or_edit_view_model.dart b/lib/view_model/node_list/node_create_or_edit_view_model.dart index 31b83faff..e24692059 100644 --- a/lib/view_model/node_list/node_create_or_edit_view_model.dart +++ b/lib/view_model/node_list/node_create_or_edit_view_model.dart @@ -18,7 +18,8 @@ abstract class NodeCreateOrEditViewModelBase with Store { address = '', port = '', login = '', - password = ''; + password = '', + trusted = false; @observable ExecutionState state; @@ -41,6 +42,9 @@ abstract class NodeCreateOrEditViewModelBase with Store { @observable bool useSSL; + @observable + bool trusted; + @computed bool get isReady => address.isNotEmpty && port.isNotEmpty; @@ -68,6 +72,7 @@ abstract class NodeCreateOrEditViewModelBase with Store { login = ''; password = ''; useSSL = false; + trusted = false; } @action @@ -76,7 +81,7 @@ abstract class NodeCreateOrEditViewModelBase with Store { state = IsExecutingState(); final node = Node(uri: uri, type: _wallet.type, login: login, password: password, - useSSL: useSSL); + useSSL: useSSL, trusted: trusted); await _nodeSource.add(node); state = ExecutedSuccessfullyState(); } catch (e) { diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index cdef6faba..25a5cc7ee 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -1,10 +1,10 @@ import 'package:cake_wallet/entities/balance_display_mode.dart'; +import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart'; import 'package:cw_core/transaction_priority.dart'; import 'package:cake_wallet/view_model/send/output.dart'; import 'package:cake_wallet/view_model/send/send_template_view_model.dart'; -import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/entities/template.dart'; @@ -42,7 +42,8 @@ abstract class SendViewModelBase with Store { : state = InitialExecutionState(), currencies = _wallet.balance.keys.toList(), selectedCryptoCurrency = _wallet.currency, - outputs = ObservableList() { + outputs = ObservableList(), + fiatFromSettings = _settingsStore.fiatCurrency { final priority = _settingsStore.priority[_wallet.type]; final priorities = priorityForWalletType(_wallet.type); @@ -52,7 +53,7 @@ abstract class SendViewModelBase with Store { outputs.add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency)); } - + @observable ExecutionState state; @@ -133,11 +134,13 @@ abstract class SendViewModelBase with Store { Validator get textValidator => TextValidator(); + final FiatCurrency fiatFromSettings; + @observable PendingTransaction? pendingTransaction; @computed - String get balance => balanceViewModel.availableBalance ?? '0.0'; + String get balance => balanceViewModel.availableBalance; @computed bool get isReadyForSend => _wallet.syncStatus is SyncedSyncStatus; @@ -166,6 +169,9 @@ abstract class SendViewModelBase with Store { bool get hasCurrecyChanger => walletType == WalletType.haven; + @computed + FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency; + final WalletBase _wallet; final SettingsStore _settingsStore; final SendTemplateViewModel sendTemplateViewModel; @@ -208,7 +214,7 @@ abstract class SendViewModelBase with Store { state = TransactionCommitting(); await pendingTransaction!.commit(); - if (pendingTransaction!.id?.isNotEmpty ?? false) { + if (pendingTransaction!.id.isNotEmpty) { _settingsStore.shouldSaveRecipientAddress ? await transactionDescriptionBox.add(TransactionDescription( id: pendingTransaction!.id, @@ -283,4 +289,12 @@ abstract class SendViewModelBase with Store { bool _isEqualCurrency(String currency) => currency.toLowerCase() == _wallet.currency.title.toLowerCase(); + + @action + void onClose() => + _settingsStore.fiatCurrency = fiatFromSettings; + + @action + void setFiatCurrency(FiatCurrency fiat) => + _settingsStore.fiatCurrency = fiat; } diff --git a/lib/view_model/settings/display_settings_view_model.dart b/lib/view_model/settings/display_settings_view_model.dart new file mode 100644 index 000000000..4e73b3399 --- /dev/null +++ b/lib/view_model/settings/display_settings_view_model.dart @@ -0,0 +1,57 @@ +import 'package:cake_wallet/entities/balance_display_mode.dart'; +import 'package:cake_wallet/entities/fiat_currency.dart'; +import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/themes/theme_base.dart'; +import 'package:mobx/mobx.dart'; + +part 'display_settings_view_model.g.dart'; + +class DisplaySettingsViewModel = DisplaySettingsViewModelBase with _$DisplaySettingsViewModel; + +abstract class DisplaySettingsViewModelBase with Store { + DisplaySettingsViewModelBase( + this._settingsStore, + ); + + final SettingsStore _settingsStore; + + @computed + FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency; + + @computed + String get languageCode => _settingsStore.languageCode; + + @computed + BalanceDisplayMode get balanceDisplayMode => _settingsStore.balanceDisplayMode; + + @computed + bool get shouldDisplayBalance => balanceDisplayMode == BalanceDisplayMode.displayableBalance; + + @computed + ThemeBase get theme => _settingsStore.currentTheme; + + @action + void setBalanceDisplayMode(BalanceDisplayMode value) => _settingsStore.balanceDisplayMode = value; + + @action + void setShouldDisplayBalance(bool value) { + if (value) { + _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance; + } else { + _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance; + } + } + + @action + void onLanguageSelected(String code) { + _settingsStore.languageCode = code; + } + + @action + void setTheme(ThemeBase newTheme) { + _settingsStore.currentTheme = newTheme; + } + + @action + void setFiatCurrency(FiatCurrency value) => _settingsStore.fiatCurrency = value; +} diff --git a/lib/view_model/settings/other_settings_view_model.dart b/lib/view_model/settings/other_settings_view_model.dart new file mode 100644 index 000000000..c57af50d9 --- /dev/null +++ b/lib/view_model/settings/other_settings_view_model.dart @@ -0,0 +1,64 @@ +import 'package:cake_wallet/bitcoin/bitcoin.dart'; +import 'package:cake_wallet/entities/priority_for_wallet_type.dart'; +import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cw_core/balance.dart'; +import 'package:cw_core/transaction_history.dart'; +import 'package:cw_core/transaction_info.dart'; +import 'package:cw_core/transaction_priority.dart'; +import 'package:cw_core/wallet_base.dart'; +import 'package:cw_core/wallet_type.dart'; +import 'package:mobx/mobx.dart'; +import 'package:package_info/package_info.dart'; + +part 'other_settings_view_model.g.dart'; + +class OtherSettingsViewModel = OtherSettingsViewModelBase with _$OtherSettingsViewModel; + +abstract class OtherSettingsViewModelBase with Store { + OtherSettingsViewModelBase(this._settingsStore, this._wallet) + : walletType = _wallet.type, + currentVersion = '' { + PackageInfo.fromPlatform() + .then((PackageInfo packageInfo) => currentVersion = packageInfo.version); + + final priority = _settingsStore.priority[_wallet.type]; + final priorities = priorityForWalletType(_wallet.type); + + if (!priorities.contains(priority)) { + _settingsStore.priority[_wallet.type] = priorities.first; + } + } + + final WalletType walletType; + final WalletBase, TransactionInfo> _wallet; + + @observable + String currentVersion; + + final SettingsStore _settingsStore; + + @computed + TransactionPriority get transactionPriority { + final priority = _settingsStore.priority[walletType]; + + if (priority == null) { + throw Exception('Unexpected type ${walletType.toString()}'); + } + + return priority; + } + + String getDisplayPriority(dynamic priority) { + final _priority = priority as TransactionPriority; + + if (_wallet.type == WalletType.bitcoin || _wallet.type == WalletType.litecoin) { + final rate = bitcoin!.getFeeRate(_wallet, _priority); + return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate); + } + + return priority.toString(); + } + + void onDisplayPrioritySelected(TransactionPriority priority) => + _settingsStore.priority[_wallet.type] = priority; +} diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart new file mode 100644 index 000000000..88311bf1f --- /dev/null +++ b/lib/view_model/settings/privacy_settings_view_model.dart @@ -0,0 +1,24 @@ +import 'package:cake_wallet/store/settings_store.dart'; +import 'package:mobx/mobx.dart'; + +part 'privacy_settings_view_model.g.dart'; + +class PrivacySettingsViewModel = PrivacySettingsViewModelBase with _$PrivacySettingsViewModel; + +abstract class PrivacySettingsViewModelBase with Store { + PrivacySettingsViewModelBase(this._settingsStore); + + final SettingsStore _settingsStore; + + @computed + bool get disableExchange => _settingsStore.disableExchange; + + @computed + bool get shouldSaveRecipientAddress => _settingsStore.shouldSaveRecipientAddress; + + @action + void setShouldSaveRecipientAddress(bool value) => _settingsStore.shouldSaveRecipientAddress = value; + + @action + void setEnableExchange(bool value) => _settingsStore.disableExchange = value; +} diff --git a/lib/view_model/settings/security_settings_view_model.dart b/lib/view_model/settings/security_settings_view_model.dart new file mode 100644 index 000000000..4a88b633f --- /dev/null +++ b/lib/view_model/settings/security_settings_view_model.dart @@ -0,0 +1,25 @@ +import 'package:cake_wallet/entities/biometric_auth.dart'; +import 'package:cake_wallet/store/settings_store.dart'; +import 'package:mobx/mobx.dart'; + +part 'security_settings_view_model.g.dart'; + +class SecuritySettingsViewModel = SecuritySettingsViewModelBase with _$SecuritySettingsViewModel; + +abstract class SecuritySettingsViewModelBase with Store { + SecuritySettingsViewModelBase(this._settingsStore) : _biometricAuth = BiometricAuth(); + + final BiometricAuth _biometricAuth; + final SettingsStore _settingsStore; + + @computed + bool get allowBiometricalAuthentication => _settingsStore.allowBiometricalAuthentication; + + @action + Future biometricAuthenticated() async { + return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated(); + } + + @action + void setAllowBiometricalAuthentication(bool value) => _settingsStore.allowBiometricalAuthentication = value; +} diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart deleted file mode 100644 index 96f11e82e..000000000 --- a/lib/view_model/settings/settings_view_model.dart +++ /dev/null @@ -1,239 +0,0 @@ -import 'package:cake_wallet/core/auth_service.dart'; -import 'package:cake_wallet/entities/pin_code_required_duration.dart'; -import 'package:cake_wallet/store/yat/yat_store.dart'; -import 'package:mobx/mobx.dart'; -import 'package:package_info/package_info.dart'; -import 'package:cw_core/wallet_base.dart'; -import 'package:cake_wallet/store/settings_store.dart'; -import 'package:cake_wallet/entities/biometric_auth.dart'; -import 'package:cw_core/wallet_type.dart'; -import 'package:cake_wallet/entities/balance_display_mode.dart'; -import 'package:cake_wallet/entities/fiat_currency.dart'; -import 'package:cw_core/node.dart'; -import 'package:cake_wallet/monero/monero.dart'; -import 'package:cake_wallet/haven/haven.dart'; -import 'package:cake_wallet/entities/action_list_display_mode.dart'; -import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cw_core/transaction_history.dart'; -import 'package:cw_core/balance.dart'; -import 'package:cw_core/transaction_info.dart'; -import 'package:cw_core/transaction_priority.dart'; -import 'package:cake_wallet/themes/theme_base.dart'; - -part 'settings_view_model.g.dart'; - -class SettingsViewModel = SettingsViewModelBase with _$SettingsViewModel; - -List priorityForWalletType(WalletType type) { - switch (type) { - case WalletType.monero: - return monero!.getTransactionPriorities(); - case WalletType.bitcoin: - return bitcoin!.getTransactionPriorities(); - case WalletType.litecoin: - return bitcoin!.getLitecoinTransactionPriorities(); - case WalletType.haven: - return haven!.getTransactionPriorities(); - default: - return []; - } -} - -abstract class SettingsViewModelBase with Store { - SettingsViewModelBase( - this._settingsStore, - this._yatStore, - this._authService, - WalletBase, - TransactionInfo> - wallet) - : itemHeaders = {}, - walletType = wallet.type, - _wallet = wallet, - _biometricAuth = BiometricAuth(), - currentVersion = '' { - PackageInfo.fromPlatform().then( - (PackageInfo packageInfo) => currentVersion = packageInfo.version); - - final priority = _settingsStore.priority[wallet.type]; - final priorities = priorityForWalletType(wallet.type); - - if (!priorities.contains(priority)) { - _settingsStore.priority[wallet.type] = priorities.first; - } - - //var connectYatUrl = YatLink.baseUrl + YatLink.signInSuffix; - //final connectYatUrlParameters = - // _yatStore.defineQueryParameters(); - - //if (connectYatUrlParameters.isNotEmpty) { - // connectYatUrl += YatLink.queryParameter + connectYatUrlParameters; - //} - - //var manageYatUrl = YatLink.baseUrl + YatLink.managePath; - //final manageYatUrlParameters = - // _yatStore.defineQueryParameters(); - - //if (manageYatUrlParameters.isNotEmpty) { - // manageYatUrl += YatLink.queryParameter + manageYatUrlParameters; - //} - - //var createNewYatUrl = YatLink.startFlowUrl; - //final createNewYatUrlParameters = - // _yatStore.defineQueryParameters(); - - //if (createNewYatUrlParameters.isNotEmpty) { - // createNewYatUrl += '?sub1=' + createNewYatUrlParameters; - //} - - } - - @observable - String currentVersion; - - @computed - Node get node => _settingsStore.getCurrentNode(walletType); - - @computed - FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency; - - @computed - PinCodeRequiredDuration get pinCodeRequiredDuration => - _settingsStore.pinTimeOutDuration; - - @computed - String get languageCode => _settingsStore.languageCode; - - @computed - ObservableList get actionlistDisplayMode => - _settingsStore.actionlistDisplayMode; - - @computed - TransactionPriority get transactionPriority { - final priority = _settingsStore.priority[walletType]; - - if (priority == null) { - throw Exception('Unexpected type ${walletType.toString()}'); - } - - return priority; - } - - @computed - BalanceDisplayMode get balanceDisplayMode => - _settingsStore.balanceDisplayMode; - - @computed - bool get shouldDisplayBalance => balanceDisplayMode == BalanceDisplayMode.displayableBalance; - - @computed - bool get shouldSaveRecipientAddress => - _settingsStore.shouldSaveRecipientAddress; - - @computed - bool get allowBiometricalAuthentication => - _settingsStore.allowBiometricalAuthentication; - - @computed - ThemeBase get theme => _settingsStore.currentTheme; - - bool get isBitcoinBuyEnabled => _settingsStore.isBitcoinBuyEnabled; - - final Map itemHeaders; - final SettingsStore _settingsStore; - final YatStore _yatStore; - final AuthService _authService; - final WalletType walletType; - final BiometricAuth _biometricAuth; - final WalletBase, - TransactionInfo> _wallet; - - @action - void setBalanceDisplayMode(BalanceDisplayMode value) => - _settingsStore.balanceDisplayMode = value; - - @action - void setFiatCurrency(FiatCurrency value) => - _settingsStore.fiatCurrency = value; - - @action - void setShouldSaveRecipientAddress(bool value) => - _settingsStore.shouldSaveRecipientAddress = value; - - @action - void setAllowBiometricalAuthentication(bool value) => - _settingsStore.allowBiometricalAuthentication = value; - - @action - void toggleTransactionsDisplay() => - actionlistDisplayMode.contains(ActionListDisplayMode.transactions) - ? _hideTransaction() - : _showTransaction(); - - @action - void toggleTradesDisplay() => - actionlistDisplayMode.contains(ActionListDisplayMode.trades) - ? _hideTrades() - : _showTrades(); - - @action - void _hideTransaction() => - actionlistDisplayMode.remove(ActionListDisplayMode.transactions); - - @action - void _hideTrades() => - actionlistDisplayMode.remove(ActionListDisplayMode.trades); - - @action - void _showTransaction() => - actionlistDisplayMode.add(ActionListDisplayMode.transactions); - - @action - void _showTrades() => actionlistDisplayMode.add(ActionListDisplayMode.trades); - - @action - Future biometricAuthenticated()async{ - return await _biometricAuth.canCheckBiometrics() && await _biometricAuth.isAuthenticated(); - } - - @action - void onLanguageSelected (String code) { - _settingsStore.languageCode = code; - } - - @action - void setTheme(ThemeBase newTheme){ - _settingsStore.currentTheme = newTheme; - } - - @action - void setShouldDisplayBalance(bool value){ - if (value) { - _settingsStore.balanceDisplayMode = BalanceDisplayMode.displayableBalance; - } else { - _settingsStore.balanceDisplayMode = BalanceDisplayMode.hiddenBalance; - } - } - - @action - setPinCodeRequiredDuration(PinCodeRequiredDuration duration) => - _settingsStore.pinTimeOutDuration = duration; - - String getDisplayPriority(dynamic priority) { - final _priority = priority as TransactionPriority; - - if (_wallet.type == WalletType.bitcoin - || _wallet.type == WalletType.litecoin) { - final rate = bitcoin!.getFeeRate(_wallet, _priority); - return bitcoin!.bitcoinTransactionPriorityWithLabel(_priority, rate); - } - - return priority.toString(); - } - - void onDisplayPrioritySelected(TransactionPriority priority) => - _settingsStore.priority[_wallet.type] = priority; - - bool checkPinCodeRiquired() => _authService.requireAuth(); - -} diff --git a/lib/view_model/transaction_details_view_model.dart b/lib/view_model/transaction_details_view_model.dart index 8992071fd..f8729715b 100644 --- a/lib/view_model/transaction_details_view_model.dart +++ b/lib/view_model/transaction_details_view_model.dart @@ -184,7 +184,7 @@ abstract class TransactionDetailsViewModelBase with Store { case WalletType.monero: return 'https://monero.com/tx/${txId}'; case WalletType.bitcoin: - return 'https://www.blockchain.com/btc/tx/${txId}'; + return 'https://mempool.space/tx/${txId}'; case WalletType.litecoin: return 'https://blockchair.com/litecoin/transaction/${txId}'; case WalletType.haven: @@ -199,7 +199,7 @@ abstract class TransactionDetailsViewModelBase with Store { case WalletType.monero: return S.current.view_transaction_on + 'Monero.com'; case WalletType.bitcoin: - return S.current.view_transaction_on + 'Blockchain.com'; + return S.current.view_transaction_on + 'mempool.space'; case WalletType.litecoin: return S.current.view_transaction_on + 'Blockchair.com'; case WalletType.haven: diff --git a/model_generator.sh b/model_generator.sh new file mode 100644 index 000000000..f4ef8bdad --- /dev/null +++ b/model_generator.sh @@ -0,0 +1,5 @@ +cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. +cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. +cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. +cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. +flutter packages pub run build_runner build --delete-conflicting-outputs \ No newline at end of file diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 8f211b102..07aa19549 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "GETRENNT", "sync_status_connecting" : "VERBINDEN", "sync_status_connected" : "VERBUNDEN", + "sync_status_attempting_sync" : "SYNC VERSUCHEN", "transaction_priority_slow" : "Langsam", @@ -436,6 +437,7 @@ "provider_error" : "${provider}-Fehler", "use_ssl" : "SSL verwenden", + "trusted" : "Vertrauenswürdige", "color_theme" : "Farbthema", "light_theme" : "Hell", @@ -652,6 +654,9 @@ "use_suggested": "Vorgeschlagen verwenden", "do_not_share_warning_text" : "Teilen Sie diese nicht mit anderen, einschließlich des Supports.\n\nSie werden Ihr Geld stehlen!", "help": "hilfe", + "connection_sync": "Verbindung und Synchronisierung", + "security_and_backup": "Sicherheit und Datensicherung", + "create_backup": "Backup erstellen", "privacy_settings": "Datenschutzeinstellungen", "privacy": "Datenschutz", "display_settings": "Anzeigeeinstellungen", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index b170316df..7e3f3c196 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "DISCONNECTED", "sync_status_connecting" : "CONNECTING", "sync_status_connected" : "CONNECTED", + "sync_status_attempting_sync" : "ATTEMPTING SYNC", "transaction_priority_slow" : "Slow", @@ -436,6 +437,7 @@ "provider_error" : "${provider} error", "use_ssl" : "Use SSL", + "trusted" : "Trusted", "color_theme" : "Color theme", "light_theme" : "Light", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 0d764e170..649231e77 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "DESCONECTADO", "sync_status_connecting" : "CONECTANDO", "sync_status_connected" : "CONECTADO", + "sync_status_attempting_sync" : "INTENTAR SINCRONIZAR", "transaction_priority_slow" : "Lento", @@ -436,6 +437,7 @@ "provider_error" : "${provider} error", "use_ssl" : "Utilice SSL", + "trusted" : "de confianza", "color_theme" : "Tema de color", "light_theme" : "Ligera", @@ -652,6 +654,9 @@ "use_suggested": "Usar sugerido", "do_not_share_warning_text" : "No comparta estos con nadie más, incluido el soporte.\n\n¡Te robarán tu dinero!", "help": "ayuda", + "connection_sync": "Conexión y sincronización", + "security_and_backup": "Seguridad y respaldo", + "create_backup": "Crear copia de seguridad", "privacy_settings": "Configuración de privacidad", "privacy": "Privacidad", "display_settings": "Configuración de pantalla", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 576ea91f8..47caa9617 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -354,6 +354,7 @@ "sync_status_failed_connect" : "DÉCONNECTÉ", "sync_status_connecting" : "CONNEXION EN COURS", "sync_status_connected" : "CONNECTÉ", + "sync_status_attempting_sync" : "TENTATIVE DE SYNCHRONISATION", "transaction_priority_slow" : "Lent", @@ -434,6 +435,7 @@ "provider_error" : "Erreur de ${provider}", "use_ssl" : "Utiliser SSL", + "trusted" : "de confiance", "color_theme" : "Thème", "light_theme" : "Clair", @@ -650,6 +652,9 @@ "use_suggested": "Utilisation suggérée", "do_not_share_warning_text" : "Ne les partagez avec personne d'autre, y compris avec l'assistance.\n\nIls vont voler votre argent!", "help": "aider", + "connection_sync": "Connexion et synchronisation", + "security_and_backup": "Sécurité et sauvegarde", + "create_backup": "Créer une sauvegarde", "privacy_settings": "Paramètres de confidentialité", "privacy": "Confidentialité", "display_settings": "Paramètres d'affichage", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index af5ce56dc..be00ba7ef 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "डिस्कनेक्ट किया गया", "sync_status_connecting" : "कनेक्ट", "sync_status_connected" : "जुड़े हुए", + "sync_status_attempting_sync" : "सिंक करने का प्रयास", "transaction_priority_slow" : "धीरे", @@ -436,6 +437,7 @@ "provider_error" : "${provider} त्रुटि", "use_ssl" : "उपयोग SSL", + "trusted" : "भरोसा", "color_theme" : "रंग विषय", "light_theme" : "रोशनी", @@ -652,6 +654,9 @@ "use_suggested": "सुझाए गए का प्रयोग करें", "do_not_share_warning_text" : "इन्हें समर्थन सहित किसी और के साथ साझा न करें।\n\nवे आपका पैसा चुरा लेंगे!", "help": "मदद करना", + "connection_sync": "कनेक्शन और सिंक", + "security_and_backup": "सुरक्षा और बैकअप", + "create_backup": "बैकअप बनाएँ", "privacy_settings": "गोपनीयता सेटिंग्स", "privacy": "गोपनीयता", "display_settings": "प्रदर्शन सेटिंग्स", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 7b160bf8d..115f2f3fc 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "ISKLJUČENO", "sync_status_connecting" : "SPAJANJE", "sync_status_connected" : "SPOJENO", + "sync_status_attempting_sync" : "POKUŠAJ SINKRONIZACIJE", "transaction_priority_slow" : "Sporo", @@ -436,6 +437,7 @@ "provider_error" : "${provider} greška", "use_ssl" : "Koristi SSL", + "trusted" : "vjerovao", "color_theme" : "Shema boja", "light_theme" : "Svijetla", @@ -652,6 +654,9 @@ "use_suggested": "Koristite predloženo", "do_not_share_warning_text" : "Nemojte ih dijeliti ni s kim, uključujući podršku.\n\nUkrast će vam novac!", "help": "pomozite", + "connection_sync": "Povezivanje i sinkronizacija", + "security_and_backup": "Sigurnost i sigurnosna kopija", + "create_backup": "Stvori sigurnosnu kopiju", "privacy_settings": "Postavke privatnosti", "privacy": "Privatnost", "display_settings": "Postavke zaslona", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 229a69f75..fffc765aa 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "DISCONNESSO", "sync_status_connecting" : "CONNESSIONE", "sync_status_connected" : "CONNESSO", + "sync_status_attempting_sync" : "TENTATIVO DI SINCRONIZZAZIONE", "transaction_priority_slow" : "Bassa", @@ -436,6 +437,7 @@ "provider_error" : "${provider} errore", "use_ssl" : "Usa SSL", + "trusted" : "di fiducia", "color_theme" : "Colore tema", "light_theme" : "Bianco", @@ -652,6 +654,9 @@ "use_suggested": "Usa suggerito", "do_not_share_warning_text" : "Non condividerli con nessun altro, incluso il supporto.\n\nTi ruberanno i soldi!", "help": "aiuto", + "connection_sync": "Connessione e sincronizzazione", + "security_and_backup": "Sicurezza e backup", + "create_backup": "Crea backup", "privacy_settings": "Impostazioni privacy", "privacy": "Privacy", "display_settings": "Impostazioni di visualizzazione", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index da1dfb708..bec36d01e 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "切断されました", "sync_status_connecting" : "接続中", "sync_status_connected" : "接続済み", + "sync_status_attempting_sync" : "同期を試みています", "transaction_priority_slow" : "スロー", @@ -436,6 +437,7 @@ "provider_error" : "${provider} エラー", "use_ssl" : "SSLを使用する", + "trusted" : "信頼できる", "color_theme" : "カラーテーマ", "light_theme" : "光", @@ -652,6 +654,9 @@ "use_suggested": "推奨を使用", "do_not_share_warning_text" : "サポートを含め、これらを他の誰とも共有しないでください。\n\n彼らはあなたのお金を盗みます!", "help": "ヘルプ", + "connection_sync": "接続と同期", + "security_and_backup": "セキュリティとバックアップ", + "create_backup": "バックアップを作成", "privacy_settings": "プライバシー設定", "privacy": "プライバシー", "display_settings": "表示設定", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 5e835a29b..89c1df817 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "연결 해제", "sync_status_connecting" : "연결 중", "sync_status_connected" : "연결됨", + "sync_status_attempting_sync" : "동기화 시도 중", "transaction_priority_slow" : "느린", @@ -436,6 +437,7 @@ "provider_error" : "${provider} 오류", "use_ssl" : "SSL 사용", + "trusted" : "신뢰할 수 있는", "color_theme" : "색상 테마", "light_theme" : "빛", @@ -652,6 +654,9 @@ "use_suggested": "추천 사용", "do_not_share_warning_text" : "지원을 포함하여 다른 사람과 이러한 정보를 공유하지 마십시오.\n\n그들은 당신의 돈을 훔칠 것입니다!", "help": "돕다", + "connection_sync": "연결 및 동기화", + "security_and_backup": "보안 및 백업", + "create_backup": "백업 생성", "privacy_settings": "개인정보 설정", "privacy": "프라이버시", "display_settings": "디스플레이 설정", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 059bb27dc..636993d52 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "LOSGEKOPPELD", "sync_status_connecting" : "AANSLUITING", "sync_status_connected" : "VERBONDEN", + "sync_status_attempting_sync" : "SYNCHRONISATIE PROBEREN", "transaction_priority_slow" : "Langzaam", @@ -436,6 +437,7 @@ "provider_error" : "${provider} fout", "use_ssl" : "Gebruik SSL", + "trusted" : "vertrouwd", "color_theme" : "Kleur thema", "light_theme" : "Licht", @@ -652,6 +654,9 @@ "use_suggested": "Gebruik aanbevolen", "do_not_share_warning_text" : "Deel deze met niemand anders, ook niet met support.\n\nZe zullen je geld stelen!", "help": "helpen", + "connection_sync": "Verbinding en synchronisatie", + "security_and_backup": "Beveiliging en back-up", + "create_backup": "Maak een back-up", "privacy_settings": "Privacy-instellingen", "privacy": "Privacy", "display_settings": "Weergave-instellingen", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 68d8595b0..6a61cd368 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "NIEPOWIĄZANY", "sync_status_connecting" : "ZŁĄCZONY", "sync_status_connected" : "POŁĄCZONY", + "sync_status_attempting_sync" : "PRÓBA SYNCHRONIZACJI", "transaction_priority_slow" : "Powolny", @@ -436,6 +437,7 @@ "provider_error" : "${provider} pomyłka", "use_ssl" : "Użyj SSL", + "trusted" : "zaufany", "color_theme" : "Motyw kolorystyczny", "light_theme" : "Lekki", @@ -652,6 +654,9 @@ "use_suggested": "Użyj sugerowane", "do_not_share_warning_text" : "Nie udostępniaj ich nikomu innemu, w tym wsparcia.\n\nUkradną twoje pieniądze!", "help": "pomoc", + "connection_sync": "Połączenie i synchronizacja", + "security_and_backup": "Bezpieczeństwo i kopia zapasowa", + "create_backup": "Utwórz kopię zapasową", "privacy_settings": "Ustawienia prywatności", "privacy": "Prywatność", "display_settings": "Ustawienia wyświetlania", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 6f8eb5f64..41a235e33 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "DESCONECTADO", "sync_status_connecting" : "CONECTANDO", "sync_status_connected" : "CONECTADO", + "sync_status_attempting_sync" : "TENTANDO SINCRONIZAR", "transaction_priority_slow" : "Lenta", @@ -436,6 +437,7 @@ "provider_error" : "${provider} erro", "use_ssl" : "Use SSL", + "trusted" : "confiável", "color_theme" : "Tema de cor", "light_theme" : "Luz", @@ -544,7 +546,6 @@ "create_account": "Criar conta", "privacy_policy": "Política de privacidade", "welcome_to_cakepay": "Bem-vindo ao Cake Pay!", - "create_account": "Registar-se", "forgot_password": "Esqueci a senha", "reset_password": "Redefinir senha", "gift_cards": "Cartões de presente", @@ -652,6 +653,9 @@ "use_suggested": "Uso sugerido", "do_not_share_warning_text" : "Não os compartilhe com mais ninguém, incluindo suporte.\n\nEles vão roubar seu dinheiro!", "help": "ajuda", + "connection_sync": "Conexão e sincronização", + "security_and_backup": "Segurança e backup", + "create_backup": "Criar backup", "privacy_settings": "Configurações de privacidade", "privacy": "Privacidade", "display_settings": "Configurações de exibição", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 9b2691ad7..76a10750a 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "ОТКЛЮЧЕНО", "sync_status_connecting" : "ПОДКЛЮЧЕНИЕ", "sync_status_connected" : "ПОДКЛЮЧЕНО", + "sync_status_attempting_sync" : "ПОПЫТКА СИНХРОНИЗАЦИИ", "transaction_priority_slow" : "Медленный", @@ -436,6 +437,7 @@ "provider_error" : "${provider} ошибка", "use_ssl" : "Использовать SSL", + "trusted" : "доверенный", "color_theme" : "Цветовая тема", "light_theme" : "Светлая", @@ -652,6 +654,9 @@ "use_suggested": "Использовать предложенный", "do_not_share_warning_text" : "Не делитесь ими с кем-либо еще, в том числе со службой поддержки.\n\nОни украдут ваши деньги!", "help": "помощь", + "connection_sync": "Подключение и синхронизация", + "security_and_backup": "Безопасность и резервное копирование", + "create_backup": "Создать резервную копию", "privacy_settings": "Настройки конфиденциальности", "privacy": "Конфиденциальность", "display_settings": "Настройки отображения", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 97e7362d1..215e003c0 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -355,6 +355,7 @@ "sync_status_failed_connect" : "ВІДКЛЮЧЕНО", "sync_status_connecting" : "ПІДКЛЮЧЕННЯ", "sync_status_connected" : "ПІДКЛЮЧЕНО", + "sync_status_attempting_sync" : "СПРОБА СИНХРОНІЗАЦІЇ", "transaction_priority_slow" : "Повільний", @@ -435,6 +436,7 @@ "provider_error" : "${provider} помилка", "use_ssl" : "Використати SSL", + "trusted" : "довіряють", "color_theme" : "Кольорова тема", "light_theme" : "Світла", @@ -651,6 +653,9 @@ "use_suggested": "Використати запропоноване", "do_not_share_warning_text" : "Не повідомляйте їх нікому, включно зі службою підтримки.\n\nВони вкрадуть ваші гроші!", "help": "допомога", + "connection_sync": "Підключення та синхронізація", + "security_and_backup": "Безпека та резервне копіювання", + "create_backup": "Створити резервну копію", "privacy_settings": "Налаштування конфіденційності", "privacy": "Конфіденційність", "display_settings": "Налаштування дисплея", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 2e07983f4..a3bb9af88 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -356,6 +356,7 @@ "sync_status_failed_connect" : "断线", "sync_status_connecting" : "连接中", "sync_status_connected" : "已连接", + "sync_status_attempting_sync" : "嘗試同步", "transaction_priority_slow" : "慢速", @@ -435,6 +436,7 @@ "provider_error" : "${provider} 错误", "use_ssl" : "使用SSL", + "trusted" : "值得信赖", "color_theme" : "主题", "light_theme" : "艳丽", @@ -650,6 +652,9 @@ "use_suggested": "使用建议", "do_not_share_warning_text" : "不要與其他任何人分享這些內容,包括支持。\n\n他們會偷你的錢!", "help": "帮助", + "connection_sync": "连接和同步", + "security_and_backup": "安全和备份", + "create_backup": "创建备份", "privacy_settings": "隐私设置", "privacy":"隐私", "display_settings": "显示设置",